Search code examples
pythonpython-2.7python-jira

Create sub package without shadowing a global package


I'm working on a Python project where I've to communicate with the Jira API. I want to use the "offical" Jira client for Python which is available here.

The package introduces a global namespace jira, meaning you have to

from jira import JIRA

to use the API.

How can I create a sub-package

company.project.datasources.jira

without shadowing the global jira package?


Let me add a few steps to reproduce my problem and to show what I have in mind:

This is my directory layout:

.
├── company
│   ├── __init__.py
│   └── project
│       ├── datasources
│       │   ├── __init__.py
│       │   └── jira.py
│       └── __init__.py
└── test.py

company/project/datasources/jira.py

# This should be the global class. I don't know how to import it
from jira import JIRA as BaseJira

class JIRA(BaseJira):
    # Add something fancy here
    pass

test.py

from company.project.datasources.jira import JIRA

custom_jira = JIRA()

When I try:

python test.py

I get the following error:

Traceback (most recent call last):
  File "test.py", line 1, in <module>
    from company.project.datasources.jira import JIRA
  File "/tmp/test/company/project/datasources/jira.py", line 2, in <module>
    from jira import JIRA as BaseJira
ImportError: cannot import name JIRA

The __init__.py are currently all empty files. I've tried a lot with them but it doesn't worked for me. Probably these files are they key to my problem?


Solution

  • You're using Python 2, which has some issues with how it resolves imports. It thinks jira refers to the jira module relative to the current module (in this case, they refer to the same thing, but this would also happen if you also tried to do this import from another module next to jira.py).

    You need to enable Python 3's import behavior. Add the following import before anything else in jira.py (or anything else at the same level that would see the shadowed package):

    from __future__ import absolute_import
    

    See PEP 328 for more information. The abstract describes the general problem:

    Imports can be ambiguous in the face of packages; within a package, it's not clear whether import foo refers to a module within the package or some module outside the package. (More precisely, a local module or package can shadow another hanging directly off sys.path.)

    It is proposed that all import statements be absolute by default (searching sys.path only) with special syntax (leading dots) for accessing package-relative imports.