Giter Club home page Giter Club logo

single-source's Introduction

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

# 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:

# 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:

# 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

pip3 install single-source

or via poetry

poetry add single-source

The library also available as a conda package in conda-forge channel

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.

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.

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:

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

single-source's People

Contributors

neki avatar rabbit72 avatar shadrintakkt avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

Forkers

erny neki hatzav-ox

single-source's Issues

Doc issue

Hello! I read the readme and don’t understand how this is supposed to work.

Dev files like pyproject.toml are not installed, so how do you find the version at runtime?

'default_return=None' does not work it was intended as (it seems)

It seems logic for keyword 'default_return=None' could be improved.

As I understood, passing default_return=None we tell function to ignore version from importlib_metadata.version(package_name) and to use version from pyproject.toml.

And here is my problem:

As I noticed from source code we never go through the line #61
(for examples in README and because during poetry project initialization we set initial version and it will be saved in package meta info when we do the first poetry install) :
image

And to pass through it we had to pass our package name with random name, i.e.
(three .parent cause I use "src layout" for my package)

__version__ = get_version("fake-package", Path(__file__).parent.parent.parent)

That works :) BUT this is not an obvious workaround.

Maybe the condition should be:

if version is None or default_return is None:

or something like this πŸ™‚

P.S. Thanks for this library πŸ‘

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.