2

This structure is just an example

pkg\
  test\
    __init__.py
    test.py
  __init__.py
  source.py
  another_source.py

another_source.py

class Bar():
  def __init__(self):
    self.name = "bar"

source.py

from another_source import Bar
class Foo():
  def __init__(self):
    self.name = "foo"
    b = Bar()

test.py

from ..source import Foo

if __name__== "__main__":
    f = Foo()
    print(f.name)

Now I want to run test.py. As it has been accepted as the answer I have to go above my current package and run

python -m pkg.test.test

But this does not work and python gives me a traceback

Traceback (most recent call last):
  File "-\Python35\lib\runpy.py", line 170, in _run_module_as_main
    "__main__", mod_spec)
  File "-\Python35\lib\runpy.py", line 85, in _run_code
    exec(code, run_globals)
  File "~\test\test.py", line 1, in <module>
    from ..source import Foo
  File "~\source.py", line 1, in <module>
    from another_source import Bar
ImportError: No module named 'another_source'

If I remove all the another_source-stuff it will work, but that is not a solution.

Now is there a sane way to import classes from places that are one directory above me?

1
  • 1
    from pkg.source import Foo if I remember correctly. Commented Oct 6, 2016 at 17:37

1 Answer 1

1

pkg.source is trying to import things from the pkg.another_source module as if it were top-level. That import needs to be corrected:

from .another_source import Bar
# or
from pkg.another_source import another_source
Sign up to request clarification or add additional context in comments.

4 Comments

But then my main-script imports ( same directory as source.py ) fail.
@Nozdrum: Then you're probably not being consistent about where the package hierarchy starts when you run these programs. You need to run those as python -m pkg.whatever from above the pkg directory too, or you need to put in a bit of boilerplate to fix __package__ and sys.path that's too much to explain here (but reading PEP 366 would be a good start).
It works if I run my main.py the same way I run my test.py. But it really doesn't make any sense to me as to why it works. The -m switch says it there to "run library module as a script", but I am not running any library modules. I am running a "main"-script, just as my test.py is not a library, but a test-case.
@Nozdrum: If you put them in the pkg directory, they're submodules of the pkg package. If you don't want them to be part of the package, you should put them somewhere else, or perhaps having pkg actually be a package isn't really what you need.