Two python packages with the same structure use function of the same name from other package

529 Views Asked by At

I have created 2 packages, named A and B. Both packages have the same structure to them, as they do very similar things, e.g. their structure looks like this:

A/
  __init__.py
  subpackage1/
    __init__.py
    submodule1.py
  subpackage2/
    __init__.py
    submodule2.py
  setup.py
  README.md
  requirements.txt

They share the same subpackage, submodule and function names. Each module has a main function, which does the argparsing for me and calls a function with those params. In my setup.py, I specified additional entry points, so that I can call the modules from the command line:

import setuptools

with open("README.md", "r") as fh:
    long_description = fh.read()

with open('requirements.txt') as f:
    requirements = f.readlines() 

setuptools.setup(
    name="A",
    version="0.0.1",
    author="Me",
    author_email="[email protected]",
    description="Test package",
    long_description=long_description,
    long_description_content_type="text/markdown",
    packages=setuptools.find_packages(),
    entry_points ={
        'console_scripts': [
            'command1 = subpackage1.submodule1:main',
            'command2 = subpackage2.submodule2:main'
        ]
    },
    classifiers=[
        "Programming Language :: Python :: 3",
        "License :: OSI Approved :: MIT License",
        "Operating System :: OS Independent",
    ],
    python_requires='>=3.6',
    install_requires = requirements
)

When I install the package in a blank docker container, it works fine and I can call my functions with 'command1' and 'command2' from the command line.

As stated before, package B has exactly the same setup.py file, except for the name. If I install that as well, the package A now uses the entry points of package B instead of its own. That means, I call the function with the right name, but from the wrong package.

I want to have them side-by-side in my docker container. How do I have to adjust my packages, so that the system can differentiate between them?

I installed the packages via pip from wheels that I generated.

1

There are 1 best solutions below

1
On BEST ANSWER

First impression, the directory structure seems wrong: the first red flag is that there shouldn't be a __init__.py in the same directory as setup.py, the second red flag is that the directories next to setup.py can not be sub-packages, they are top-level packages.

In your example the top-level packages are subpackage1 and subpackage2 in the project A, and in the project B as well. So in both cases, after installation the importable items are import subpackage1 and import subpackage2. It also means that when you install A, then B, the top-level packages of B overwrite those that were previously installed as part of A (since they have the exact same name).

What you probably want to do is to add a directory a in the project A right next to its setup.py, and move both subpackageN as well as the __init__.py into that a directory (same in the project B). So that directory structure looks like:

A/
  a/
    __init__.py
    subpackage1/
      __init__.py
      submodule1.py
    subpackage2/
      __init__.py
      submodule2.py
  setup.py
  README.md
  requirements.txt

Then the imports will look like:

import a.subpackage1
import b.subpackage1

from a import subpackage2 as subpackagea2
from b import subpackage2 as subpackageb2

Following that the setup.py files should be adjusted accordingly:

# ...

setuptools.setup(
    # ...
    entry_points ={
        'console_scripts': [
            'commanda1 = a.subpackage1.submodule1:main',
            'commanda2 = a.subpackage2.submodule2:main'
        ]
    },
)