Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How are Python modules (which are shared libraries) imported without a .py file?

I am running an interactive Python shell and trying to see the path from which a module is being imported using the 'inspect' module. The modules I am trying to import have Python wrappers around C++ APIs using SWIG.

The following snippet shows my steps :

>>> import os
>>> import inspect
>>>      
>>> import db
>>> inspect.getfile(db)
'mypath1/lib/db/db.pyc'
>>>
>>> import dart
>>> inspect.getfile(dart)
'mypath2/lib/dart.so'
>>>

My PYTHONPATH contains both mypath1/lib/db and mypath2/lib.

I was under the impression that in order to be able to load modules, the interpreter needs access to a .py file which then calls imp.load_module to load the required shared library (.so file). This is what I see in case of the db module which has a db.py file under mypath1/lib/db. However, dart does not have a .py file under mypath2/lib.

Is it possible to import a module without the .py file as is happening in the case of the dart module ?

like image 753
kniyogi Avatar asked Aug 18 '15 17:08

kniyogi


People also ask

How are libraries imported in Python?

Import in python is similar to #include header_file in C/C++. Python modules can get access to code from another module by importing the file/function using import. The import statement is the most common way of invoking the import machinery, but it is not the only way.

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.

How does Python import modules from some other directory?

The most Pythonic way to import a module from another folder is to place an empty file named __init__.py into that folder and use the relative path with the dot notation. For example, a module in the parent folder would be imported with from .. import module .


1 Answers

Python searches for several different files for any given import including a directory by that name and containing an __init__.py, an .so file for pure-native Python modules and .pyc files which can be used even if the .py is removed.

Run strace -o trace_output.txt python to see how this works. Partial example for import md5:

stat("/usr/lib/python2.7/md5", 0x7fff81ff16d0) = -1 ENOENT (No such file or directory)
open("/usr/lib/python2.7/md5.x86_64-linux-gnu.so", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/lib/python2.7/md5.so", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/lib/python2.7/md5module.so", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/lib/python2.7/md5.py", O_RDONLY) = 3

On my setup, it actually searches:

  • ~/.local/lib/python2.7/
  • /usr/local/lib/python2.7/dist-packages
  • /usr/lib/python2.7/dist-packages
  • /usr/lib/python2.7/

Within each directory, the pattern of calling stat to find a directory then looking for .so files, then .py is followed.

For more info on writing a purely native python module, see here: https://docs.python.org/2/extending/index.html

like image 190
Brian McFarland Avatar answered Sep 17 '22 04:09

Brian McFarland