Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there any practical reason why I must have a code version embedded in python source code?

Is there any practical reason why I must have a code version embedded in the source code? Explicitly I'm interested in setup.py but also some use __version__. By "embed in source code" I mean must I write the version number in as text in the file rather than populating python fields by other means.

In other languages, I've set up the build scripts to be aware of git tags and then managed version numbers entirely through tags. This means that there is never a commit in the repo to "bump the version number". All I have to do is tag the commit for the new version and run the build.

So as a theoretical example I might:

def _get_version()
    command = ['git', 'describe', '--tags', '--match' 'versions/[0-9]*.[0-9]*']
    result = subprocess.run(command, stdout=subprocess.PIPE).stdout.decode('utf-8')
    return result.replace('-', '+', 1).replace('versions/', '')

setuptools.setup(
    name="example-pkg-YOUR-USERNAME-HERE", # Replace with your own username
    version=_get_version(),
    author="Example Author",
    author_email="[email protected]",
    description="A small example package",
    long_description=long_description,
    long_description_content_type="text/markdown",
    url="https://github.com/pypa/sampleproject",
    packages=setuptools.find_packages(),
    classifiers=[
        "Programming Language :: Python :: 3",
        "License :: OSI Approved :: MIT License",
        "Operating System :: OS Independent",
    ],
    python_requires='>=3.6',
)

What's not clear to me is whether or not this would work. Is the result of setuptools.setup parsed before uploading to a package repository or when it's downloaded by a third party? Of course, the git repo is only available before it's uploaded not when the package downloaded by someone else through pip.

Likewise, am I correct in thinking this would utterly fail to populate if applied to a __version__ file?

like image 744
Philip Couling Avatar asked Sep 29 '20 22:09

Philip Couling


1 Answers

Technically, you don't have to embed the version in your package. Passing the version to setuptools.setup() will ensure that it will be save in the package metadata for the packaging mechanism to handle (e.g. setuptools, pip, poetry, etc.).

It has been deemed is a good practice to also include it to the package as it could be useful when you write code which needs to check version of the library (the __version__ "dundler" is first mentioned in PEP 8 and clarified in PEP 396), but it might not be necessary anymore since Python 3.8 embed importlib.metadata:

>>> from importlib.metadata import version
>>> version("wheel")
'0.35.1'

So your solution would work fine, but I would recommend you to use setuptools-scm instead which will prevent you for managing the subprocess yourself.

like image 106
jeremyr Avatar answered Oct 17 '22 04:10

jeremyr