Two import questions in Python 3.0

K

Kay Schluehr

1. I'd expected that absolute imports are used in Python 3.0 by
default. I may be wrong. I've written two versions of a module
sucks.py

sucks.py
-------------
print ("import from lib.sucks")

sucks.py
-------------
print ("import from package.sucks")

The first is placed in the lib directory that is globally visible by
means of PYTHONPATH. The second one is placed in a package

package/
__init__.py
sucks.py
A.py

The package also contains a module A.py defined by

A.py
------
import sucks

Running A yields "import from package.sucks" which means unconditional
relative import. It shadows the globally visible sucks.py module. I've
expected it the other way round.

2. This is kind of a change request.

In a former life I used to call test-scripts as test-scripts. The dumb
idea was to point e.g. to
lib/tests and run

python test_ast.py
test_nodeclasses (__main__.AST_Tests) ... ok
....
test_parse (__main__.ASTHelpers_Test) ... ok


----------------------------------------------------------------------
Ran 12 tests in 0.219s

OK

The new style is implemented rather in lib2to3. If I point to lib/
lib2to3/tests and run

python test_parser.py
Traceback (most recent call last):
File "test_parser.py", line 12, in <module>
from . import support
ValueError: Attempted relative import in non-package

The standard error of the years to come that makes working with Python
harder and reminds me that it is not a scripting language anymore
because you can't run anything as a script not even a test.

For pedagogical reasons the behavior of test_ast.py and other standard
library tests shall show uniform behavior when called from the command
line i.e. they shall all fail with this import error message. What do
you think?
 
G

Gabriel Genellina

1. I'd expected that absolute imports are used in Python 3.0 by
default. I may be wrong. I've written two versions of a module
sucks.py

sucks.py
-------------
print ("import from lib.sucks")

sucks.py
-------------
print ("import from package.sucks")

The first is placed in the lib directory that is globally visible by
means of PYTHONPATH. The second one is placed in a package

package/
__init__.py
sucks.py
A.py

The package also contains a module A.py defined by

A.py
------
import sucks

Running A yields "import from package.sucks" which means unconditional
relative import. It shadows the globally visible sucks.py module. I've
expected it the other way round.

If you run A.py as a script, it does not "know" it lives inside a package.
You must *import* A for it to become aware of the package.
Also, the directory containing the script comes earlier than PYTHONPATH
entries in sys.path -- so watch for that case too.
python test_parser.py
Traceback (most recent call last):
File "test_parser.py", line 12, in <module>
from . import support
ValueError: Attempted relative import in non-package

The standard error of the years to come that makes working with Python
harder and reminds me that it is not a scripting language anymore
because you can't run anything as a script not even a test.

I always consider that packages are libraries. Application code "uses" a
library (by importing things from it). Test code should mimic closely that
behavior: my tests always import the package, like the application would
do.

Anyway I should revisit the strategy, I've not evaluated yet how much is
affected by absolute imports and other changes in 3.0
 
K

Kay Schluehr

If you run A.py as a script, it does not "know" it lives inside a package.
You must *import* A for it to become aware of the package.
Also, the directory containing the script comes earlier than PYTHONPATH
entries in sys.path -- so watch for that case too.

Thanks, yes. I always make the same error thinking that a directory
with the ritual __init__ file is actually a package ( as some kind of
platonic entity ), something that is more obvious to me than it is to
the runtime. The relative import semantics introduced with Python 2.5
has made the error just visible that was hidden to me for about a
decade. Shit.
 
K

Kay Schluehr

Temper the language a bit. You lose your effectiveness by some people
reading the color of your words, rather than their meaning in code.

Sigh, yes... sorry. I'm just too frustrated. Actually I don't even
know why the import machinery is such a mess and I don't want to spend
a huge amount of time ( like Brett Cannon ) to figure it out.

I'll spent a few hours of time writing a script that turns all
relative paths into absolute ones without changing the source
otherwise. Then I'm at least done with that and won't ever see the
"relative import in non-packages" exceptions anymore in any code I
touch ( I can also ignore __package__, -m and all the other
workarounds ). It's not the first time Python is in my way but this
time it hurts.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,770
Messages
2,569,584
Members
45,075
Latest member
MakersCBDBloodSupport

Latest Threads

Top