How can I get the version defined in setup.py setuptools in my package?
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
If your package needs to know its own version, the wrong approach is to import setup.py at runtime. The reliable approach is to keep the version in normal package code and let setup.py read from that source, or to query installed package metadata after installation.
Do Not Import setup.py From Your Package
setup.py is a build script, not an application module. Importing it at runtime can trigger packaging logic, dependency side effects, or path issues that do not belong inside your package.
Instead of asking "how do I read the version from setup.py," the better design is "how do I make setup.py and my package share one source of truth."
Put the Version in Package Code
A common pattern is to define the version in a module:
Then read that value in setup.py:
Now your package can access __version__ directly:
This keeps the value in ordinary Python code instead of forcing runtime code to inspect packaging metadata.
Use a Dedicated _version.py File
Many projects prefer not to store extra metadata in __init__.py. A small dedicated module is cleaner:
Package import:
Build script:
This pattern makes the ownership of the version string obvious and avoids accidental import-time side effects from the rest of the package.
Query the Installed Package Version
If the package is already installed and you want the installed version, use importlib.metadata:
This reads package metadata from the installed distribution, not from setup.py. That is the right choice when you want to know what the environment actually installed.
For Python versions before importlib.metadata was built in, older projects often used pkg_resources, but importlib.metadata is the lighter modern choice.
Why a Single Source of Truth Matters
Version drift is easy to create if you hardcode the value in more than one place. For example:
- '
setup.pysays1.4.0' - '
mypackage.__version__says1.3.9' - The installed wheel metadata says something else
That leads to confusing bug reports and deployment mistakes. The solution is to define the version once and reference it everywhere else.
Practical Recommendation
For a setuptools-based project that still uses setup.py, the best baseline is:
- Store
__version__in package code. - Read that value from
setup.py. - Use
importlib.metadata.version()when you need the installed distribution version.
If you are maintaining a modern packaging setup, you may eventually move to pyproject.toml, but the single-source principle remains the same.
Common Pitfalls
- Importing
setup.pyinside the package at runtime. - Duplicating the version string in multiple files and letting them drift apart.
- Reading installed package metadata when the real question is about source-tree version during development.
- Putting complex imports in the file that defines
__version__, which makes setup-time reads fragile. - Assuming
setup.pyis the authoritative runtime source rather than a build-time consumer of version data.
Summary
- Do not import
setup.pyfrom your package just to read the version. - Keep the version in package code, usually as
__version__. - Let
setup.pyread that version so there is only one source of truth. - Use
importlib.metadata.version()when you need the installed package version. - A simple
_version.pymodule is often the cleanest implementation.

