0

I want to try really simple example of Python package. It seems to be okay on IDE as it does not show any error or warnings, but when i execute the files, i get error which is really weird.

$ tree                                                
.
├── ReadMe.md
├── __init__.py
├── a.py
└── b.py


$ pwd         
$HOME/workspace/devops-essentials/languages/python/simple_package

a.py

def bar():
    print("Hello, function 'bar' from module 'a' calling")

b.py

from simple_package import a

def foo():
    print("Hello, function 'foo' from module 'b' calling")

a.bar()
$ python3 b.py
Traceback (most recent call last):
  File "/Users/ankitsinghrathi/Ankit/workspace/devops-essentials/languages/python/simple_package/b.py", line 1, in <module>
    from simple_package import a
ModuleNotFoundError: No module named 'simple_package'


$ python3 simple_package/b.py 
Traceback (most recent call last):
  File "/Users/ankitsinghrathi/Ankit/workspace/devops-essentials/languages/python/simple_package/b.py", line 1, in <module>
    from simple_package import a
ModuleNotFoundError: No module named 'simple_package'
codeaprendiz
  • 2,703
  • 1
  • 25
  • 49
  • 1
    What directory are you calling `python3` in? Python will add that directory to the search path. So you need to be in the directory which contains `simple_package` (i.e. `$HOME/workspace/devops-essentials/languages/python`) – Peter Wood Jun 11 '21 at 08:43
  • Thanks @PeterWood, i tried from the same path. But still the same error. I updated the question description. – codeaprendiz Jun 11 '21 at 08:47
  • Does this answer your question? [Relative imports for the billionth time](https://stackoverflow.com/questions/14132789/relative-imports-for-the-billionth-time) – mkrieger1 Jun 11 '21 at 08:52
  • Honestly, I don't have that much patience. I would go there and leave. My problem is extremely simple and should have a short concise answer. – codeaprendiz Jun 11 '21 at 08:55

2 Answers2

1

If

$ tree $HOME/workspace/devops-essentials/languages/python/simple_package
├── ReadMe.md
├── __init__.py
├── a.py
└── b.py

then you'll need to be in $HOME/workspace/devops-essentials/languages/python and run

python -m simple_package.a

– using -m to execute the module will fix up your Python interpreter's path in a way that your imports work.

AKX
  • 152,115
  • 15
  • 115
  • 172
  • Amazing, you are the god @AKX, works like a charm. I wonder why this is not given anywhere in any python docs. I wanted to get this information for far too long. Gave up all hopes but then you came, the saviour :) – codeaprendiz Jun 11 '21 at 08:50
  • 2
    Another way around this would have been a `test_my_package.py` file in `python/` that does `import simple_package.a`, but yeah – this is documented in https://docs.python.org/3.9/using/cmdline.html#cmdoption-m – AKX Jun 11 '21 at 08:55
  • Why not `python simple_package/b.py`? – Peter Wood Jun 11 '21 at 10:28
  • @PeterWood Because it doesn't fix up `sys.path` like this does. – AKX Jun 11 '21 at 10:32
  • But, it will only find module `simple_package.a` because the path has been fixed up by running `python` in the directory containing `simple_package`. How does `-m` do any further "fixing up"? – Peter Wood Jun 11 '21 at 11:17
0

You need to change import statement in b.py

from simple_package import a
import a

import a

def foo():
    print("Hello, function 'foo' from module 'b' calling")

a.bar()

It will work perfectly fine, you can also use relative import like from . import a but when you will execute b.py it will throw RelativeImport error however when you use it outside the package it will work perfectly fine.

Paras Gupta
  • 264
  • 3
  • 11