single-source


Namesingle-source JSON
Version 0.4.0 PyPI version JSON
download
home_pagehttps://github.com/rabbit72/single-source
SummaryAccess to the project version in Python code for PEP 621-style projects
upload_time2024-06-11 10:08:33
maintainerDaniil Shadrin
docs_urlNone
authorDaniil Shadrin
requires_python<4.0,>=3.8
licenseMIT
keywords pyproject version __version__ poetry single source
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # Single-source: There is only one truth
> `single-source` helps to reduce the entropy in your Python project by keeping
> single source of truth.

The targets of this library are modern Python projects which want to have
one source of truth for version, name and etc.

At the moment, the library provides the single point for a package version.

It supports Python 3.8+.

## Quick start

```python
# root_package/__init__.py
from pathlib import Path
from single_source import get_version

__version__ = get_version(__name__, Path(__file__).parent.parent)
```

## Root of the problem

You use modern `pyproject.toml` and want to keep the version of your package
here:
```toml
# pyproject.toml
[tool.poetry]
name = "modern-project"
version = "0.1.0"
```

Let's imagine the version of your package is required in some place of the code.

Since you need the version in your Python code, you may want to duplicate the version by putting it as a string variable to some python file:
```python
# modern_project/__init__.py
__version__ = "0.1.0"

# modern_project/version.py
version = "0.1.0"
```

Then you realize you don't want to have the version in a python file and in pyproject.toml at the same time. It's harder to keep them consistent and easier to forget to bump both versions before release.

Also, you don't want to build the wheel by creating some script for auto incrementing the version in both places (and use it in your CI flow, for example). Instead you want use `poetry version` commands.

## Installation
You can install `single-source` via [pip](https://pip.pypa.io/en/stable/)
```bash
pip3 install single-source
```

or via [poetry](https://python-poetry.org/docs/#installation)
```bash
poetry add single-source
```

The library also available as
[a conda package](https://docs.conda.io/projects/conda/en/latest/) in
[conda-forge](https://anaconda.org/conda-forge/repo) channel
```bash
conda install single-source --channel conda-forge
```

## Advanced usage
### Changing default value
If it's not possible to get the version from package metadata or
there is no pyproject.toml `get_version` returns `""` - empty string by default.
You can change this value by providing a value as a `default_return` keyword argument.

```python
from pathlib import Path
from single_source import get_version

path_to_pyproject_dir = Path(__file__).parent.parent
__version__ = get_version(__name__, path_to_pyproject_dir, default_return=None)
```

### Raising an exception
You may want to raise an exception in case the version of the package
has not been found.
```python
from pathlib import Path
from single_source import get_version, VersionNotFoundError

path_to_pyproject_dir = Path(__file__).parent.parent
try:
    __version__ = get_version(__name__, path_to_pyproject_dir, fail=True)
except VersionNotFoundError:
    pass
```


### Not only pyproject.toml
You can use `single-source` even if you still store the version of your library
in `setup.py` or in any other `utf-8` encoded text file.

>First, try without custom `regex`, probably it can parse the version

If the default internal `regex` does not find the version in your file,
the only thing you need to provide is a custom `regex` to `get_version`:
```python
from single_source import get_version

custom_regex = r"\s*version\s*=\s*[\"']\s*([-.\w]{3,})\s*[\"']\s*"

path_to_file = "~/my-project/some_file_with_version.txt"
__version__ = get_version(__name__, path_to_file, version_regex=custom_regex)
```
Version must be in the first group `()` in the custom regex.

## Contributing
Pull requests are welcome. For major changes, please open an issue first to
discuss what you would like to change.

Please make sure to update tests as appropriate.

## License
[MIT](https://choosealicense.com/licenses/mit/)

            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/rabbit72/single-source",
    "name": "single-source",
    "maintainer": "Daniil Shadrin",
    "docs_url": null,
    "requires_python": "<4.0,>=3.8",
    "maintainer_email": "rabbit72rus@gmail.com",
    "keywords": "pyproject, version, __version__, poetry, single source",
    "author": "Daniil Shadrin",
    "author_email": "rabbit72rus@gmail.com",
    "download_url": "https://files.pythonhosted.org/packages/85/c5/096cda37599fb12f9930266ebb66e72e0ef3c39eb8be1934025f44e9c7ed/single_source-0.4.0.tar.gz",
    "platform": null,
    "description": "# Single-source: There is only one truth\n> `single-source` helps to reduce the entropy in your Python project by keeping\n> single source of truth.\n\nThe targets of this library are modern Python projects which want to have\none source of truth for version, name and etc.\n\nAt the moment, the library provides the single point for a package version.\n\nIt supports Python 3.8+.\n\n## Quick start\n\n```python\n# root_package/__init__.py\nfrom pathlib import Path\nfrom single_source import get_version\n\n__version__ = get_version(__name__, Path(__file__).parent.parent)\n```\n\n## Root of the problem\n\nYou use modern `pyproject.toml` and want to keep the version of your package\nhere:\n```toml\n# pyproject.toml\n[tool.poetry]\nname = \"modern-project\"\nversion = \"0.1.0\"\n```\n\nLet's imagine the version of your package is required in some place of the code.\n\nSince you need the version in your Python code, you may want to duplicate the version by putting it as a string variable to some python file:\n```python\n# modern_project/__init__.py\n__version__ = \"0.1.0\"\n\n# modern_project/version.py\nversion = \"0.1.0\"\n```\n\nThen you realize you don't want to have the version in a python file and in pyproject.toml at the same time. It's harder to keep them consistent and easier to forget to bump both versions before release.\n\nAlso, you don't want to build the wheel by creating some script for auto incrementing the version in both places (and use it in your CI flow, for example). Instead you want use `poetry version` commands.\n\n## Installation\nYou can install `single-source` via [pip](https://pip.pypa.io/en/stable/)\n```bash\npip3 install single-source\n```\n\nor via [poetry](https://python-poetry.org/docs/#installation)\n```bash\npoetry add single-source\n```\n\nThe library also available as\n[a conda package](https://docs.conda.io/projects/conda/en/latest/) in\n[conda-forge](https://anaconda.org/conda-forge/repo) channel\n```bash\nconda install single-source --channel conda-forge\n```\n\n## Advanced usage\n### Changing default value\nIf it's not possible to get the version from package metadata or\nthere is no pyproject.toml `get_version` returns `\"\"` - empty string by default.\nYou can change this value by providing a value as a `default_return` keyword argument.\n\n```python\nfrom pathlib import Path\nfrom single_source import get_version\n\npath_to_pyproject_dir = Path(__file__).parent.parent\n__version__ = get_version(__name__, path_to_pyproject_dir, default_return=None)\n```\n\n### Raising an exception\nYou may want to raise an exception in case the version of the package\nhas not been found.\n```python\nfrom pathlib import Path\nfrom single_source import get_version, VersionNotFoundError\n\npath_to_pyproject_dir = Path(__file__).parent.parent\ntry:\n    __version__ = get_version(__name__, path_to_pyproject_dir, fail=True)\nexcept VersionNotFoundError:\n    pass\n```\n\n\n### Not only pyproject.toml\nYou can use `single-source` even if you still store the version of your library\nin `setup.py` or in any other `utf-8` encoded text file.\n\n>First, try without custom `regex`, probably it can parse the version\n\nIf the default internal `regex` does not find the version in your file,\nthe only thing you need to provide is a custom `regex` to `get_version`:\n```python\nfrom single_source import get_version\n\ncustom_regex = r\"\\s*version\\s*=\\s*[\\\"']\\s*([-.\\w]{3,})\\s*[\\\"']\\s*\"\n\npath_to_file = \"~/my-project/some_file_with_version.txt\"\n__version__ = get_version(__name__, path_to_file, version_regex=custom_regex)\n```\nVersion must be in the first group `()` in the custom regex.\n\n## Contributing\nPull requests are welcome. For major changes, please open an issue first to\ndiscuss what you would like to change.\n\nPlease make sure to update tests as appropriate.\n\n## License\n[MIT](https://choosealicense.com/licenses/mit/)\n",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "Access to the project version in Python code for PEP 621-style projects",
    "version": "0.4.0",
    "project_urls": {
        "Bug Tracker": "https://github.com/rabbit72/single-source/issues",
        "Homepage": "https://github.com/rabbit72/single-source",
        "Repository": "https://github.com/rabbit72/single-source.git"
    },
    "split_keywords": [
        "pyproject",
        " version",
        " __version__",
        " poetry",
        " single source"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "7f34c26bc3fbd88437ae3417f57f10c5eff926e095cc3d61a235478907c28b2d",
                "md5": "08519458458d9968279a5594c95dec3b",
                "sha256": "38880b16e6e0ca2e012f85dc3820eb31999ace5f1d9a588395ea38f8bd0775f5"
            },
            "downloads": -1,
            "filename": "single_source-0.4.0-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "08519458458d9968279a5594c95dec3b",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": "<4.0,>=3.8",
            "size": 5590,
            "upload_time": "2024-06-11T10:08:31",
            "upload_time_iso_8601": "2024-06-11T10:08:31.626599Z",
            "url": "https://files.pythonhosted.org/packages/7f/34/c26bc3fbd88437ae3417f57f10c5eff926e095cc3d61a235478907c28b2d/single_source-0.4.0-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "85c5096cda37599fb12f9930266ebb66e72e0ef3c39eb8be1934025f44e9c7ed",
                "md5": "c390c767c8847d49c2331187fbe948dd",
                "sha256": "7917aa113bda60072f01952e2966cd7247f0ec16fe52a1555f3c066b553e98b4"
            },
            "downloads": -1,
            "filename": "single_source-0.4.0.tar.gz",
            "has_sig": false,
            "md5_digest": "c390c767c8847d49c2331187fbe948dd",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": "<4.0,>=3.8",
            "size": 4803,
            "upload_time": "2024-06-11T10:08:33",
            "upload_time_iso_8601": "2024-06-11T10:08:33.357291Z",
            "url": "https://files.pythonhosted.org/packages/85/c5/096cda37599fb12f9930266ebb66e72e0ef3c39eb8be1934025f44e9c7ed/single_source-0.4.0.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-06-11 10:08:33",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "rabbit72",
    "github_project": "single-source",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "lcname": "single-source"
}
        
Elapsed time: 0.31485s