598

How do I learn where the source file for a given Python module is installed? Is the method different on Windows than on Linux?

I'm trying to look for the source of the datetime module in particular, but I'm interested in a more general answer as well.

Zizouz212
  • 4,908
  • 5
  • 42
  • 66
Daryl Spitzer
  • 143,156
  • 76
  • 154
  • 173

20 Answers20

453

For a pure python module you can find the source by looking at themodule.__file__. The datetime module, however, is written in C, and therefore datetime.__file__ points to a .so file (there is no datetime.__file__ on Windows), and therefore, you can't see the source.

If you download a python source tarball and extract it, the modules' code can be found in the Modules subdirectory.

For example, if you want to find the datetime code for python 2.6, you can look at

Python-2.6/Modules/datetimemodule.c

You can also find the latest version of this file on github on the web at https://github.com/python/cpython/blob/main/Modules/_datetimemodule.c

Moe
  • 28,607
  • 10
  • 51
  • 67
  • If you edit your answer to indicate that datetime.__file__ points to a .so on Linux & Mac OS X (though on Windows the datetime module object has no __file__ attribute), I'll accept your answer. – Daryl Spitzer Nov 06 '08 at 19:06
  • Actually on Windows (at least on the version I'm using), datetime just doesn't have a __file__ attribute. – Daryl Spitzer Nov 06 '08 at 19:15
  • 1
    Works great for self-installed modules. – fytao Apr 19 '22 at 02:47
266

Running python -v from the command line should tell you what is being imported and from where. This works for me on Windows and Mac OS X.

C:\>python -v
# installing zipimport hook
import zipimport # builtin
# installed zipimport hook
# C:\Python24\lib\site.pyc has bad mtime
import site # from C:\Python24\lib\site.py
# wrote C:\Python24\lib\site.pyc
# C:\Python24\lib\os.pyc has bad mtime
import os # from C:\Python24\lib\os.py
# wrote C:\Python24\lib\os.pyc
import nt # builtin
# C:\Python24\lib\ntpath.pyc has bad mtime
...

I'm not sure what those bad mtime's are on my install!

jblocksom
  • 14,127
  • 5
  • 34
  • 30
150

I realize this answer is 4 years late, but the existing answers are misleading people.

The right way to do this is never __file__, or trying to walk through sys.path and search for yourself, etc. (unless you need to be backward compatible beyond 2.1).

It's the inspect module—in particular, getfile or getsourcefile.

Unless you want to learn and implement the rules (which are documented, but painful, for CPython 2.x, and not documented at all for other implementations, or 3.x) for mapping .pyc to .py files; dealing with .zip archives, eggs, and module packages; trying different ways to get the path to .so/.pyd files that don't support __file__; figuring out what Jython/IronPython/PyPy do; etc. In which case, go for it.

Meanwhile, every Python version's source from 2.0+ is available online at http://hg.python.org/cpython/file/X.Y/ (e.g., 2.7 or 3.3). So, once you discover that inspect.getfile(datetime) is a .so or .pyd file like /usr/local/lib/python2.7/lib-dynload/datetime.so, you can look it up inside the Modules directory. Strictly speaking, there's no way to be sure of which file defines which module, but nearly all of them are either foo.c or foomodule.c, so it shouldn't be hard to guess that datetimemodule.c is what you want.

abarnert
  • 354,177
  • 51
  • 601
  • 671
  • 3
    Why is the is `__file__` not applicable for non-builtins? I understand where crawling sys.path can be painful (especially without knowing about meta_path), but is your concern about namespacing between `__file__` definitions and binaries? –  Jan 06 '15 at 15:56
  • 2
    I do this in 2.7.8 on datetime and just get a TypeError for both getfile and getsourcefile. Personally I have multiple versions of python installed and I need to know WHICH version of datetimemodule.c it's pointed at, because right now I know it's not pointed at the one it should be pointed at given the interpreter version that's running... – mmitchell Apr 02 '15 at 21:39
  • 1
    @mmitchell: If you're getting a TypeError from inspect.getfile(datetime), assuming datetime is actually the module and not something else you've assigned to the same name, I'm pretty sure that means you made a custom build to statically link in datetime to the interpreter instead of making it a loadable module. But there could be other reasons I haven't thought of. You need to ask a new question, and give a lot more info to reproduce this. – abarnert Apr 03 '15 at 22:37
  • @mmitchell: Meanwhile, there's no way to find out which version of datetimemodule.c it's pointing at, because it's not pointing at datetimemodule.c, it's pointing at a compiled module built from that C file; the C file may not exist on your system, may have been edited since you compiled it, whatever. – abarnert Apr 03 '15 at 22:38
  • @tristan: I'm not sure I understand what you're asking, but maybe this will answer it: Whenever `__file__` works, `inspect.getfile` works; there is no situation where guessing whether to use `__file__` will be better than just using the inspect module. – abarnert Apr 03 '15 at 22:40
  • IIRC, when I wrote that, I think I was commenting on the fact that you're telling people to always avoid simply just using `__file__` or doing a bit of looking. –  Apr 03 '15 at 23:19
  • 1
    Yeah I know how compilation works, I was going with the ".c" for consistency with your answer. ;) I wasn't expecting a full solution to my problem either, just pointing out that your answer isn't working. I tested on a clean, vanilla install of 2.7.8 and got the error so it's nothing to do with custom stuff -- it just doesn't work on Windows. – mmitchell Apr 06 '15 at 16:53
  • @mmitchell: You're right, Windows sucks, at least for Python 2.x. As far as I can tell from looking under the hood, the information just isn't accessible at all. In 3.4 it's simple to find the file that would be imported by "import foo" (assuming it's actually a file, as opposed to, say, a member of a zip archive), which is almost always right (unless you, say, edited sys.path after the import), but in 2.7 that doesn't exist, and faking it is tough and not very robust. – abarnert Apr 07 '15 at 23:06
  • @mmitchell: One thing that _should_ work, but I don't want to code it. :) The HANDLE to the DLL is stored inside the object at the C API level, and you can ask Win32 for paths and handles of DLLs, so with ctypes.pythonapi and pywin32, this should be doable. (It looks like .pyd files inside .zip archives are loaded by unpacking them to a temp location, so that's what you presumably get for anything but a straightforward import; not sure how useful it is, but...) – abarnert Apr 07 '15 at 23:09
