pytype icon indicating copy to clipboard operation
pytype copied to clipboard

pytype gets the wrong import when __init__ collides with file

Open vuryleo opened this issue 5 years ago • 4 comments

assume we have a project like this

- /lib
  - __init__.py
  - m.py
- main.py

and in m.py

def m():
    return None

in __init__.py

from .m import m

and finally in main.py

from lib import m  # <-- the m here should refer to lib/__init__.m, which is a function

print(m())  # <- prints 'None'

However, pytype will think the m is lib/m which is an module, and report

pytype-single --imports_info [redacted]/pytype_output/imports/main.imports --module-name a -V 3.5 -o [redacted]/pytype_output/pyi/main.pyi --analyze-annotated --nofail --quick [redacted]/main.py
File "[redacted]/main.py", line 3, in <module>: 'lib.m' object is not callable [not-callable]

vuryleo avatar Mar 19 '19 05:03 vuryleo

Hmm, when I look at pytype_outpyt/pyi, I see that pytype has generated a type stub for lib.m but not lib.__init__. And indeed, importlab main.py --tree yields:

Source tree:
+ main.py
      lib/m.py

So the problem is that pytype isn't generating a stub for the __init__ file because importlab only lists the submodule as a dependency, leading to pytype not being able to see the variable in __init__ that shadows the submodule name. The fix is probably to always add the __init__ file as a dependency, although it's unclear whether that should be done in importlab or pytype.

In the meantime, a workaround would be to change main.py to do:

import lib
print(lib.m())

which causes the right dependencies to be found.

rchen152 avatar Mar 19 '19 21:03 rchen152

Wondering if the following issue is related:

import jwt

token_data = jwt.decode('token', 'key')

works as expected. But adding an import for a jwt submodules breaks:

import jwt
import jwt.exceptions

token_data = jwt.decode('token', 'key')
# No attribute 'decode' on module 'jwt' [module-attr]

encode and decode are imported in __init__ from another submodule:

from .api_jwt import (
    encode, decode, register_algorithm, unregister_algorithm,
    get_unverified_header, PyJWT
)

FlorianLudwig avatar Jun 16 '19 14:06 FlorianLudwig

@FlorianLudwig That looks like it's probably a different bug, since encode and decode aren't the names of submodules. Could you open a new issue and also describe what your pytype configuration looks like?

rchen152 avatar Jun 17 '19 21:06 rchen152

Hi there, any update ? Would that bug be corrected in the next version ?

qgallouedec avatar Oct 12 '21 17:10 qgallouedec