Skip to content

'from .foo import *' introduces 'foo' as symbol that mypy doesn't recognise #4140

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

Closed
Wilfred opened this issue Oct 20, 2017 · 11 comments
Closed

Comments

@Wilfred
Copy link

Wilfred commented Oct 20, 2017

The typeshed definition for yaml/__init__.pyi contains the following (src):

from yaml.error import *

This has two side effects: it adds every symbol foo in yaml/error.py as yaml.foo. However, it also defines yaml.error.

I believe this is why the mypy complains about the following correct code:

import yaml

def foo():
    # type: () -> None
    yaml.error
$ mypy --py2 foo.py
foo.py:5: error: Module has no attribute "error"

Oddly, I can't reproduce this on Python 3. The following code does not produce a type error:

import yaml

def foo() -> None:
    yaml.error
@gvanrossum
Copy link
Member

gvanrossum commented Oct 20, 2017 via email

@Wilfred
Copy link
Author

Wilfred commented Oct 23, 2017

I can reproduce this on both mypy 0.530 and 0.540. I don't have a mypy.ini.

$ cat example.py
import yaml

def foo():
    # type: () -> None
    yaml.error
$ mypy --py2 example.py
example.py:5: error: Module has no attribute "error"

@gvanrossum
Copy link
Member

I still can't repro it. I wonder... Do you have a file named yaml.py in your current directory or in your $PYTHONPATH?

@Wilfred
Copy link
Author

Wilfred commented Oct 24, 2017

Nope, empty directory and PYTHONPATH isn't set.

$ ls -a
./  ../  example.py

$ cat example.py
import yaml

def foo():
    # type: () -> None
    yaml.error

$ mypy --py2 example.py
example.py:5: error: Module has no attribute "error"

$ echo $PYTHONPATH

$ mypy --version
mypy 0.540

I'm using mypy in a Conda environment on OS X. I don't have yaml or pyyaml installed in that environment.

Interestingly, I can't reproduce this with pyvenv:

$ python3.6 -m venv myenv
$ source ./myenv/bin/activate

$ pip install mypy
Collecting mypy
  Using cached mypy-0.540-py3-none-any.whl
Collecting typed-ast<1.2.0,>=1.1.0 (from mypy)
  Using cached typed_ast-1.1.0-cp36-cp36m-macosx_10_11_x86_64.whl
Installing collected packages: typed-ast, mypy
Successfully installed mypy-0.540 typed-ast-1.1.0

$ mypy --py2 example.py

@ilevkivskyi
Copy link
Member

Then it means this is a broken installation with old typeshed, try installing with --no-cache or similar, see #3768

@gvanrossum
Copy link
Member

@Wilfred If Ivan's suggestion works, I would love to understand how your system got into this state (and what exactly that state was -- seems an old typeshed is taking precedence over the correct one). Perhaps before deleting anything could you run mypy -v -2 example.py for me? That should show where the yaml.pyi file lives. Then can you confirm that the various import * line in its __init__.py are commented out? See python/typeshed#1439.

@Wilfred
Copy link
Author

Wilfred commented Oct 27, 2017

Running mypy with -v:

