Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

mypy errors with suggested tomli/tomllib compatibility layer #219

Closed
JonathonReinhart opened this issue Apr 17, 2023 · 2 comments · Fixed by #220
Closed

mypy errors with suggested tomli/tomllib compatibility layer #219

JonathonReinhart opened this issue Apr 17, 2023 · 2 comments · Fixed by #220
Labels
enhancement New feature or request

Comments

@JonathonReinhart
Copy link

Hello, I'm attempting to write forward-looking code which uses the documented tomli/tomllib compatibility layer:

try:
    import tomllib
except ModuleNotFoundError:
    import tomli as tomllib

result = tomllib.loads("")
reveal_type(result)

When I check this code with mypy, I am met with the following errors:
(Python 3.10.9, mypy 0.991)

$ mypy example.py
example.py:2: error: Cannot find implementation or library stub for module named "tomllib"  [import]
example.py:2: note: See https://mypy.readthedocs.io/en/stable/running_mypy.html#missing-imports
example.py:4: error: Name "tomllib" already defined (possibly by an import)  [no-redef]
example.py:7: note: Revealed type is "Any"
Found 2 errors in 1 file (checked 1 source file
  • Line 2: The tomllib import error is expected since I am running Python 3.10 (and it was added to the standard lib in 3.11). This is resolved by ignoring the import error.

  • Line 4: The Name "tomllib" already defined error is resolved by upgrading to mypy 1.2.0 or ingoring the redef error.

try:
    import tomllib  # type: ignore[import]
except ModuleNotFoundError:
    import tomli as tomllib  # type: ignore[no-redef]

result = tomllib.loads("")
reveal_type(result)
$ mypy example.py
example.py:7: note: Revealed type is "Any"
Success: no issues found in 1 source file
  • Line 7: This is the unfortunate part. When using the prescribed pattern, tomllib is Any, so all functions and their return values are Any as well.

When the compatibility layer is not used, the typing is correctly provided (presumably via typeshed, although I can't find it?)

import tomli
reveal_type(tomli)

result = tomli.loads("")
reveal_type(result)
$ mypy example_nolayer.py
example_nolayer.py:2: note: Revealed type is "types.ModuleType"
example_nolayer.py:5: note: Revealed type is "builtins.dict[builtins.str, Any]"

Is this a limitation of mypy that we have to live with, or can the pattern be somehow updated to resolve these issues?

@hauntsaninja
Copy link
Collaborator

Try:

if sys.version_info >= (3, 11):
    import tomllib
else:
    import tomli as tomllib

hauntsaninja added a commit that referenced this issue Apr 17, 2023
Fixes #219

Static type checkers are able to understand checks against sys.version_info much better than try-except. In general, if type checkers tried to handle conditional imports fancily, this would result in unsoundness.

Another reason is that you may have tomli conditionally installed based on Python version, in which case a type checker would not even have a way of knowing what tomli is.
@encukou
Copy link
Collaborator

encukou commented Apr 18, 2023

This sounds like a bug in mypy: python/mypy#13914

hukkin added a commit that referenced this issue Dec 12, 2023
* Use sys.version_info in compatibility layer

Fixes #219

Static type checkers are able to understand checks against sys.version_info much better than try-except. In general, if type checkers tried to handle conditional imports fancily, this would result in unsoundness.

Another reason is that you may have tomli conditionally installed based on Python version, in which case a type checker would not even have a way of knowing what tomli is.

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Taneli Hukkinen <[email protected]>
@hukkin hukkin added the enhancement New feature or request label Oct 21, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants