Standard way to embed version into Python package?
Not directly an answer to your question, but you should consider naming it __version__
, not version
.
This is almost a quasi-standard. Many modules in the standard library use __version__
, and this is also used in lots of 3rd-party modules, so it's the quasi-standard.
Usually, __version__
is a string, but sometimes it's also a float or tuple.
As mentioned by S.Lott (Thank you!), PEP 8 says it explicitly:
Module Level Dunder Names
Module level "dunders" (i.e. names with two leading and two trailing
underscores) such as__all__
,__author__
,__version__
, etc.
should be placed after the module docstring but before any import
statements except from__future__
imports.
You should also make sure that the version number conforms to the format described in PEP 440 (PEP 386 a previous version of this standard).
How to have the python program version only in setup.cfg for runtime and packaging?
Two options I can think of – I'd go with the first.
1. Use setup.cfg
's attr:
support to read the version from the source
setup.cfg
[metadata]
version = attr:my_app.__version__
my_app/init.py
# ...
__version__ = '0.1.3'
2. Use importlib.metadata
to read the version from the installation metadata
(New in Python 3.8, has backports for older Pythons)
from importlib.metadata import version
my_version = version('my_app')
What is the correct way to share package version with setup.py and the package?
Set the version in setup.py
only, and read your own version with pkg_resources
, effectively querying the setuptools
metadata:
file: setup.py
setup(
name='foobar',
version='1.0.0',
# other attributes
)
file: __init__.py
from pkg_resources import get_distribution
__version__ = get_distribution('foobar').version
To make this work in all cases, where you could end up running this without having installed it, test for DistributionNotFound
and the distribution location:
from pkg_resources import get_distribution, DistributionNotFound
import os.path
try:
_dist = get_distribution('foobar')
# Normalize case for Windows systems
dist_loc = os.path.normcase(_dist.location)
here = os.path.normcase(__file__)
if not here.startswith(os.path.join(dist_loc, 'foobar')):
# not installed, but there is another version that *is*
raise DistributionNotFound
except DistributionNotFound:
__version__ = 'Please install this project with setup.py'
else:
__version__ = _dist.version
How can I get the version defined in setup.py (setuptools) in my package?
Interrogate version string of already-installed distribution
To retrieve the version from inside your package at runtime (what your question appears to actually be asking), you can use:
import pkg_resources # part of setuptools
version = pkg_resources.require("MyProject")[0].version
Store version string for use during install
If you want to go the other way 'round (which appears to be what other answer authors here appear to have thought you were asking), put the version string in a separate file and read that file's contents in setup.py
.
You could make a version.py in your package with a __version__
line, then read it from setup.py using execfile('mypackage/version.py')
, so that it sets __version__
in the setup.py namespace.
Warning about race condition during install
By the way, DO NOT import your package from your setup.py as suggested in another answer here: it will seem to work for you (because you already have your package's dependencies installed), but it will wreak havoc upon new users of your package, as they will not be able to install your package without manually installing the dependencies first.
How do I get a python module's version number through code?
Generalized answer from Matt's, do a dir(YOURMODULE)
and look for __version__
, VERSION
, or version
. Most modules like __version__
but I think numpy
uses version.version
Related Topics
Accessing Attributes on Literals Work on All Types, But Not 'Int'; Why
Generate a Random Letter in Python
Python Dictionary Keys. "In" Complexity
What's the Difference Between _Builtin_ and _Builtins_
How to Get a Raw, Compiled SQL Query from a SQLalchemy Expression
Typeerror: Unsupported Operand Type(S) for /: 'Str' and 'Str'
How to Select All Columns Whose Names Start with X in a Pandas Dataframe
Debugging (Displaying) SQL Command Sent to the Db by SQLalchemy
Typeerror: Module._Init_() Takes at Most 2 Arguments (3 Given)
Executing Multiple Statements with Postgresql via SQLalchemy Does Not Persist Changes
Using Multipartposthandler to Post Form-Data with Python
What Exactly Is Contained Within a Obj._Closure_
List() Uses Slightly More Memory Than List Comprehension
Subprocess Readline Hangs Waiting for Eof