131

If you're using pip to install your modules, just pip show $module the location is returned.

James Mark Mackenzie
  • 1,439
  • 1
  • 9
  • 4
  • 19
    (I think `$module` was meant as a placeholder variable, not literally what one would type. E.g., `m=numpy; pip show $m` ...etc, for any `m`) – michael Sep 16 '18 at 03:45
  • 1
    this should be marked as the most accurate answer for the question asked. – Rahul Goyal Mar 20 '20 at 06:50
  • 3
    Actually, this method is not reliable if you have multiple pythons installed, because the `pip` that is executed from the shell may not be the same one called within python. Instead, you should do `python -m pip show $module`. See [umesh's answer](https://stackoverflow.com/questions/269795/how-do-i-find-the-location-of-python-module-sources/61095592#61095592). – wisbucky Aug 29 '21 at 20:40
81

The sys.path list contains the list of directories which will be searched for modules at runtime:

python -v
>>> import sys
>>> sys.path
['', '/usr/local/lib/python25.zip', '/usr/local/lib/python2.5', ... ]
Ben Liyanage
  • 4,993
  • 1
  • 21
  • 23
Greg Hewgill
  • 951,095
  • 183
  • 1,149
  • 1,285
53

from the standard library try imp.find_module

>>> import imp
>>> imp.find_module('fontTools')
(None, 'C:\\Python27\\lib\\site-packages\\FontTools\\fontTools', ('', '', 5))
>>> imp.find_module('datetime')
(None, 'datetime', ('', '', 6))
Codespaced
  • 537
  • 5
  • 9
  • 1
    This is fantastic. I `apt-get remove`'d DataDog and could still import it. This helped me find where the files were (so I could delete them) when the other solutions didn't help. – s g May 14 '15 at 01:00
  • 1
    for python3.x, the `imp` package is deprecated (since version 3.4) in favor of `importlib` (since 3.1) https://docs.python.org/3.6/library/imp.html – michael Sep 16 '18 at 03:53
  • 5
    Now you need to use it in this way for python3. `import importlib` then `importlib.util.find_spec('fontTools')` – Medhat Jan 28 '20 at 17:52
  • This is the answer. If you run python interactive session when a virtual environment is activated you can get details for both the modules in the VE and in the underlying python installation, unlike `python -m pip show xxx` for example, which appears only to show pip-installed modules. Confirm that `imp` is deprecated and "slated for removal in Python 3.12" – mike rodent Apr 16 '23 at 13:59
46

datetime is a builtin module, so there is no (Python) source file.

For modules coming from .py (or .pyc) files, you can use mymodule.__file__, e.g.

> import random
> random.__file__
'C:\\Python25\\lib\\random.pyc'
Bjarke Ebert
  • 1,920
  • 18
  • 26
14

Here's a one-liner to get the filename for a module, suitable for shell aliasing:

echo 'import sys; t=__import__(sys.argv[1],fromlist=[\".\"]); print(t.__file__)'  | python - 

Set up as an alias:

alias getpmpath="echo 'import sys; t=__import__(sys.argv[1],fromlist=[\".\"]); print(t.__file__)'  | python - "

To use:

$ getpmpath twisted
/usr/lib64/python2.6/site-packages/twisted/__init__.pyc
$ getpmpath twisted.web
/usr/lib64/python2.6/site-packages/twisted/web/__init__.pyc
Azat Ibrakov
  • 9,998
  • 9
  • 38
  • 50
Ernest
  • 889
  • 8
  • 11
  • The first version is wrong, too many backslashes. From a shell script, this works for me: `echo 'import sys; t=__import__(sys.argv[1],fromlist=["."]); print(t.__file__)' | python - "$@"` – Metamorphic Nov 13 '20 at 07:55
13

On windows you can find the location of the python module as shown below:i.e find rest_framework module enter image description here

Duncan O. N.
  • 778
  • 12
  • 24
13

In the python interpreter you could import the particular module and then type help(module). This gives details such as Name, File, Module Docs, Description et al.

Ex:

import os

help(os)


Help on module os:

NAME

os - OS routines for Mac, NT, or Posix depending on what system we're on.

FILE

/usr/lib/python2.6/os.py

MODULE DOCS

http://docs.python.org/library/os

DESCRIPTION

This exports:

- all functions from posix, nt, os2, or ce, e.g. unlink, stat, etc.

- os.path is one of the modules posixpath, or ntpath

- os.name is 'posix', 'nt', 'os2', 'ce' or 'riscos'

et al

Vijay
  • 924
  • 7
  • 14
  • This gave me a full path to the module file while other answers only gave relative paths. Thanks. – Jerther Mar 10 '17 at 14:30
11

New in Python 3.2, you can now use e.g. code_info() from the dis module: http://docs.python.org/dev/whatsnew/3.2.html#dis

evdama
  • 2,166
  • 1
  • 16
  • 17
10

Check out this nifty "cdp" command to cd to the directory containing the source for the indicated Python module:

cdp () {
  cd "$(python -c "import os.path as _, ${1}; \
    print _.dirname(_.realpath(${1}.__file__[:-1]))"
  )"
}
ire_and_curses
  • 68,372
  • 23
  • 116
  • 141
