Poetry 构建的包缺少运行时依赖项

l0b*_*0b0 4 requirements python-packaging python-poetry

我一直在从事一个项目,到目前为止只涉及构建一些云基础设施,现在我正在尝试添加一个 CLI来简化一些 AWS Lambda 的运行。不幸的是,使用构建的 sdist 和wheel 软件包poetry build似乎都不包含依赖项,因此我必须手动运行pip install所有这些软件包才能运行该命令。基本上我

\n
    \n
  1. poetry build在项目中运行,
  2. \n
  3. cd "$(mktemp --directory)",
  4. \n
  5. python -m venv .venv,
  6. \n
  7. . .venv/bin/activate,
  8. \n
  9. pip install /path/to/result/of/poetry/build/above, 进而
  10. \n
  11. 运行新的 .venv/bin/ 可执行文件。
  12. \n
\n

此时可执行文件失败,因为pip没有安装任何包依赖项。如果我pip show PACKAGE该行Requires是空的。

\n

Poetry 手册似乎没有指定如何将依赖项链接到构建的包,那么我该怎么办呢?

\n

我正在使用一些可选的依赖项,这会干扰构建过程吗?需要明确的是,即使是非可选依赖项也不会显示在依赖项中。

\n

pyproject.toml:

\n
[build-system]\nrequires = ["poetry-core>=1.0.0"]\nbuild-backend = "poetry.core.masonry.api"\n\n[tool.black]\nline-length = 100\n\n[tool.coverage.report]\nexclude_lines = [\n    \'if TYPE_CHECKING:\',\n    \'if __name__ == "__main__":\',\n    \'pragma: no cover\',\n]\nfail_under = 100\n\n[tool.coverage.run]\nbranch = true\nomit = [\n    ".venv/*",\n]\n\n[tool.isort]\ncase_sensitive = true\nline_length = 100\nprofile = "black"\n\n[tool.mypy]\nshow_error_codes = true\nstrict = true\n\n[[tool.mypy.overrides]]\nmodule = [\n    "jsonschema",\n    "jsonschema._utils",\n    "jsonschema.validators",\n    "multihash",\n    "pystac",\n    "pystac.layout",\n    "pytest_subtests",\n    "smart_open",\n    "linz_logger"\n]\nignore_missing_imports = true\n\n[tool.poetry]\nname = "geostore"\nversion = "0.1.0"\ndescription = "Central storage, management and access for important geospatial datasets developed by LINZ"\nauthors = [\n    "Bill M. Nelson <bmnelson@linz.govt.nz>",\n    "Daniel Silk <dsilk@linz.govt.nz>",\n    "Ivan Mincik <ivan.mincik@gmail.com>",\n    "Mitchell Paff <mpaff@linz.govt.nz>",\n    "Sandro Santilli <strk@kbt.io>",\n    "Simon Planzer <splanzer@linz.govt.nz>",\n    "Victor Engmark <vengmark@linz.govt.nz>",\n]\nlicense = "MIT"\nreadme = "README.md"\nhomepage = "https://github.com/linz/geostore"\nrepository = "https://github.com/linz/geostore"\nkeywords = [\n    "SpatioTemporal Asset Catalog (STAC)",\n    "Toit\xc5\xab Te Whenua Land Information New Zealand",\n]\nclassifiers = [\n    "Development Status :: 4 - Beta",\n    "Environment :: Console",\n    "Framework :: AWS CDK",\n    "Framework :: Pytest",\n    "Intended Audience :: End Users/Desktop",\n    "Intended Audience :: Information Technology",\n    "License :: OSI Approved :: MIT License",\n    "Natural Language :: English",\n    "Operating System :: POSIX",\n    "Programming Language :: Python :: 3.8",\n    "Topic :: Communications :: File Sharing",\n    "Topic :: Scientific/Engineering :: GIS",\n    "Topic :: Utilities",\n    "Typing :: Typed",\n]\n\n[tool.poetry.dependencies]\npython = "^3.8"\n"aws-cdk.aws-dynamodb" = {version = "*", optional = true}\n"aws-cdk.aws-ec2" = {version = "*", optional = true}\n"aws-cdk.aws-ecr" = {version = "*", optional = true}\n"aws-cdk.aws-ecr_assets" = {version = "*", optional = true}\n"aws-cdk.aws-ecs" = {version = "*", optional = true}\n"aws-cdk.aws-events" = {version = "*", optional = true}\n"aws-cdk.aws-events-targets" = {version = "*", optional = true}\n"aws-cdk.aws-iam" = {version = "*", optional = true}\n"aws-cdk.aws-lambda" = {version = "*", optional = true}\n"aws-cdk.aws-lambda-event-sources" = {version = "*", optional = true}\n"aws-cdk.aws-lambda-python" = {version = "*", optional = true}\n"aws-cdk.aws-s3" = {version = "*", optional = true}\n"aws-cdk.aws-sns" = {version = "*", optional = true}\n"aws-cdk.aws-stepfunctions" = {version = "*", optional = true}\n"aws-cdk.aws-stepfunctions_tasks" = {version = "*", optional = true}\nawscli = {version = "*", optional = true}\nboto3 = "*"\ncattrs = {version = "*", optional = true}\njsonschema = {version = "*", extras = ["format"], optional = true}\nmultihash = {version = "*", optional = true}\npynamodb = {version = "*", optional = true}\npystac = {version = "*", optional = true}\nslack-sdk = {version = "*", extras = ["models", "webhook"], optional = true}\nsmart-open = {version = "*", extras = ["s3"], optional = true}\nstrict-rfc3339 = {optional = true, version = "*"}\ntyper = "*"\nulid-py = {version = "*", optional = true}\nlinz-logger = {version = "*", optional = true}\n\n[tool.poetry.dev-dependencies]\nblack = "*"\nboto3-stubs = {version = "*", extras = ["batch", "dynamodb", "events", "lambda", "lambda-python", "s3", "s3control", "sns", "sqs", "ssm", "stepfunctions", "sts"]}\ngitlint = "*"\nipdb = "*"\nisort = "*"\nlanguage-formatters-pre-commit-hooks = "*"\nmutmut = "*"\nmypy = "*"\npre-commit = "*"\npylint = "*"\npytest = "*"\npytest-randomly = "*"\npytest-socket = "*"\npytest-subtests = "*"\npytest-timeout = "*"\ntypes-pkg-resources = "*"\ntypes-python-dateutil = "*"\ntypes-requests = "*"\ntypes-six = "*"\ntypes-toml = "*"\n\n[tool.poetry.dev-dependencies.coverage]\nversion = "*"\nextras = ["toml"]\n\n[tool.poetry.extras]\ncdk = [\n    "aws-cdk.aws-dynamodb",\n    "aws-cdk.aws-ec2",\n    "aws-cdk.aws-ecr",\n    "aws-cdk.aws-ecr_assets",\n    "aws-cdk.aws-ecs",\n    "aws-cdk.aws-events",\n    "aws-cdk.aws-events-targets",\n    "aws-cdk.aws-iam",\n    "aws-cdk.aws-lambda",\n    "aws-cdk.aws-lambda-event-sources",\n    "aws-cdk.aws-lambda-python",\n    "aws-cdk.aws-s3",\n    "aws-cdk.aws-sns",\n    "aws-cdk.aws-stepfunctions",\n    "aws-cdk.aws-stepfunctions_tasks",\n    "awscli",\n    "cattrs",\n]\ncheck_files_checksums = [\n    "boto3",\n    "linz-logger",\n    "multihash",\n    "pynamodb",\n]\ncheck_stac_metadata = [\n    "boto3",\n    "jsonschema",\n    "linz-logger",\n    "pynamodb",\n    "strict-rfc3339",\n]\ncli = [\n    "boto3",\n    "typer",\n]\ncontent_iterator = [\n    "jsonschema",\n    "linz-logger",\n    "pynamodb",\n]\ndatasets = [\n    "boto3",\n    "jsonschema",\n    "linz-logger",\n    "pynamodb",\n    "pystac",\n    "ulid-py",\n]\ndataset_versions = [\n    "jsonschema",\n    "linz-logger",\n    "pynamodb",\n    "ulid-py",\n]\nimport_asset_file = [\n    "boto3",\n    "linz-logger",\n    "smart-open",\n]\nimport_dataset = [\n    "boto3",\n    "jsonschema",\n    "linz-logger",\n    "pynamodb",\n    "smart-open",\n    "ulid-py",\n]\nimport_metadata_file = [\n    "boto3",\n    "linz-logger",\n]\nimport_status = [\n    "boto3",\n    "jsonschema",\n    "linz-logger",\n    "pynamodb",\n]\nnotify_status_update = [\n    "boto3",\n    "jsonschema",\n    "linz-logger",\n    "pynamodb",\n    "slack-sdk"\n]\npopulate_catalog = [\n    "boto3",\n    "jsonschema",\n    "linz-logger",\n    "pystac",\n]\nupdate_dataset_catalog = [\n    "boto3",\n    "jsonschema",\n    "linz-logger",\n    "pynamodb",\n    "ulid-py"\n]\nupload_status = [\n    "boto3",\n    "jsonschema",\n    "linz-logger",\n    "pynamodb",\n]\nvalidation_summary = [\n    "jsonschema",\n    "linz-logger",\n    "pynamodb",\n]\n\n[tool.poetry.scripts]\ngeostore = "geostore.cli:app"\n\n[tool.pylint.MASTER]\ndisable = [\n    "duplicate-code",\n    "missing-class-docstring",\n    "missing-function-docstring",\n    "missing-module-docstring",\n]\nload-plugins = [\n    "pylint.extensions.mccabe",\n]\nmax-complexity = 6\n\n[tool.pytest.ini_options]\naddopts = "--randomly-dont-reset-seed"\nmarkers = [\n    "infrastructure: requires a deployed infrastructure",\n]\npython_functions = "should_*"\ntestpaths = [\n    "tests"\n]\n
Run Code Online (Sandbox Code Playgroud)\n

正如您所看到的,boto3 和 typer 运行时依赖项不是可选的,因此我希望在poetry show geostore.

\n

ano*_*non 5

这似乎是诗歌中的一个错误。或者至少从文档中不清楚在像您这样的情况下预期的行为是什么。

\n

In your pyproject.toml, you specify two dependencies as required in this section:

\n
[tool.poetry.dependencies]\n\xe2\x80\xa6\nawscli = {version = "*", optional = true}\nboto3 = "*"\n\xe2\x80\xa6\ntyper = "*"\n\xe2\x80\xa6\n
Run Code Online (Sandbox Code Playgroud)\n

So, as opposed to awscli among many others, boto3 and typer should be required because the optional attribute is not set and defaults to false. But you also list the two required dependencies as "extras" in this section:

\n
[tool.poetry.extras]\n\xe2\x80\xa6\ncli = [\n    "boto3",\n    "typer",\n]\n\xe2\x80\xa6\n
Run Code Online (Sandbox Code Playgroud)\n

Poetry takes that to mean that they are in fact optional, not required. Which makes sense, in a way, because extras are effectively optional. If you inspect the .whl wheel file built by Poetry (it\'s just a zip archive), specifically the METADATA file in it (which is what Pip refers to when installing the package), then it contains this line:

\n
[tool.poetry.dependencies]\n\xe2\x80\xa6\nawscli = {version = "*", optional = true}\nboto3 = "*"\n\xe2\x80\xa6\ntyper = "*"\n\xe2\x80\xa6\n
Run Code Online (Sandbox Code Playgroud)\n

So that dependency is in fact optional: It will only get installed if users ask for it explicitly with pip install geostore[cli].

\n

The solution then is simple: Remove all references to the required dependencies from the extras section. They are not needed there anyway.

\n

事实上,诗歌文档对于optional真正的含义并不是很清楚。该属性(当前)仅在文件部分pyproject.toml中简要提及。人们还可能会争辩说,如果optionalfalse,则该extras部分不应覆盖该值。

\n