2

When I have a package test, I'm used to import another file script from it as:

import test.script

and libraries as:

import library

This works as long as I don't need any library that's name corresponds with any of my scripts. When it happens, the script is loaded, instead of the library. Is there a way to force local imports to use the full path to file as I'm using it? Or is there another way to prevent the name clash, without renaming the script?

Fido
  • 320
  • 1
  • 2
  • 15

1 Answers1

1

When you name a "script" with the same name as a dependency, you have intercepted the lookup for that name.

You could modify your PYTHONPATH i.e. sys.path, putting your dependencies in front of your "scripts" but then you've intercepted your scripts - this seems like a very bad idea.

>>> import sys
>>> import pprint
>>> pprint.pprint(sys.path)
['',                               # Current Working Directory
 '~\\Anaconda3\\python36.zip',
 '~\\Anaconda3\\DLLs',
 '~\\Anaconda3\\lib',
 '~\\Anaconda3',
 '~\\Anaconda3\\lib\\site-packages',
 '~\\Anaconda3\\lib\\site-packages\\Sphinx-1.5.6-py3.6.egg',
 '~\\Anaconda3\\lib\\site-packages\\win32',
 '~\\Anaconda3\\lib\\site-packages\\win32\\lib',
 '~\\Anaconda3\\lib\\site-packages\\Pythonwin',
 '~\\Anaconda3\\lib\\site-packages\\setuptools-27.2.0-py3.6.egg']

Don't modify the lookup order in your sys.path.

I would not name any script with the same name as a dependency, with the sole exception that I was intending to intercept the name with something that is semantically the same thing.

Namespaces are one honking great idea -- let's do more of those!

You need your own namespace. Create a directory, for example a_namespace, put your scripts in that directory, and work from the parent directory. For example:

>>> from pathlib import Path
>>> Path('a_namespace').mkdir()
>>> (Path('a_namespace') / 'sys.py').write_text('print("importing my sys")')
25
>>> import a_namespace.sys
importing my sys

And you can still get to your dependencies:

>>> import sys
>>> sys.version
'3.6.1 |Anaconda 4.4.0 (64-bit)| (default, May 11 2017, 13:25:24) [MSC v.1900 64 bit (AMD64)]'
Russia Must Remove Putin
  • 374,368
  • 89
  • 403
  • 331
  • So basically, I have to put anything that could cause name clash to some child package? – Fido Jun 18 '18 at 14:09
  • @Fido As you likely don't know all of your dependencies, I strongly recommend putting your "scripts" into a package. The large-scale developments I'm familiar with do that. You don't *have* to, but the only exceptions I can think of are projects that stick to a single file (for example, bottle). The more files you make, the more chances you have for name collisions. Use a namespace package, at least. It seems like a best practice, and I haven't seen any large-scale development that doesn't do that. – Russia Must Remove Putin Jun 18 '18 at 14:28