0

I have several different repositories from which I need to programmatically import a package with a common name, say my_package, e..g /foo/bar/my_package and /foo/baz/my_package. I need to be able to retrieve my_package from these different repositories and keep them in separate variables.

I've tried to do this with importlib.import_module but it just does not work - I end up with the same package variable.

os.chdir('/foo/bar')
foobar_my_package = importlib.import_module('my_package')

os.chdir('/foo/baz')
foobaz_my_package = importlib.import_module('my_package')

> foobar_my_package == foobaz_my_package
> True

I don't understand why this is happening.

D. Joe
  • 63
  • 1
  • 10
  • try `foobar_my_package is foobaz_my_package` – Daniel Lee Nov 17 '17 at 12:41
  • It returns `True`. – D. Joe Nov 17 '17 at 12:42
  • It seems on the first call of`importlib.import_module('my_package')` this value is cached and the subsequent call yields the same value. – D. Joe Nov 17 '17 at 12:45
  • 1
    Maybe this works `import imp foobar_my_package = imp.load_source('/foo/bar/my_package', '/foo/bar/my_package.py') foobaz_my_package = imp.load_source('/foo/baz/my_package', '/foo/baz/my_package.py')` – SaiBot Nov 17 '17 at 12:45
  • well, it is the same package. Try import another pacakge – Daniel Lee Nov 17 '17 at 12:47
  • 1
    `importlib` does not take account of the current directory. – Daniel Roseman Nov 17 '17 at 12:48
  • Thanks, but there is no module named `my_package`, it is just a package name, the modules contained inside have different names. – D. Joe Nov 17 '17 at 12:49
  • `/foo/bar/my_package` will have different content compared with `/foo/baz/my_package` - the package names are the same but the content is different. – D. Joe Nov 17 '17 at 12:50
  • Possible duplicate of [import module from string variable](https://stackoverflow.com/questions/8718885/import-module-from-string-variable) – Elis Byberi Nov 17 '17 at 12:54
  • I need a reference to the package not the modules inside. – D. Joe Nov 17 '17 at 12:56
  • You get an error, don't you? If you do, would you mind posting it here (in question). – Elis Byberi Nov 17 '17 at 12:59
  • I don't really get an error, but I keep getting a reference to the same object for both `/foo/bar/my_package` and `/foo/baz/my_package` - these are packages with the same name but different content. I need to be able to have different variables for these packages. I am not interested in the modules inside, just the packages. – D. Joe Nov 17 '17 at 13:02
  • I assumed `importlib.import_module` would also work for packages, that's why I used it, but clearly it does not work and there appears to be no way of getting references to packages as opposed to modules. – D. Joe Nov 17 '17 at 13:03

1 Answers1

0

You could try something like this:

import imp

def myImporter(num, p):
    tup = imp.find_module('__init__', [p])
    module = imp.load_module('package%s' % i, *tup)
    tup[0].close()
    return module


if __name__ == '__main__':
    packages =  {}
    for i, p in enumerate(['/tmp/bar/my_package', '/tmp/foo/my_package']):
        _name = 'package%d' % i
        _module = myImporter(i, p)
        packages[_name] = _module

    for k,v in packages.items():
        print (v.__name__, v.main())

For the following directory structure:

.
├── bar
│   └── my_package
│       └── __init__.py
├── foo
│   └── my_package
│       └── __init__.py

Each __init__.py has a main() function:

def main():
        return "<name>/my_package/main"

It returns:

('package0', 'bar/my_package/main')
('package1', 'foo/my_package/main')
Maurice Meyer
  • 17,279
  • 4
  • 30
  • 47
  • Thanks, will try it and let know. – D. Joe Nov 17 '17 at 13:51
  • Doesn't work unfortunately - it is complaining about a relative import in a non-package, i.e. the `__init__.py` in one of the packages. – D. Joe Nov 18 '17 at 12:45
  • You can try to add `sys.path.append(p)` in `myImporter()` before `find_module()`. Elsewise you need to provide more information to your question ... – Maurice Meyer Nov 18 '17 at 13:11