Python
Programming
Development
File Path
Modules

How to retrieve a module's path?

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

Introduction

In Python, "the path of a module" usually means the file or package directory from which that module was imported. For ordinary modules, the answer is often as simple as reading module.__file__, but that is not universal.

Some modules are built in, some are namespace packages, and some are loaded through custom import machinery. A correct answer depends on whether you already have the module object and whether you need a filesystem path or only import metadata.

The Simple Case: __file__

For regular modules loaded from disk, __file__ is the most direct answer.

python
1import json
2from pathlib import Path
3
4module_path = Path(json.__file__)
5print(module_path)
6print(module_path.parent)

This usually points to one of the following:

  • a .py source file
  • a compiled .pyc file in some environments
  • an extension module such as .so or .pyd
  • a package __init__.py

If you only need to inspect a module that is already imported and you know it is file-backed, this is the best option.

Use importlib When You Have Only the Name

If you want to look up a module by name without importing it first, importlib.util.find_spec is a better fit.

python
1import importlib.util
2
3
4def module_origin(name: str) -> str | None:
5    spec = importlib.util.find_spec(name)
6    if spec is None:
7        return None
8    return spec.origin
9
10
11print(module_origin("json"))
12print(module_origin("sys"))

This is useful for tooling and diagnostics because it works from a string name and returns richer metadata through the module spec. For built-in modules, the origin may be something like built-in rather than a normal path, which is still informative.

Use inspect When You Already Have an Object

If you are starting with a class, function, or module object, inspect can be more convenient than manually checking attributes.

python
1import inspect
2import os
3
4print(inspect.getfile(os))
5print(inspect.getsourcefile(os))

inspect.getfile is broad and practical, especially when your code does not know in advance whether it is handling a module, class, or function. getsourcefile is narrower and may return None for objects without source code.

Module File Versus Package Directory

The path to the module file and the path to the containing package are related, but not identical. If the imported module is a package initializer, the file path might end in __init__.py, while the package directory is the parent folder.

python
1import requests
2from pathlib import Path
3
4module_file = Path(requests.__file__)
5package_dir = module_file.parent
6
7print("module file:", module_file)
8print("package dir:", package_dir)

That distinction matters when you want package resources rather than the exact module file. If you need bundled files, prefer modern resource APIs such as importlib.resources instead of manually building paths from __file__.

Built-In Modules and Special Cases

Not every module has a real filesystem path. A built-in module may not define __file__ at all:

python
import sys

print(hasattr(sys, "__file__"))

Namespace packages can also behave differently because they may span multiple directories. In those cases, thinking in terms of a single path can be misleading. The import system exposes those packages through spec and package metadata rather than one obvious source file.

This is why robust introspection code should not assume __file__ always exists.

A Small Utility Function

If you need a safe helper for arbitrary module names, combine spec lookup with a simple fallback strategy:

python
1import importlib
2import importlib.util
3
4
5def describe_module_location(name: str) -> str:
6    spec = importlib.util.find_spec(name)
7    if spec is None:
8        return "module not found"
9    if spec.origin is None:
10        return "origin unavailable"
11    return spec.origin
12
13
14for name in ["json", "sys", "pathlib"]:
15    print(name, "->", describe_module_location(name))

This is a better pattern for diagnostics than directly accessing module.__file__ and hoping every module behaves the same way.

Common Pitfalls

The most common mistake is assuming __file__ exists for every module. Built-in modules and some special loaders break that assumption immediately.

Another mistake is confusing the current runtime location with the original project source tree. In a virtual environment, container, or editable install, the module path reflects where Python imported the code from in that environment, not necessarily where your repository lives.

It is also easy to confuse a package directory with a module file. If you need resource loading, use package-resource APIs instead of manual parent-directory arithmetic whenever possible.

Finally, be careful when writing tooling around namespace packages. The idea of "one module path" may not match how the package is actually composed.

Summary

  • 'module.__file__ is the simplest way to get the path of a normal file-backed module.'
  • 'importlib.util.find_spec is better when you only have a module name or need richer metadata.'
  • 'inspect.getfile is useful when you already have a loaded object rather than only a name.'
  • Not every module has a real filesystem path, especially built-in modules.
  • Distinguish between a module file, a package directory, and package resources before choosing an approach.

Related reading
Free course
Beginner
7 lessons
2 hours
Tackling System Design Interview Problems

A short course that equips you with the skills to approach system design interviews methodically.

Start the free course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

All Rights Reserved.