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
.
I.e., 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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With