Search code examples
pythonpipsetuptoolspython-packaging

My Python multi-module package won't distribute with a py.typed file


I've created a package for Pip that contains multiple modules, which I am using for some other projects. On one of those projects, I recently added MyPy as Pylance was missing some potential errors, but when I import those modules, MyPy flags them as errors as they are missing a py.typed file. I have added one of these files to each submodule, so that the directory structure is as follows:

* MyRepo:
    * src
    |   * modulea
    |   |   * __init__.py
    |   |   * modulea.py
    |   |   * py.typed
    |   * moduleb
    |   |   * __init__.py
    |   |   * moduleb.py
    |   |   * py.typed
    * setup.cfg

I have also specified in setup.cfg to include package data, using the include_package_data = True flag.

[metadata]
# Other details

[options]
packages = find:
package_dir =
    =src
python_requires = >=3.9.1
include_package_data = True

[options.packages.find]
where = src

However when I distribute the package, it doesn't include any of the py.typed files. I have no idea why this is, and it's especially confusing considering that when I install it manually, using pip install -e ., I don't get any errors. I'd massively appreciate any help fixing this, as I am completely stumped.


Solution

  • I'm not 100% sure this is correct since I don't have the package in front of me but I'll take a crack at it.

    I believe since py.typed is not a Python file, you need to specifically specify that you want to include it. For that, in your top level package, you need a MANIFEST.in. See the MANIFEST.in link for the default files that are normally included by default in a package distribution - py.typed is not in there. In the MANIFEST.in file, you would write a line such as:

    global-include py.typed
    

    I believe include_package_data being set to true causes the package manager to look at the MANIFEST.in for any additional files that need to be distributed that are not python files.

    I might also consider including and init.py in the src directory, and then just having one py.typed file there.