Skip to content

Commit 44fb9f5

Browse files
author
hauntsaninja
committed
Document new source finding behaviour
This should cover the current state on master, as previously discussed / implemented across python#9742, python#9683, python#9632, python#9616, python#9614, etc. This will need to be changed if we can make `--namespace-packages` the default (python#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)
1 parent 734e4ad commit 44fb9f5

File tree

2 files changed

+65
-44
lines changed

2 files changed

+65
-44
lines changed

docs/source/command_line.rst

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -110,10 +110,17 @@ 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 also affects how mypy determines fully qualified module names for
114+
files, modules and packages explicitly passed on the command line. See
115+
:ref:`Mapping file paths to modules <mapping-paths-to-modules>` for details.
116+
117+
.. option:: --explicit-package-bases
118+
119+
This flag tells mypy to that the current directory, the ``MYPYPATH``
120+
environment variable, and the :confval:`mypy_path` config option as the
121+
directories in which top-level packages are located. This option is only
122+
useful in conjunction with :option:`--namespace-packages`. See :ref:`Mapping
123+
file paths to modules <mapping-paths-to-modules>` for details.
117124

118125
.. option:: --ignore-missing-imports
119126

docs/source/running_mypy.rst

Lines changed: 54 additions & 40 deletions
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,74 @@ 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.
355359

356-
- Files not ending in ``.py`` or ``.pyi`` are assumed to be Python
357-
scripts and checked as such.
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+
add to mypy's module search paths.
358364

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).
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.
363368

364-
- Directories that don't represent Python packages (i.e. not directly
365-
containing an ``__init__.py[i]`` file) are checked as follows:
369+
First, if :option:`--namespace-packages <mypy --namespace-packages>` is off,
370+
mypy will rely solely upon the presence of ``__init__.py[i]`` files to determine
371+
the fully qualified module name. That is, mypy will crawl up the directory tree
372+
for as long as it continues to find ``__init__.py`` (or ``__init__.pyi``) files.
366373

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

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

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.
386+
You'll notice that that method still relies on ``__init__.py``. If you can't put
387+
an ``__init__.py`` in your top-level package, but still wish to pass paths (as
388+
opposed to packages or modules using the ``-p`` or ``-m`` flags),
389+
:option:`--explicit-package-bases <mypy --explicit-package-bases>` provides a
390+
solution.
378391

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.
392+
Third, with :option:`--explicit-package-bases <mypy --explicit-package-bases>`,
393+
mypy will locate the nearest parent directory that is a member of the
394+
``MYPYPATH`` environment variable, the :confval:`mypy_path` config or is the
395+
current working directory. mypy will then use the relative path to determine the
396+
fully qualified module name.
383397

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``.
398+
For example, say your directory tree consists solely of
399+
``src/namespace_pkg/mod.py``. If you run the command following command, mypy
400+
will correctly associate ``mod.py`` with ``namespace_pkg.mod``::
387401

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.
402+
$ MYPYPATH=src mypy --namespace-packages --explicit-package-bases .
403+
404+
If you pass a file not ending in ``.py[i]``, the module name assumed is
405+
``__main__`` (matching the behavior of the Python interpreter), unless
406+
:option:`--scripts-are-modules <mypy --scripts-are-modules>` is passed.
407+
408+
Passing :option:`-v <mypy -v>` will show you the files and associated module
409+
names that mypy will check.
391410

392411

393412
.. _finding-imports:
@@ -407,7 +426,7 @@ This is computed from the following items:
407426
(a colon-separated list of directories).
408427
- The :confval:`mypy_path` config file option.
409428
- The directories containing the sources given on the command line
410-
(see below).
429+
(see :ref:`Mapping file paths to modules <mapping-paths-to-modules>`).
411430
- The installed packages marked as safe for type checking (see
412431
:ref:`PEP 561 support <installed-packages>`)
413432
- The relevant directories of the
@@ -418,11 +437,6 @@ This is computed from the following items:
418437
You cannot point to a :pep:`561` package via the ``MYPYPATH``, it must be
419438
installed (see :ref:`PEP 561 support <installed-packages>`)
420439

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-
426440
Second, mypy searches for stub files in addition to regular Python files
427441
and packages.
428442
The rules for searching for a module ``foo`` are as follows:

0 commit comments

Comments
 (0)