Skip to content

Commit 37a107e

Browse files
authored
Document new source finding behaviour (#9923)
This should cover the current state on master, as previously discussed / implemented across #9742, #9683, #9632, #9616, #9614, etc. This will need to be changed if we can make `--namespace-packages` the default (#9636). I haven't documented some of the finer points of the changes, since it felt like an inappropriate level of detail (e.g. using absolute paths when crawling, how directories with invalid package names affect crawling, etc) Co-authored-by: hauntsaninja <>
1 parent fffbe88 commit 37a107e

File tree

2 files changed

+71
-44
lines changed

2 files changed

+71
-44
lines changed

docs/source/command_line.rst

+12-4
Original file line numberDiff line numberDiff line change
@@ -110,10 +110,18 @@ imports.
110110
passed on the command line, the ``MYPYPATH`` environment variable,
111111
and the :confval:`mypy_path` config option.
112112

113-
Note that this only affects import discovery -- for modules and
114-
packages explicitly passed on the command line, mypy still
115-
searches for ``__init__.py[i]`` files in order to determine the
116-
fully-qualified module/package name.
113+
This flag affects how mypy finds modules and packages explicitly passed on
114+
the command line. It also affects how mypy determines fully qualified module
115+
names for files passed on the command line. See :ref:`Mapping file paths to
116+
modules <mapping-paths-to-modules>` for details.
117+
118+
.. option:: --explicit-package-bases
119+
120+
This flag tells mypy that top-level packages will be based in either the
121+
current directory, or a member of the ``MYPYPATH`` environment variable or
122+
:confval:`mypy_path` config option. This option is only useful in
123+
conjunction with :option:`--namespace-packages`. See :ref:`Mapping file
124+
paths to modules <mapping-paths-to-modules>` for details.
117125

118126
.. option:: --ignore-missing-imports
119127

docs/source/running_mypy.rst

+59-40
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,11 @@ actual way mypy type checks your code, see our
2424
Specifying code to be checked
2525
*****************************
2626

27-
Mypy lets you specify what files it should type check in several
28-
different ways.
27+
Mypy lets you specify what files it should type check in several different ways.
28+
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>`.
2932

3033
1. First, you can pass in paths to Python files and directories you
3134
want to type check. For example::
@@ -336,58 +339,79 @@ while this option can be quite powerful, it can also cause many
336339
hard-to-debug errors.
337340

338341

339-
340342
.. _mapping-paths-to-modules:
341343

342344
Mapping file paths to modules
343345
*****************************
344346

345-
One of the main ways you can tell mypy what files to type check
346-
is by providing mypy the paths to those files. For example::
347+
One of the main ways you can tell mypy what to type check
348+
is by providing mypy a list of paths. For example::
347349

348350
$ mypy file_1.py foo/file_2.py file_3.pyi some/directory
349351

350352
This section describes how exactly mypy maps the provided paths
351353
to modules to type check.
352354

353-
- Files ending in ``.py`` (and stub files ending in ``.pyi``) are
354-
checked as Python modules.
355+
- Mypy will check all paths provided that correspond to files.
356+
357+
- Mypy will recursively discover and check all files ending in ``.py`` or
358+
``.pyi`` in directory paths provided.
359+
360+
- For each file to be checked, mypy will attempt to associate the file (e.g.
361+
``project/foo/bar/baz.py``) with a fully qualified module name (e.g.
362+
``foo.bar.baz``). The directory the package is in (``project``) is then
363+
added to mypy's module search paths.
355364

356-
- Files not ending in ``.py`` or ``.pyi`` are assumed to be Python
357-
scripts and checked as such.
365+
How mypy determines fully qualified module names depends on if the options
366+
:option:`--namespace-packages <mypy --namespace-packages>` and
367+
:option:`--explicit-package-bases <mypy --explicit-package-bases>` are set.
358368

359-
- Directories representing Python packages (i.e. containing a
360-
``__init__.py[i]`` file) are checked as Python packages; all
361-
submodules and subpackages will be checked (subpackages must
362-
themselves have a ``__init__.py[i]`` file).
369+
1. If :option:`--namespace-packages <mypy --namespace-packages>` is off,
370+
mypy will rely solely upon the presence of ``__init__.py[i]`` files to
371+
determine the fully qualified module name. That is, mypy will crawl up the
372+
directory tree for as long as it continues to find ``__init__.py`` (or
373+
``__init__.pyi``) files.
363374

364-
- Directories that don't represent Python packages (i.e. not directly
365-
containing an ``__init__.py[i]`` file) are checked as follows:
375+
For example, if your directory tree consists of ``pkg/subpkg/mod.py``, mypy
376+
would require ``pkg/__init__.py`` and ``pkg/subpkg/__init__.py`` to exist in
377+
order correctly associate ``mod.py`` with ``pkg.subpkg.mod``
366378

367-
- All ``*.py[i]`` files contained directly therein are checked as
368-
toplevel Python modules;
379+
2. If :option:`--namespace-packages <mypy --namespace-packages>` is on, but
380+
:option:`--explicit-package-bases <mypy --explicit-package-bases>` is off,
381+
mypy will allow for the possibility that directories without
382+
``__init__.py[i]`` are packages. Specifically, mypy will look at all parent
383+
directories of the file and use the location of the highest
384+
``__init__.py[i]`` in the directory tree to determine the top-level package.
369385

370-
- All packages contained directly therein (i.e. immediate
371-
subdirectories with an ``__init__.py[i]`` file) are checked as
372-
toplevel Python packages.
386+
For example, say your directory tree consists solely of ``pkg/__init__.py``
387+
and ``pkg/a/b/c/d/mod.py``. When determining ``mod.py``'s fully qualified
388+
module name, mypy will look at ``pkg/__init__.py`` and conclude that the
389+
associated module name is ``pkg.a.b.c.d.mod``.
373390

374-
One more thing about checking modules and packages: if the directory
375-
*containing* a module or package specified on the command line has an
376-
``__init__.py[i]`` file, mypy assigns these an absolute module name by
377-
crawling up the path until no ``__init__.py[i]`` file is found.
391+
3. You'll notice that the above case still relies on ``__init__.py``. If
392+
you can't put an ``__init__.py`` in your top-level package, but still wish to
393+
pass paths (as opposed to packages or modules using the ``-p`` or ``-m``
394+
flags), :option:`--explicit-package-bases <mypy --explicit-package-bases>`
395+
provides a solution.
378396

379-
For example, suppose we run the command ``mypy foo/bar/baz.py`` where
380-
``foo/bar/__init__.py`` exists but ``foo/__init__.py`` does not. Then
381-
the module name assumed is ``bar.baz`` and the directory ``foo`` is
382-
added to mypy's module search path.
397+
With :option:`--explicit-package-bases <mypy --explicit-package-bases>`, mypy
398+
will locate the nearest parent directory that is a member of the ``MYPYPATH``
399+
environment variable, the :confval:`mypy_path` config or is the current
400+
working directory. mypy will then use the relative path to determine the
401+
fully qualified module name.
383402

384-
On the other hand, if ``foo/bar/__init__.py`` did not exist, ``foo/bar``
385-
would be added to the module search path instead, and the module name
386-
assumed is just ``baz``.
403+
For example, say your directory tree consists solely of
404+
``src/namespace_pkg/mod.py``. If you run the command following command, mypy
405+
will correctly associate ``mod.py`` with ``namespace_pkg.mod``::
387406

388-
If a script (a file not ending in ``.py[i]``) is processed, the module
389-
name assumed is ``__main__`` (matching the behavior of the
390-
Python interpreter), unless :option:`--scripts-are-modules <mypy --scripts-are-modules>` is passed.
407+
$ MYPYPATH=src mypy --namespace-packages --explicit-package-bases .
408+
409+
If you pass a file not ending in ``.py[i]``, the module name assumed is
410+
``__main__`` (matching the behavior of the Python interpreter), unless
411+
:option:`--scripts-are-modules <mypy --scripts-are-modules>` is passed.
412+
413+
Passing :option:`-v <mypy -v>` will show you the files and associated module
414+
names that mypy will check.
391415

392416

393417
.. _finding-imports:
@@ -407,7 +431,7 @@ This is computed from the following items:
407431
(a colon-separated list of directories).
408432
- The :confval:`mypy_path` config file option.
409433
- The directories containing the sources given on the command line
410-
(see below).
434+
(see :ref:`Mapping file paths to modules <mapping-paths-to-modules>`).
411435
- The installed packages marked as safe for type checking (see
412436
:ref:`PEP 561 support <installed-packages>`)
413437
- The relevant directories of the
@@ -418,11 +442,6 @@ This is computed from the following items:
418442
You cannot point to a :pep:`561` package via the ``MYPYPATH``, it must be
419443
installed (see :ref:`PEP 561 support <installed-packages>`)
420444

421-
For sources given on the command line, the path is adjusted by crawling
422-
up from the given file or package to the nearest directory that does not
423-
contain an ``__init__.py`` or ``__init__.pyi`` file. If the given path
424-
is relative, it will only crawl as far as the current working directory.
425-
426445
Second, mypy searches for stub files in addition to regular Python files
427446
and packages.
428447
The rules for searching for a module ``foo`` are as follows:

0 commit comments

Comments
 (0)