Daryl Spitzer
  • 143,156
  • 76
  • 154
  • 173
8

Just updating the answer in case anyone needs it now, I'm at Python 3.9 and using Pip to manage packages. Just use pip show, e.g.:

pip show numpy

It will give you all the details with the location of where pip is storing all your other packages.

bcb
  • 1,977
  • 2
  • 22
  • 21
Ritik Attri
  • 109
  • 1
  • 2
7

Another way to check if you have multiple python versions installed, from the terminal.

$ python3 -m pip show pyperclip

Location: /Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-

$ python -m pip show pyperclip

Location: /Users/umeshvuyyuru/Library/Python/2.7/lib/python/site-packages

wisbucky
  • 33,218
  • 10
  • 150
  • 101
vub
  • 119
  • 2
  • 3
5

On Ubuntu 12.04, for example numpy package for python2, can be found at:

/usr/lib/python2.7/dist-packages/numpy

Of course, this is not generic answer

nexayq
  • 606
  • 1
  • 9
  • 13
1

Not all python modules are written in python. Datetime happens to be one of them that is not, and (on linux) is datetime.so.

You would have to download the source code to the python standard library to get at it.

Dave Forgac
  • 3,146
  • 7
  • 39
  • 54
JimB
  • 104,193
  • 13
  • 262
  • 255
1

For those who prefer a GUI solution: if you're using a gui such as Spyder (part of the Anaconda installation) you can just right-click the module name (such as "csv" in "import csv") and select "go to definition" - this will open the file, but also on the top you can see the exact file location ("C:....csv.py")

Anon
  • 619
  • 1
  • 9
  • 18
1

If you are not using interpreter then you can run the code below:

import site
print (site.getsitepackages())

Output:

['C:\\Users\\<your username>\\AppData\\Local\\Programs\\Python\\Python37', 'C:\\Users\\<your username>\\AppData\\Local\\Programs\\Python\\Python37\\lib\\site-packages']

The second element in Array will be your package location. In this case:

C:\Users\<your username>\AppData\Local\Programs\Python\Python37\lib\site-packages
Supradeep
  • 161
  • 1
  • 11
0

In an IDE like Spyder, import the module and then run the module individually. enter image description here

  • Import and print the `str()` of the model is a more accurate description of what you are doing in the screenshot, plus the IDE seems irrelevant for this solution – mousetail Apr 06 '20 at 14:27
  • 2
    Welcome to StackOverflow! Please do not post code using images. Images are hard to read, cannot be searched, and are not viewable to some readers. Instead, please include any relevant code directly in the body of your answer. – Brian61354270 Apr 06 '20 at 20:18
-1

as written above in python just use help(module) ie

import fractions

help(fractions)

if your module, in the example fractions, is installed then it will tell you location and info about it, if its not installed it says module not available

if its not available it doesn't come by default with python in which case you can check where you found it for download info

Harry P
  • 1
  • 1