【问题标题】:Python's Namespace Packages are not Visible in Local Development ProjectPython 的命名空间包在本地开发项目中不可见
【发布时间】:2020-02-10 13:26:33
【问题描述】:

我正在尝试使用 Python namespace packages 将一个大型(几乎是单片的)Python 项目拆分为多个部分。因此,我将*.rules 文件的解析器提取到命名空间包中。 Python 将其称为发行版

我遵循了该指南,据我所知它部分有效,但是...

简而言之: 在主项目中,单独分布的命名空间包的命名空间是不可见的,因为包搜索会先找到本地包,不会与site-packages的系统包合并。

项目结构

这是我的目录/包和模块结构的一部分。

主要项目:

pyIPCMI/                  # Git repository root
  pyIPCMI/
    __init__.py
    Common/
      __init__.py
      File1.py
    Compiler/
      __init__.py
      Vendor1.py
      Vendor2.py
  setup.py

规则解析器的分发

pyIPCMI.Parser.Rules/     # Git repository root
  pyIPCMI/
    Parser/
      Rules/
        __init__.py
        Parser.py
  setup.py

包说明(安装工具)

主工程是这样打包的:

import setuptools

setuptools.setup(
  name="pyIPCMI",
  version="1.1.5",
  author="Paebbels",
  author_email="abc@xyz.de",
  description="",
  long_description="",
  url="https://github.com/Paebbels/pyIPCMI",

  packages=setuptools.find_packages(),

  classifiers=["License :: OSI Approved :: Apache Software License"],
  python_requires='>=3.5',
  install_requires=[],
)

嵌入的命名空间是这样封装的:

import setuptools

namespace =   ["pyIPCMI", "Parser", "Rules"]

setuptools.setup(
  name=".".join(namespace),
  version="1.1.4",
  author="Paebbels",
  author_email="abc@xyz.de",
  description="",
  long_description="",
  url="https://github.com/Paebbels/pyIPCMI.Parser.Rules",

  packages=setuptools.find_namespace_packages(
    include=[".".join(namespace), ".".join(namespace) + ".*"]
  ),
  namespace_packages=namespace[0:1],

  classifiers=["License :: OSI Approved :: Apache Software License"],
  python_requires='>=3.5',
  install_requires=[],
)

所有发行版均已:

  • 使用 Travis-CI 与 setuptools 打包
  • 部署到 PyPI,然后
  • 使用pip安装在本地机器上。

PyPI 的命名空间结构

pyIPCMI
pyIPCMI.Parser.Files
pyIPCMI.Parser.Rules
pyIPCMI.Toolchains
pyIPCMI.Toolchains.Vendor1
pyIPCMI.Toolchains.Vendor2

问题描述

在主项目中开发时,例如PyCharm,本地找到的命名空间比来自site-packages 的包更受欢迎。此外,这些命名空间不会被合并。 因为主项目具有相同的根命名空间pyIPCMI,所以在本地开发项目中继续搜索,但不在site-packages中搜索。

知道如何开发主项目吗?


请告知需要什么信息来解决这个问题。我试图写下我目前掌握的所有信息。但这个问题可能需要改进才能得到解决方案。

【问题讨论】:

  • 您找到问题的答案了吗?
  • 过去几个月我无法进一步调查。我想将我的问题简化为一个非常简单的包/子包设置,其中包含多个文件/模块中的一些导入和打印语句,以便进一步测试和/或报告。

标签: python-3.x pip python-packaging namespace-package


【解决方案1】:

上周我遇到了同样的问题并找到了解决方案。作为第一个例子, 让我给你我的初始(非工作)布局。

目录结构 1(尚未提取插件)

project-dir
  +-- pyproject.toml/setup.py
  +-- myproject
        +-- __init__.py
        +-- app.py
        +-- plugins
              +-- __init__.py
              +-- plugin1
                    +-- __init__.py
                    +-- plugmodule.py
              +-- plugin2
                    +-- __init__.py
                    +-- plugmodule.py

应用程序已经有代码可以基于此查找插件模块 结构体。在写这篇文章时,我最初的理解是我可以提供 通过创建具有以下结构的 Python 包来附加插件:

plugin-package-dir
  +-- pyproject.toml/setup.py
  +-- myproject
        +-- plugins
              +-- plugin3
                    +-- __init__.py
                    +-- plugmodule.py

正如官方文档中提到的,命名空间包不包含 __init__.py 文件在这里。

但这不起作用

解决方案

为了完成这项工作,我需要提取“插件”包 通过将其设为纯名称空间,完全来自主项目子树 包也是如此。然后需要手动将这个新包添加到您的setup.py/pyproject.toml,因为默认包发现无法识别它。

我最终得到了以下结构:

project-dir
  +-- pyproject.toml/setup.py
  +-- myproject
        +-- __init__.py
        +-- app.py
  +-- myproject_plugins
        +-- plugins
              +-- plugin1
                    +-- __init__.py  # <-- not strictly needed? (see note)
                    +-- plugmodule.py
              +-- plugin2
                    +-- __init__.py  # <-- not strictly needed? (see note)
                    +-- plugmodule.py

然后对于插件包我有这个:

plugin-package-dir
  +-- pyproject.toml/setup.py
  +-- myproject_plugins
        +-- plugins
              +-- plugin3
                    +-- plugmodule.py
              +-- plugin4
                    +-- plugmodule.py

注意__init__.py 文件存在于主项目插件中,因为 我加载插件的方式。为了迭代命名空间,我将其导入 在插件发现期间。我可以改为抓住ImportError 并报告 根本没有找到插件。

如果我可以删除__init__.py 并抓住 导入错误。我已经在这方面浪费了太多时间,不想打破 现在正在工作的东西;)

【讨论】:

    【解决方案2】:

    据我所知,命名空间包必须是空的,并且在所有已安装的项目中都是如此。

    显然您的pyIPCMI 项目有一个顶级非命名空间包 pyIPCMI,即您有一个pyIPCMI/__init__.py 文件。所以我认为你不能在其他项目中拥有pyIPCMI 命名空间包。如果您希望 pyIPCMI 成为其他项目中的命名空间包,我会尝试删除此 pyIPCMI/__init__.py 文件(并将其设为命名空间包)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-07-01
      • 2014-03-13
      • 2011-10-25
      • 1970-01-01
      • 1970-01-01
      • 2012-02-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多