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?

Community
  • 1
  • 1

1 Answers1

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
user2357112
  • 260,549
  • 28
  • 431
  • 505
  • But then my main-script imports ( same directory as source.py ) fail. –  Oct 06 '16 at 17:46
  • 1
    @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](https://www.python.org/dev/peps/pep-0366/) would be a good start). – user2357112 Oct 06 '16 at 17:50
  • 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. –  Oct 06 '16 at 17:56
  • 1
    @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. – user2357112 Oct 06 '16 at 18:58