How could I get the version defined in from my package (for --version, or other purposes)?

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

You could make a in your package with a __version__ line, then read it from using execfile('mypackage/'), so that it sets __version__ in the namespace.

Warning about race condition during install

By the way, DO NOT import your package from your 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.

example study: mymodule

Imagine this configuration:

Then imagine some usual scenario where you have dependencies and looks like:

    install_requires=['dep1','dep2', ...]

And an example

from mymodule.myclasses import *
from mymodule.version import __version__

And for example

# these are not installed on your system.
# importing mymodule.myclasses would give ImportError
import dep1
import dep2

problem #1: importing mymodule during setup

If your imports mymodule then during setup you would most likely get an ImportError. This is a very common error when your package has dependencies. If your package does not have other dependencies than the builtins, you may be safe; however this isn’t a good practice. The reason for that is that it is not future-proof; say tomorrow your code needs to consume some other dependency.

problem #2: where’s my __version__ ?

If you hardcode __version__ in then it may not match the version that you would ship in your module. To be consistent, you would put it in one place and read it from the same place when you need it. Using import you may get the problem #1.

solution: à la setuptools

You would use a combination of open, exec and provide a dict for exec to add variables:

from setuptools import setup, find_packages
from distutils.util import convert_path

main_ns = {}
ver_path = convert_path('mymodule/')
with open(ver_path) as ver_file:
    exec(, main_ns)


And in mymodule/ expose the version:

__version__ = 'some.semantic.version'

This way, the version is shipped with the module, and you do not have issues during setup trying to import a module that has missing dependencies (yet to be installed).

The best technique is to define __version__ in your product code, then import it into from there. This gives you a value you can read in your running module, and have only one place to define it.

The values in are not installed, and doesn’t stick around after installation.

What I did (for example) in

# coverage/
__version__ = "3.2"

from coverage import __version__

    version = __version__,

UPDATE (2017): no longer imports itself to get the version. Importing your own code can make it uninstallable, because you product code will try to import dependencies, which aren’t installed yet, because is what installs them.

Your question is a little vague, but I think what you are asking is how to specify it.

You need to define __version__ like so:

__version__ = '1.4.4'

And then you can confirm that knows about the version you just specified:

% ./ --version

I wasn’t happy with these answers… didn’t want to require setuptools, nor make a whole separate module for a single variable, so I came up with these.

For when you are sure the main module is in pep8 style and will stay that way:

version = '0.30.unknown'
with file('mypkg/') as f:
    for line in f:
        if line.startswith('__version__'):
            _, _, version = line.replace("'", '').split()

If you’d like to be extra careful and use a real parser:

import ast
version = '0.30.unknown2'
with file('mypkg/') as f:
    for line in f:
        if line.startswith('__version__'):
            version = ast.parse(line).body[0].value.s
            break is somewhat of a throwaway module so not an issue if it is a bit ugly.

Update: funny enough I’ve moved away from this in recent years and started using a separate file in the package called I put lots of meta data in there that I might want to change frequently. So, not just for one value.

With a structure like this:

where contains:

__version__ = 'version_string'

You can do this in

import sys

sys.path[0:0] = ['mymodule']

from version import __version__

This won’t cause any problem with whatever dependencies you have in your mymodule/

Create a file in your source tree, e.g. in yourbasedir/yourpackage/ . Let that file contain only a single line of code, like this:

__version__ = "1.1.0-r4704"

Then in your, open that file and parse out the version number like this:

verstr = "unknown"
    verstrline = open('yourpackage/', "rt").read()
except EnvironmentError:
    pass # Okay, there is no version file.
    VSRE = r"^__version__ = ['\"]([^'\"]*)['\"]"
    mo =, verstrline, re.M)
    if mo:
        verstr =
        raise RuntimeError("unable to find version in yourpackage/")

Finally, in yourbasedir/yourpackage/ import _version like this:

__version__ = "unknown"
    from _version import __version__
except ImportError:
    # We're running in a tree that doesn't have a, so we don't know what our version is.

An example of code that does this is the “pyutil” package that I maintain. (See PyPI or google search — stackoverflow is disallowing me from including a hyperlink to it in this answer.)

@pjeby is right that you shouldn’t import your package from its own That will work when you test it by creating a new Python interpreter and executing in it first thing: python, but there are cases when it won’t work. That’s because import youpackage doesn’t mean to read the current working directory for a directory named “yourpackage”, it means to look in the current sys.modules for a key “yourpackage” and then to do various things if it isn’t there. So it always works when you do python because you have a fresh, empty sys.modules, but this doesn’t work in general.

