-
Notifications
You must be signed in to change notification settings - Fork 1.4k
WIP: updated single_source_version with a much simpler page. #1578
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Closed
ChrisBarker-NOAA
wants to merge
20
commits into
pypa:main
from
ChrisBarker-NOAA:simplify_single_source
Closed
Changes from 6 commits
Commits
Show all changes
20 commits
Select commit
Hold shift + click to select a range
fb3ec88
updated single_source_version with a much simpler page -- essentially
ChrisBarker-NOAA c7fa00c
Update source/single_source_version.rst
ChrisBarker-NOAA 49842a8
Update source/single_source_version.rst
ChrisBarker-NOAA 840801f
Added links to build tools
ChrisBarker-NOAA 3724c8d
swap prefer for require
ChrisBarker-NOAA 5368956
replace text about __version__
ChrisBarker-NOAA 56db0d9
Update source/single_source_version.rst
ChrisBarker-NOAA 9bace5d
Update source/single_source_version.rst
ChrisBarker-NOAA 035c2bd
Update source/single_source_version.rst
ChrisBarker-NOAA dd1b70e
updated the __version__ description
ChrisBarker-NOAA eaf458a
Update source/single_source_version.rst
ChrisBarker-NOAA 29aa220
Update source/single_source_version.rst
ChrisBarker-NOAA de722f6
Update source/single_source_version.rst
ChrisBarker-NOAA 63061bd
Update source/single_source_version.rst
ChrisBarker-NOAA bfdc474
Update source/single_source_version.rst
ChrisBarker-NOAA c69e2c0
a few suggestions from the PR discussion
ChrisBarker-NOAA ddb077c
Merge branch 'simplify_single_source' of https://github.com/ChrisBark…
ChrisBarker-NOAA 648c427
minor formatting edit
ChrisBarker-NOAA b9ced45
Update source/single_source_version.rst
ChrisBarker-NOAA 0f5d2d3
a few more edits from the PR comments, and adding it back to the inde…
ChrisBarker-NOAA File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -7,111 +7,41 @@ Single-sourcing the Project Version | |
| :Page Status: Complete | ||
| :Last Reviewed: 2015-09-08 | ||
|
|
||
| One of the challenges in building packages is that the version string can be required in multiple places. | ||
|
|
||
| There are a few techniques to store the version in your project code without duplicating the value stored in | ||
| ``setup.py``: | ||
| * It needs to be specified when building the package (e.g. in :file:``pyproject.toml``) | ||
ChrisBarker-NOAA marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| - That will assure that it is properly assigned in the distribution file name, and in the installed package. | ||
ChrisBarker-NOAA marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
ChrisBarker-NOAA marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| #. Read the file in ``setup.py`` and parse the version with a regex. Example ( | ||
| from `pip setup.py <https://github.com/pypa/pip/blob/1.5.6/setup.py#L33>`_):: | ||
| * A package may, if the maintainers think it useful, to be able to determine the version of the package from Python code without relying on a package manager's metadata, set a top level ``__version__`` attribute. | ||
ChrisBarker-NOAA marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| The value of ``__version__`` attribute and that passed to the build system can (and should) be kept in sync in :ref:`the build systems's recommended way <how_to_set_version_links>`. | ||
|
|
||
| def read(*names, **kwargs): | ||
| with io.open( | ||
| os.path.join(os.path.dirname(__file__), *names), | ||
| encoding=kwargs.get("encoding", "utf8") | ||
| ) as fp: | ||
| return fp.read() | ||
| Should a package not set a top level ``__version__`` attribute, the version can still be accessed using ``importlib.metadata.version("distribution_name")``. | ||
ChrisBarker-NOAA marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| def find_version(*file_paths): | ||
| version_file = read(*file_paths) | ||
| version_match = re.search(r"^__version__ = ['\"]([^'\"]*)['\"]", | ||
| version_file, re.M) | ||
| if version_match: | ||
| return version_match.group(1) | ||
| raise RuntimeError("Unable to find version string.") | ||
| While different projects have different needs, it's important to make sure that there is a single source of truth for the version number. | ||
ChrisBarker-NOAA marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| setup( | ||
| ... | ||
| version=find_version("package", "__init__.py") | ||
| ... | ||
| ) | ||
| In general, the options are: | ||
|
|
||
| .. note:: | ||
| 1) If the code is in a version control system (VCS), e.g. git, then the version can be extracted from the VCS. | ||
ChrisBarker-NOAA marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| This technique has the disadvantage of having to deal with complexities of regular expressions. | ||
| 2) The version can be hard-coded into the `pyproject.toml` file -- and the build system can copy it into other locations it may be required. | ||
ChrisBarker-NOAA marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| #. Use an external build tool that either manages updating both locations, or | ||
| offers an API that both locations can use. | ||
| 3) The version string can be hard-coded into the source code -- either in a special purpose file, such as ``_version.txt``, or as a attribute in the ``__init__.py``, and the build system can extract it at build time. | ||
ChrisBarker-NOAA marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
ChrisBarker-NOAA marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| Few tools you could use, in no particular order, and not necessarily complete: | ||
| `bumpversion <https://pypi.python.org/pypi/bumpversion>`_, | ||
| `changes <https://pypi.python.org/pypi/changes>`_, `zest.releaser <https://pypi.python.org/pypi/zest.releaser>`_. | ||
|
|
||
| Consult your build system documentation for how to implement your preferred method. | ||
ChrisBarker-NOAA marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| #. Set the value to a ``__version__`` global variable in a dedicated module in | ||
| your project (e.g. ``version.py``), then have ``setup.py`` read and ``exec`` the | ||
| value into a variable. | ||
| .. _how_to_set_version_links: | ||
|
||
|
|
||
| Using ``execfile``: | ||
| Build System Version Handling | ||
| ---------------------------- | ||
|
|
||
| :: | ||
| * `Hatch <https://hatch.pypa.io/1.9/version/>`_ | ||
ChrisBarker-NOAA marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| execfile('...sample/version.py') | ||
| # now we have a `__version__` variable | ||
| # later on we use: __version__ | ||
| * `Setuptools <https://setuptools.pypa.io/en/latest/userguide/distribution.html#specifying-your-project-s-version>`_ | ||
|
|
||
| Using ``exec``: | ||
| - `setuptools_scm <https://setuptools-scm.readthedocs.io/en/latest/>`_ | ||
|
|
||
| :: | ||
| * `Flit <https://flit.pypa.io/en/stable/>`_ | ||
|
|
||
| version = {} | ||
| with open("...sample/version.py") as fp: | ||
| exec(fp.read(), version) | ||
| # later on we use: version['__version__'] | ||
| * `PDM <https://pdm-project.org/en/latest/reference/pep621/#__tabbed_1_2>`_ | ||
|
|
||
| Example using this technique: `warehouse <https://github.com/pypa/warehouse/blob/master/warehouse/__about__.py>`_. | ||
|
|
||
| #. Place the value in a simple ``VERSION`` text file and have both ``setup.py`` | ||
| and the project code read it. | ||
|
|
||
| :: | ||
|
|
||
| with open(os.path.join(mypackage_root_dir, 'VERSION')) as version_file: | ||
| version = version_file.read().strip() | ||
|
|
||
| An advantage with this technique is that it's not specific to Python. Any | ||
| tool can read the version. | ||
|
|
||
| .. warning:: | ||
|
|
||
| With this approach you must make sure that the ``VERSION`` file is included in | ||
| all your source and binary distributions. | ||
|
|
||
| #. Set the value in ``setup.py``, and have the project code use the | ||
| ``pkg_resources`` API. | ||
|
|
||
| :: | ||
|
|
||
| import pkg_resources | ||
| assert pkg_resources.get_distribution('pip').version == '1.2.0' | ||
|
|
||
| Be aware that the ``pkg_resources`` API only knows about what's in the | ||
| installation metadata, which is not necessarily the code that's currently | ||
| imported. | ||
|
|
||
|
|
||
| #. Set the value to ``__version__`` in ``sample/__init__.py`` and import | ||
| ``sample`` in ``setup.py``. | ||
|
|
||
| :: | ||
|
|
||
| import sample | ||
| setup( | ||
| ... | ||
| version=sample.__version__ | ||
| ... | ||
| ) | ||
|
|
||
| Although this technique is common, beware that it will fail if | ||
| ``sample/__init__.py`` imports packages from ``install_requires`` | ||
| dependencies, which will very likely not be installed yet when ``setup.py`` | ||
| is run. | ||
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.