Skip to content

Enable strict optional by default - #4971

Merged
JukkaL merged 3 commits into
masterfrom
strict-optional-on
Apr 26, 2018
Merged

JukkaL merged 3 commits into
masterfrom
strict-optional-on

Conversation

@JukkaL

@JukkaL JukkaL commented Apr 25, 2018

Copy link
Copy Markdown
Collaborator

As an exception, tests still don't do this since there are
hundreds of tests that would have to be updated. If tests
explicitly define command line options, strict optional will
be on by default -- basically command line options in tests
default to --no-strict-optional.

Fixes #359.

As an exception, tests still don't do this since there are
hundreds of tests that would have to be updated. If tests
explicitly define command line options, strict optional will
be on by default -- basically command line options in tests
default to `--no-strict-optional`.

Fixes #359.

@ilevkivskyi ilevkivskyi left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, looks good! Just some optional comments.


If you don't know what types to add, you can use ``Any``, but beware:

- **One of the values involved has type ``Any``.** Extending the above

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you can do something like **Text** ``Any`` **more text**. Then you will have both bold face and proper formatting for Any. (also below for None)

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good idea, I'll give it a try.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd just write 'Any'

Comment thread docs/source/kinds_of_types.rst Outdated
.. note::

``None`` is also used as the return type for functions that don't
return a value, i.e. that implicitly return ``None``. (Mypy doesn't

@ilevkivskyi ilevkivskyi Apr 25, 2018 •

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PEP 484 already specifies this, I am not sure we need to discuss this here again (on the other hand there was a recent issue that proposed to improve some wording there).

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you expect mypy users to read through PEP 484 (which is rather long and complex)? Especially for a fairly basic thing like this.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd like the mypy documentation to be self-contained and PEP 484 should be strictly optional reading.

@ilevkivskyi ilevkivskyi Apr 25, 2018 •

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Then I would reformulate this to make message more clear. Currently it starts from mentioning return type, but then moves to something else. Also I would not mention NoneType at all, it can only add to the confusion, I would just re-iterate that for simplicity None in type context means a type with a single value None. And separately mention that Python (this is not specific to mypy) returns None from a function that either reaches its end without return statement, or has a bare return.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, NoneType never works in annotations. (Nor does type(None).) NoneType isn't even defined in the stdlib.

Comment thread runtests.py
if f == os.path.join('test-data', 'samples', 'crawl2.py'):
# This test requires 3.5 for async functions
driver.add_mypy_cmd('file {}'.format(f), ['--python-version=3.5', f])
driver.add_mypy_cmd('file {}'.format(f), ['--python-version=3.5',

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not sure we actually need the --python-version=3.5 flag. I thought mypy now uses the latest Python version by default.

@emmatyping emmatyping Apr 25, 2018 •

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unless I missed a PR, mypy uses the Python version uses sys.version_info of the executable used to run mypy, which still may be 3.4.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed, I was confused that the Python 3.6 syntax can be used in 2.7 stubs.


If you don't know what types to add, you can use ``Any``, but beware:

- **One of the values involved has type ``Any``.** Extending the above

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd just write 'Any'

:ref:`optional` for details on strict optional checking, which allows mypy to
check ``None`` values precisely, and will soon become default.
You may have disabled strict optional checking (see
:ref:`no_strict_optional` for more).

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if we should have a bullet for complaints about None as well. It will be a common issue for people who have used mypy with the default setting (for strict_optional anyway) before.

generally check the use of ``None`` values -- they are valid
everywhere. See :ref:`strict_optional` for more about this feature.
This flag will become the default in the near future.
everywhere. See :ref:`no_strict_optional` for more about this feature.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe mention that the default changed in mypy 0.600, like you do in the config file section about strict_optional.

Comment thread docs/source/config_file.rst Outdated

- ``strict_optional`` (Boolean, default True) enables or disables
strict Optional checks. If False, mypy treats ``None`` as
compatible with every type. This was False by default in mypy

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

**NOTE:** This was False ...

doesn't treat primitives types
specially: ``None`` is also valid for primitive types such as ``int``
and ``float``.
You can use the ``Optional`` type modifier to define a type variant

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd start (redundantly) by noting that this is on by default as of 0.600.

Comment thread docs/source/kinds_of_types.rst Outdated

``Optional[...]`` *does not* mean a function argument with a default value.
However, if the default value of an argument is ``None``, you can use
an optional type for the argument.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe make this stronger? There's a flag --no-implicit-optional that requires using Optional[] here, and there's talk of deprecating the default behavior altogether.

Comment thread docs/source/kinds_of_types.rst Outdated

x = inc(None) # No error reported by mypy!

In mypy versions before 0.600 this was the default mode, and if you

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Move this up?

Comment thread docs/source/revision_history.rst Outdated
* Publish ``mypy-lang`` version 0.4.3 on PyPI.

* Add :ref:`strict_optional`.
* Add ``--strict-optional``.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add link to chapter.

Comment thread mypy/main.py
parser.add_argument('--strict-optional', action='store_true',
help=argparse.SUPPRESS)
parser.add_argument('--no-strict-optional', action='store_false', dest='strict_optional',
help="disable strict Optional checks (inverse: --no-strict-optional)")

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the inverse should be --strict-optional? Also can't this use add_invertible_flag()?

Comment thread runtests.py
if modules:
driver.add_mypy_modules('stdlibsamples (%s)' % (version,), modules,
cwd=stdlibsamples_dir)
cwd=stdlibsamples_dir, extra_args=['--no-strict-optional'])

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add the TODO here too?

@JukkaL
JukkaL merged commit c2bdbae into master Apr 26, 2018
JukkaL added a commit that referenced this pull request Apr 26, 2018
Forgot to add these changes to #4971.
gvanrossum pushed a commit that referenced this pull request Apr 26, 2018
@gvanrossum
gvanrossum deleted the strict-optional-on branch April 26, 2018 15:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants