Skip to content

Commit aa947e2

Browse files
authored
Make --namespace-packages the default (#9636)
1 parent 027c58a commit aa947e2

9 files changed

+40
-50
lines changed

docs/source/command_line.rst

+13-19
Original file line numberDiff line numberDiff line change
@@ -129,30 +129,12 @@ Import discovery
129129
The following flags customize how exactly mypy discovers and follows
130130
imports.
131131

132-
.. option:: --namespace-packages
133-
134-
This flag enables import discovery to use namespace packages (see
135-
:pep:`420`). In particular, this allows discovery of imported
136-
packages that don't have an ``__init__.py`` (or ``__init__.pyi``)
137-
file.
138-
139-
Namespace packages are found (using the PEP 420 rules, which
140-
prefers "classic" packages over namespace packages) along the
141-
module search path -- this is primarily set from the source files
142-
passed on the command line, the ``MYPYPATH`` environment variable,
143-
and the :confval:`mypy_path` config option.
144-
145-
This flag affects how mypy finds modules and packages explicitly passed on
146-
the command line. It also affects how mypy determines fully qualified module
147-
names for files passed on the command line. See :ref:`Mapping file paths to
148-
modules <mapping-paths-to-modules>` for details.
149-
150132
.. option:: --explicit-package-bases
151133

152134
This flag tells mypy that top-level packages will be based in either the
153135
current directory, or a member of the ``MYPYPATH`` environment variable or
154136
:confval:`mypy_path` config option. This option is only useful in
155-
conjunction with :option:`--namespace-packages`. See :ref:`Mapping file
137+
in the absence of `__init__.py`. See :ref:`Mapping file
156138
paths to modules <mapping-paths-to-modules>` for details.
157139

158140
.. option:: --ignore-missing-imports
@@ -236,6 +218,18 @@ imports.
236218
setting the :option:`--fast-module-lookup` option.
237219

238220

221+
.. option:: --no-namespace-packages
222+
223+
This flag disables import discovery of namespace packages (see :pep:`420`).
224+
In particular, this prevents discovery of packages that don't have an
225+
``__init__.py`` (or ``__init__.pyi``) file.
226+
227+
This flag affects how mypy finds modules and packages explicitly passed on
228+
the command line. It also affects how mypy determines fully qualified module
229+
names for files passed on the command line. See :ref:`Mapping file paths to
230+
modules <mapping-paths-to-modules>` for details.
231+
232+
239233
.. _platform-configuration:
240234

241235
Platform configuration

docs/source/config_file.rst

+4-3
Original file line numberDiff line numberDiff line change
@@ -254,10 +254,11 @@ section of the command line docs.
254254
.. confval:: namespace_packages
255255

256256
:type: boolean
257-
:default: False
257+
:default: True
258258

259259
Enables :pep:`420` style namespace packages. See the
260-
corresponding flag :option:`--namespace-packages <mypy --namespace-packages>` for more information.
260+
corresponding flag :option:`--no-namespace-packages <mypy --no-namespace-packages>`
261+
for more information.
261262

262263
This option may only be set in the global section (``[mypy]``).
263264

@@ -269,7 +270,7 @@ section of the command line docs.
269270
This flag tells mypy that top-level packages will be based in either the
270271
current directory, or a member of the ``MYPYPATH`` environment variable or
271272
:confval:`mypy_path` config option. This option is only useful in
272-
conjunction with :confval:`namespace_packages`. See :ref:`Mapping file
273+
the absence of `__init__.py`. See :ref:`Mapping file
273274
paths to modules <mapping-paths-to-modules>` for details.
274275

275276
This option may only be set in the global section (``[mypy]``).

docs/source/running_mypy.rst

+9-17
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,6 @@ Specifying code to be checked
2626

2727
Mypy lets you specify what files it should type check in several different ways.
2828

29-
Note that if you use namespace packages (in particular, packages without
30-
``__init__.py``), you'll need to specify :option:`--namespace-packages <mypy
31-
--namespace-packages>`.
32-
3329
1. First, you can pass in paths to Python files and directories you
3430
want to type check. For example::
3531

@@ -322,11 +318,6 @@ this error, try:
322318
you must run ``mypy ~/foo-project/src`` (or set the ``MYPYPATH`` to
323319
``~/foo-project/src``.
324320

325-
4. If you are using namespace packages -- packages which do not contain
326-
``__init__.py`` files within each subfolder -- using the
327-
:option:`--namespace-packages <mypy --namespace-packages>` command
328-
line flag.
329-
330321
In some rare cases, you may get the "Cannot find implementation or library
331322
stub for module" error even when the module is installed in your system.
332323
This can happen when the module is both missing type hints and is installed
@@ -423,10 +414,10 @@ to modules to type check.
423414
added to mypy's module search paths.
424415

425416
How mypy determines fully qualified module names depends on if the options
426-
:option:`--namespace-packages <mypy --namespace-packages>` and
417+
:option:`--no-namespace-packages <mypy --no-namespace-packages>` and
427418
:option:`--explicit-package-bases <mypy --explicit-package-bases>` are set.
428419

429-
1. If :option:`--namespace-packages <mypy --namespace-packages>` is off,
420+
1. If :option:`--no-namespace-packages <mypy --no-namespace-packages>` is set,
430421
mypy will rely solely upon the presence of ``__init__.py[i]`` files to
431422
determine the fully qualified module name. That is, mypy will crawl up the
432423
directory tree for as long as it continues to find ``__init__.py`` (or
@@ -436,12 +427,13 @@ How mypy determines fully qualified module names depends on if the options
436427
would require ``pkg/__init__.py`` and ``pkg/subpkg/__init__.py`` to exist in
437428
order correctly associate ``mod.py`` with ``pkg.subpkg.mod``
438429

439-
2. If :option:`--namespace-packages <mypy --namespace-packages>` is on, but
440-
:option:`--explicit-package-bases <mypy --explicit-package-bases>` is off,
441-
mypy will allow for the possibility that directories without
442-
``__init__.py[i]`` are packages. Specifically, mypy will look at all parent
443-
directories of the file and use the location of the highest
444-
``__init__.py[i]`` in the directory tree to determine the top-level package.
430+
2. The default case. If :option:`--namespace-packages <mypy
431+
--no-namespace-packages>` is on, but :option:`--explicit-package-bases <mypy
432+
--explicit-package-bases>` is off, mypy will allow for the possibility that
433+
directories without ``__init__.py[i]`` are packages. Specifically, mypy will
434+
look at all parent directories of the file and use the location of the
435+
highest ``__init__.py[i]`` in the directory tree to determine the top-level
436+
package.
445437

446438
For example, say your directory tree consists solely of ``pkg/__init__.py``
447439
and ``pkg/a/b/c/d/mod.py``. When determining ``mod.py``'s fully qualified

mypy/build.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -1401,8 +1401,8 @@ def validate_meta(
14011401
st = manager.get_stat(path)
14021402
except OSError:
14031403
return None
1404-
if not (stat.S_ISREG(st.st_mode) or stat.S_ISDIR(st.st_mode)):
1405-
manager.log(f"Metadata abandoned for {id}: file {path} does not exist")
1404+
if not stat.S_ISDIR(st.st_mode) and not stat.S_ISREG(st.st_mode):
1405+
manager.log(f"Metadata abandoned for {id}: file or directory {path} does not exist")
14061406
return None
14071407

14081408
manager.add_stats(validate_stat_time=time.time() - t0)

mypy/main.py

+3-2
Original file line numberDiff line numberDiff line change
@@ -544,8 +544,9 @@ def add_invertible_flag(
544544
title="Import discovery", description="Configure how imports are discovered and followed."
545545
)
546546
add_invertible_flag(
547-
"--namespace-packages",
548-
default=False,
547+
"--no-namespace-packages",
548+
dest="namespace_packages",
549+
default=True,
549550
help="Support namespace packages (PEP 420, __init__.py-less)",
550551
group=imports_group,
551552
)

mypy/options.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ def __init__(self) -> None:
9595
# This allows definitions of packages without __init__.py and allows packages to span
9696
# multiple directories. This flag affects both import discovery and the association of
9797
# input files/modules/packages to the relevant file and fully qualified module name.
98-
self.namespace_packages = False
98+
self.namespace_packages = True
9999
# Use current directory and MYPYPATH to determine fully qualified module names of files
100100
# passed by automatically considering their subdirectories as packages. This is only
101101
# relevant if namespace packages are enabled, since otherwise examining __init__.py's is

test-data/unit/check-modules.test

+3-2
Original file line numberDiff line numberDiff line change
@@ -2665,12 +2665,13 @@ from foo.bar import x
26652665
x = 0
26662666

26672667
[case testClassicNotPackage]
2668+
# flags: --no-namespace-packages
26682669
from foo.bar import x
26692670
[file foo/bar.py]
26702671
x = 0
26712672
[out]
2672-
main:1: error: Cannot find implementation or library stub for module named "foo.bar"
2673-
main:1: note: See https://mypy.readthedocs.io/en/stable/running_mypy.html#missing-imports
2673+
main:2: error: Cannot find implementation or library stub for module named "foo.bar"
2674+
main:2: note: See https://mypy.readthedocs.io/en/stable/running_mypy.html#missing-imports
26742675

26752676
[case testNamespacePackage]
26762677
# flags: --namespace-packages

test-data/unit/fine-grained-modules.test

+1-1
Original file line numberDiff line numberDiff line change
@@ -845,7 +845,7 @@ main:2: error: Argument 1 to "f" has incompatible type "int"; expected "str"
845845
==
846846
main:1: error: Cannot find implementation or library stub for module named "p.a"
847847
main:1: note: See https://mypy.readthedocs.io/en/stable/running_mypy.html#missing-imports
848-
main:1: error: Cannot find implementation or library stub for module named "p"
848+
main:2: error: "object" has no attribute "a"
849849

850850
[case testDeletePackage2]
851851
import p

test-data/unit/semanal-errors.test

+4-3
Original file line numberDiff line numberDiff line change
@@ -316,15 +316,16 @@ x = y
316316
tmp/k.py:2: error: Name "y" is not defined
317317

318318
[case testPackageWithoutInitFile]
319+
# flags: --no-namespace-packages
319320
import typing
320321
import m.n
321322
m.n.x
322323
[file m/n.py]
323324
x = 1
324325
[out]
325-
main:2: error: Cannot find implementation or library stub for module named "m.n"
326-
main:2: note: See https://mypy.readthedocs.io/en/stable/running_mypy.html#missing-imports
327-
main:2: error: Cannot find implementation or library stub for module named "m"
326+
main:3: error: Cannot find implementation or library stub for module named "m.n"
327+
main:3: note: See https://mypy.readthedocs.io/en/stable/running_mypy.html#missing-imports
328+
main:3: error: Cannot find implementation or library stub for module named "m"
328329

329330
[case testBreakOutsideLoop]
330331
break

0 commit comments

Comments
 (0)