我正在尝试重新组织我的python包版本,所以我只需要在一个地方更新版本,最好是python模块或文本文件。对于我需要我的版本的所有地方,似乎有一种方法从源from mypkg import __version__
加载它或至少将其作为文本从文件中解析出来。我似乎找不到使用我的conda meta.yaml文件的方法。有没有办法从meta.yaml文件中的外部源加载版本?
我知道有git环境变量,但我不想标记通过本地conda存储库测试的每个alpha / beta / rc提交。我可以在pyyaml中使用!!python/object
加载python对象,但是conda不支持任意python执行。我没有看到任何其他jinja2功能的方法。我还可以编写一个脚本来更新多个版本号,但我真的希望只修改一个文件作为最终版本号。谢谢你的帮助。
答案 0 :(得分:5)
从conda-build-3.16.1
(2018年11月)开始,这是在conda配方中以编程方式设置version
的方法。
如here所述,这些示例是传递给meta.yaml
的{{1}}的一部分。
conda-build
的版本:如果您构建python软件包,则此食谱非常理想,因为setup.py
仍然需要它,因此您必须已经弄清楚了。
setup.py
请注意,有时候,如果与{% set data = load_setup_py_data() %}
package:
name: mypackage
version: {{ data.get('version') }}
不在同一个目录中,则必须明确告知conda配方在哪里可以找到它:
setup.py
,然后继续:
{% set data = load_setup_py_data(setup_file='../setup.py', from_recipe_dir=True) %}
如果您的项目使用git标记,并且您使用conda接受为有效版本号的标记格式(例如$ conda-build conda-recipe
或2.5.1
),则此食谱很好。
v2.5.1
,然后继续:
package:
name: hub
version: {{ GIT_DESCRIBE_TAG }}
这对于非Python conda软件包很有用,该软件包的版本来自不同的地方,您可以完善其价值-例如将$ conda-build conda-recipe
转换为v2.5.1
。
2.5.1
然后创建一个获取版本的可执行脚本,我们将其称为package:
name: mypkg
version: {{ environ.get('MYPKG_VERSION', '') }}
,现在继续加载将设置版本的环境变量:
script-to-get-mypkg-version
根据conda-build版本的不同,您可能必须使用$ MYPKG_VERSION=`script-to-get-mypkg-version` conda-build conda-recipe
而不是os.environ.get
。 docs使用后者。
请注意,如果过去曾经奏效,如2016年的一份答复所述,现在就行不通了。
environ.get
package:
name: mypkg
build:
script_env:
- VERSION
$ VERSION=`script-to-get-mypkg-version` conda-build conda-recipe
在这种情况下会忽略环境变量conda-build
。
答案 1 :(得分:3)
有很多方法可以访问您的终端。这就是康达本身所做的事情......
conda的版本信息的真实来源是__version__
中的conda/__init__.py
。它可以像你建议的那样在python代码中以from conda import __version__
的形式加载。它也很难连接到setup.py
here(注意this code),因此从命令行python setup.py --version
获取该信息的规范方法。< / p>
在1.x版本的conda-build中,添加一行
$PYTHON setup.py --version > __conda_version__.txt
build.sh
中的将使用我们的真实来源为构建的包设置版本。 不推荐使用__conda_version__.txt
文件,并且可能会在发布conda-build 2.0时将其删除。在conda-build的最新版本中,执行此操作的首选方法是在jinja2上下文中使用load_setup_py_data()
,这样您就可以访问setup.py
中的所有元数据。具体来说,在meta.yaml
文件中,我们有类似的内容
package:
name: conda
version: "{{ load_setup_py_data().version }}"
现在,如何在__version__
...
conda/__init__.py
变量
see in the source code对auxlib.packaging.get_version()
函数的调用setup.py
file。此功能按顺序执行以下操作
conda/.version
,如果找到则返回内容作为版本标识符VERSION
环境变量的下一个,如果设置,则返回值作为版本标识符git describe --tags
输出的最后一个,并在可能的情况下返回版本标识符(必须安装git,必须是git repo等等)None
现在还有一个最后的伎俩。在conda的Dart JS Library, how to pass callback functions中,我们将cmdclass
和build_py
的{{1}}设置为sdist
提供的auxlib.packaging
。基本上我们有
from auxlib import packaging
setup(
cmdclass={
'build_py': packaging.BuildPyCommand,
'sdist': packaging.SDistCommand,
}
)
这些特殊的命令类实际上修改了构建/安装包中的conda/__init__.py
文件,因此__version__
变量被硬编码为字符串文字,并且不使用{{1}功能。
在您的情况下,不想标记每个版本,您可以使用上述所有内容,并从命令行使用auxlib.packaging.get_version()
环境变量设置版本。像
VERSION
在您的VERSION=1.0.0alpha1 conda build conda.recipe
部分meta.yaml配方中,您需要添加一个build
密钥,告诉conda-build将script_env
环境变量一直传递给构建环境。
VERSION
答案 2 :(得分:0)
__version__
如果您在单独的_version.py
中拥有版本,则可以在不加载整个程序包的情况下进行导入。
# 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'
对于我来说,这是自动生成的,但下一步保持不变。
在__init__.py
中,您有一行from ._version import version as __version__
,然后在setup.py
中可以执行以下操作。
这也是我在狮身人面像conf.py
source_dir = Path("src/<my_package>")
sys.path.insert(0, str(source_dir))
from _version import version
setup(version=version)
...
或者,您可以尝试手动解析文件,而不是导入_version
文件,因此不必向sys.path
添加文件
,然后在meta.yaml
{% set data = load_setup_py_data() %}
{% set version = data.get('version') %}
package:
name: <my_package>
version: {{ version }}
我遇到了相反的问题。我忘了不时更新其版本,因此一直在寻找一种方法来将git
存储库作为软件包版本的单一来源。我使用了setuptools_scm
我已经尝试了很多方法,无论是否符合pep517标准pyproject.toml
等,但最终,这是最适合我的方法。
这样做的好处是您不需要那么大的versioneer.py
,但是它会在构建时写入_version.py
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,)
setup()
中其余的setup.cfg
元数据和选项。需要在那里的一个是
[options]
package_dir=
=src
packages = <my_package>
install_requires = setuptools_scm
src/<my_package>/_version.py
生成:
# 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'
,然后将其添加到我的.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
也可以使用pip wheel .
您需要pyproject.toml
[build-system]
requires = ["setuptools>=34.4", "wheel", "setuptools_scm"]
build-backend = "setuptools.build_meta"