具有以下包结构
.
??? my_package
? ??? __init__.py
??? setup.cfg
??? setup.py
Run Code Online (Sandbox Code Playgroud)
的内容 setup.py
from setuptools import setup
setup()
Run Code Online (Sandbox Code Playgroud)
的内容 setup.cfg
[metadata]
name = my_package
version = 0.1
[options]
packages = find:
Run Code Online (Sandbox Code Playgroud)
我可以my_package像这样构建轮子或源代码分发
pip wheel --no-deps -w dist .
# generates file ./dist/my_package-0.1-py3-none-any.whl
python setup.py sdist
# generates file ./dist/my_package-0.1.tar.gz
Run Code Online (Sandbox Code Playgroud)
但是根据setuptools 的维护者的说法,声明式构建配置是理想的,使用命令式构建将是一种代码味道。所以我们替换setup.py为pyproject.toml:
.
??? my_package
? ??? __init__.py
??? setup.cfg
??? pyproject.toml
Run Code Online (Sandbox Code Playgroud)
的内容 pyproject.toml
[build-system]
build-backend = "setuptools.build_meta"
requires = ["setuptools", "wheel"]
Run Code Online (Sandbox Code Playgroud)
你仍然可以像以前一样构建一个轮子,它可以工作。但是 …
我正在学习 Python 打包,根据本指南,构建 python 分发包的命令似乎是python3 -m build.
但我还发现 setuptools 中有一个用于 setup.py 文件的命令行界面:
\n$ python setup.py --help-commands\nStandard commands:\n build build everything needed to install\n sdist create a source distribution (tarball, zip file, etc.)\n bdist create a built (binary) distribution\n bdist_dumb create a "dumb" built distribution\n bdist_rpm create an RPM distribution\n ...\nRun Code Online (Sandbox Code Playgroud)\n似乎python setup.py build,sdist或者 也bdist可以构建发行版,但我没有找到这些命令的详细说明,setuptools 命令参考缺少对build sdist bdist.
所以我有点困惑,python setup.py build和之间有什么区别 …
因此,我尝试按照本教程创建一个新的 Python 包:https://packaging.python.org/en/latest/tutorials/packaging-projects/
正如教程所说,在我的pyproject.tomlI 中应该具有以下结构:
[project]
name = "example_package_YOUR_USERNAME_HERE"
version = "0.0.1"
authors = [
{ name="Example Author", email="author@example.com" },
]
description = "A small example package"
Run Code Online (Sandbox Code Playgroud)
但是当我用 创建这个文件时poetry init,它创建了这个结构:
[tool.poetry]
name = "example_package_YOUR_USERNAME_HERE"
version = "0.0.1"
authors = [
{ name="Example Author", email="author@example.com" },
]
description = "A small example package"
Run Code Online (Sandbox Code Playgroud)
两者之间的主要区别在于[project]代替[tool.poetry]节标题。我还看到,poetry当没有[tool.poetry]部分时,这对项目没有任何作用pyproject.toml
这两者有什么区别?
我的 中应该只有一个还是同时有两个pyproject.toml?如果我应该保留两者,它应该包含什么?
如果应该只有[tool.poetry],我是否需要遵循与 相同的内容和子部分规则[project]?例如, …
setuptools pypi python-packaging python-poetry pyproject.toml
序言:
Python setuptools用于包分发.我有一个Python包(让我们称之为my_package),它有几个extra_require包.一切工作只是找到(安装和构建包,以及额外的,如果被要求),因为所有extra_require都是python包本身和pip正确解决了一切.一个简单的pip install my_package工作就像一个魅力.
设置:
现在,对于其中一个附加内容(让我们称之为extra1),我需要调用非python库的二进制文件X.
模块X本身(源代码)已添加到my_package代码库中,并包含在发行版中my_package.遗憾的是,要使用,X需要首先在目标机器上编译成二进制文件(C++实现;我假设这样的编译将在my_package安装的构建阶段进行).有一个Makefile在X不同的平台的编译优化库,使所有需要的,是运行make在各自的目录X库的my_package构建过程中运行时.
问题1:如何make使用setuptools/distutils在包的构建过程中运行终端命令(即在我的情况下)?
问题2:如何确保只有extra1在安装过程中指定了相应的终端命令才能执行?
例:
pip install my_package,则不会发生这种额外的库编译X.pip install my_package [extra1],则X需要编译模块,因此将在目标计算机上创建并提供相应的二进制文件.有没有办法获得给定python包的依赖项列表而不先安装它?
我目前可以获得要求列表,但它需要安装包.例如,我可以使用pip来显示基本需求信息,但它不包含版本信息:
$ pip show pytest
Name: pytest
Version: 3.0.6
...
Requires: colorama, setuptools, py
Run Code Online (Sandbox Code Playgroud)
我已经尝试过一个名为pipdeptree包含更好输出要求的库,但它也需要安装包
$ pipdeptree -p pytest
pytest==3.0.6
- colorama [required: Any, installed: 0.3.7]
- py [required: >=1.4.29, installed: 1.4.32]
- setuptools [required: Any, installed: 34.0.0]
- appdirs [required: >=1.4.0, installed: 1.4.0]
...
Run Code Online (Sandbox Code Playgroud)
理想情况下,我会得到pipdeptree提供的详细程度.此外,能够requirements.txt从python wheel或pypi 生成文件pip也足够了.
编辑:
我看过类似的问题.它们要么过时,需要安装,要么它们不列出给定包的单个依赖项,只列出解决依赖性要求后最终下载的包的列表.例如,我并不关心pip下载package-2.3.4,我宁愿知道这package>=2.1是一个要求.
多级相对导入
我有以下文件夹结构
top\
__init__.py
util\
__init__.py
utiltest.py
foo\
__init__.py
foo.py
bar\
__init__.py
foobar.py
Run Code Online (Sandbox Code Playgroud)
我想从foobar.py模块访问utiltest.py.我试过跟随相对导入,但这不起作用:
from ...util.utiltest import *
我总是得到
ValueError: Attempted relative import beyond toplevel package
怎么做这样的多重相对导入?
检查 PyPI 包名称是否被占用的最佳方法是什么?
我已经多次在pypi中搜索软件包但没有收到任何结果。然后我花时间创建了一个包,其名称似乎没有被占用,但在部署时却收到错误。有没有更好的方法来检查包名称的可用性?
Pip 支持该pyproject.toml文件,但到目前为止,新模式的所有实际使用都需要一个 3rd 方工具来自动生成这些文件(例如,诗歌和 pip)。不像setup.py已经是人类可写的,pyproject.toml不是(还)。
[build-system]
requires = [
"setuptools >= 40.9.0",
"wheel",
]
build-backend = "setuptools.build_meta"
Run Code Online (Sandbox Code Playgroud)
但是,此文件不包含包依赖项(如 PEP 621 中所述)。Pip 确实支持使用安装包,pyproject.toml但 pep 没有指定如何pyproject.toml为官方构建系统编写包依赖项setuptools。
我如何编写包依赖项pyproject.toml?
相关的 StackOverflow 问题:
这个问题要求一种自动生成的方法pyproject.toml,我的问题有所不同,因为我要求使用人工编写的pyproject.toml.
setuptools python-packaging python-poetry pyproject.toml pep517
setup.py在使用不受支持的Python版本时,我们可以在文件中放置什么来阻止pip收集并尝试安装包?
例如,magicstack是使用特洛伊分类器列出的项目:
Programming Language :: Python :: 3 :: Only
Run Code Online (Sandbox Code Playgroud)
所以我希望以下行为如果pip --version与python 2.7绑定:
$ pip install magicstack
Collecting magicstack
Could not find a version that satisfies the requirement magicstack (from versions: )
No matching distribution found for magicstack
Run Code Online (Sandbox Code Playgroud)
但实际行为是pip收集一个版本,下载它,尝试安装它并失败.curio例如,还有其他仅支持Python3的版本,实际上安装得很好 - 因为它setup.py没有使用任何特定的Python 3 - 只在导入时失败,只使用了一些Python 3语法.而且我确定有些软件包安装正常,导入正常,可能只在运行时失败!
以pip尊重的方式指定支持的Python版本的正确方法是什么? 我找到了一个解决方法,只涉及上传一个轮文件,并拒绝上传.tar.gz发行版,但我很想知道正确的修复.
编辑:如果Python/os/architecture不匹配 ,pip如何知道不下载wheel分布?它只是使用.whl文件名约定还是比幕后更复杂?我们能不能以某种方式将元数据提供给源代码分发,以使pip使用.tar.gz上传做正确的事情?
python-packaging ×10
python ×7
setuptools ×5
pypi ×4
pip ×2
makefile ×1
pep517 ×1
pycharm ×1
setup.py ×1