0

I have some difficulties with python module/package usage in my code. The code is here: https://github.com/cjlano/svg

.
└── svg
    ├── geometry.py
    ├── __init__.py
    ├── LICENSE
    ├── README.md
    ├── svg.py
    ├── svg.test.py
    └── tests
        └── [...]

In the module svg I need to use the module geometry. As this module did not exist in the beginning when all the code was in svg.py, I decided to import the entire geometry namespace into svg (from geometry import *).

My issue is that, when I import the svg module from my package, it works well in python2 but fails in python3:

Python 2.7.5 (default, Sep  6 2013, 09:59:46) 
[GCC 4.8.1 20130725 (prerelease)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from svg import svg
>>> help(svg)

Gives me access to the svg module documentation. Whereas

Python 3.3.2 (default, Sep  6 2013, 09:35:59) 
[GCC 4.8.1 20130725 (prerelease)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from svg import svg
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "./svg/svg.py", line 27, in <module>
    from geometry import *
ImportError: No module named 'geometry'

Gives an error on import.

Any ideas on how to write my code to be usable in python3?

Thanks!

2 Answers 2

1

Python 3 doesn't do implicit relative imports any more.

This means you need to either make the import of geometry in svg.py an explicit relative import, or better yet, change it to an absolute import:

from svg.geometry import *

As pointed out by @CJlano, this then also requires from __future__ import absolute_import for it to still work on Python 2.

Sign up to request clarification or add additional context in comments.

2 Comments

For Python2, from __future__ import absolute_import is required
Good catch, thank you. I updated my answer accordingly.
1

It will work in both python 2.7 and 3.x if you use a relative import in svg.py:

from .geometry import *

Note the "." in front of the module name.

6 Comments

Thanks this works find but it breaks my test script svg.test.py: from .geometry import * ValueError: Attempted relative import in non-package How to make everything work together?
How are you executing that file? I think you are inviting trouble by having a file with a "." in the middle of the module name (I would expect that to confuse the python import logic). Try renaming that file to something like svg_test.py and see if that fixes the problem.
Renaming does not help. I call $ python svg_test.py from bash command line to run my script. Python2 says from .geometry import * ValueError: Attempted relative import in non-package and Python3 from .geometry import * SystemError: Parent module '' not loaded, cannot perform relative import, both for import svg and from svg import svg method of import in svg_test.py.
The problem is that you are running the file directly so the package/module hierarchy is not created (and therefore, the relative import fails). If you are at your top-level directory, this will give your error: python svg/svg_test.py. Whereas this will work: python -m svg.svg_test.
Relative module references are fine for submodule implementation (especially when you have generic module names like "geometry", "svg", etc.) but not good for test code, which should should usually emulate external client code (i.e., test code should be written from a perspective outside of your package's namespace. So for test modules, consider using absolute references instead (e.g., as in Lukas' answer).
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.