Search code examples
pythonimportpypi

Creating Python package with new name keeping old package import intact


Not sure if I have got the title correct but here short description on the issue. I have a package A on GitHub and PyPI and its usage is:

pip install A
import A 
A.module()

Current directory structure:

  • A
    • __init__.py

I would like to create a new package B on PyPI but would like keep backward compatibility so below works:

pip install B
import A 
A.module()

import B
B.module()

just so existing applications don’t break want to ensure import A works.

What are the possible solutions to achieve this?


Solution

  • The distribution name (what goes after "pip install") and the package import name(s) are entirely independent. It is only a common convention for the install name to match the import name.

    So just do like this in your installer:

    # setup.py
    
    from setuptools import setup
    
    setup(
        name="B",
        version="0.1",
        packages=["A", "B"],
        ...
    )
    

    In the setup call, the "name" keyword argument is the distribution name that users would use to install the package - python -m pip install B in this case. The generated artifacts which you upload to PyPI would have this B in the filename, e.g.

    B-0.1-py3-none-any.whl
    B-0.1.tar.gz
    

    The packages keyword argument are the top-level import names, of which there can be multiple, and these would usually match your project directory structure:

    .
    ├── A
    │   └── __init__.py
    ├── B
    │   └── __init__.py
    └── setup.py
    

    This allows the "B" distribution to provide both A and B imports, and act as a drop-in replacement for the "A" distribution.