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

Posted

技术标签:

【中文标题】在导入中分配 .src 前缀的 Src 布局?在 PyCharm 终端中激活 venv 以进行开发安装【英文标题】:Src layout to dispense .src prefix in imports? Activate venv in PyCharm terminal for development installs 【发布时间】:2020-10-11 08:27:36 【问题描述】:

我想了解在导入时使用 src. 前缀的方式使用带有 "src/ layout" 的 setuptools 的正确极简方式是什么?

我已经阅读了大部分 PyPA 和 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()

使用这个目录/文件结构:

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

当我使用development mode install 和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']

【问题讨论】:

你已经在开发模式下安装了这个包,这应该足够了。有时重新安装是必要的,但仅当您在项目中添加/删除源或更改包元数据时。 egg 符号链接未写入 venv 站点包 - 这可能是根本问题,pip -V 返回什么?它指向venv的网站吗?该软件包是否在已安装软件包列表中(pip show mylibrary 产生什么)? 【参考方案1】:

更新/解决方法

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

源根 源根图标包含实际的源文件和 资源。 PyCharm 使用源根作为起点 解析导入

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

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 . 进行安装

【讨论】:

【参考方案2】:

所描述的问题源于activate the venv inside PyCharm's terminal。

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

需要注意的是:

在development mode 中安装时使用详细标志-v 提供了pipsetuptools 正在尝试做什么的线索。

决定性的 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 和 Python 基础安装之外的 site-packages(注意路径)。您可能想要避免的事情,因为 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,这很可能是您想要的。

【讨论】:

以上是关于在导入中分配 .src 前缀的 Src 布局?在 PyCharm 终端中激活 venv 以进行开发安装的主要内容,如果未能解决你的问题,请参考以下文章

OSError:/lib/aarch64-linux-gnu/libgomp.so.1:无法在静态 TLS 块中分配内存

为啥我们可以直接在ByteBuffer中分配字节而不在FloatBuffer中分配浮点数

在 Spring Boot 应用程序中分离集成测试

自动前缀在 webpack 中不起作用

为 Symfony 中的每个 src 文件夹设置安全性

eclipse 导入工程 src文件丢失