LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   Python Error: Parent module '' not loaded (https://www.linuxquestions.org/questions/programming-9/python-error-parent-module-not-loaded-4175616940/)

Fergupicus 11-04-2017 12:17 AM

Python Error: Parent module '' not loaded
 
Okay, so I haven't been on here in a while as I've been working on a python project. However I've run into a bit of an error with relative imports. So my project directory looks like this:
Code:

/X3cute
  /bin
      configuration.py
      __init__.py
      main.py
      scriptcall.py
      /sub
        duck.py
        help.py
        __init__.py
  /docs
  /lib
  __init__.py

etc. etc.

The problem however is when I try to run main.py I get this error [I] SystemError: Parent module '' not loaded, cannot perform relative import.
The code for the project is here. (Yes i know the __pycache__ is still in there. I was in a rush!)

So any suggestions? Thanks in advance :)

DaneM 11-05-2017 02:34 AM

I'm just learning Python, myself, but I found a StackOverflow solution to this error that might be relevant:
https://stackoverflow.com/questions/...n-with-init-py

Also, have you tried editing the "from .<name> import <method>" lines to reflect exact filenames and paths, including the .py extension? If that works, you could work backward to determine what it's choking on.

Fergupicus 11-05-2017 03:53 AM

Unfortunately I have already looked over these answers and none of them have helped. :( Also I can't seem to put in directories into the import statement as it returns an invalid syntax error.

Thanks anyway, your help is greatly appreciated :)

traene 11-05-2017 05:48 AM

Also not an expert here, eg. difference between python packages and python modules. I have no idea about those. But to me, it looks like that 'relative' path can only be used, if you're using python packages. For those you need to run the program like 'python -m <python_package_name>'

I've tried to run your project on my computer and had to do the following changes:

Code:


% git diff
diff --git i/bin/main.py w/bin/main.py
index f1e73fe..513c539 100644
--- i/bin/main.py
+++ w/bin/main.py
@@ -1,6 +1,6 @@
 import sys
-from .scriptcall import command
-from .configuration import Colour, banner
+from scriptcall import command
+from configuration import Colour, banner
 
 banner()
 
diff --git i/bin/scriptcall.py w/bin/scriptcall.py
index 8c7916b..7ddabf8 100644
--- i/bin/scriptcall.py
+++ w/bin/scriptcall.py
@@ -1,6 +1,5 @@
-from .configuration import banner
-from .main import main
-from .sub.help import help_page
+from configuration import banner
+from sub.help import help_page
 
 
 def command(cmd):
@@ -15,4 +14,3 @@ def command(cmd):
        exit()
    else:
        print("Please select a proper option!")
-        main()
\ No newline at end of file
diff --git i/bin/sub/help.py w/bin/sub/help.py
index 576cbd5..59b319b 100644
--- i/bin/sub/help.py
+++ w/bin/sub/help.py
@@ -1,4 +1,4 @@
-from ..configuration import Colour
+from configuration import Colour
 
 # Module for the Help command

I'm not sure about the changes to bin/scriptcall.py - to me that looked like a recursive import (main imports scriptcall which imports main again). You may need to reorganize the code in that regard a bit.

With those changes, i could run it with python2 or python3, eg. like:
Code:

python bin/main.py
python3 bin/main.py


Fergupicus 11-14-2017 01:00 AM

Sorry for radio silence!
 
Hey sorry for the radio silence, I had exams. :( I don't quite understand what you did there, could you please explain it to me? Haha sorry if it's obvious but it just looks random to me. For examples of what I don't understand:what are the +'s and -'s? what is index and diff? and what are the @@ lines for?

Thanks for your reply :)

DaneM 11-14-2017 01:34 AM

I can't speak to the code, itself, but I know a diff when I see one. :-D

The diff command specifies two files: for example, i/bin/scriptcall.py and w/bin/scriptcall.py. By convention, the old one is usually the first specified, and the new one is the last specified. So, you can think of it as "diff [options] old new". The "-" symbol in the output represents lines of the old file. The "+" symbol in the output represents lines of the new file. So, lines with "-" before them are being replaced with the lines that have "+" before them.

Just to be sure, the lines starting with "---" and "+++" tell you which file is which, based on the directory path that was used when executing the command.

@@ -1,6 +1,5 @@
Means that a change starts at line 1 of the old file (note the "-" symbol) and is 6 lines long. Its corresponding replacements start at line 1 of the new file ("+") and are 5 lines long.

So, for example:
Code:

--- i/bin/scriptcall.py
+++ w/bin/scriptcall.py
@@ -1,6 +1,5 @@
-from .configuration import banner
-from .main import main
-from .sub.help import help_page
+from configuration import banner
+from sub.help import help_page

