Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a best practice to make a package PEP-561 compliant?

I'm writing a Python project which is published as a package to a pypi-like repository (using setuptools and twine). I use type hints in my code.

The issue is, when importing the package from a different project and running mypy, I get the following error: error: Skipping analyzing 'XXX': found module but no type hints or library stubs

As I understand, I got this error because my package was not compliant with https://www.python.org/dev/peps/pep-0561/ .

After some searching online, I didn't find a way that was not manual to add the required files to the package.

I resorted to writing my own code to:

  1. Run stubgen to create stub files.
  2. Create py.typed files in every directory.
  3. Collect all the created files in a dict in package_data field in the setup.py file.

This code solved the issue and mypy runs without errors. But this feels very wrong to me. Is there a standard tool for making a package PEP-561 compliant? Am I missing something else?

like image 871
Tsah Weiss Avatar asked Jul 19 '20 11:07

Tsah Weiss


People also ask

Where do I put PY typed files?

For stub-packages distributing within a namespace package (see PEP 420), the py. typed file should be in the submodules of the namespace.

What are Python stubs?

A type stub is a file with a .pyi extension that describe a module's types while omitting implementation details. For example, if a module foo has the following source code: class Foo: CONSTANT = 42 def do_foo(x): return x. then foo.

How do I add PY typed?

Adding py. typed. It's faily simple to include this file: just touch a py. typed file in your package directory and include it in your distribution.


1 Answers

As mentioned before, You need to add the py.typed in the package folder of the module. You also need to add that file to the setup.py package_data - otherwise the file would not be part of the package when You deploy it.

I personally put the type annotations in the code and dont create extra stub files - but that is only possible from python 3.4 upwards. If You want to make python2.7 compatible code, You can not use inline type annotation - in that case You can use stub files.

If You want to type annotate a third party library, You can write a *.pyi file for the functions You use for that library. That can be a bit tricky, because MYPY must only find that *.pyi file ONCE in the MYPY Path.

So I handle it that way :

for local testing, the MYPY path is set to a directory were I collect all the 3rd party stubs, for testing on travis, I have a subdirectory in the package with the stubs needed for that module to test it on travis, and set the mypy path accordingly.

like image 173
bitranox Avatar answered Oct 02 '22 16:10

bitranox