Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get package version for conda meta.yaml from source file

Tags:

python

conda

I'm trying to reorganize my python package versioning so I only have to update the version in one place, preferably a python module or a text file. For all the places I need my version there seems to be a way to load it from the source from mypkg import __version__ or at least parse it out of the file as text. I can't seem to find a way to do it with my conda meta.yaml file though. Is there a way to load the version from an external source in the meta.yaml file?

I know there are the git environment variables, but I don't want to tag every alpha/beta/rc commit that gets tested through out local conda repository. I could load the python object using !!python/object in pyyaml, but conda doesn't support arbitrary python execution. I don't see a way to do it with any other jinja2 features. I could also write a script to update the version number in more than one place, but I was really hoping to only modify one file as the definitive version number. Thanks for any help.

like image 446
djhoese Avatar asked Aug 12 '16 13:08

djhoese


1 Answers

Manual __version__

If you have the version in a separate _version.py that you can import without loading the whole package.

# coding: utf-8
# file generated by setuptools_scm
# don't change, don't track in version control
version = '0.0.9.post2+g6481728.d20200518.dirty'

In my case this gets automatically generated, but the next step stays the same.

in __init__.py you have a line from ._version import version as __version__

and then in setup.py you could do something like this. This is also how I import the version in my sphinx conf.py

source_dir = Path("src/<my_package>")
sys.path.insert(0, str(source_dir))

from _version import  version

setup(version=version)
...

Alternatively, instead of importing the _version file, you can try to parse it manually, so you don't have to add something to sys.path

and then in meta.yaml

{% set data = load_setup_py_data() %}
{% set version = data.get('version')  %}


package:
  name: <my_package>
  version: {{ version }}

I had the reverse issue. I forgot to update my version from time to sime, so was looking for a way to have the git repository as single source of the package version. I used setuptools_scm

I've tried a lot of things, with and without pep517 compliant pyproject.toml etcetera, but eventually, this is the one that works for me.

The advantage of this is you don't need that huge versioneer.py, but it gets written to _version.py at build time

setup.py

from setuptools import setup
import setuptools_scm


def my_local_scheme(version: setuptools_scm.version.ScmVersion) -> str:
    """My local node and date version."""
    node_and_date = setuptools_scm.version.get_local_node_and_date(version)
    dirty = ".dirty" if version.dirty else ""
    return str(node_and_date) + dirty

version = setuptools_scm.get_version(
    write_to="src/<my_package>/_version.py",
    version_scheme="post-release",
    local_scheme=my_local_scheme,
)
setup(version=version,)

The rest of the setup() metadata and options in in setup.cfg. One that needs to be there is:

[options]
package_dir=
    =src
packages = <my_package>
install_requires = setuptools_scm

src/<my_package>/_version.py

gets generated:

# coding: utf-8
# file generated by setuptools_scm
# don't change, don't track in version control
version = '0.0.3.post0+g887e418.d20200518.dirty'

and I add it to my .gitignore

src/<my_package>/__init__.py

"""<package_description>"""
from ._version import version as  __version__

meta.yaml

{% set data = load_setup_py_data() %}
{% set version = data.get('version')  %}


package:
  name: capacity_simulation
  version: {{ version }}

source:
  path: .

build:
  noarch: python
  number: {{ environ.get('GIT_DESCRIBE_NUMBER', 0) }}
  script: python -m pip install --no-deps --ignore-installed .
  include_recipe: False

requirements:
  build:
    - setuptools_scm
...

pyproject.toml

To also be able to use pip wheel .

you need this section in pyproject.toml

[build-system]
requires = ["setuptools>=34.4", "wheel", "setuptools_scm"]
build-backend = "setuptools.build_meta"
like image 131
Maarten Fabré Avatar answered Sep 23 '22 07:09

Maarten Fabré