Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python can import a module that isn't installed

So, I'm playing around with packaging a python script I've written, and it has a submodule, let's call it submodule. The folder structure looks like this:

cool_script/
  setup.py
  cool_script.py
  submodule/
    __init__.py
    implementation.py

Now, after many pip install . and pip install -e . calls, I have the situation where submodule can be imported globally. No matter where on my system, this will always work:

$ python3
[...]
>>> import submodule
>>> submodule.__file__
'/home/me/fake/path/cool_script/submodule/__init__.py'

But I don't know why.

The package I made was uninstalled again, and pip cannot find the submodule in its index. There's nothing in dist-packages either, I manually deleted the cool_script.egg-link that was still sitting around there:

$ ls /usr/local/lib/python3.4/dist-packages | ack cool 
$ ls /usr/local/lib/python3.4/dist-packages | ack submodule
$ 

The PYTHONPATH is empty as well:

$ echo $PYTHONPATH

$

Why does Python know the location of submodule? How can I find out?

like image 677
iFreilicht Avatar asked Nov 30 '17 15:11

iFreilicht


People also ask

How we can import Python modules without installing?

If you are not able to install modules on a machine(due to not having enough permissions), you could use either virtualenv or save the module files in another directory and use the following code to allow Python to search for modules in the given module: >>> import os, sys >>> file_path = 'AdditionalModules/' >>> sys.

Why can't I import modules in Python?

This is caused by the fact that the version of Python you're running your script with is not configured to search for modules where you've installed them. This happens when you use the wrong installation of pip to install packages.

Can you manually import a module in Python?

append() Function. This is the easiest way to import a Python module by adding the module path to the path variable. The path variable contains the directories Python interpreter looks in for finding modules that were imported in the source files.

How do I know if a Python module is installed or not?

To check all the installed Python modules, we can use the following two commands with the 'pip': Using 'pip freeze' command. Using 'pip list command.


Video Answer


1 Answers

First run python -c "import site; print(site.getsitepackages())". It will print a list like this:

['/XXX/something/site-packages']

Normally there is a single path in this list, and it points to a directory where pip installs your scripts. You can ls into it if you're curious: ls /XXX/something/site-packages/.

More interestingly, though, pip puts a "link" file in that directory when you're using developer installs (a.k.a. pip install -e). The "link" file is named after the original project with a .egg-link extension at the end.

So you probably have a cool_script.egg-link file in that directory. And if you try to print it out you should find that its contents list the original filesystem location of your module. Something like:

$ cat /XXX/something/site-packages/cool_script.egg-link
/home/me/fake/path/cool_script/
.

This is how pip records that it has installed something in developer mode, but it isn't how Python actually knows how to find your module (that would have been too easy, right? :-)).

Python doesn't know about .egg-link files, but it reads all .pth files in the site-packages directory to get additional paths for sys.path (*). So, for Python to be able to import developer mode installs, pip writes all theirs paths in a single .pth file conventionally called easy-install.pth (because the old easy-install tool actually pioneered that technique). And if you print out that file, you'll get the list of all projects paths installed in developer mode:

$ cat /XXX/something/site-packages/easy-install.pth
/home/me/fake/path/cool_script/
/home/me/another/project/

And you can check that indeed all those paths listed in easy-install.pth indeed get added to your sys.path.

(*) Technically, the part of Python that reads those .pth file is the site module which is normally imported automatically at startup. There is an option to disable the site module, though, for example by using python -S. In that case, you'll see that sys.path contains neither the site-packages directory nor the developer install paths.

like image 135
Antoine P. Avatar answered Sep 28 '22 09:09

Antoine P.