ChumiestBucket
ChumiestBucket

Reputation: 1073

cannot import package from one directory up

I can't seem to figure out how to fix the error below when trying to import a file from one directory up and it's making me crazy. Python 3.6.7.

Here's how The Internet says it should be done, one directory up:

from .. import app

Here's the error:

Traceback (most recent call last):
  File "module1.py", line 16, in <module>
    from .. import app
ValueError: attempted relative import beyond top-level package

Here's the dir structure (It should be noted that I'm calling the script module1.py from inside package1):

--- project/
    --- __init__.py
    --- app.py
    --- package1/
        --- __init__.py
        --- module1.py

Here's what I've tried to fix it:

Method 1 (same error)

import sys

HERE = Path(__file__).parent
sys.path.append(str(HERE / '../'))
from .. import app

Method 2 (found here, same error)

import os
import sys

sys.path.append(os.path.join(os.path.dirname(__file__)))
from .. import app

Method 3 ( also found here, same error)

import sys

sys.path.append('.')
from .. import app

Upvotes: 1

Views: 223

Answers (2)

thebjorn
thebjorn

Reputation: 27311

A standard package structure for Python looks like this:

c:\srv\tmp> tree project
project
|-- project
|   |-- __init__.py
|   |-- app.py
|   `-- package1
|       |-- __init__.py
|       `-- module1.py
`-- setup.py

where the project-root c:\srv\tmp\project contains a setup.py file and a subdirectory that is also named project containing the source code.

The contents of module1.py:

from .. import app

def module1_fn():
    print("In module1, have imported app as:", app)

and the contents of setup.py:

from setuptools import setup

setup(
    name='project',
    packages=['project'],    # where to find sources
    entry_points={
        'console_scripts': """
            module1-fn = project.package1.module1:module1_fn
        """
    }
)

now the "magic" part, from the directory containing setup.py run (note the . at the end):

c:\srv\tmp\project> pip install -e .
Obtaining file:///C:/srv/tmp/project
Installing collected packages: project
  Running setup.py develop for project
Successfully installed project

And now, from any directory, you can run:

c:\srv\tmp\project> module1-fn
In module1, have imported app as: <module 'project.app' from 'c:\srv\tmp\project\project\app.pyc'>

ie. module1-fn can be called directly from the shell(!), and from .. import app works directly(!!)

Upvotes: 2

jose_bacoy
jose_bacoy

Reputation: 12684

I got this working on my laptop so I hope it works on your side as well.

module1.py

import sys
from os import path

sys.path.append(path.join(path.dirname(__file__), '..'))
from app import print_app


print_app()

app.py:

def print_app():
    print('success')
    return None

Result:

$python module1.py 

'success'

Upvotes: 1

Related Questions