mypkg/
├── mypkg-1_0_0/
│ ├── __init__.py
├── __init__.py
The above directory is an example of what my modules directory looks like. The master module mypkg
contains all the sub-versions. When I do import mypkg
the __init__
file is meant to redirect the import to the correct version while running the target versions __init__
file and also setting the attributes to globals()
Here is what the __init__.py
in mypkg
looks like:
def __load():
import os
pkgrelease = "mypkg-1_0_0"
if pkgrelease:
current_path = __path__[0]
new_path = os.path.join( current_path, pkgrelease )
init_path = os.path.join( new_path, "__init__.py" )
__path__[:] = [new_path]
initf = open( init_path )
exec compile( initf.read(), init_path, "exec" ) in globals()
initf.close()
else:
raise ImportError( "Could not find [%s] package version" % os.path.basename(__path__) )
__load()
del __load
In python2
this works fine, the package gets redirected to version 1_0_0
, and stuff like __version__
in that versions __init__
file, are retained and set in the globals()
. But I also know there is a much better way to do what I'm trying to achieve here that is cross-compatible. This will not work in python3 due the exec compile statement.
I found one solution that works on both py2/3. Simply just need to tweak the exec
function to take in the globals()
an argument. This is shown here in the docs. Here is the revised code:
def load():
import os
pkgrelease = "mypkg-1_0_0"
current_path = __path__[0]
new_path = os.path.join( current_path, pkgrelease )
init_path = os.path.join( new_path, "__init__.py" )
__path__[:] = [new_path]
initf = open(init_path)
module = compile(initf.read(), init_path, "exec")
exec(module, globals())
initf.close()
load()
del load