Src 布局在导入中分配 .src 前缀?在 PyCharm 终端中激活 venv 以进行开发安装

Src layout to dispense .src prefix in imports? Activate venv in PyCharm terminal for development installs

我想了解什么被认为是使用带有 "src/ layout" 的 setuptools 的正确极简主义方式,以一种无需在导入中使用 src. 前缀的方式?

我已经阅读了大部分 PyPA and setuptools 文档(及其许多用例),但我不明白什么是执行此示例的正确方法。

下面的布局重现了我想要实现的目标。我不明白如何让第二个导入而不是第一个跨 mylibrary 包的所有模块工作:

from src.mylibrary.hello_word import hello_function # <- This works.
from mylibrary.hello_word import hello_function  # <- How to get this working?

hello_function()

使用这个 directory/file 结构:

C:\MyProject
│
│   setup.py
│
└───src
    │
    ├──mylibrary
    │      hello_word.py
    │      module_two.py
    │      __init__.py
    │

当我使用 development mode 安装时 pip install -e . egg 目录被添加到上面的树中:

    │ (...)
    │ 
    └──mylibrary.egg-info
           dependency_links.txt
           PKG-INFO
           SOURCES.txt
           top_level.txt

有了这个 setup.py:

from setuptools import setup, find_packages, find_namespace_packages

setup(
    name='mylibrary',
    version='0.1',
    package_dir={'': 'src'},
    # packages=find_namespace_packages(where='src'),  # <- I suppose this isn't the deciding factor.
    packages=find_packages(where='src'),
)

我想要分配的简单 hello_world.py 模块在导入时必须写 src.

def hello_function():
    print("hello world")

__init__.py留空。

我正在使用 venv,令我惊讶的是,egg 符号链接并未写入 venv sitepackages,而是写入 C:\Users\Name\AppData\Roaming\Python\Python38\site-packages...

Python 控制台指示 mylibrary 包已找到:

>>> from setuptools import find_packages
>>> find_packages(where='src')
['mylibrary']

所描述的问题是由于必须 activate the venv inside PyCharm's terminal

下面是对您可能会遇到的情况的描述。 (问题不是很明显,因为与终端不同,调试、运行 等功能以无缝方式集成了 venv。)

需要注意的是:

  • development mode 中安装时使用详细标志 -v 提供有关 pipsetuptools[ 的线索=67=] 正在尝试做。

  • 决定性的 pip 消息基于您 site-packages 的写入权限,但是您不必更改任何默认权限如果在终端上激活你的 venv。

  • 如果您使用 1 个 venv,将涉及 3 个不同的 site-packages(注意路径)。

您可能会尝试的 3 个选项:

选项 1. 运行 PyCharm 作为管理员,从终端执行以下命令得到:

C:\MyProject>pip install -v -e .

Non-user install because site-packages writeable
(...)
Creating c:\program files\python38\lib\site-packages\mylibrary.egg-link (link to src)

这会安装到 Python 基本安装中的 site-packages(注意路径)。您可能想避免的事情,因为它会污染您的基本安装。

选项 2. 运行 PyCharm 作为用户。 没有在终端上激活 venv。

C:\MyProject>pip install -v -e .

Defaulting to user installation because normal site-packages is not writeable
(...)
Creating c:\users\name\appdata\roaming\python\python38\site-packages\mylibrary.egg-link (link to src)

这将安装到您的 venv 之外的 site-packages(注意路径),以及您的 Python 基本安装之外。您可能想要避免的事情,因为 PyCharm 完成后将无法识别开发安装。

注意:终端中的消息“(...) site-packages is not writeable”指的是您 Python 基础安装中的 site-packages。但是,如果没有显式激活 venv,即使您将权限设置为可写,开发安装也不会写入您的 venv site-packages.

选项 3. 运行 PyCharm 作为用户。 正在终端上激活 venv。

(MyProject_venv) C:\MyProject>pip install -v -e .

Non-user install because user site-packages disabled
(...)
Creating c:\myproject_venv\lib\site-packages\mylibrary.egg-link (link to src)

这里您确实在您的 venv 中写入了 site-packages,这可能是您想要的。

更新/解决方法

可以按照 this link 中的步骤将文件夹标记为 source root。来自 link:

Source roots the Source root icon contain the actual source files and resources. PyCharm uses the source roots as the starting point for resolving imports

这样我们就不必再安装它或更改路径了(尽管对我来说它仍然感觉有点棘手)

1。 Pycharm 有一个 pip 问题:

每当我在 pycharm 终端中 运行 pip 出于某种原因它 运行 是系统的 pip。您可以使用 which pip 命令进行检查。但是如果我 运行 python -m pip 它做对了。

2。它实际上应该识别进口:

话虽如此,我真的不知道为什么 pycharm 无法识别没有 src. 前缀的导入。我从 github 克隆了 `cryptography 包,它可以正常识别它,src 文件夹会自动添加到路径,但我还不知道如何。

无论哪种方式,您的代码都可以在没有前缀的情况下按预期工作,并且 Vim(使用 Pyright)可以完美地识别它。即使 运行 在 pycharm 上使用它实际上也可以解决所有导入错误。

3。现在怎么办?

在他们修复它或我找到解决方案之前,我将手动将 src 文件夹添加到我在解释器设置中的路径,因为我不想安装它(但我希望能够达到峰值并转到定义)。

如果我真的想安装这个包,我会在终端中或在 pycharm 中使用 python -m pip install -e -v .