独立于平台的conda软件包

时间:2019-12-27 09:39:42

标签: python conda

我正在尝试构建一个conda包,其中包含一个Python包,该包在导入时会读取静态文件。尽管程序包本身可以正常工作,但程序包的位置最终取决于用于构建程序包的平台,因此最终无法在与用于构建程序包的平台不同的平台上导入程序包。

由于完全没有平台依赖性,而且conda允许通过noarch进行跨平台的软件包,因此似乎应该有可能在单个平台上构建该软件包,而不是每个平台一次平台。

这是一个最小的例子:

/setup.py

from setuptools import setup, find_packages


setup(
    name='mypackage',
    description='My platform independent package',
    packages=find_packages(),
    data_files=[('mypackage', ['mypackage/myfile.txt'])]
)

/conda_recipe/meta.yaml

{% set data = load_setup_py_data() %}

build:
  noarch: python

package:
  name: mypackage

source:
  path: ..

requirements:
  build:
    - python
    - setuptools

about:
  summary: {{ data.get('description') }}

/mypackage/myfile.txt

foo

/mypackage/__init__.py

import os

# Print contents of myfile.txt when the package is imported
with open(os.path.join(os.path.dirname(__file__), 'myfile.txt')) as f:
    print(f.read())

通过删除noarch: python的{​​{1}}部分,我可以构建在其构建平台上工作的软件包。但是,如果我在Windows上使用meta.yaml来构建noarch程序包,并在两个平台上都使用conda build,则Python模块和数据文件都以conda install结尾。在Linux上构建它,然后在两个平台上{conda-env}/Lib/site-packages上进行构建,它们最终都以conda install(注意小写的{conda-env}/lib/python3.7/site-packages)。

这是一个问题,因为确定包含路径的环境变量在两个平台上不同。结果,基于Windows的软件包在Windows上运行良好,而基于Linux的软件包在Linux上运行良好,但是基于一个平台构建的软件包将无法在另一平台上运行。特别是,默认情况下,Linux上的Miniconda在l中包含后者路径,因此它将无法找到在Linux上安装的Windows上构建的软件包。

也就是说,即使软件包内容本身与平台无关,我也不能简单地在一个平台上构建该软件包,将其转储到我的频道的sys.path中并感到高兴。当然,静态数据文件不是这里的罪魁祸首,但是无论如何,我都将其包含在我的问题中,仅仅是因为确保将其最终放在正确的位置本身并不是一件容易的事。

在Windows和WSL上使用最新版本的Miniconda时,会发生此问题。

所以我的问题变成:

  

如果我要构建一个仅包含一个简单文件的conda程序包,并且在导入该程序包时noarch会读取该文件,我是否可以摆脱在单个平台上构建该程序包的麻烦?

1 个答案:

答案 0 :(得分:1)

在Windows和Linux上更新conda-build和Python之后,我不再能够重现我的问题。安装后,这些软件包仍将位于不同的目录中:Linux上的lib/python3.8/site-packages和Windows上的lib/site-packages;奇怪的是,l现在在Windows上是小写字母,由于Windows是Windows,因此最终变得无关紧要。

不幸的是,这对原始问题了解甚少,但是至少这足以开始。

尤其是,以下步骤适用于我的原始问题中包含的最小示例,即使用WSL测试基于Windows的软件包:

  1. 创建一个新环境mypackage-build,激活它,然后运行conda install python conda-build
  2. 在Windows上,使用conda build conda_recipe构建软件包。
  3. 不指定其他任何内容,构建的程序包最终存储在我的计算机上的C:\Users\username\AppData\Local\Continuum\miniconda3\envs\mypackage-build\conda-bld中。
  4. 停用构建环境,创建一个名为mypackage-test的新环境,将其激活,安装Python,并使用conda install -c C:\Users\username\AppData\Local\Continuum\miniconda3\envs\mypackage-build\conda-bld mypackage安装上面构建的软件包。
  5. 运行where python以确保从python.exe环境中提取了mypackage-test,运行Python,调用import mypackage,并注意该软件包确实已导入。 / li>
  6. 在WSL上,创建一个名为mypackage-test-wsl的新环境,激活它,安装Python,然后运行conda install -c /mnt/c/Users/username/AppData/Local/Continuum/miniconda3/envs/mypackage-build/conda-bld mypackage(如果驱动器的安装方式不同,则进行相应的修改)。
  7. 运行Python,import mypackage,并注意一切正常(这是我最初遇到问题的地方)。
  8. 镜像该过程,在WSL上构建软件包,在Windows上安装它,并注意一切正常。

在测试上述内容时,我确实碰到了一个难题,因此为了完整性起见,请在这里注意:第一次创建mypackage-test时,是从mypackage-build环境开始的。结果,即使将软件包安装在mypackage-test中,父级环境的Python运行时也将具有优先权(我认为这很奇怪,但是可以),这将导致上面的“第5步”失败; < / p>

>where python
C:\Users\username\AppData\Local\Continuum\miniconda3\envs\mypackage-build\python.exe
C:\Users\username\AppData\Local\Continuum\miniconda3\envs\mypackage-build\envs\mypackage-test\python.exe
C:\Users\username\AppData\Local\Continuum\miniconda3\python.exe