5

I have a trouble with imports in my project.

My directories structure is the following:

base_directory
  - examples
  - src
    - folder_1
      - __init__.py
      - file.py
    - folder_2
      - __init__.py
      - class1.py
      - class2.py
      - class3.py
      - class4.py

In file.py I'm trying: from ..folder2.class1 import Class1 then, I get the error:

ImportError: attempted relative import with no known parent package

In folder2/__init__.py I did what I saw on a tutorial for making packages in Python:

from class1 import Class1

my_class_1 = Class1()

So far, anything has worked. What should I do? I use Python 3.7.5

Thanks.

James
  • 32,991
  • 4
  • 47
  • 70
Francisco
  • 53
  • 1
  • 5
  • try this once `from .class1 import Class1` – Abhishek Chatterjee Jun 23 '20 at 17:25
  • 1
    Oddly enough, although it shouldn't, I seem to be able to [get it to work](https://repl.it/@EnochKumala/CautiousWeirdScriptinglanguages#src/folder_1/file.py) without any errors, but the answer is correct – Daneolog Jun 23 '20 at 17:27
  • what you propose @AbhishekChatterjee it does not work, it seems like the only way to make this works is putting all the files in `base_directory` – Francisco Jun 23 '20 at 21:08
  • Does this answer your question? [Attempted relative import with no known parent package](https://stackoverflow.com/questions/55084977/attempted-relative-import-with-no-known-parent-package) – theX Jul 14 '20 at 01:31

1 Answers1

4

In your example, folder_1 and folder_2 are two separate and unique packages. There are no relative imports between them. Put them in a single outer package to get it to work

base_directory
  - examples
  - src
      - mypackage
        - __init__.py
        - folder_1
          - __init__.py
          - file.py
                print("imported", __file__)
                from ..folder_2.class1 import Class1
                print("file.py found", Class1)
        - folder_2   
          - __init__.py
          - class1.py
                print("imported", __file__)
                class Class1:
                def __init__(self):
                    print("Created Class1 instance")
          - class2.py
          - class3.py 
          - class4.py
      - test.py
            import myproject.folder_1.file

Running test.py script

~/tmp/base_directory/src$ python test.py
imported /home/td/tmp/base_directory/src/myproject/folder_1/file.py
imported /home/td/tmp/base_directory/src/myproject/folder_2/class1.py
file.py found <class 'myproject.folder_2.class1.Class1'>

But there is a workaround where modules can be called using the "-m" option. But his only works if myproject is in the python path. It works here because I'm in the parent of myproject when I call it.

~/tmp/base_directory/src$ python -m myproject.folder_1.file
imported /home/td/tmp/base_directory/src/myproject/folder_1/file.py
imported /home/td/tmp/base_directory/src/myproject/folder_2/class1.py
file.py found <class 'myproject.folder_2.class1.Class1'>
tdelaney
  • 73,364
  • 6
  • 83
  • 116
  • Yes this is correct. A file under ‘src’ but above the two sub-packages is needed to call the main function in file.py or whatever file holds the main function of how the program starts and runs. – Eno Gerguri Jun 23 '20 at 17:29
  • Are you running `file.py` as a script or importing it as a module? Scripts aren't in packages so relative imports don't work. I'll update the example with some code to demonstrate. – tdelaney Jun 23 '20 at 21:28
  • @Francisco , maybe https://stackoverflow.com/questions/62886769/is-it-possible-to-import-a-python-file-from-outside-the-directory-the-main-file could solve your problem? – theX Jul 14 '20 at 02:21