Skip to content

Instantly share code, notes, and snippets.

@dyens
Last active March 5, 2023 19:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dyens/a9ea6c3392ebc62865b2c308661cb68c to your computer and use it in GitHub Desktop.
Save dyens/a9ea6c3392ebc62865b2c308661cb68c to your computer and use it in GitHub Desktop.
Pip install poetry dev dependencies
# Code have some little changes from the origial https://github.com/python-poetry/poetry-core/blob/main/src/poetry/core/masonry/api.py
# Usage:
# 1. copy this file to /project/build.py
# 2. modify build-system section in pyproject file:
#
# [build-system]
# requires = ["poetry-core"]
# build-backend = "build"
# backend-path = "."
#
# 3. Run to install dev deps:
# pip install --config-settings dev=true .
from __future__ import annotations
import logging
from pathlib import Path
from typing import Any
from poetry.core.factory import Factory as OriginFactory
from poetry.core.masonry.builders.sdist import SdistBuilder
from poetry.core.masonry.builders.wheel import WheelBuilder
log = logging.getLogger(__name__)
class Factory(OriginFactory):
def create_poetry(
self, cwd: Path | None = None, with_groups=False, with_dev=False,
):
from poetry.core.poetry import Poetry
from poetry.core.pyproject.toml import PyProjectTOML
poetry_file = self.locate(cwd)
local_config = PyProjectTOML(path=poetry_file).poetry_config
# Checking validity
check_result = self.validate(local_config)
if check_result["errors"]:
message = ""
for error in check_result["errors"]:
message += f" - {error}\n"
raise RuntimeError("The Poetry configuration is invalid:\n" + message)
# Load package
name = local_config["name"]
assert isinstance(name, str)
version = local_config["version"]
assert isinstance(version, str)
package = self.get_package(name, version)
if with_dev is True:
for dep, version in local_config["group"]["dev"]["dependencies"].items():
local_config["dependencies"][dep] = version
package = self.configure_package(
package, local_config, poetry_file.parent, with_groups=with_groups
)
return Poetry(poetry_file, local_config, package)
def get_requires_for_build_wheel(
config_settings: dict[str, Any] | None = None,
) -> list[str]:
"""
Returns an additional list of requirements for building, as PEP508 strings,
above and beyond those specified in the pyproject.toml file.
This implementation is optional. At the moment it only returns an empty list, which would be the same as if
not define. So this is just for completeness for future implementation.
"""
return []
# For now, we require all dependencies to build either a wheel or an sdist.
get_requires_for_build_sdist = get_requires_for_build_wheel
def use_with_dev(config_settings: dict[str, Any] | None = None) -> bool:
return config_settings is not None and config_settings.get("dev", "") == "true"
def prepare_metadata_for_build_wheel(
metadata_directory: str, config_settings: dict[str, Any] | None = None
) -> str:
with_dev = use_with_dev(config_settings)
poetry = Factory().create_poetry(Path(".").resolve(), with_groups=False, with_dev=True)
builder = WheelBuilder(poetry)
metadata_path = Path(metadata_directory)
dist_info = builder.prepare_metadata(metadata_path)
return dist_info.name
def build_wheel(
wheel_directory: str,
config_settings: dict[str, Any] | None = None,
metadata_directory: str | None = None,
) -> str:
"""Builds a wheel, places it in wheel_directory"""
with_dev = use_with_dev(config_settings)
poetry = Factory().create_poetry(Path(".").resolve(), with_groups=False, with_dev=True)
metadata_path = None if metadata_directory is None else Path(metadata_directory)
return WheelBuilder.make_in(
poetry, Path(wheel_directory), metadata_directory=metadata_path
)
def build_sdist(
sdist_directory: str, config_settings: dict[str, Any] | None = None
) -> str:
"""Builds an sdist, places it in sdist_directory"""
with_dev = use_with_dev(config_settings)
poetry = Factory().create_poetry(Path(".").resolve(), with_groups=False, with_dev=True)
path = SdistBuilder(poetry).build(Path(sdist_directory))
return path.name
def build_editable(
wheel_directory: str,
config_settings: dict[str, Any] | None = None,
metadata_directory: str | None = None,
) -> str:
with_dev = use_with_dev(config_settings)
poetry = Factory().create_poetry(Path(".").resolve(), with_groups=False, with_dev=True)
metadata_path = None if metadata_directory is None else Path(metadata_directory)
return WheelBuilder.make_in(
poetry, Path(wheel_directory), metadata_directory=metadata_path, editable=True
)
get_requires_for_build_editable = get_requires_for_build_wheel
prepare_metadata_for_build_editable = prepare_metadata_for_build_wheel
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment