8

I have a number of small utils modules that i organize under a 'msa' namespace so I can use in a number of different research projects. Currently I have them organized like this:

# folder structure:
packages  <-- in my pythonpath
--msa
----msa_utils.py
----msa_geom.py
----msa_pyglet.py
----msa_math.py
----etc

# imported and used this like
from msa import msa_pyglet
from msa import msa_math
msa_pyglet.draw_rect(msa_math.lerp(...))

However I would like to avoid the 'msa_' in the names and use like this:

# folder structure:
packages  <-- in my pythonpath
--msa
----utils.py
----geom.py
----pyglet.py
----math.py
----etc

# imported and used this like
import msa.pyglet
import msa.math
msa.pyglet.draw_rect(msa.math.lerp(...))

This shouldn't cause name conflicts when importing from outside, however there are name conflicts when the modules themselves import modules with conflicting names. E.g. msa/pyglet needs to imports pyglet (the external one), but ends up trying to import itself. Likewise any module which tries to import the standard math library imports only my math module. Which is all understandable. But what is the usual pythonic way of dealing with this? Do I have to give each module file a globally unique name?

memo
  • 3,554
  • 4
  • 31
  • 36
  • 1
    possibly related: [Importing from builtin library when module with same name exists](http://stackoverflow.com/questions/6031584/importing-from-builtin-library-when-module-with-same-name-exists) – Aprillion Aug 05 '16 at 16:12
  • @Aprillion: that talks about one top-level package with the same name shadowing another, and doesn't concern *packages*. – Martijn Pieters Aug 05 '16 at 16:13

1 Answers1

5

In Python 2, imports in packages without a package qualifier indeed first look for package local modules.

Thus, import pyglet will find msa.pyglet before the top-level pyglet is considered.

Switch to absolute imports to make the Python 3 behaviour the default, where unqualified names are always top level names:

from __future__ import absolute_import

Now import pyglet can only ever find the top-level name, never msa.pyglet. To reference other modules within your msa namespace, use from . import pyglet or from msa import pyglet.

See PEP 328 -- Imports: Multi-Line and Absolute/Relative for more details.

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
  • ok super that works and is exactly what I needed thanks. And this is safe (and clean) to do? i.e. if I add that line as the first line of all of my modules, there's no chance of it breaking any other apps by other people etc I have on my system? – memo Aug 05 '16 at 16:25
  • @memo: `from __future__ import` declarations only ever apply to that module, not to anything else. You'll not break any other apps. – Martijn Pieters Aug 05 '16 at 16:25
  • yes it's not that bit I was concerned about, but I was wondering if having my own math.py, pyglet.py etc. in a subfolder of a path (msa) in PYTHONPATH would create any problems. But having read PEP328 it seems like this is a common problem (one can't always find names for their modules which are not used by others) and is trying to be addressed with python3/absolute import. – memo Aug 05 '16 at 23:20