![](/img/trans.png)
[英]Python Packaging: Creating a dependency on a `conda-forge` package in `conda` `meta.yaml` file
[英]Get package version for conda meta.yaml from source file
我正在嘗試重新組織我的 python 包版本控制,所以我只需要在一個地方更新版本,最好是 python 模塊或文本文件。 對於我需要我的版本的所有地方,似乎有一種方法可以from mypkg import __version__
的源中加載它,或者至少將它從文件中解析為文本。 我似乎無法找到一種方法來使用我的 conda meta.yaml 文件。 有沒有辦法從 meta.yaml 文件中的外部源加載版本?
我知道有 git 環境變量,但我不想標記通過本地 conda 存儲庫進行測試的每個 alpha/beta/rc 提交。 我可以在 pyyaml 中使用!!python/object
加載 python 對象,但 conda 不支持任意 python 執行。 我看不到任何其他 jinja2 功能的方法。 我也可以編寫一個腳本來在多個地方更新版本號,但我真的希望只修改一個文件作為最終版本號。 感謝您的幫助。
從conda-build-3.16.1
(2018 年 11 月)開始,這里是在 conda 配方中以編程方式設置version
的方法。
這些例子的一部分meta.yaml
你傳遞給conda-build
,作為解釋在這里。
setup.py
的版本: 如果你構建一個 python 包,這個秘籍是完美的,因為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) %}
現在繼續:
$ conda-build conda-recipe
如果您的項目在 git 中標記,並且您使用 conda 接受作為有效版本號的標記格式(例如2.5.1
或v2.5.1
),則此方法很好。
package:
name: hub
version: {{ GIT_DESCRIBE_TAG }}
現在繼續:
$ conda-build conda-recipe
這對於非 python conda 包很有用,其中版本來自各種不同的地方,您可以完善其價值 - 例如將v2.5.1
轉換為2.5.1
。
package:
name: mypkg
version: {{ environ.get('MYPKG_VERSION', '') }}
然后創建一個獲取版本的可執行腳本,我們稱之為script-to-get-mypkg-version
現在繼續加載將設置版本的環境變量:
$ MYPKG_VERSION=`script-to-get-mypkg-version` conda-build conda-recipe
根據 conda-build 版本,您可能必須使用os.environ.get
而不是environ.get
。 文檔使用后者。
請注意,如果這在過去有效,如 2016 年的一個答案中所述,現在就行不通了。
package:
name: mypkg
build:
script_env:
- VERSION
$ VERSION=`script-to-get-mypkg-version` conda-build conda-recipe
在這種情況下, conda-build
忽略 env var VERSION
。
來源。
有很多方法可以到達終點。 這就是 conda 本身所做的......
__version__
版本信息的真實來源是__version__
conda/__init__.py
。 它可以按照您的建議在 python 代碼中以編程方式加載,如from conda import __version__
。 它也被硬連接到setup.py
此處(也請注意此代碼),因此從命令行python setup.py --version
是獲取該信息的規范方式。
在 conda-build 的 1.x 版本中,放置一行
$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
設置__version__
變量...
您在源代碼中看到的是對auxlib.packaging.get_version()
函數的調用。 此函數按順序執行以下操作
conda/.version
,如果找到則返回內容作為版本標識符VERSION
環境變量,如果設置,則返回值作為版本標識符git describe --tags
輸出,並在可能的情況下返回版本標識符(必須安裝 git,必須是 git repo 等)None
現在還有一個最后的技巧。 在康達的setup.py
文件中,我們設置cmdclass
為build_py
和sdist
到規定的那些auxlib.packaging
。 基本上我們有
from auxlib import packaging
setup(
cmdclass={
'build_py': packaging.BuildPyCommand,
'sdist': packaging.SDistCommand,
}
)
這些特殊的命令類實際上會修改內置/安裝包中的__version__
conda/__init__.py
文件,因此__version__
變量被硬編碼為字符串文字,並且不使用auxlib.packaging.get_version()
函數。
在您的情況下,不想標記每個版本,您可以使用上述所有內容,並從命令行使用VERSION
環境變量設置版本。 類似的東西
VERSION=1.0.0alpha1 conda build conda.recipe
在您的build
部分 meta.yaml 配方中,您需要添加一個script_env
鍵來告訴script_env
-build 將VERSION
環境變量一直傳遞到構建環境。
build:
script_env:
- VERSION
__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
你可以做這樣的事情。 這也是我在 sphinx conf.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
我已經嘗試了很多東西,有和沒有符合pyproject.toml
等等,但最終,這對我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.cfg
的其余setup()
元數據和選項。 需要存在的一個是:
[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"
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.