Skip to content

Not finding attributes within __init__ modules when nested under a namespace package #5854

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
basicdays opened this issue Oct 29, 2018 · 9 comments

Comments

@basicdays
Copy link

  • Are you reporting a bug, or opening a feature request?
    Bug
  • What are the versions of mypy and Python you are using?
    0.641
    Do you see the same issue after installing mypy from Git master?
    I haven't tried the master branch yet, I certainly can if folks would like me to.

Currently I have a structure similar to this:

namespace_package/
    package1/
        __init__.py  (Contains relative imports to .moduleA)
        moduleA.py
    package2/
        __init__.py
        moduleB.py
setup.cfg

Let's also say I have some relative imports in namespace_package.package1.__init__ that imports from moduleA.

If I don't have any mypy settings, and run mypy namespace_package, things seem to work fine. If I add namespace_packages = True to setup.cfg, then it seems all the imports that were done in namespace_package.package1.__init__.py seem to fail.

I figured if I attempt to instead do mypy -p namespace_package, that mypy might be able to correctly figure out the relative imports, but I seem to be getting a message that its can't find the package namespace_package. Same message if I try mypy -p namespace_package.package2. I see this is referenced in issue #5759. I'm guessing these two might be related?

I think I'm also finding that having [mypy-namespace-package.*] in setup.cfg isn't having much of an effect when I'm not using namespace_packages = True. I could probably report this one in a separate issue if folks would like me to.

@gvanrossum
Copy link
Member

What exactly is the form of the relative imports you have, and what exactly is the error?

@basicdays
Copy link
Author

Ok, my apologizes, I went through and tested to make sure I can exactly reproduce the error in a simplified environment. I've committed a simple example of code here: https://github.com/basicdays/mypy_test

To reproduce, I've been running pipenv run mypy namespace_package. The output is as follows:

namespace_package/package2/__init__.py:1: error: Module 'namespace_package.package1' has no attribute 'add_stuff'

I wanted to narrow down exactly what causes the error. It seems mypy is not picking up any module exports within __init__.py modules that are nested under a namespace package. Whether or not the __init__ modules are using relative imports don't seem to make a difference.

It also currently seems to work if I reference a re-export from another module that is not the __init__. For example, if I have namespace_package.package1.module_a, and namespace_package.package1.module_b, and I re-export a function from module_a in module_b.

Just to clarify my first comment on this issue thread, not having namespace_packages = True causes nothing to be found as expected. I was confused earlier since I also had ignore_missing_imports = True, which masked that issue.

@basicdays basicdays changed the title Issues with relative imports in namespace packages Not finding attributes within __init__ modules when nested under a namespace package Oct 29, 2018
@basicdays
Copy link
Author

Also just to add, if I add a stubbed __init__.py file directly to namespace_package, then everything works as expected.

@rafales
Copy link

rafales commented Nov 30, 2018

I'm running into the same problem, although with a little bit different setup:

src
├── graphql
│   ├── setup.py
│   └── nspkg
│       └── graphql
│           └── __init__.py
└── pytools
    ├── setup.py
    └── nspkg
        └── pytools
            ├── __init__.py
            └── pytools_test.py

I have some problems even figuring out how to run mypy in such monorepo setup. I ended up with something that should work:

MYPYPATH=./src/pytools mypy --namespace-packages src/graphql/nspkg

but I end up with the following error:

src/graphql/nspkg/graphql/__init__.py:3: error: Module 'nspkg.pytools' has no attribute 'map_list'

mypy 0.641

@rafales
Copy link

rafales commented Nov 30, 2018

@basicdays
There is a work around: place empty py.typed files inside package1 and package2 but there is a gotcha: make sure that those packages' names do not conflict with anything that is installed globally.

Then you can run mypy namespace_package/*

@rafales
Copy link

rafales commented Dec 4, 2018

@basicdays I started working on namespace packages support. I'll contribute this to mypy when it's in better shape, but currently it should work for your setup.

Make sure that your namespace package is in python path and you'll be able to run mypy --namespace-packages some-folder/. Here's repo: https://github.com/rafales/mypy/tree/namespace-packages

@basicdays
Copy link
Author

@rafales Awesome! I'll have to try that out and see what happens when I get the opportunity to.

@bwahlgreen
Copy link

It looks like I'm currently running into this issue. @rafales I already have an empty py.typed inside my sub-package, nested under a namespace-package. Was/is there any resolution to this issue? I'm happy to provide more information regarding my particular setup, if need be.

awelzel added a commit to awelzel/mypy that referenced this issue Jun 30, 2019
…e package

When used with --namespace-packages, a directory containing no __init__.pyi
file was previously added as a candidate to near_misses even if it contains
a __init__.py file. This logic is doesn't seem sensible, particularly as
the this directory was then chosen as the result instead of __init__.py
inside the directory.

Add a number of "unit tests" to verify FindModuleCache.find_module() using
a sample directory structure under `test-data/packages` as well.

This should cure python#5854.
awelzel added a commit to awelzel/mypy that referenced this issue Jun 30, 2019
…ckage

When used with --namespace-packages, a directory containing no __init__.pyi
was previously added as a candidate to near_misses even if it contained
a __init__.py. This logic doesn't seem sensible, particularly as this
directory was then chosen as the result of find_module() instead of
the __init__.py inside the directory.

This should cure python#5854.
@awelzel
Copy link
Contributor

awelzel commented Jun 30, 2019

We're running into the same issue and had a look. It seems like a simple bug in the FindModuleCache class - see #7108 for the fix and number of tests.

I tried @rafales test at https://github.com/basicdays/mypy_test and it works correctly after the fix.

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

5 participants