...says that from the first file (i/bin/scriptcall.py), the lines starting with "-" are removed, and are being replaced with the lines starting with "+" (from file "w/bin/scriptcall.py). In this case, the periods before "scriptcall" and "configuration" are being removed. Also, the line, "from .main import main" is being removed (notice that the new file has fewer lines in this section than the old file).

A ways below that, you'll notice that the line, "main()" is being removed. (Note that I'm not giving a complete rundown of all changes made, just pointing out examples of how to read diff output.)

It's possible to apply a diff to your code as a text file patch, using the "patch" command; but it's best to understand the code, before applying a patch. (You'll want to look up a tutorial on "patch" before you try it. It's useful for installing kernel patchsets, for example...)

As to why these changes work...idunno...I'm new to Python. Hopefully, traene can tell you. ;-)

ondoho 11-14-2017 02:03 AM

Code:

man diff
git diff --help


Fergupicus 11-14-2017 02:07 AM

@DaneM (sorry if that's not how you tag someone, idk how this works :P ) Thanks for the speedy reply :) That was the answer I was looking for the diff thing!

DaneM 11-14-2017 12:42 PM

Any time. :-)
(I don't know how tagging works on LQ, either.)

traene 11-14-2017 03:04 PM

Here is what i tried:

1. Clone X3cute-Framework from github

% git clone https://github.com/Fergupicus/X3cute-Framework.git

2. Try to run it

% python bin/main.py

3. Made some change and repeated 2 (until i got it somewhat running)

The diff in my former post could be applied to your local copy of the X3cute-Framework, when you're on master branch. Eg. copy the lines to some temp file and try to apply those. I assume that you are also using git, if so then you could apply the patch with

% git apply tempfile_name

Alternatively, you could also use the patch utility directly, eg. apply the patch with:

% patch -p 1 < tempfile_name

You can start the X3cute-Framework then with:

% python bin/main.py


I'll try to give some more insight in another post.

traene 11-14-2017 03:20 PM

NOTE: That the above is probably not what you want, as you were already using the 'relative imports', eg. 'from .configuration import banner'. Those only work when you run your project as a python module. (This is also new to me, so sorry about my first attempt)

Let's try to start the programme with

Code:

% python -m bin
/usr/bin/python: No module named bin.__main__; 'bin' is a package and cannot be directly executed

Python complains that there is no module named 'bin.__main__'.

I try to fill the 'bin.__init__.py' (see below)

Code:

% python -m bin
Traceback (most recent call last):
  File "/usr/lib/python3.6/runpy.py", line 183, in _run_module_as_main
    mod_name, mod_spec, code = _get_module_details(mod_name, _Error)
  File "/usr/lib/python3.6/runpy.py", line 142, in _get_module_details
    return _get_module_details(pkg_main_name, error)
  File "/usr/lib/python3.6/runpy.py", line 109, in _get_module_details
    __import__(pkg_name)
  File "/home/jim/stage/X3cute-Framework/bin/__init__.py", line 1, in <module>
    from bin import main
  File "/home/jim/stage/X3cute-Framework/bin/main.py", line 2, in <module>
    from .scriptcall import command
  File "/home/jim/stage/X3cute-Framework/bin/scriptcall.py", line 2, in <module>
    from .main import main
ImportError: cannot import name 'main'

Here a python stacktrace shows up: python's runpy.py appears on the top 3 places, and then it imports 'bin/__init__.py' and it fails in 'bin/scriptcall.py' with an ImportError. It can't import main from bin/scriptcall.py -- but we where already in bin/main.py

Now, i've removed the calls to 'main' in bin/scriptcall.py -- as that seems to cause some 'recursive' import issue.

Please see the changes to bin/__init__.py file. It now contains:
Code:

from bin import main
main.main()

With the following patch, you can start the X3cute-Framework via:

% python -m bin



Code:

% git diff                                                                                                                                                             
diff --git i/bin/__init__.py w/bin/__init__.py
index e69de29..206f820 100644
--- i/bin/__init__.py
+++ w/bin/__init__.py
@@ -0,0 +1,2 @@
+from bin import main
+main.main()
diff --git i/bin/scriptcall.py w/bin/scriptcall.py
index 8c7916b..cd0adf1 100644
--- i/bin/scriptcall.py
+++ w/bin/scriptcall.py
@@ -1,18 +1,14 @@
 from .configuration import banner
-from .main import main
 from .sub.help import help_page
 
 
 def command(cmd):
    if cmd == "banner":
        banner()
-        main()
    elif cmd == "help":
        help_page()
        print(" ")
-        main()
    elif cmd.lower == "exit":
        exit()
    else:
        print("Please select a proper option!")
-        main()
\ No newline at end of file



All times are GMT -5. The time now is 02:57 AM.