Friday, August 12, 2022

Re: WIP, RFC: handling python ports with pyproject.toml and various backends (pep517)

On 2022/08/04 21:08, Stuart Henderson wrote:
> Some Python ports now use pyproject.toml with various build backends. It
> seems that the best way for us to work with these is going to be to use
> "pip wheel" to generate a wheel, and py-installer to place files from
> that wheel into the fake-install directory.
>
> There are a few flit_core-based ports where so far I've been using
> "python -m flit_core.wheel" directly to generate the wheel, and all of
> these are working by instead using "pip wheel -v --no-index --no-cache
> --no-deps --no-build-isolation ."
>
> Also it looks like the same works for other ports using hatchling
> (I need to do some rearrangement to split combined py2+3 py- ports
> off into a separate py2- so I can update the py3 version to get
> deps updated before we can use that).
>
> So here are some WIP changes to python.port.mk and those ports to
> handle it more nicely.
>
> Does anyone else have any kind of handle on this stuff? If so does
> this seem sane?

Updated to add a missing BUILD_DEPENDS, fix a copy+paste error that
jca@ spotted, and use grep to show the build backend if pyproject.toml
is present and MODPY_PEP517 isn't set (as an aid to port maintainers;
I may tweak how that's done when I have more experience using it).

I'd like to start using it to clean up some of the pep517-based ports
in tree already and iterate further from there, does anyone have
concerns?

Using "MODPY_PEP517=hatchling" requires the 2 ports I've just sent
separately.

Index: python.port.mk
===================================================================
RCS file: /cvs/ports/lang/python/python.port.mk,v
retrieving revision 1.147
diff -u -p -r1.147 python.port.mk
--- python.port.mk 4 Aug 2022 19:15:59 -0000 1.147
+++ python.port.mk 12 Aug 2022 14:20:15 -0000
@@ -147,8 +147,23 @@ RUN_DEPENDS += ${MODPY_RUN_DEPENDS}
TEST_DEPENDS += ${MODPY_TEST_DEPENDS}
.endif

+MODPY_SETUPTOOLS ?=
+MODPY_SETUPUTILS ?=
+MODPY_PEP517 ?= No
+MODPY_PI ?=
+
_MODPY_PRE_BUILD_STEPS = :
-.if defined(MODPY_SETUPTOOLS) && ${MODPY_SETUPTOOLS:L} == "yes"
+
+.if ${MODPY_PEP517:L} == "no"
+_MODPY_PRE_BUILD_STEPS += ; if [ -e ${WRKSRC}/pyproject.toml ] && \
+ ! grep -q ^build-backend.*setuptools ${WRKSRC}/pyproject.toml; then \
+ printf "\n***\n\nOpenBSD ports: should this use MODPY_PEP517?\n"; \
+ grep ^build-backend ${WRKSRC}/pyproject.toml || true; \
+ printf "\n***\n\n"; fi
+.endif
+
+
+.if ${MODPY_SETUPTOOLS:L} == "yes"
# The setuptools module provides a package locator (site.py) that is
# required at runtime for the pkg_resources stuff to work
. if ${MODPY_MAJOR_VERSION} == 2
@@ -160,6 +175,7 @@ MODPY_SETUPUTILS_DEPEND ?= devel/py-setu
MODPY_RUN_DEPENDS += ${MODPY_SETUPUTILS_DEPEND}
BUILD_DEPENDS += ${MODPY_SETUPUTILS_DEPEND}
MODPY_SETUPUTILS = Yes
+
# The setuptools uses test target
TEST_TARGET ?= test
_MODPY_USERBASE =
@@ -174,6 +190,16 @@ _MODPY_PRE_BUILD_STEPS += ;${MODPY_CMD}
# that plugin will cause failure at the end of build.
# In the absence of a targetted means of disabling this, use a big hammer:
DPB_PROPERTIES += nojunk
+.elif ${MODPY_PEP517:L} != no
+BUILD_DEPENDS += devel/py-installer${MODPY_FLAVOR} \
+ devel/py-pip${MODPY_FLAVOR}
+. if ${MODPY_PEP517:L:Mflit_core}
+BUILD_DEPENDS += devel/py-flit_core${MODPY_FLAVOR}
+. elif ${MODPY_PEP517:L:Mflit}
+BUILD_DEPENDS += devel/py-flit${MODPY_FLAVOR}
+. elif ${MODPY_PEP517:L:Mhatch}
+BUILD_DEPENDS += devel/py-hatchling${MODPY_FLAVOR}
+. endif
.else
# Try to detect the case where a port will build regardless of setuptools
# but the final plist will be different if it's present.
@@ -192,7 +218,7 @@ MODPY_SETUPUTILS = No
_MODPY_USERBASE = ${WRKDIR}
.endif

-.if defined(MODPY_PI) && ${MODPY_PI:L} == "yes"
+.if ${MODPY_PI:L} == "yes"
_MODPY_EGG_NAME = ${DISTNAME:S/-${MODPY_EGG_VERSION}//}
MODPY_PI_DIR ?= ${DISTNAME:C/^([a-zA-Z0-9]).*/\1/}/${_MODPY_EGG_NAME}
MASTER_SITES = ${MASTER_SITE_PYPI:=${MODPY_PI_DIR}/}
@@ -268,6 +294,17 @@ MODPY_ADJ_FILES ?=
MODPYTHON_pre-configure += cd ${WRKSRC} && ${MODPY_BIN_ADJ} ${MODPY_ADJ_FILES}
.endif

+.if ${MODPY_PEP517:L} != no
+MODPY_BUILD_TARGET = ${_MODPY_PRE_BUILD_STEPS}; \
+ cd ${WRKSRC} && pip wheel -v --no-index --no-cache --no-deps --no-build-isolation .
+MODPY_INSTALL_TARGET = \
+ ${INSTALL_DATA_DIR} ${WRKINST}${MODPY_LIBDIR}; \
+ ${MODPY_BIN} -m installer -d ${WRKINST} ${WRKSRC}/*.whl
+MODPY_TEST_TARGET = ${MODPY_TEST_CMD}
+. if ${MODPY_PYTEST:L} == "yes"
+MODPY_TEST_TARGET += ${MODPY_PYTEST_ARGS}
+. endif
+.else
MODPY_BUILD_TARGET = ${_MODPY_PRE_BUILD_STEPS}; \
${MODPY_CMD} ${MODPY_DISTUTILS_BUILD} ${MODPY_DISTUTILS_BUILDARGS}
MODPY_INSTALL_TARGET = \
@@ -275,10 +312,11 @@ MODPY_INSTALL_TARGET = \
${MODPY_DISTUTILS_INSTALL} ${MODPY_DISTUTILS_INSTALLARGS}

MODPY_TEST_TARGET = ${MODPY_TEST_CMD}
-.if ${MODPY_PYTEST:L} == "yes"
+. if ${MODPY_PYTEST:L} == "yes"
MODPY_TEST_TARGET += ${MODPY_PYTEST_ARGS}
-.elif ${MODPY_SETUPUTILS:L} == "yes"
+. elif ${MODPY_SETUPUTILS:L} == "yes"
MODPY_TEST_TARGET += ${TEST_TARGET}
+. endif
.endif

# dirty way to do it with no modifications in bsd.port.mk

No comments:

Post a Comment