$ mypy -v -2 example.py
LOG:  Mypy version 0.540
LOG:  Metadata not found for example
LOG:  Parsing example.py (example)
LOG:  Metadata not found for yaml
LOG:  Parsing /Users/whughes/miniconda2/envs/scratch3/lib/mypy/typeshed/third_party/2/yaml/__init__.pyi (yaml)
LOG:  Metadata not found for builtins
LOG:  Parsing /Users/whughes/miniconda2/envs/scratch3/lib/mypy/typeshed/stdlib/2/__builtin__.pyi (builtins)
LOG:  Metadata not found for typing
LOG:  Parsing /Users/whughes/miniconda2/envs/scratch3/lib/mypy/typeshed/stdlib/2/typing.pyi (typing)
LOG:  Metadata not found for abc
LOG:  Parsing /Users/whughes/miniconda2/envs/scratch3/lib/mypy/typeshed/stdlib/2/abc.pyi (abc)
LOG:  Metadata not found for mypy_extensions
LOG:  Parsing /Users/whughes/miniconda2/envs/scratch3/lib/mypy/typeshed/third_party/2and3/mypy_extensions.pyi (mypy_extensions)
LOG:  Metadata not found for types
LOG:  Parsing /Users/whughes/miniconda2/envs/scratch3/lib/mypy/typeshed/stdlib/2/types.pyi (types)
LOG:  Metadata not found for collections
LOG:  Parsing /Users/whughes/miniconda2/envs/scratch3/lib/mypy/typeshed/stdlib/2/collections.pyi (collections)
LOG:  Metadata not found for _weakrefset
LOG:  Parsing /Users/whughes/miniconda2/envs/scratch3/lib/mypy/typeshed/stdlib/2/_weakrefset.pyi (_weakrefset)
LOG:  Loaded graph with 9 nodes
LOG:  Found 3 SCCs; largest has 7 nodes
LOG:  Processing SCC of size 7 (types mypy_extensions abc typing _weakrefset collections builtins) as inherently stale
LOG:  Writing types /Users/whughes/miniconda2/envs/scratch3/lib/mypy/typeshed/stdlib/2/types.pyi .mypy_cache/2.7/types.meta.json .mypy_cache/2.7/types.data.json
LOG:  Cached module types has changed interface
LOG:  Writing mypy_extensions /Users/whughes/miniconda2/envs/scratch3/lib/mypy/typeshed/third_party/2and3/mypy_extensions.pyi .mypy_cache/2.7/mypy_extensions.meta.json .mypy_cache/2.7/mypy_extensions.data.json
LOG:  Cached module mypy_extensions has changed interface
LOG:  Writing abc /Users/whughes/miniconda2/envs/scratch3/lib/mypy/typeshed/stdlib/2/abc.pyi .mypy_cache/2.7/abc.meta.json .mypy_cache/2.7/abc.data.json
LOG:  Cached module abc has changed interface
LOG:  Writing typing /Users/whughes/miniconda2/envs/scratch3/lib/mypy/typeshed/stdlib/2/typing.pyi .mypy_cache/2.7/typing.meta.json .mypy_cache/2.7/typing.data.json
LOG:  Cached module typing has changed interface
LOG:  Writing _weakrefset /Users/whughes/miniconda2/envs/scratch3/lib/mypy/typeshed/stdlib/2/_weakrefset.pyi .mypy_cache/2.7/_weakrefset.meta.json .mypy_cache/2.7/_weakrefset.data.json
LOG:  Cached module _weakrefset has changed interface
LOG:  Writing collections /Users/whughes/miniconda2/envs/scratch3/lib/mypy/typeshed/stdlib/2/collections.pyi .mypy_cache/2.7/collections.meta.json .mypy_cache/2.7/collections.data.json
LOG:  Cached module collections has changed interface
LOG:  Writing builtins /Users/whughes/miniconda2/envs/scratch3/lib/mypy/typeshed/stdlib/2/__builtin__.pyi .mypy_cache/2.7/builtins.meta.json .mypy_cache/2.7/builtins.data.json
LOG:  Cached module builtins has changed interface
LOG:  Processing SCC singleton (yaml) as inherently stale with stale deps (builtins typing)
LOG:  Writing yaml /Users/whughes/miniconda2/envs/scratch3/lib/mypy/typeshed/third_party/2/yaml/__init__.pyi .mypy_cache/2.7/yaml/__init__.meta.json .mypy_cache/2.7/yaml/__init__.data.json
LOG:  Cached module yaml has changed interface
LOG:  Processing SCC singleton (example) as inherently stale with stale deps (builtins yaml)
LOG:  Deleting example /Users/whughes/tmp/example.py .mypy_cache/2.7/example.meta.json .mypy_cache/2.7/example.data.json
LOG:  No fresh SCCs left in queue
LOG:  Build finished in 0.517 seconds with 9 modules, 1385 types, and 1 errors
example.py:5: error: Module has no attribute "error"

@Wilfred
Copy link
Author

Wilfred commented Oct 27, 2017

This rather looks like it's using a copy of typeshed from inside mypy itself. Are there any other tests you'd like me to run?

@Wilfred
Copy link
Author

Wilfred commented Oct 27, 2017

The typeshed inside my conda env does indeed have yaml/error.pyi:

~/miniconda2/envs/scratch3/lib/mypy/typeshed/third_party/2and3/yaml
$ ls
__init__.pyi  constructor.pyi  emitter.pyi  events.pyi  nodes.pyi   reader.pyi       resolver.pyi  serializer.pyi
composer.pyi  dumper.pyi       error.pyi    loader.pyi  parser.pyi  representer.pyi  scanner.pyi   tokens.pyi

~/miniconda2/envs/scratch3/lib/mypy/typeshed/third_party/2/yaml
$ ls
__init__.pyi  constructor.pyi  emitter.pyi  events.pyi  nodes.pyi   reader.pyi       resolver.pyi  serializer.pyi
composer.pyi  dumper.pyi       error.pyi    loader.pyi  parser.pyi  representer.pyi  scanner.pyi   tokens.pyi

I've also confirmed that creating a fresh conda env does not reproduce this issue.

@gvanrossum
Copy link
Member

So does Ivan's suggestion solve your problem or not?

The key bit of information is whether yaml/init.pyi contains a from errors import * that's not commented-out. In older typeshed versions it was commented out -- uncommenting it caused the error object to appear upon mere import of yaml. (Emulating the behavior of yaml at runtime.)

If you really can't fix this problem in your environment, a workaround is to add import yaml.error to your code. That should work in all environments.

@Wilfred
Copy link
Author

Wilfred commented Jan 19, 2018

I'm not sure how my conda environment got into this state, so I'm going to close this. If I encounter it again, I'll reopen with reproduction steps.

I'm happily using mypy in other virtualenvs/conda environments.

@Wilfred Wilfred closed this as completed Jan 19, 2018
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

No branches or pull requests

3 participants