Discussion:
python3 package import difference?
(too old to reply)
Tobiah
2024-08-07 15:35:36 UTC
Permalink
I have an old library from 20 some years ago
for use with python2, that is structured like this:

rcs
├── dbi
│   ├── __init__.py
│   ├── dbi.py
│   └── regos.py
└── __init__.py -- *empty*


the __init__.py file under 'rcs' is empty.
The one under rcs.dbi contains:

from dbi import *
from regos import *


With python2, I'd go:

import rcs.dbi

then I'd have access to stuff in regos.py
as:

rcs.dbi.feature() (Where 'feature' is defined in regos.py)


When I do the same import with python3, I get:

Traceback (most recent call last):
File "/home/toby/me", line 1, in <module>
import rcs.dbi
File "/usr/regos-1.0/lib/python/rcs/dbi/__init__.py", line 1, in <module>
from dbi import *
ModuleNotFoundError: No module named 'dbi'


What's changed, and how do I fix it?


Thanks!
Stefan Ram
2024-08-07 21:00:13 UTC
Permalink
Post by Tobiah
File "/usr/regos-1.0/lib/python/rcs/dbi/__init__.py", line 1, in <module>
from dbi import *
ModuleNotFoundError: No module named 'dbi'
The directory of the outermost script executed is in the system path.

E.g., the directory "d" when you invoke "python d/s.py".

To see the system path:

import sys
print( sys.path )

. "dbi" should not be in any of those directories in the system path.
Therefore, it is not found!

You could use a relative import:

from .dbi import *

or manipulate the sys.path (or an "editable install" of dbi might
also help, but I'm not sure about this as I have not tested it).
Ronaldo Sc
2024-08-07 22:22:33 UTC
Permalink
I believe you will need to track the modules in the folder *dbi *in the
root file '__init__.py'.

So there's an alternative to use the statement __all__ in the root filet
__init__.py, check the link where I find a use case:

*https://sentry.io/answers/what-is-init-py-for-in-python/#using-__init__py-to-run-code-and-control--imports
<https://sentry.io/answers/what-is-init-py-for-in-python/#using-__init__py-to-run-code-and-control--imports>*


References to take more deep in those issues:
PEP-3147 <https://peps.python.org/pep-3147/>
https://docs.python.org/3/tutorial/modules.html
<https://docs.python.org/3/tutorial/modules.html#intra-package-references>
in this link above we have some examples of relative imports:
from . import echo
from .. import formats
from ..filters import equalizer


In your code you're using "import *" , this is not a good practice when
using only some features in your module(s) because you'll inject more
garbage into memory if there are features you're not using.

Share with us the updates on your code.

Ronaldo

Em qua., 7 de ago. de 2024 às 14:40, Tobiah via Python-list <
Post by Tobiah
I have an old library from 20 some years ago
rcs
├── dbi
│ ├── __init__.py
│ ├── dbi.py
│ └── regos.py
└── __init__.py -- *empty*
the __init__.py file under 'rcs' is empty.
from dbi import *
from regos import *
import rcs.dbi
then I'd have access to stuff in regos.py
rcs.dbi.feature() (Where 'feature' is defined in regos.py)
File "/home/toby/me", line 1, in <module>
import rcs.dbi
File "/usr/regos-1.0/lib/python/rcs/dbi/__init__.py", line 1, in <module>
from dbi import *
ModuleNotFoundError: No module named 'dbi'
What's changed, and how do I fix it?
Thanks!
--
https://mail.python.org/mailman/listinfo/python-list
Chris Angelico
2024-08-07 22:43:54 UTC
Permalink
On Thu, 8 Aug 2024 at 03:40, Tobiah via Python-list
Post by Tobiah
from dbi import *
from regos import *
You probably want these to be package-relative now:

from .dbi import *
from .regos import *

Or, since you're using namespaced imports anyway ("rcs.dbi.feature"),
you may prefer this form:

from . import dbi, regos

ChrisA
Cameron Simpson
2024-08-08 01:17:56 UTC
Permalink
Post by Tobiah
File "/home/toby/me", line 1, in <module>
import rcs.dbi
File "/usr/regos-1.0/lib/python/rcs/dbi/__init__.py", line 1, in <module>
from dbi import *
ModuleNotFoundError: No module named 'dbi'
Python 3 imports are absolute (they start from the top of the package
tree and you have no `dbi` at the top). You want a relative import i.e.:

from .dbi import *

Cheers,
Cameron Simpson <***@cskk.id.au>
Gilmeh Serda
2024-08-08 21:55:58 UTC
Permalink
Post by Tobiah
from dbi import *
from regos import *
If I change that to:

from .dbi import * ¹
from .regos import * ²

It seems to be working.

In my tests, ¹ contains:
def bar():
pass

² contains:
def testing():
pass
def foo():
pass
Post by Tobiah
rcs.dbi.bar()
rcs.dbi.testing()
rcs.dbi.foo()
I guess in a sense Py2 was smarter figuring out what whent where and where
it came from. Or it was a bad hack that has been removed.
--
Gilmeh

You can always pick up your needle and move to another groove. -- Tim
Leary
Cameron Simpson
2024-08-08 23:53:52 UTC
Permalink
Post by Gilmeh Serda
I guess in a sense Py2 was smarter figuring out what whent where and where
it came from. Or it was a bad hack that has been removed.
No, Python 2 offered less control.

Loading...