简体   繁体   中英

How do I alias a python module at packaging time?

For historic reasons and backwards compatibility I want to package a module (let's call it myapi ) in a way that this set of imports:

from myapi.utils import helpers
from myapi.api.rest import MyRest
import myapi

Import the same code (without duplication) as these below:

from oldname.utils import helpers
from oldname.api.rest import MyRest
import oldname

Assuming the package was installed the regular way with pip install myapi or pip install --user myapi .

Ie, I want to alias the complete module structure of myapi under another name oldname at packaging , so the user can import any module using oldname or the new name (here myapi ) without duplicating the code. Is there something in Python or setuptools that can accomplish that?

Alternatives, that don't work for me:

I'm aware that the user could just do:

import myapi as oldname

My goal is to avoid confusion, because the package name changed at some point. The users should be able to use both the old and the new name interchangeably, without having to know the name changed at all.

On some systems, the easiest way would be to just create a symbolic link upon running setup.py install :

ln -s /usr/local/lib/python2.7/dist-packages/myapi \
      /usr/local/lib/python2.7/dist-packages/oldname

But that is hacky and will most certainly confuse Python's import system and lead to other problems ( oldname.__name__ , pip show oldname and such). Also it won't work with wheels. I prefer a built-in way but am not that deep into Python packaging that I would know one. Maybe there is a something I could put in my setup.py (which btw. uses setuptools ). Any suggestions? Is there a better way?

What I ended up using is the following package strucutre:

$ tree
./
├── myapi/
│   ├── utils/
│   │   ├── ...
│   │   └── __init__.py
│   └── api/
│       ├── rest.py
│       ├── ...
│       └── __init__.py
├── oldname/
│   └── __init__.py
└── setup.py

Where these are the relevent parts of the files:

# ./setup.py
from setuptools import setup, find_packages

setup(
    # ...
    packages=find_packages('./'),
    package_dir={'': './'},
)
# ./oldname/__init__.py

import sys, myapi
from myapi import *

sys.modules['oldname'] = myapi

Seems to work, but no idea if there are any edge-cases or whether there is a better solution and/or more canonical solution.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM