Modules & Packaging

15 questions found

How does importlib let you dynamically import a module by name at runtime?

Advanced
importlib.import_module(name) programmatically imports a module given its string name, which is essential when the module to load isn't known until runtime -- such as a plugin system loading modules based on configuration or discovered files. It returns the module object just as a static `import` statement would bind it.
import importlib

module_name = 'json'  # could come from config or user input
mod = importlib.import_module(module_name)
print(mod.dumps({'key': 'value'}))
Real-world example A plugin architecture reads a list of enabled plugin module names from a config file and uses importlib.import_module() to load each one dynamically without hardcoding import statements.

Common follow-ups: How does importlib.reload() differ from a fresh import_module call?;How do you dynamically import from a file path, not just a module name?

Modules & Packaging;Decorators

What is the purpose of a `requirements.txt` file, and how does it differ from dependency declarations in pyproject.toml?

Intermediate
requirements.txt lists exact package versions to install via `pip install -r requirements.txt`, traditionally used for reproducible environments (especially pinned/locked versions from `pip freeze`). pyproject.toml's [project.dependencies] instead declares a package's abstract dependency requirements (often with version ranges) as part of its distributable metadata -- requirements.txt is often still used alongside it for locking exact versions in deployment or CI environments.
# requirements.txt (exact pins for reproducibility)
requests==2.31.0
click==8.1.7

# pyproject.toml (abstract ranges for a distributable package)
[project]
dependencies = ["requests>=2.28", "click>=8.0"]
Real-world example A team's CI pipeline installs from a pinned requirements.txt (generated via pip-compile) for exact reproducibility, while the package's pyproject.toml declares looser version ranges for compatibility with downstream consumers.

Common follow-ups: What is pip-tools and how does pip-compile generate lock files?;How do tools like Poetry unify both concerns?

Virtual Environments & Dependency Management;Modules & Packaging

How do entry points in packaging metadata enable a package to register CLI commands or plugins?

Advanced
Entry points, declared in pyproject.toml's [project.scripts] (for console commands) or [project.entry-points] (for arbitrary plugin groups), let a package advertise callables that other tools or the shell can discover and invoke by name after installation -- powering both `pip install`-generated CLI commands and plugin systems (like pytest plugins) that scan installed packages for registered entry points.
# pyproject.toml
[project.scripts]
mycli = "mypackage.cli:main"

# After pip install, running `mycli` in the shell calls mypackage.cli.main()
Real-world example A CLI tool distributed via PyPI declares a `[project.scripts]` entry point so that after `pip install mycli-tool`, users can simply type `mycli` in their terminal instead of `python -m mycli_tool`.

Common follow-ups: How does pytest discover plugins via entry points?;How do you inspect installed entry points programmatically with importlib.metadata?

Command-Line Interfaces (argparse);Virtual Environments & Dependency Management

What does 'editable install' (pip install -e .) mean, and why is it useful during development?

Intermediate
An editable install links the installed package directly to your source directory (via a path configuration) instead of copying files into site-packages, so changes to your source code take effect immediately without reinstalling. This is standard practice when developing a package that other local code or tests need to import as if it were properly installed.
# From the project root containing pyproject.toml
pip install -e .

# Now edits to mypackage/*.py are immediately visible
# to any code that does `import mypackage`
Real-world example A developer working on a library alongside a sample application installs the library with `pip install -e .` so changes to the library's source are picked up instantly when running the sample app, without repackaging.

Common follow-ups: How does editable install differ from adding the source directory to PYTHONPATH manually?;What changed with PEP 660's editable install standard?

Virtual Environments & Dependency Management;Modules & Packaging

How does the module search and caching system handle submodule imports like `import package.subpackage.module`?

Advanced
Python imports each level of a dotted path in order, caching each intermediate package in sys.modules (e.g., both 'package' and 'package.subpackage' get their own entries), and binds only the top-level name ('package') into the importing namespace -- accessing the submodule requires the full dotted path unless you explicitly import it with `from package.subpackage import module` or alias it.
import package.subpackage.module

# 'package' is bound in the namespace, not 'module' directly
print(package.subpackage.module.some_function())

# To bind 'module' directly:
from package.subpackage import module
module.some_function()
Real-world example A newcomer is confused why `import mypackage.utils` doesn't let them call `utils.helper()` directly -- understanding that only `mypackage` is bound clarifies they need `mypackage.utils.helper()` or a `from...import` instead.

Common follow-ups: Why does `import a.b.c` only bind 'a' in the namespace?;How does `import a.b.c as x` change this binding?

Modules & Packaging;Functions & Scope

Showing 11–15 of 15