For example, what if py2exe is executing your as part of the process of packaging up an application? I’ve seen a case like this where py2exe would put the wrong version number on a package because the package was getting its version number from import myownthing in its, but a different version of that package had previously been imported during the py2exe run. Likewise, what if setuptools, easy_install, distribute, or distutils2 is trying to build your package as part of a process of installing a different package that depends on yours? Then whether your package is importable at the time that its is being evaluated, or whether there is already a version of your package that has been imported during this Python interpreter’s life, or whether importing your package requires other packages to be installed first, or has side-effects, can change the results. I’ve had several struggles with trying to re-use Python packages which caused problems for tools like py2exe and setuptools because their imports the package itself in order to find its version number.

By the way, this technique plays nicely with tools to automatically create the yourpackage/ file for you, for example by reading your revision control history and writing out a version number based on the most recent tag in revision control history. Here is a tool that does that for darcs: and here is a code snippet which does the same thing for git:

This should also work, using regular expressions and depending on the metadata fields to have a format like this:

__fieldname__ = 'value'

Use the following at the beginning of your

import re
main_py = open('').read()
metadata = dict(re.findall("__([a-z]+)__ = '([^']+)'", main_py))

After that, you can use the metadata in your script like this:

print 'Author is:', metadata['author']
print 'Version is:', metadata['version']

We wanted to put the meta information about our package pypackagery in, but could not since it has third-party dependencies as PJ Eby already pointed out (see his answer and the warning regarding the race condition).

We solved it by creating a separate module that contains only the meta information:

"""Define meta information about pypackagery package."""

__title__ = 'pypackagery'
__description__ = ('Package a subset of a monorepo and '
                   'determine the dependent packages.')
__url__ = ''
__version__ = '1.0.0'
__author__ = 'Marko Ristin'
__author_email__ = '[email protected]'
__license__ = 'MIT'
__copyright__ = 'Copyright 2018 Parquery AG'

then imported the meta information in packagery/

# ...

from pypackagery_meta import __title__, __description__, __url__, \
    __version__, __author__, __author_email__, \
    __license__, __copyright__

# ...

and finally used it in

import pypackagery_meta

    # ...
    py_modules=['packagery', 'pypackagery_meta'],

You must include pypackagery_meta into your package with py_modules setup argument. Otherwise, you can not import it upon installation since the packaged distribution would lack it.

To avoid importing a file (and thus executing its code) one could parse it and recover the version attribute from the syntax tree:

# assuming 'path' holds the path to the file

import ast

with open(path, 'rU') as file:
    t = compile(, path, 'exec', ast.PyCF_ONLY_AST)
    for node in (n for n in t.body if isinstance(n, ast.Assign)):
        if len(node.targets) == 1:
            name = node.targets[0]
            if isinstance(name, ast.Name) and \
           in ('__version__', '__version_info__', 'VERSION'):
                v = node.value
                if isinstance(v, ast.Str):
                    version = v.s
                if isinstance(v, ast.Tuple):
                    r = []
                    for e in v.elts:
                        if isinstance(e, ast.Str):
                        elif isinstance(e, ast.Num):
                    version = '.'.join(r)

This code tries to find the __version__ or VERSION assignment at the top level of the module return is string value. The right side can be either a string or a tuple.

There’s a thousand ways to skin a cat — here’s mine:

# Copied from (and hacked):
def get_version(filename):
    import os
    import re

    here = os.path.dirname(os.path.abspath(__file__))
    f = open(os.path.join(here, filename))
    version_file =
    version_match ="^__version__ = ['\"]([^'\"]*)['\"]",
                              version_file, re.M)
    if version_match:
    raise RuntimeError("Unable to find version string.")

Cleaning up from @gringo-suave:

from itertools import ifilter
from os import path
from ast import parse

