Closed
Labels
false-positivemypy gave an error on correct codemypy gave an error on correct codefeaturepriority-0-high
Description
Take this directory tree:
/path/to/src
└───namespace
└───package
│ __init__.py
│
└───__pycache__
__init__.cpython-35.pyc
And this MYPYPATH:
> $env:MYPYPATH
/path/to/src
then running mypy -p namespace.package gives:
> mypy -p namespace.package
Can't find package 'namespace.package'
However, mypy works fine when you add an empty __init__.py into namepace (turning it into a regular package).
Reacted by David Jetelina, Michael Bull, Stefano Mazzucco, Alexey Strokach, Cam Cope, Gilbert Gilb's, Ziyad Edher, Austin Pray, Hunt Zhan, Max Sistemich and 6 more
Metadata
Metadata
Assignees
Labels
false-positivemypy gave an error on correct codemypy gave an error on correct codefeaturepriority-0-high
Activity
[-]MYPYPATCH doesn't respect PEP420 namespace packages[/-][+]MYPYPATH doesn't respect PEP420 namespace packages[/+]gvanrossum commentedon Jun 4, 2016
I know... I'm not sure what to do about this. The algorithm from PEP 420 is quite complex (namespace packages are only considered if no "classic" package or module is found). The workaround of adding a dummy
__init__.pyis simple enough (you could also have a dummy__init__.pyiso that Python is not affected by this file).I also expect that usually you'd want to create a separate set of stubs rather than type-check the original source code (though obviously this may vary per package).
djetelina commentedon May 21, 2017
I'd like to bump this. In future, there will be python programmers who never heard of pre PEP420 era of
__init__.pyand that's good. What's not good is mypy forcing them to create dummy files.agronholm commentedon May 21, 2017
It might get the ball rolling if somebody explained why this is such a big problem for mypy.
agronholm commentedon May 21, 2017
I just bumped into Jukka Lehtosalo and he said there shouldn't be any major issue blocking this. But given the easy workaround that exists for this, it'll likely require an outsider to write a PR.
gvanrossum commentedon May 21, 2017
This issue is more complex than you think.
djetelina commentedon May 21, 2017
I don't think it's trivial, I've read your previous comment - so I don't even think I'd be able to write a PR. I just think it's an issue worth looking into eventually
richardmss commentedon Jul 27, 2017
I'm working on a project with a directory structure like the following:
Note that both, a and b, contain a subfolder called c. Adding an
__init__everywhere defines some modules multiple times (the actual project contains dozens folders) and things get hairy. Any progress on this issue would be much appreciated.gvanrossum commentedon Jul 27, 2017
I presume you mean in each
cfolder but not inaorbright? Socis a namespace package and you have bothaandbinPYTHONPATHorsys.path. (And when running mypy, you pass it bothaandb, which will have the same effect -- or perhaps you pass it their parent directory or the current directory.)With that setup, I agree you have a predicament. We will have to support namespace packages in mypy. At the very least it should be possible to do something like setting
MYPYPATH=a:band then runmypy -m cand have it find both parts ofc.carljm commentedon Nov 26, 2017
Just a philosophical note here that might influence the way mypy handles this: in my experience in a Py3-only world, packages without
__init__.pyare not a special edge case for namespace packages, they are the default case. It's pretty unreasonable to expect a new Py3 developer to remember to drop empty__init__.pyturds everywhere when their code demonstrably runs perfectly fine without them. It's hard to even make a sensible case in code review for why they should add__init__.py(other than "it's the way we've always done things in the old world, get off my lawn" or "the typechecker is buggy and won't find your code without it.") The presence of__init__.pybecomes the special case, used only when you need some package-level code or imports.This reversal may not have been an intended consequence of PEP 420, but AFAICS it's an inevitable one.
gvanrossum commentedon Nov 26, 2017
carljm commentedon Nov 26, 2017
Certainly possible. I'd be curious to hear from another Py3-only culture
which (convincing to new Python 3 developers) arguments are used in
favor of continuing the tradition of empty
__init__.pyfiles. I'm notaware of a strong practical argument that can be made for them, but if
I'm missing a good one I may start using it ;)
18 remaining items
gvanrossum commentedon Mar 13, 2019
Yeah, that's why we eventually implemented
mypy --namespace-packages.nicktimko commentedon May 29, 2019
And for those that stumble on this issue via Google, that flag was added in 0.640, so make sure you're on that or later, then use the aforementioned
--namespace-packagesargument (permalink)warsaw commentedon Aug 19, 2019
FYI. For completeness, I'll mention that I recently realized that my patch only works for the top level namespace package. It doesn't help traversing in to nested sub-namespace packages. That doesn't affect us in practice so I'm not motivated to fix it.
lynn-ca commentedon Mar 10, 2020
It is the year 2020. Python 3 is the only supported major release of Python. Is using the non-default
--namespace-packagesflag still the recommended solution?As a creator of various namespaced packages targeted for Python 3, this requires users of my packages to set this flag to get any type information out of my packages (requiring them to somehow know that my package is a namespace package, carrying all this baggage). Also as a developer of these packages, getting the
__init__.pyialternative to work inbdist_wheelseems downright impossible with Python 3, so I'm having a hard time building something that works on the major supported platform using a major supported feature in what is a pure python package.I would open a PR to change the default but given the discussion here, the decision appears a lot more nuanced and personal than I currently understand, and I do not wish to upset the maintainers.
ErwanDL commentedon Mar 14, 2020
I hope that I am not unaware of some context around this issue, but I agree with @nickroeker that it would make sense for the
--namespace-packagesflag to be the default behaviour for mypy, especially as the current behaviour is really confusing for Py3-only users like myself.I very recently stumbled into an issue (#8497) that I believe was due to this (adding the
--namespace-packagesflag solved it), and being a "relatively new" Python user that has never used Python 2, I had a very confusing time understanding why I was expected to add an empty __init__.py in a namespace package for mypy to work.Is the main obstacle to making this behaviour default the need for retrocompatibility with Python 2 ?
JukkaL commentedon Mar 20, 2020
Enabling support for namespace packages by default in Python 3 mode sounds like a good thing. Would somebody create a new issue about it? I haven't looked into this in detail, but we might need to fix some issues with namespace package support first.
ErwanDL commentedon Mar 20, 2020
I can create an issue this afternoon 👍
russelldavis commentedon Mar 30, 2020
Here's the issue that proposes supporting this by default: #8584
(Thanks @JukkaL -- I am very much in favor of the proposal.)
static: mypy requires __init__.py
static: mypy requires __init__.py (#3027)
aloosley commentedon Jul 6, 2020
I'm confused because I still get the same error when running
mypy --namespace-packages .at the root of my repo that doesn't have a py file (mypy 0.782, python 3.7.7):So what exactly is the work-around if --namespace-packages doesn't work?
I have several python packages I want to check under the root folder as well various folders and subfolders with python files.
I'm probably missing something simple and dumb. Thanks for the help.
lynn-ca commentedon Jul 6, 2020
@aloosley It's been a while so I'm not honestly sure anymore, but I think for
--namespace-packagesto work you may still need apy.typedfile in the right place. I think the right place for that is in the non-namespace folders. For example, if you have packagecompany.service, theservice/folder would need apy.typedfile.Aside from that, I find I generally need to run
mypyfrom the outside. So instead of being incompany/and runningmypy ./, go up a directory and runmypy company/.csymeonides-mf commentedon Feb 1, 2021
@aloosley @nickroeker alternatively you can use the
-parg, this worked for me (note that you can specify either a package or a directory, not both):hauntsaninja commentedon Feb 1, 2021
The behaviour is buggy in mypy v0.790 and earlier, this should be fixed in v0.800