I'm trying to support multiple versions of a python package without impacting client code.
Consider the following repo:
.
|-- client_code.py
`-- lib
|-- __init__.py
`-- foo.py
client_code.py:
from lib.foo import f
...
f()
I'd like to leave client_code.py
unchanged. I first tried to do something like this:
lib
|-- __init__.py
|-- v1
| |-- __init__.py
| `-- foo.py
`-- v2
|-- __init__.py
`-- foo.py
lib/__init__.py:
import os
if os.environ.get("USE_V2", "0") == "0": # Or some other runtime check
from .v1 import foo
else:
from .v2 import foo
But the client code fails with the following error:
Traceback (most recent call last):
File "client_code.py", line 1, in <module>
from lib.foo import f
ImportError: No module named foo
I'm aware that the following options would work, but they would require clients changing code:
if os.environ.get("USE_V2", "0") == "0":
from lib.v1.foo import f
else:
from lib.v2.foo import f
f()
if os.environ.get("USE_V2", "0") == "0":
import lib.v1.foo as foo
else:
import lib.v2.foo as foo
foo.f()
Is something like this possible?
A more general version of the question is here: Support two versions of a python package without clients needing to change code
I'm not sure it's the most elegant, but this seems to work.
├── client.py
└── lib
├── __init__.py
├── foo.py
├── v1
│ └── foo.py
└── v2
└── foo.py
import os
if os.environ.get("USE_V2", "0") == "0":
from lib.v1.foo import *
else:
from lib.v2.foo import *
def f():
print("I'm v1.f")
def f():
print("I'm v2.f")
from lib.foo import f
f()
$ env | grep USE_V2
USE_V2=1
$ python client.py
I'm v2.f
$ unset USE_V2
$ python client.py
I'm v1.f
Having the actual foo.py import *
looks bad, but it's just the lazy approach. Given a v1 and v2 contents that were somewhat different, you could have foo.py adapt the imports to present an uniform API in both cases. Or you could say prepare a functools.partial
version of a V1 function that doesn't exist in V2 anymore.
__init__.py
is empty and doesn't even need to exist under Python 3.
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