| For fun, you could add this to Python and I think it would it cover a lot of edge cases? You would need: A function v_tree_install(spec) which installs a versioned pypi package like “foo=3.2” and all its dependencies in its own tree, rather than in site-packages. Another pair of functions v_import and v_from_import to wrap importlib with a name, version, and symbols. These functions know how to find the versioned package in its special tree and push that tree to sys.path before starting the import. To cover the case for when the imported code has dynamic imports you could also wrap any callable code (functions, classes) with a wrapper that also does the sys.push/pop before/after each call. You then replace third party imports in your code with calls assigning to symbols in your module: # import foo
foo = v_import(“foo==3.2”)
# from foo import bar, baz as q
bar, q = v_from_import(
“foo>=3.3”,
“bar”,
“baz”,
)
Finally, provide a function (or CLI tool) to statically scan your code looking for v_import and calling v_tree_install ahead of time. Or just let v_import do it.Edit: …and you’d need to edit the sys.modules cache too, or purge it after each “clever” import? |
You depend on two packages, each with a function that returns a “requests.Request” object. These packages depend on different versions of “requests”.
How would you implement “isinstance(return_value, requests.Request)” on each of these calls?
Or, the indirect case of this: catching a “requests.HttpException” from each of these calls?
Importing the right thing isn’t hard, but doing things with it is the hard bit.