当包在子目录中时,从顶层包含包数据 Python [英] Including Package Data Python from Top-level when Package is in Subdirectory

查看:39
本文介绍了当包在子目录中时,从顶层包含包数据 Python的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试打包一系列配置文件以及一些源代码.我有这样的目录结构(由于团队的性质,我无法更改)

<预><代码>.├── 配置│ ├── 机器│ ├──范围├── esm_tools│ ├── __init__.py├── README.rst├── setup.cfg├── setup.py61 个目录,45 个文件(截断)

据我了解(https://docs.python.org/3/distutils/setupscript.html#installing-package-data),我可以在设置调用中添加一些部分:

设置(# ... 其他的东西include_package_data=真,名称=esm_tools",包=[配置",esm_tools"],package_dir={"configs": "configs", "esm_tools": "esm_tools"},package_data={'configs': ['*']},版本=4.1.5",zip_safe=假,)

但是,我无法访问包数据:

在[1]中:导入pkg_resources在 [2]: pkg_resources.resource_listdir("esm_tools", "config")---------------------------------------------------------------------------FileNotFoundError 追溯(最近一次调用最后一次)<ipython-input-2-f0f255c14df6>在<模块>---->1 pkg_resources.resource_listdir("esm_tools", "config")/global/AWIsoft/miniconda/4.7.12/lib/python3.7/site-packages/pkg_resources/__init__.py in resource_listdir(self, package_or_requirement, resource_name)1161"列出指定资源目录的内容""1162 返回get_provider(package_or_requirement).resource_listdir(->第1163章第1164章1165/global/AWIsoft/miniconda/4.7.12/lib/python3.7/site-packages/pkg_resources/__init__.py in resource_listdir(self, resource_name)14391440 def resource_listdir(自我,resource_name):->第1441章1442第 1443 章/global/AWIsoft/miniconda/4.7.12/lib/python3.7/site-packages/pkg_resources/__init__.py in _listdir(self, path)16081609 def_listdir(自我,路径):->1610 返回 os.listdir(路径)16111612 def get_resource_stream(自我,经理,资源名称):FileNotFoundError: [Errno 2] 没有那个文件或目录:'/home/ollie/pgierz/dev/esm_tools/esm_tools/esm_tools/config'

任何帮助将不胜感激,我不确定我做错了什么......

解决方案

根据你的调用 pkg_resources.resource_listdir("esm_tools", "config"),我假设你想重新映射 configs 到安装包中的 esm_tools.config :

site-packages├── esm_tools│ ├── __init__.py│ ├── 配置│ │ ├──机器│ │ ├──范围

这意味着您必须执行以下操作:

  1. 告诉 setuptools 包含一个子包 esm_tools.config(即使它并不真正存在于源代码库中并且在技术上是一个命名空间,我们将构造它通过进一步配置)
  2. 告诉 setuptools 新的 esm_tools.config 包的源位于何处(这再次只是告诉 setuptools 什么的必要措施包含在 dist 中.包本身不会提供任何 Python 源代码,因为 configs 中没有 Python 文件.
  3. 告诉 setuptools 从正确的路径包含 esm_tools.config 的包数据.

示例:

设置(...,包=['esm_tools', 'esm_tools.config'], # 1package_dir={'esm_tools.config': 'configs'}, # 2package_data={'esm_tools.config': ['../configs/*']}, # 3)

请注意,这不适用于可编辑安装(无论是通过 pip install --editable . 还是 python setup.py develop),因此您必须使用符号链接或 .pth 文件或其他任何内容构建或多或少丑陋的本地解决方法.wheel dist(通过 python setup.py bdist_wheelpip wheel 构建)将开箱即用,对于源 dist,您必须包含 configs dir 通过 MANIFEST.in 作为 package_data 不会在 sdist 时间被读取:

# MANIFEST.in...嫁接配置

I'm trying to package a series of configuration files along with some source code. I have a directory structure like this (which I cannot change, due to the nature of the team)

.
├── configs
│   ├── machines
│   ├── scope
├── esm_tools
│   ├── __init__.py
├── README.rst
├── setup.cfg
├── setup.py

61 directories, 45 files (Truncated)

From what I understand here (https://docs.python.org/3/distutils/setupscript.html#installing-package-data), I can add some parts to the setup call:


setup(
    # ... other stuff
    include_package_data=True,
    name="esm_tools",
    packages=["configs", "esm_tools"],
    package_dir={"configs": "configs", "esm_tools": "esm_tools"},
    package_data={'configs': ['*']},
    version="4.1.5",
    zip_safe=False,
)

However, I can't access the package data with:

In [1]: import pkg_resources                                                                                                                                                                                                                                                                       

In [2]: pkg_resources.resource_listdir("esm_tools", "config")                                                                                                                                                                                                                                      
---------------------------------------------------------------------------
FileNotFoundError                         Traceback (most recent call last)
<ipython-input-2-f0f255c14df6> in <module>
----> 1 pkg_resources.resource_listdir("esm_tools", "config")

/global/AWIsoft/miniconda/4.7.12/lib/python3.7/site-packages/pkg_resources/__init__.py in resource_listdir(self, package_or_requirement, resource_name)
   1161         """List the contents of the named resource directory"""
   1162         return get_provider(package_or_requirement).resource_listdir(
-> 1163             resource_name
   1164         )
   1165 

/global/AWIsoft/miniconda/4.7.12/lib/python3.7/site-packages/pkg_resources/__init__.py in resource_listdir(self, resource_name)
   1439 
   1440     def resource_listdir(self, resource_name):
-> 1441         return self._listdir(self._fn(self.module_path, resource_name))
   1442 
   1443     def metadata_listdir(self, name):

/global/AWIsoft/miniconda/4.7.12/lib/python3.7/site-packages/pkg_resources/__init__.py in _listdir(self, path)
   1608 
   1609     def _listdir(self, path):
-> 1610         return os.listdir(path)
   1611 
   1612     def get_resource_stream(self, manager, resource_name):

FileNotFoundError: [Errno 2] No such file or directory: '/home/ollie/pgierz/dev/esm_tools/esm_tools/esm_tools/config'

Any help would be greatly appreciated, I'm not sure what I'm doing wrong...

解决方案

Based on your call pkg_resources.resource_listdir("esm_tools", "config"), I assume you want to remap configs to esm_tools.config in the installed package:

site-packages
├── esm_tools
│   ├── __init__.py
│   ├── config
│   │   ├── machines
│   │   ├── scope

This means you have to do the following things:

  1. Tell setuptools to include a subpackage esm_tools.config (even if it doesn't really exist in source code base and is technically a namespace one, we'll construct it via further configuration)
  2. Tell setuptools where the sources for the new esm_tools.config package are located (this is again just a necessary measure to tell setuptools what to include in the dist. The package itself won't provide any Python sources since no Python files are located in configs).
  3. Tell setuptools to include package data for esm_tools.config from the correct path.

Example:

setup(
    ...,
    packages=['esm_tools', 'esm_tools.config'],           # 1
    package_dir={'esm_tools.config': 'configs'},          # 2
    package_data={'esm_tools.config': ['../configs/*']},  # 3
)

Note that this won't work with editable installs (neither via pip install --editable . nor with python setup.py develop), so you will have to construct more or less ugly local workarounds with symlinks or .pth files or whatever. The wheel dist (built via python setup.py bdist_wheel or pip wheel) will work out of the box, for source dists you'll have to include the configs dir via MANIFEST.in as package_data won't be read at sdist time:

# MANIFEST.in
...
graft configs

这篇关于当包在子目录中时,从顶层包含包数据 Python的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