From cd6642d2f2620da1ebdd57fbe8ac063d121498cd Mon Sep 17 00:00:00 2001 From: Ethan Smith Date: Tue, 12 Sep 2017 16:21:12 -0700 Subject: [PATCH] Updates for PEP 561 (#416) --- pep-0561.rst | 69 ++++++++++++++++++++++++++++++++-------------------- 1 file changed, 42 insertions(+), 27 deletions(-) diff --git a/pep-0561.rst b/pep-0561.rst index ebc8158cfa4..15f14f0444c 100644 --- a/pep-0561.rst +++ b/pep-0561.rst @@ -23,24 +23,30 @@ architecture. Rationale ========= +Currently, package authors wish to distribute code that has +inline type information. However, there is no standard method to distribute +packages with inline type annotations or syntax that can simultaneously +be used at runtime and in type checking. Additionally, if one wished to +ship typing information privately the only method would be via setting +``MYPYPATH`` or the equivalent to manually point to stubs. If the package +can be released publicly, it can be added to typeshed [1]_. However, this +does not scale and becomes a burden on the maintainers of typeshed. +Additionally, it ties bugfixes to releases of the tool using typeshed. + PEP 484 has a brief section on distributing typing information. In this -section [1]_ the PEP recommends using ``shared/typehints/pythonX.Y/`` for +section [2]_ the PEP recommends using ``shared/typehints/pythonX.Y/`` for shipping stub files. However, manually adding a path to stub files for each third party library does not scale. The simplest approach people have taken -is to add ``site-packages`` to their ``PYTHONPATH``, but this causes type +is to add ``site-packages`` to their ``MYPYPATH``, but this causes type checkers to fail on packages that are highly dynamic (e.g. sqlalchemy and Django). -Furthermore, package authors are wishing to distribute code that has -inline type information, and there currently is no standard method to -distribute packages with inline type annotations or syntax that can -simultaneously be used at runtime and in type checking. - Specification ============= -There are several motivations and methods of supporting typing in a package. This PEP recognizes three (3) types of packages that may be created: +There are several motivations and methods of supporting typing in a package. +This PEP recognizes three (3) types of packages that may be created: 1. The package maintainer would like to add type information inline. @@ -54,22 +60,28 @@ packaging and deployment. The two major parts of this specification are the packaging specifications and the resolution order for resolving module type information. This spec -is meant to replace the ``shared/typehints/pythonX.Y/`` spec of PEP 484 [1]_. +is meant to replace the ``shared/typehints/pythonX.Y/`` spec of PEP 484 [2]_. + +New third party stub libraries are encouraged to distribute stubs via the +third party packaging proposed in this PEP in place of being added to +typeshed. Typeshed will remain in use, but if maintainers are found, third +party stubs in typeshed are encouraged to be split into their own package. Packaging Type Information -------------------------- Packages must opt into supporting typing. This will be done though a distutils -extension [2]_, providing a ``typed`` keyword argument to the distutils +extension [3]_, providing a ``typed`` keyword argument to the distutils ``setup()`` command. The argument value will depend on the kind of type -information the package provides. The distutils extension will be added to the -``typing`` package. Therefore a package maintainer may write +information the package provides. The new keyword will be added to +Python 3.7 and will also be accessible in the ``typing_extensions`` package +though a distutils extension. This enables a package maintainer to write :: - + setup( ... - setup_requires=["typing"], + setup_requires=["typing_extensions"], typed="inline", ... ) @@ -109,10 +121,10 @@ are for the library ``flyingcircus`` then the package should be named named ``flyingcircus``. This allows the stubs to be checked as if they were in a regular package. These packages should also pass ``"stubs"`` as the value of ``typed`` argument in ``setup()``. These packages are suggested to use -``package_data`` to package stub files. +``package_data`` to package stub files. -The version of the ``flyingcircus-stubs`` package should match the version of -the ``flyingcircus`` package it is providing types for. +In addition, the package should indicate which version(s) of the runtime +package are supported via the ``install_requires`` argument to ``setup()``. Type Checker Module Resolution Order ------------------------------------ @@ -122,22 +134,24 @@ resolve modules containing type information: 1. User code - the files the type checker is running on. -2. Stubs or Python source in ``PYTHONPATH``. This is to allow the user - complete control of which stubs to use, and patch broken stubs/inline - types from packages. +2. Stubs or Python source manually put in the beginning of the path. Type + checkers should provide this to allow the user complete control of which + stubs to use, and patch broken stubs/inline types from packages. 3. Third party stub packages - these packages can supersede the installed untyped packages. They can be found at ``pkg-stubs`` for package ``pkg``, however it is encouraged to check their metadata to confirm that they opt - into type checking. + into type checking via the ``typed`` keyword. 4. Inline packages - finally, if there is nothing overriding the installed package, and it opts into type checking. -5. Typeshed (if used) - Provides the stdlib types and several third party libraries +5. Typeshed (if used) - Provides the stdlib types and several third party + libraries When resolving step (3) type checkers should assure the version of the stubs -match the installed runtime package. +is compatible with the installed runtime package through the method described +above. Type checkers that check a different Python version than the version they run on must find the type information in the ``site-packages``/``dist-packages`` @@ -149,17 +163,18 @@ binary, in case it is not in the path. To check if a package has opted into type checking, type checkers are recommended to use the ``pkg_resources`` module to query the package metadata. If the ``typed`` package metadata has ``None`` as its value, the -package has not opted into type checking, and the type checker should skip that -package. +package has not opted into type checking, and the type checker should skip +that package. References ========== +.. [1] Typeshed (https://github.com/python/typeshed) -.. [1] PEP 484, Storing and Distributing Stub Files +.. [2] PEP 484, Storing and Distributing Stub Files (https://www.python.org/dev/peps/pep-0484/#storing-and-distributing-stub-files) -.. [2] Distutils Extensions, Adding setup() arguments +.. [3] Distutils Extensions, Adding setup() arguments (http://setuptools.readthedocs.io/en/latest/setuptools.html#adding-setup-arguments) Copyright