with open(path.join('package_name', '')) as f:
    __version__ = parse(next(ifilter(lambda line: line.startswith('__version__'),

Now this is gross and needs some refining (there may even be an uncovered member call in pkg_resources that I missed), but I simply do not see why this doesn’t work, nor why no one has suggested it to date (Googling around has not turned this up)…note that this is Python 2.x, and would require requiring pkg_resources (sigh):

import pkg_resources

version_string = None
    if pkg_resources.working_set is not None:
        disto_obj = pkg_resources.working_set.by_key.get('<my pkg name>', None)
        # (I like adding ", None" to gets)
        if disto_obj is not None:
            version_string = disto_obj.version
except Exception:
    # Do something

Simple and straight, create a file called source/package_name/ with the following contents:

#!/usr/bin/env python3
# -*- coding: UTF-8 -*-
__version__ = "2.6.9"

Then, on your file source/package_name/, you import the version for other people to use:

#!/usr/bin/env python3
# -*- coding: UTF-8 -*-
from .version import __version__

Now, you can put this on

#!/usr/bin/env python3
# -*- coding: UTF-8 -*-
import re
import sys

    version_file = open( filepath )
    __version__ ,= re.findall( '__version__ = "(.*)"', )

except Exception as error:
    __version__ = "0.0.1"
    sys.stderr.write( "Warning: Could not open '%s' due %s\n" % ( filepath, error ) )


Tested this with Python 2.7, 3.3, 3.4, 3.5, 3.6 and 3.7 on Linux, Windows and Mac OS. I used on my package which has Integration and Unit Tests for all theses platforms. You can see the results from .travis.yml and appveyor.yml here:


An alternate version is using context manager:

#!/usr/bin/env python3
# -*- coding: UTF-8 -*-
import re
import sys


    with open( filepath ) as file:
        __version__ ,= re.findall( '__version__ = "(.*)"', )

except Exception as error:
    __version__ = "0.0.1"
    sys.stderr.write( "Warning: Could not open '%s' due %s\n" % ( filepath, error ) )

You can also be using the codecs module to handle unicode errors both on Python 2.7 and 3.6

#!/usr/bin/env python3
# -*- coding: UTF-8 -*-
import re
import sys
import codecs


    with filepath, 'r', errors="ignore" ) as file:
        __version__ ,= re.findall( '__version__ = "(.*)"', )

except Exception as error:
    __version__ = "0.0.1"
    sys.stderr.write( "Warning: Could not open '%s' due %s\n" % ( filepath, error ) )

If you are writing a Python module 100% in C/C++ using Python C Extensions, you can do the same thing, but using C/C++ instead of Python.

On this case, create the following

#!/usr/bin/env python3
# -*- coding: UTF-8 -*-
import re
import sys
import codecs
from setuptools import setup, Extension


    with filepath, 'r', errors="ignore" ) as file:
        __version__ ,= re.findall( '__version__ = "(.*)"', )

except Exception as error:
    __version__ = "0.0.1"
    sys.stderr.write( "Warning: Could not open '%s' due %s\n" % ( filepath, error ) )

        version = __version__,

        package_data = {
                '': [ '**.txt', '**.md', '**.py', '**.h', '**.hpp', '**.c', '**.cpp' ],

        ext_modules = [
                sources = [
                include_dirs = ['source'],

Which reads the version from the file version.h:

const char* __version__ = "1.0.12";

But, do not forget to create the to include the version.h file:

include LICENSE.txt

recursive-include source *.h

And it is integrated into the main application with:

#include <Python.h>
#include "version.h"

// create the module
PyMODINIT_FUNC PyInit_package_name(void)
    PyObject* thismodule;

    PyObject_SetAttrString( thismodule, "__version__", Py_BuildValue( "s", __version__ ) );



  1. python open file error
  2. Define a global in a Python module from a C API
  3. How to include package data with setuptools/distribute?
  5. How to use setuptools packages and ext_modules with the same name?
  6. Is it possible to include subdirectories using dist utils ( as part of package data?

deploy package to server and file naming convention for indices packages :

example for pip dynamic version conversion:

  • win:

    • test_pkg-1.0.0-cp36-cp36m-win_amd64.whl
    • test_pkg-1.0.0-py3.6-win-amd64.egg
  • mac:

    • test_pkg-1.0.0-py3.7-macosx-10.12-x86_64.egg
    • test_pkg-1.0.0-py3.7-macosx-10.12-x86_64.whl
  • linux:
    • test_pkg-1.0.0-cp36-cp36m-linux_x86_64.whl
from setuptools_scm import get_version

def _get_version():

     dev_version = str(".".join(map(str, str(get_version()).split("+")[0]\

    return dev_version

Find the sample calls the dynamic pip version matching from git commit


# add few more for wheel wheel package ...conversion


For what is worth, I wrote getversion to solve this issue for one of our projects’ needs. It relies on a sequence of PEP-compliant strategies to return the version for a module, and adds some strategies for development mode (git scm).


from getversion import get_module_version

# Get the version of an imported module
from xml import dom
version, details = get_module_version(dom)


Why was this version found ? You can understand it from the details:

> print(details)
Version '' found for module 'xml.dom' by strategy 'get_builtin_module_version', after the following failed attempts:
 - Attempts for module 'xml.dom':
   - <get_module_version_attr>: module 'xml.dom' has no attribute '__version__'
 - Attempts for module 'xml':
   - <get_module_version_attr>: module 'xml' has no attribute '__version__'
   - <get_version_using_pkgresources>: Invalid version number: None
   - <get_builtin_module_version>: SUCCESS:

More can be found in the documentation.

I am using an environment variable as below

VERSION=0.0.0 python sdist bdist_wheel


import os


For consistency check with packer version, I am using below script.

PKG_VERSION=`python -c "import pkg; print(pkg.__version__)"`
if [ $PKG_VERSION == $VERSION ]; then
    python sdist bdist_wheel
    echo "Package version differs from set env variable"