Python Package Problem @ Erwin Li | 2023-12-14T11:31:54Z | 2 minutes read | Update at 2023-12-14T11:31:54Z

Introduce the Python naming problem and Pip’s –install-option problem.

Python package naming problem

A classic setup function:

setup(
    name='myproject',
    version='0.1.0',
    package_dir={'':'src'},
    packages=find_packages(where='src')
)

name is the project name listed in pip list. packages is the package names when using import in python code.

package_dir={'':'src'} is unprefix importing. For example: If the project’s structure like this with the using of previous classic setup function

myproject/
│
├── src/
│   ├── common/
│   │   ├── __init__.py
│   │   └── ...
│   │
│   └── components/
│       ├── __init__.py
│       └── ...
│
└── setup.py

After installing this package, there are package common and components in Python environment. In code, they should be imported like import common and import components. However, when listing packages using pip list, it only shows myproject 0.1.0.

We can add prefix in package_dir like:

package_dir={
    'myproject.common': 'src/common',
    'myproject.components': 'src/components'
},
packages=find_packages(where='src')

Then, It can be imported like import myproject.common and myproject.components.

This can be consider as a naming space problem.

Pip’s –install-option problem

--install-option can pass argument to setup.py when using pip install XXX --install-option="xxx". However, it will force every dependencies package to be build from source code instead of using existing wheel files, which will lead to slow installing.

Try to avoid using it. It is simple to using environment viriables to control setup.py’s behavior. For example, controling build which Cython extension:

if os.environ.get("INSTALL_SELECTOR")==None or os.environ.get("INSTALL_SELECTOR")=="all":
    compile_cpu = True
    compile_gpu = True
    print("Install both CPU and GPU version")
elif os.environ.get("INSTALL_SELECTOR")=="cpu":
    compile_cpu = True
    compile_gpu = False
    print("Only install CPU version")
elif os.environ.get("INSTALL_SELECTOR")=="gpu":
    compile_cpu = False
    compile_gpu = True
    print("Only install GPU version")
else:
    raise Exception("INSTALL_SELECTOR should be in [\"all\", \"cpu\", \"gpu\"], or do not define it for \"all\". Got %s."%os.environ.get("INSTALL_SELECTOR"))

extensions = []

extensions.append(Extension(
                        "fastpermut.c_conf",  # Name of the resulting python extension
                        ......
                    ))

if compile_cpu:
    cpu_extension = Extension(
                        "fastpermut.permutation",  # Name of the resulting python extension
                        ......
                		)
    extensions.append(cpu_extension)
if compile_gpu:
    gpu_extension = Extension(
                        "fastpermut.permutation_cuda",  # Name of the resulting python extension
                        ......
                	)
    extensions.append(gpu_extension)
    
setup(
    ......
    ext_modules=cythonize(extensions, language_level=3),
)

© 2020 - 2024 Li Yuanhao's Blog

Powered by Hugo with theme Dream.

avatar

Li Yuanhao's BlogJust do it

Social Links