1# Provide support for Python related ports. This includes detecting Python
2# interpreters, ports providing package and modules for python as well as
3# consumer ports requiring Python at build or run time.
4#
5# Feature:	python
6# Usage:	USES=python[:version-spec][,arg,...]
7# Valid ARGS:	<version-spec>, patch, build, run, test, env
8#
9# version-spec 	Declarative specification for the Python version(s) the
10#		port supports. Subsets and ranges can be specified:
11#
12#			* <version>
13#			* <minimum-version>-<maximum-version>
14#			* <minimum-version>+
15#			* -<maximum-version>
16#
17#		Examples:
18#
19#			USES=python:2.7		# Supports Python 2.7 Only
20#			USES=python:3.11+	# Supports Python 3.11 or later
21#			USES=python:3.11-3.12	# Supports Python 3.11 to 3.12
22#			USES=python:-3.11	# Supports Python up to 3.11
23#			USES=python		# Supports 3.10+
24#
25# NOTE:	<version-spec> should be as specific as possible, matching the versions
26#	upstream declares support for, without being incorrect. In particular,
27#	USES=python *without* a <version-spec> means 3.11+,
28#	including unreleased versions, which is probably incorrect.
29#
30#	Not specifying a <version-spec> should only be used when a more specific
31#	<version-spec> cannot be specified due to syntax limitations, for
32#	example: 2.7,3.11-3.12, but even in this case, X.Y+ (2.7+), or -X.Y (-3.11)
33#	is preferred and likely more correct.
34#
35# patch		Python is needed at patch time. Adds dependency to PATCH_DEPENDS.
36# build		Python is needed at build time. Adds dependency to BUILD_DEPENDS.
37# run		Python is needed at run time. Adds dependency to RUN_DEPENDS.
38# test		Python is needed at test time. Adds dependency to TEST_DEPENDS.
39# env		Does not depend on Python but needs the environment set up. This
40#		is mainly used when depending on flavored python ports, or when a
41#		correct PYTHON_CMD is required.  It has the same effect as setting
42#		PYTHON_NO_DEPENDS.
43#
44# If build, run and test are omitted, Python will be added as BUILD_DEPENDS,
45# RUN_DEPENDS and TEST_DEPENDS.
46# patch is independant, it does not prevent the default build/run/test
47# dependency.
48# env or PYTHON_NO_DEPENDS can be set to not add any dependencies.
49#
50# Exported variables:
51#
52# PYTHON_VERSION	- The chosen Python interpreter including the version,
53#			  e.g. python2.7, python3.11, etc.
54#
55# Variables, which can be set by the port:
56#
57# USE_PYTHON		- A list of additional features and functionality to
58#			  enable. Supported features are:
59#
60#	concurrent 	- Indicates that the port can be installed for
61#			  different python versions at the same time. The port
62#			  is supposed to use a unique prefix for certain
63#			  directories using USES=uniquefiles:dirs (see the
64#			  uniquefiles.mk Uses for details about the
65#			  directories), if set to yes. Binaries receive an
66#			  additional suffix, based on ${PYTHON_VER}.
67#
68#			  The values for the uniquefiles USES are set as
69#			  follows:
70#
71#				UNIQUE_PREFIX=  ${PYTHON_PKGNAMEPREFIX}
72#				UNIQUE_SUFFIX=  -${PYTHON_VER}
73#
74#			  If the port is installed for the current default
75#			  python version, scripts and binaries in
76#
77#				${PREFIX}/bin
78#				${PREFIX}/sbin
79#				${PREFIX}/libexec
80#
81#			  are linked from the prefixed version to the
82#			  prefix-less original name, e.g.
83#			  bin/foo-2.7 --> bin/foo.
84#
85#	cryptography_build
86#			- Depend on security/cryptography at build-time.
87#
88#	cryptography	- Depend on security/cryptography at run-time.
89#
90#	cryptography_test
91#			- Depend on security/cryptography at test-time.
92#
93#	cython		- Depend on lang/cython at build-time.
94#
95#	cython_run	- Depend on lang/cython at run-time.
96#
97#	cython_test	- Depend on lang/cython for tests.
98#
99#	cython0		- Depend on lang/cython0 at build-time.
100#
101#	cython0_run	- Depend on lang/cython0 at run-time.
102#
103#	flavors		- Force creation of flavors for Python 2 and 3 default
104#			  versions, where applicable.
105#
106#	noflavors	- Disable automatic creation of flavors if they would
107#			  otherwise be created and they are not wanted.
108#
109#	allflavors 	- Generate flavors for all possible versions and not
110#			  simply the default ones.  Only to be used for py-*
111#			  ports that are part of the Python distribution, but
112#			  kept as separate ports.
113#
114#	optsuffix	- Set PKGNAMESUFFIX to PYTHON_PKGNAMESUFFIX if not the
115#			  default python version.
116#
117#	distutils	- Use distutils as do-configure, do-build and
118#			  do-install targets. implies flavors.
119#
120#	pep517		- Follow the PEP-517 standard to build and install wheels
121#			  as do-build and do-install targets. implies flavors.
122#
123#	autoplist	- Automatically generates the packaging list for a
124#			  port that uses distutils when defined.
125#			  requires: distutils
126#
127#	py3kplist	- Automatically generates Python 3.x compatible
128#			  __pycache__ entries from a Python 2.x packaging list
129#			  when defined. Use this for ports that do *not* use
130#			  standard Python packaging mechanisms such as
131#			  distutils, and support *both* Python 2.x and 3.x.
132#			  Not needed, if USE_PYTHON=autoplist is set.
133#
134#	pythonprefix	- Says that the port installs in ${PYTHONBASE} instead
135#			  of ${PREFIX}.
136#
137#	noegginfo	- Skip an egg-info entry from plist, if defined.
138#
139#	nose		- Run tests with nose (devel/py-nose)
140#
141#	nose2		- Run tests with nose2 (devel/py-nose2)
142#
143#	pytest		- Run tests with latest pytest (devel/py-pytest)
144#
145#	unittest	- Run tests with unittest
146#
147#	unittest2	- Run tests with unittest2 (devel/py-unittest2)
148#
149# PYTHON_CMD		- Python's command line file name, including the
150#			  version number (used for dependencies).
151#			  default: ${PYTHONBASE}/bin/${PYTHON_VERSION}
152#
153# PEP517_BUILD_CMD	- Command sequence for a PEP-517 build frontend that builds a wheel.
154#			  default: ${PYTHON_CMD} -m build --no-isolation --wheel ${PEP517_BUILD_CONFIG_SETTING}
155#
156# PEP517_BUILD_DEPEND	- Port needed to execute ${PEP517_BUILD_CMD}.
157#			  default: ${PYTHON_PKGNAMEPREFIX}build>=0:devel/py-build@${PY_FLAVOR}
158#
159# PEP517_BUILD_CONFIG_SETTING
160#			- Options for the build backend. Must include -C or --config-setting per option.
161#			  default: <empty>
162#
163# PEP517_INSTALL_CMD	- Command sequence for a PEP-517 install frontend that installs a wheel.
164#			  default: ${PYTHON_CMD} -m installer --destdir ${STAGEDIR} --prefix ${PREFIX} ${BUILD_WRKSRC}/dist/${PORTNAME:C|[-_]+|_|g}-${DISTVERSION}*.whl
165#
166# PEP517_INSTALL_DEPEND	- Port needed to execute ${PEP517_INSTALL_CMD}.
167#			  default: ${PYTHON_PKGNAMEPREFIX}installer>=0:devel/py-installer@${PY_FLAVOR}
168#
169# PYSETUP		- Name of the setup script used by the distutils
170#			  package.
171#			  default: setup.py
172#
173# PYDISTUTILS_PKGNAME
174#			- Internal name in the distutils for egg-info.
175#			  default: ${PORTNAME}
176#
177# PYDISTUTILS_PKGVERSION
178#			- Internal version in the distutils for egg-info.
179#			  default: ${PORTVERSION}
180#
181# PYDISTUTILS_CONFIGURE_TARGET
182#			- Pass this command to distutils on configure stage.
183#			  default: config
184#
185# PYDISTUTILS_BUILD_TARGET
186#			- Pass this command to distutils on build stage.
187#			  default: build
188#
189# PYDISTUTILS_INSTALL_TARGET
190#			- Pass this command to distutils on install stage.
191#			  default: install
192#
193# PYDISTUTILS_CONFIGUREARGS
194#			- Arguments to config with distutils.
195#			  default: <empty>
196#
197# PYDISTUTILS_BUILDARGS
198#			- Arguments to build with distutils.
199#			  default: <empty>
200#
201# PYDISTUTILS_INSTALLARGS
202#			- Arguments to install with distutils.
203#			  default: -c -O1 --prefix=${PREFIX} --single-version-externally-managed --root=${FAKE_DESTDIR}
204#
205# PYDISTUTILS_EGGINFO
206#			- Canonical name for egg-info.
207#			  default: ${PYDISTUTILS_PKGNAME:C/[^A-Za-z0-9.]+/_/g}-${PYDISTUTILS_PKGVERSION:C/[^A-Za-z0-9.]+/_/g}-py${PYTHON_VER}.egg-info
208#
209# PYTEST_BROKEN_TESTS	- Lists of 'pytest -k' patterns to skip tests which
210#			  require fixing.
211#			  default: <empty>
212#
213# PYTEST_IGNORED_TESTS	- Lists of 'pytest -k' patterns to skip tests which are
214#			  not expected to pass, e.g. requiring a database access.
215#			  default: <empty>
216#
217# The following variables can be read by ports and must not be modified:
218#
219# PYTHONBASE		- The installation prefix of the chosen Python
220#			  interpreter, e.g. /usr/local
221#
222# PYTHON_DISTVERSION
223#			- Version number suitable for ${DISTVERSION}.
224#
225# PYTHON_PORTSDIR	- The port directory of the chosen Python interpreter
226#
227# PYTHON_REL		- The release number of the chosen Python interpreter
228#			  without dots, e.g. 20706, 31114, ...
229#
230# PYTHON_SUFFIX		- The major-minor release number of the chosen Python
231#			  interpreter without dots, e.g. 27, 310, ...
232#			  Used for prefixes and suffixes.
233#
234# PYTHON_BASESUFFIX	- PYTHON_SUFFIX without the threaded ABI flag.
235#
236# PYTHON_TAG		- Defined by PEP 3147, magic tag containing
237#			  implementation name and shorthand version,
238#			  primarily for bytecode files. Includes
239#			  preceding dot, e.g. .cpython-312,
240#			  .cpython-313, ...
241#
242# PYTHON_SOABI		- Defined by PEP 3149, tag containing
243#			  implementation name, shorthand version
244#			  and ABI tags, primarily for compiled
245#			  extension modules. Includes preceding
246#			  dot, e.g. .cpython-313, .cpython-313t,
247#			  .cpython-313td, ...
248#
249# PYTHON_MAJOR_VER	- The major release version of the chosen Python
250#			  interpreter, e.g. 2, 3, ...
251#
252# PYTHON_VER		- The major-minor release version of the chosen Python
253#			  interpreter, e.g. 2.7, 3.12, ...
254#
255# PYTHON_BASEVER	- PYTHON_VER without the threaded ABI flag.
256#
257# PYTHON_ABIVER		- Additional ABI flags set by the chosen Python
258#			  interpreter, e.g. md
259#
260# PYTHON_INCLUDEDIR	- Location of the Python include files.
261#			  default: ${PYTHONBASE}/include/${PYTHON_VERSION}
262#
263# PYTHON_LIBDIR		- Base of the python library tree
264#			  default: ${PYTHONBASE}/lib/${PYTHON_VERSION}
265#
266# PYTHON_SITELIBDIR	- Location of the site-packages tree. Don't change,
267#			  unless you know what you do.
268#			  default: ${PYTHON_LIBDIR}/site-packages
269#
270# There are PREFIX-clean variants of the PYTHON_*DIR variables above.
271# They are meant to be used by ports instead of the above variables, so the
272# ports respect ${PREFIX} (unless USE_PYTHON=pythonprefix is specified).
273#
274# PYTHONPREFIX_INCLUDEDIR	default: ${PREFIX}/include/${PYTHON_VERSION}
275# PYTHONPREFIX_LIBDIR		default: ${PREFIX}/lib/${PYTHON_VERSION}
276# PYTHONPREFIX_SITELIBDIR	default: ${PYTHONPREFIX_LIBDIR}/site-packages
277#
278# PYTHON_PLATFORM	- Python's idea of the OS release.
279#			  This is faked with ${OPSYS} and ${OSREL} until we
280#			  find out how to delay defining a variable until
281#			  after a certain target has been built.
282#
283# PYTHON_PKGNAMEPREFIX
284#			- Use this as a ${PKGNAMEPREFIX} to distinguish
285#			  packages for different Python versions.
286#			  default: py${PYTHON_SUFFIX}-
287#
288# PYTHON_PKGNAMESUFFIX
289#			- Use this as a ${PKGNAMESUFFIX} to distinguish
290#			  packages for different Python versions.
291#			  default: -py${PYTHON_SUFFIX}
292#
293# Using USES=python also will add some useful entries to SUB_LIST and PLIST_SUB:
294#
295#	PYTHON_INCLUDEDIR=${PYTHONPREFIX_INCLUDEDIR:S;${PREFIX}/;;}
296#	PYTHON_LIBDIR=${PYTHONPREFIX_LIBDIR:S;${PREFIX}/;;}
297#	PYTHON_PLATFORM=${PYTHON_PLATFORM}
298#	PYTHON_SITELIBDIR=${PYTHONPREFIX_SITELIBDIR:S;${PREFIX}/;;}
299#	PYTHON_SUFFIX=${PYTHON_SUFFIX}
300#	PYTHON_VER=${PYTHON_VER}
301#	PYTHON_VERSION=${PYTHON_VERSION}
302#
303# where PYTHON_INCLUDEDIR, PYTHON_LIBDIR and PYTHON_SITELIBDIR have their PREFIX
304# stripped for PLIST_SUB.
305#
306# PYTHON2 and PYTHON3 will also be set according to the Python version:
307#
308#	PYTHON2="" PYTHON3="@comment " for Python 2.x
309#	PYTHON2="@comment " PYTHON3="" for Python 3.x
310#
311# PYDISTUTILS_INSTALLNOSINGLE
312#			- Deprecated without replacement
313#
314# Dependency lines of selected Python modules:
315#
316# PY_SETUPTOOLS			- setuptools port based on USE_PYTHON=distutils
317# PYGAME			- pygame port
318# PYNUMPY			- NumPy port
319# PY_MERCURIAL			- mercurial port, PKGNAME varies based on default
320#				  Python version
321# PY_BOOST			- Boost Python libraries port
322#
323# The following variables may be set by the user:
324#
325# PYTEST_ENABLE_ALL_TESTS	- Enable tests skipped by PYTEST_BROKEN_TESTS
326#				  and PYTEST_IGNORED_TESTS.
327# PYTEST_ENABLE_BROKEN_TESTS	- Enable tests skipped by PYTEST_BROKEN_TESTS.
328# PYTEST_ENABLE_IGNORED_TESTS	- Enable tests skipped by PYTEST_IGNORED_TESTS.
329#
330# MAINTAINER: ports@MidnightBSD.org
331
332.if !defined(_INCLUDE_USES_PYTHON_MK)
333_INCLUDE_USES_PYTHON_MK=	yes
334
335ZEROREGS_UNSAFE=	yes
336
337# What Python version and what Python interpreters are currently supported?
338# When adding a version, please keep the comment in
339# Mk/bsd.default-versions.mk in sync.
340_PYTHON_VERSIONS=		3.11 3.12 3.13 3.13t 3.14 3.10 2.7 # preferred first
341_PYTHON_PORTBRANCH=		3.11		# ${_PYTHON_VERSIONS:[1]}
342_PYTHON_BASECMD=		${LOCALBASE:S;^${FAKE_DESTDIR};;}/bin/python
343_PYTHON_RELPORTDIR=		lang/python
344
345# List all valid USE_PYTHON features here
346_VALID_PYTHON_FEATURES=	allflavors \
347			autoplist \
348			concurrent \
349			cryptography_build \
350			cryptography \
351			cryptography_test \
352			cython \
353			cython_run \
354			cython_test \
355			cython0 \
356			cython0_run \
357			distutils \
358			flavors \
359			noegginfo \
360			noflavors \
361			nose \
362			nose2 \
363			optsuffix \
364			pep517 \
365			py3kplist \
366			pytest \
367			pythonprefix \
368			unittest \
369			unittest2
370_INVALID_PYTHON_FEATURES=
371.  for var in ${USE_PYTHON}
372.    if empty(_VALID_PYTHON_FEATURES:M${var})
373_INVALID_PYTHON_FEATURES+=	${var}
374.    endif
375.  endfor
376.  if !empty(_INVALID_PYTHON_FEATURES)
377IGNORE=	uses unknown USE_PYTHON features: ${_INVALID_PYTHON_FEATURES}
378.  endif
379
380# Make each individual feature available as _PYTHON_FEATURE_<FEATURENAME>
381.  for var in ${USE_PYTHON}
382_PYTHON_FEATURE_${var:C/=.*$//:tu}=	${var:C/.*=//:S/,/ /g}
383.  endfor
384
385# distutils automatically generates flavors depending on the supported
386# versions.
387.  if defined(_PYTHON_FEATURE_DISTUTILS)
388_PYTHON_FEATURE_FLAVORS=	yes
389.  endif
390
391# pep517 automatically generates flavors depending on the supported
392# versions.
393.  if defined(_PYTHON_FEATURE_PEP517)
394_PYTHON_FEATURE_FLAVORS=	yes
395.  endif
396
397.  if defined(_PYTHON_FEATURE_NOFLAVORS)
398.undef _PYTHON_FEATURE_FLAVORS
399.  endif
400
401# Make sure that no dependency or some other environment variable
402# pollutes the build/run dependency detection
403.undef _PYTHON_BUILD_DEP
404.undef _PYTHON_RUN_DEP
405.undef _PYTHON_TEST_DEP
406_PYTHON_ARGS=		${python_ARGS:S/,/ /g}
407.  if ${_PYTHON_ARGS:Mpatch}
408_PYTHON_PATCH_DEP=	yes
409_PYTHON_ARGS:=		${_PYTHON_ARGS:Npatch}
410.  endif
411.  if ${_PYTHON_ARGS:Mbuild}
412_PYTHON_BUILD_DEP=	yes
413_PYTHON_ARGS:=		${_PYTHON_ARGS:Nbuild}
414.  endif
415.  if ${_PYTHON_ARGS:Mrun}
416_PYTHON_RUN_DEP=	yes
417_PYTHON_ARGS:=		${_PYTHON_ARGS:Nrun}
418.  endif
419.  if ${_PYTHON_ARGS:Mtest}
420_PYTHON_TEST_DEP=	yes
421_PYTHON_ARGS:=		${_PYTHON_ARGS:Ntest}
422.  endif
423.  if ${_PYTHON_ARGS:Menv}
424PYTHON_NO_DEPENDS=	yes
425_PYTHON_ARGS:=		${_PYTHON_ARGS:Nenv}
426.  endif
427
428# The port does not specify a build, run or test dependency, assume all are
429# required.
430.  if !defined(_PYTHON_BUILD_DEP) && !defined(_PYTHON_RUN_DEP) && \
431    !defined(_PYTHON_TEST_DEP) && !defined(PYTHON_NO_DEPENDS)
432_PYTHON_BUILD_DEP=	yes
433_PYTHON_RUN_DEP=	yes
434_PYTHON_TEST_DEP=	yes
435.  endif
436
437.  if ${_PYTHON_ARGS} == 2.7
438DEV_WARNING+=		"lang/python27 reached End of Life and will be removed somewhere in the future, please convert to a modern version of python"
439.  elif ${_PYTHON_ARGS} == 2
440DEV_ERROR+=		"USES=python:2 is no longer supported, use USES=python:2.7"
441.  elif ${_PYTHON_ARGS} == 3
442DEV_ERROR+=		"USES=python:3 is no longer supported, use USES=python:3.11+ or an appropriate version range"
443.  endif  # ${_PYTHON_ARGS} == 2.7
444
445_PYTHON_VERSION:=	${PYTHON_DEFAULT}
446
447.  if empty(_PYTHON_ARGS)
448_PYTHON_ARGS=	3.10+
449.  endif
450
451# Validate Python version whether it meets the version restriction.
452_PYTHON_VERSION_CHECK:=		${_PYTHON_ARGS:C/^([1-9]\.[1-9]?[0-9])$/\1-\1/}
453_PYTHON_VERSION_MINIMUM_TMP:=	${_PYTHON_VERSION_CHECK:C/([1-9]\.[1-9]?[0-9])[-+].*/\1/}
454_PYTHON_VERSION_MINIMUM:=	${_PYTHON_VERSION_MINIMUM_TMP:M[1-9].[0-9]}${_PYTHON_VERSION_MINIMUM_TMP:M[1-9].[1-9][0-9]}
455_PYTHON_VERSION_MAXIMUM_TMP:=	${_PYTHON_VERSION_CHECK:C/.*-([1-9]\.[1-9]?[0-9])/\1/}
456_PYTHON_VERSION_MAXIMUM:=	${_PYTHON_VERSION_MAXIMUM_TMP:M[1-9].[0-9]}${_PYTHON_VERSION_MAXIMUM_TMP:M[1-9].[1-9][0-9]}
457
458# At this point we should have no argument left in ${_PYTHON_ARGS}
459# except a version spec
460_V1=		[1-9].[0-9]
461_V2=		[1-9].[1-9][0-9]
462_PYTHON_ARGS:=	${_PYTHON_ARGS:N${_V1}-${_V1}:N${_V1}-${_V2}:N${_V2}-${_V2}:N${_V1}:N${_V2}:N${_V1}+:N${_V2}+:N-${_V1}:N-${_V2}}
463.  if !empty(_PYTHON_ARGS)
464IGNORE=	uses unknown USES=python arguments: ${_PYTHON_ARGS}
465.  endif
466
467# Pattern to convert python versions (X.Y or X.YY) to comparable format X.YY
468_VC=		C/^([1-9]\.)([0-9])$$/\10\2/
469
470.undef _PYTHON_VERSION_NONSUPPORTED
471.  if !empty(_PYTHON_VERSION_MINIMUM) && (${_PYTHON_VERSION:${_VC}:S/t$//} < ${_PYTHON_VERSION_MINIMUM:${_VC}:S/t$//})
472_PYTHON_VERSION_NONSUPPORTED=	${_PYTHON_VERSION_MINIMUM} at least
473.  elif !empty(_PYTHON_VERSION_MAXIMUM) && (${_PYTHON_VERSION:${_VC}:S/t$//} > ${_PYTHON_VERSION_MAXIMUM:${_VC}:S/t$//})
474_PYTHON_VERSION_NONSUPPORTED=	${_PYTHON_VERSION_MAXIMUM} at most
475.  endif
476
477# If we have an unsupported version of Python, try another.
478.  if defined(_PYTHON_VERSION_NONSUPPORTED)
479.undef _PYTHON_VERSION
480.    for ver in ${PYTHON_DEFAULT} ${PYTHON2_DEFAULT} ${_PYTHON_VERSIONS}
481__VER=		${ver}
482.      if !defined(_PYTHON_VERSION) && \
483	!(!empty(_PYTHON_VERSION_MINIMUM) && ( \
484		${__VER:${_VC}:S/t$//} < ${_PYTHON_VERSION_MINIMUM:${_VC}:S/t$//})) && \
485	!(!empty(_PYTHON_VERSION_MAXIMUM) && ( \
486		${__VER:${_VC}:S/t$//} > ${_PYTHON_VERSION_MAXIMUM:${_VC}:S/t$//}))
487_PYTHON_VERSION=	${ver}
488.      endif
489.    endfor
490.    if !defined(_PYTHON_VERSION)
491IGNORE=		needs an unsupported version of Python
492.    endif
493.  endif	# defined(_PYTHON_VERSION_NONSUPPORTED)
494
495# Automatically generates FLAVORS if empty
496.  if empty(FLAVORS) && defined(_PYTHON_FEATURE_FLAVORS)
497.  undef _VALID_PYTHON_VERSIONS
498.    for ver in ${PYTHON_DEFAULT} ${PYTHON2_DEFAULT} ${_PYTHON_VERSIONS}
499__VER=		${ver}
500.      if !(!empty(_PYTHON_VERSION_MINIMUM) && ( \
501		${__VER:${_VC}:S/t$//} < ${_PYTHON_VERSION_MINIMUM:${_VC}:S/t$//})) && \
502	!(!empty(_PYTHON_VERSION_MAXIMUM) && ( \
503		${__VER:${_VC}:S/t$//} > ${_PYTHON_VERSION_MAXIMUM:${_VC}:S/t$//}))
504.        if empty(_VALID_PYTHON_VERSIONS:M${ver})
505_VALID_PYTHON_VERSIONS+=	${ver}
506.        endif
507.      endif
508.    endfor
509# Get all possible flavors depending on version requirements
510.    if defined(_VALID_PYTHON_VERSIONS)
511_ALL_PYTHON_FLAVORS=	${_VALID_PYTHON_VERSIONS:S/.//:S/^/py/}
512.    else
513_ALL_PYTHON_FLAVORS=	${_PYTHON_VERSIONS:S/.//:S/^/py/}
514.    endif
515# Decide how many flavors we want.  By default, only generate the default
516# versions.
517.    if defined(BUILD_ALL_PYTHON_FLAVORS) || defined(_PYTHON_FEATURE_ALLFLAVORS)
518FLAVORS=	${_ALL_PYTHON_FLAVORS}
519.    else
520.      for _v in ${PYTHON_DEFAULT} ${PYTHON2_DEFAULT}
521_f=	py${_v:S/.//}
522.        if ${_ALL_PYTHON_FLAVORS:M${_f}} && !${FLAVORS:M${_f}}
523.          if !empty(FLAVORS)
524FLAVORS:=	${FLAVORS} ${_f}
525.          else
526FLAVORS:=	${_f}
527.          endif
528.        endif
529.      endfor
530.    endif
531.    if !empty(FLAVORS) && empty(FLAVOR)
532FLAVOR=	${FLAVORS:[1]}
533.    endif
534.  endif
535
536.  if ${FLAVOR:Mpy[23][0-9]}${FLAVOR:Mpy[23][1-9][0-9]}${FLAVOR:Mpy31[3-9]t}
537_PYTHON_VERSION=	${FLAVOR:S/py//:C/(.)/\1./}
538.  endif
539
540.  if !empty(FLAVOR) && ${_PYTHON_VERSION} != ${PYTHON_DEFAULT}
541.    if defined(_PYTHON_FEATURE_OPTSUFFIX)
542DEV_WARNING+=	"USE_PYTHON=optsuffix is deprecated, consider migrating to using unconditional PKGNAMESUFFIX or PKGNAMEPREFIX"
543PKGNAMESUFFIX=	${PYTHON_PKGNAMESUFFIX}
544.    endif
545.  endif
546
547# To avoid having dependencies with @ and empty flavor:
548# _PYTHON_VERSION is either set by (first that matches):
549# - If using Python flavors, from the current Python flavor
550# - If using a version restriction (USES=python:3.11+), from the first
551#   acceptable default Python version.
552# - From PYTHON_DEFAULT
553PY_FLAVOR=	py${_PYTHON_VERSION:S/.//}
554
555PYTHON_VERSION=	python${_PYTHON_VERSION}
556
557# Got the correct python version, set some publicly accessible variables
558PYTHON_VER=		${_PYTHON_VERSION}
559PYTHON_BASEVER=		${PYTHON_VER:S/t$//}
560PYTHON_SUFFIX=		${_PYTHON_VERSION:S/.//g}
561PYTHON_BASESUFFIX=	${PYTHON_SUFFIX:S/t$//}
562PYTHON_MAJOR_VER=	${PYTHON_VER:R}
563PYTHON_REL=		# empty
564PYTHON_ABIVER=		# empty
565PYTHON_PORTSDIR=	${_PYTHON_RELPORTDIR}${PYTHON_SUFFIX}
566
567# Protect partial checkouts from Mk/Scripts/functions.sh:export_ports_env().
568.  if !defined(_PORTS_ENV_CHECK) || exists(${PORTSDIR}/${PYTHON_PORTSDIR})
569.include "${PORTSDIR}/${PYTHON_PORTSDIR:S/t$//}/Makefile.version"
570.  endif
571# Create a 5 integer version string, prefixing 0 to the minor and patch
572# tokens if it's a single character. Only use the first 3 tokens of
573# DISTVERSION to stay consistent regardless of pre-release or ABI flags
574PYTHON_REL=	${PYTHON_DISTVERSION:C/^([0-9]+\.[0-9]+\.[0-9]+).*/\1/:C/\.([0-9])$/.0\1/:C/\.([0-9]\.[0-9]+)/.0\1/:S/.//g}
575
576# Might be overridden by calling ports
577PYTHON_CMD?=		${_PYTHON_BASECMD}${_PYTHON_VERSION}
578.  if ${PYTHON_MAJOR_VER} > 2
579.    if exists(${PYTHON_CMD}-config)
580PYTHON_ABIVER!=		${PYTHON_CMD}-config --abiflags
581.    endif
582.  endif
583
584.  if ${PYTHON_REL} >= 30807
585PYTHON_TAG=	.cpython-${PYTHON_BASESUFFIX}
586PYTHON_SOABI=	.cpython-${PYTHON_SUFFIX}
587.  else
588PYTHON_TAG=	# empty
589PYTHON_SOABI=	# empty
590.  endif
591
592.  if ${PYTHON_MAJOR_VER} < 3
593DEPRECATED?=	Uses Python 2.7 which is EOLed upstream
594.  endif
595
596.  if !defined(PYTHONBASE)
597PYTHONBASE!=	(${PYTHON_CMD} -c 'import sys; print(sys.prefix)' \
598			2> /dev/null || ${ECHO_CMD} ${LOCALBASE}) | ${TAIL} -1
599.  endif
600_EXPORTED_VARS+=	PYTHONBASE
601
602PYTHON_INCLUDEDIR=	${PYTHONBASE}/include/python${_PYTHON_VERSION}${PYTHON_ABIVER}
603PYTHON_LIBDIR=		${PYTHONBASE}/lib/python${_PYTHON_VERSION}
604PYTHON_PLATFORM=	${OPSYS:tl}${OSREL:C/\.[0-9.]*//}
605PYTHON_SITELIBDIR=	${PYTHON_LIBDIR}/site-packages
606PYTHON_PKGNAMEPREFIX=	py${PYTHON_SUFFIX}-
607PYTHON_PKGNAMESUFFIX=	-py${PYTHON_SUFFIX}
608
609PYTHONPREFIX_INCLUDEDIR=	${PYTHON_INCLUDEDIR:S;${PYTHONBASE};${TRUE_PREFIX};}
610PYTHONPREFIX_LIBDIR=		${PYTHON_LIBDIR:S;${PYTHONBASE};${TRUE_PREFIX};}
611PYTHONPREFIX_SITELIBDIR=	${PYTHON_SITELIBDIR:S;${PYTHONBASE};${TRUE_PREFIX};}
612
613# Used for recording the installed files.
614_PYTHONPKGLIST=	${WRKDIR}/.PLIST.pymodtmp
615
616# Ports bound to a certain python version SHOULD
617# - use the PYTHON_PKGNAMEPREFIX
618# - use directories using the PYTHON_PKGNAMEPREFIX
619# - install binaries using the required PYTHON_VER, with
620#   the default python version creating a symlink to the original binary
621#   name (for staging-aware ports).
622#
623# What makes a port 'bound' to a certain python version?
624# - it installs data into PYTHON_SITELIBDIR, PYTHON_INCLUDEDIR, ...
625# - it links against libpython*.so
626# - it uses USE_PYTHON=distutils
627#
628
629# cryptography* support
630.  if ${PYCRYPTOGRAPHY_DEFAULT} == rust
631CRYPTOGRAPHY_DEPENDS=	${PYTHON_PKGNAMEPREFIX}cryptography>=0:security/py-cryptography@${PY_FLAVOR}
632.  else
633CRYPTOGRAPHY_DEPENDS=	${PYTHON_PKGNAMEPREFIX}cryptography-legacy>=0:security/py-cryptography-legacy@${PY_FLAVOR}
634.  endif
635
636.  if defined(_PYTHON_FEATURE_CRYPTOGRAPHY_BUILD)
637BUILD_DEPENDS+=	${CRYPTOGRAPHY_DEPENDS}
638.  endif
639
640.  if defined(_PYTHON_FEATURE_CRYPTOGRAPHY)
641RUN_DEPENDS+=	${CRYPTOGRAPHY_DEPENDS}
642.  endif
643
644.  if defined(_PYTHON_FEATURE_CRYPTOGRAPHY_TEST)
645TEST_DEPENDS+=	${CRYPTOGRAPHY_DEPENDS}
646.  endif
647
648# cython* support
649CYTHON_DEPENDS=	${PYTHON_PKGNAMEPREFIX}cython>=3.2.4:lang/cython@${PY_FLAVOR}
650CYTHON0_DEPENDS=${PYTHON_PKGNAMEPREFIX}cython0>=0.29.37:lang/cython0@${PY_FLAVOR}
651
652.  if defined(_PYTHON_FEATURE_CYTHON)
653BUILD_DEPENDS+=	${CYTHON_DEPENDS}
654.  endif
655
656.  if defined(_PYTHON_FEATURE_CYTHON_RUN)
657RUN_DEPENDS+=	${CYTHON_DEPENDS}
658.  endif
659
660.  if defined(_PYTHON_FEATURE_CYTHON_TEST)
661TEST_DEPENDS+=	${CYTHON_DEPENDS}
662.  endif
663
664.  if defined(_PYTHON_FEATURE_CYTHON0)
665BUILD_DEPENDS+=	${CYTHON0_DEPENDS}
666.  endif
667
668.  if defined(_PYTHON_FEATURE_CYTHON0_RUN)
669RUN_DEPENDS+=	${CYTHON0_DEPENDS}
670.  endif
671
672.  if defined(_PYTHON_FEATURE_CONCURRENT)
673.    if !defined(_PYTHON_FEATURE_FLAVORS) && (${_PYTHON_VERSION_MINIMUM:M3*} || ${_PYTHON_VERSION_MAXIMUM:M2*})
674DEV_WARNING+=	"USE_PYTHON=concurrent when only one of Python 2 or 3 is supported AND not using flavors does not make any sense"
675.    endif
676_USES_POST+=		uniquefiles:dirs
677.    if defined(_PYTHON_FEATURE_FLAVORS) && ${FLAVOR} == ${FLAVORS:[1]}
678UNIQUE_DEFAULT_LINKS=	yes
679.    elif !defined(_PYTHON_FEATURE_FLAVORS) && ${_PYTHON_VERSION} == ${PYTHON_DEFAULT}
680UNIQUE_DEFAULT_LINKS=	yes
681.    else
682UNIQUE_DEFAULT_LINKS=	no
683.    endif
684UNIQUE_PREFIX=		${PYTHON_PKGNAMEPREFIX}
685UNIQUE_SUFFIX=		-${PYTHON_VER}
686UNIQUE_SUFFIX_TYPES+=	SUFFIX_MAN
687UNIQUE_SUFFIX_MAN_WITH_EXT=	.[1-9ln]
688UNIQUE_SUFFIX_MAN_EXTRA_EXT=	.gz
689
690.if defined(_PYTHON_FEATURE_AUTOPLIST)
691_UNIQUE_FIND_SUFFIX_FILES=	${SED} -e 's|^${TRUE_PREFIX}/||' ${_PYTHONPKGLIST} ${TMPPLIST}
692.else
693_UNIQUE_FIND_SUFFIX_FILES=	${SED} -e 's|^${TRUE_PREFIX}/||' ${TMPPLIST} 2>/dev/null
694.endif
695UNIQUE_FIND_SUFFIX_FILES+=	${_UNIQUE_FIND_SUFFIX_FILES} | \
696				${EGREP} -he '^bin/.*$$|^sbin/.*$$|^libexec/.*$$'
697UNIQUE_FIND_SUFFIX_MAN_FILES+=	${_UNIQUE_FIND_SUFFIX_FILES} | \
698				${EGREP} -he '^man/man[1-9ln]/.*$$|^share/man/man[1-9ln]/.*$$'
699.  endif # defined(_PYTHON_FEATURE_CONCURRENT)
700
701_CURRENTPORT:=	${PKGNAMEPREFIX}${PORTNAME}${PKGNAMESUFFIX}
702.  if defined(_PYTHON_FEATURE_DISTUTILS) && \
703	${_CURRENTPORT} != ${PYTHON_PKGNAMEPREFIX}setuptools && \
704	${_CURRENTPORT} != ${PYTHON_PKGNAMEPREFIX}setuptools58 && \
705	${_CURRENTPORT} != ${PYTHON_PKGNAMEPREFIX}setuptools44
706.    if ${PYTHON_VER} == 2.7
707BUILD_DEPENDS+=		${PYTHON_PKGNAMEPREFIX}setuptools44>0:devel/py-setuptools44@${PY_FLAVOR}
708RUN_DEPENDS+=		${PYTHON_PKGNAMEPREFIX}setuptools44>0:devel/py-setuptools44@${PY_FLAVOR}
709.    else
710BUILD_DEPENDS+=		${PYTHON_PKGNAMEPREFIX}setuptools>0:devel/py-setuptools@${PY_FLAVOR}
711.    endif
712.  endif
713
714.  if defined(_PYTHON_FEATURE_PEP517)
715.    if ${PYTHON_MAJOR_VER} < 3
716DEV_ERROR+=		"USES=python:2.7 is incompatible with USE_PYTHON=pep517"
717.    endif
718.    if defined(_PYTHON_FEATURE_DISTUTILS)
719DEV_ERROR+=		"USE_PYTHON=distutils is incompatible with USE_PYTHON=pep517"
720.    endif
721.    if defined(_PYTHON_FEATURE_PY3KPLIST)
722DEV_ERROR+=		"USE_PYTHON=py3kplist is incompatible with USE_PYTHON=pep517"
723.    endif
724.    if defined(_PYTHON_FEATURE_NOEGGINFO)
725DEV_ERROR+=		"USE_PYTHON=noegginfo is incompatible with USE_PYTHON=pep517"
726.    endif
727.  endif
728
729# distutils support
730PYSETUP?=		setup.py
731PYDISTUTILS_SETUP?=	-c \
732	"import sys; import setuptools; \
733	__file__='${PYSETUP}'; sys.argv[0]='${PYSETUP}'; \
734	exec(compile(open(__file__, 'rb').read().replace(b'\\r\\n', b'\\n'), __file__, 'exec'))"
735PYDISTUTILS_CONFIGUREARGS?=	# empty
736PYDISTUTILS_BUILDARGS?=		# empty
737PYDISTUTILS_INSTALLARGS?=	-c -O1 --prefix=${TRUE_PREFIX}
738.  if defined(_PYTHON_FEATURE_DISTUTILS)
739.    if !defined(PYDISTUTILS_INSTALLNOSINGLE)
740PYDISTUTILS_INSTALLARGS+=	--single-version-externally-managed
741.    endif
742PYDISTUTILS_INSTALLARGS+=	--root=${FAKE_DESTDIR}
743.  endif
744PYDISTUTILS_INSTALLARGS:=	--record ${_PYTHONPKGLIST} \
745		${PYDISTUTILS_INSTALLARGS}
746
747PYDISTUTILS_PKGNAME?=	${PORTNAME}
748PYDISTUTILS_PKGVERSION?=${PORTVERSION}
749PYDISTUTILS_EGGINFO?=	${PYDISTUTILS_PKGNAME:C/[^A-Za-z0-9.]+/_/g}-${PYDISTUTILS_PKGVERSION:C/[^A-Za-z0-9.]+/_/g}-py${PYTHON_VER}.egg-info
750PYDISTUTILS_EGGINFODIR?=${FAKE_DESTDIR}${PYTHONPREFIX_SITELIBDIR}
751
752# PEP-517 support
753PEP517_BUILD_CMD?=	${PYTHON_CMD} -m build --no-isolation --wheel ${PEP517_BUILD_CONFIG_SETTING}
754PEP517_BUILD_DEPEND?=	${PYTHON_PKGNAMEPREFIX}build>=0:devel/py-build@${PY_FLAVOR}
755PEP517_INSTALL_CMD?=	${PYTHON_CMD} -m installer --destdir ${FAKE_DESTDIR} --prefix ${TRUE_PREFIX} ${BUILD_WRKSRC}/dist/${PORTNAME:C|[-_]+|_|g}-${DISTVERSION}*.whl
756PEP517_INSTALL_DEPEND?=	${PYTHON_PKGNAMEPREFIX}installer>=0:devel/py-installer@${PY_FLAVOR}
757
758# nose support
759.  if defined(_PYTHON_FEATURE_NOSE)
760TEST_DEPENDS+=	${PYTHON_PKGNAMEPREFIX}nose>=0:devel/py-nose@${PY_FLAVOR}
761.  endif
762
763# nose2 support
764.  if defined(_PYTHON_FEATURE_NOSE2)
765TEST_DEPENDS+=	${PYTHON_PKGNAMEPREFIX}nose2>=0:devel/py-nose2@${PY_FLAVOR}
766.  endif
767
768# pytest support
769.  if defined(_PYTHON_FEATURE_PYTEST)
770TEST_DEPENDS+=	${PYTHON_PKGNAMEPREFIX}pytest>=7,1:devel/py-pytest@${PY_FLAVOR}
771PYTEST_BROKEN_TESTS?=	# empty
772PYTEST_IGNORED_TESTS?=	# empty
773_PYTEST_SKIPPED_TESTS?=	# empty
774.    if !defined(PYTEST_ENABLE_ALL_TESTS)
775.      if !defined(PYTEST_ENABLE_BROKEN_TESTS)
776_PYTEST_SKIPPED_TESTS+=	${PYTEST_BROKEN_TESTS}
777.      endif
778.      if !defined(PYTEST_ENABLE_IGNORED_TESTS)
779_PYTEST_SKIPPED_TESTS+=	${PYTEST_IGNORED_TESTS}
780.      endif
781.    endif # !defined(PYTEST_ENABLE_ALL_TESTS)
782_PYTEST_FILTER_EXPRESSION=	${_PYTEST_SKIPPED_TESTS:C/^(.)/and not \1/:tW:C/^and //}
783.  endif # defined(_PYTHON_FEATURE_PYTEST)
784
785# unittest2 support
786.  if defined(_PYTHON_FEATURE_UNITTEST2)
787TEST_DEPENDS+=	${PYTHON_PKGNAMEPREFIX}unittest2>=0:devel/py-unittest2@${PY_FLAVOR}
788.  endif
789
790.  if !defined(_PYTHON_FEATURE_NOEGGINFO) && \
791	!defined(_PYTHON_FEATURE_AUTOPLIST) && \
792	defined(_PYTHON_FEATURE_DISTUTILS) && \
793	defined(PYTHON_REL)
794_USES_fake+=    933:add-plist-egginfo
795add-plist-egginfo:
796.    for egginfo in ${PYDISTUTILS_EGGINFO}
797	if [ -d "${PYDISTUTILS_EGGINFODIR}/${egginfo}" ]; then \
798		${LS} ${PYDISTUTILS_EGGINFODIR}/${egginfo} | while read f; do \
799			${ECHO_CMD} ${PYDISTUTILS_EGGINFODIR:S;^${FAKE_DESTDIR}${TRUE_PREFIX}/;;}/${egginfo}/$${f} >> ${TMPPLIST}; \
800		done; \
801	fi;
802.    endfor
803.  endif
804
805.  if defined(_PYTHON_FEATURE_AUTOPLIST) && (defined(_PYTHON_FEATURE_DISTUTILS) || defined(_PYTHON_FEATURE_PEP517))
806_RELSITELIBDIR=	${PYTHONPREFIX_SITELIBDIR:S;${TRUE_PREFIX}/;;}
807_RELLIBDIR=		${PYTHONPREFIX_LIBDIR:S;${TRUE_PREFIX}/;;}
808
809_USES_fake+=	934:add-plist-pymod
810add-plist-pymod:
811	@${SED} -e 's|^"\(.*\)"$$|\1|' \
812		-e 's|^${FAKE_DESTDIR}${TRUE_PREFIX}/||' \
813		-e 's|^${TRUE_PREFIX}/||' \
814		-e 's|^\(man/.*man[0-9]\)/\(.*\.[0-9]\)$$|\1/\2.gz|' \
815		-e 's|^\(share/man/.*man[0-9]\)/\(.*\.[0-9]\)$$|\1/\2.gz|' \
816		-e 's|[[:alnum:]|[:space:]]*/\.\./*||g; s|/\./|/|g' \
817		${_PYTHONPKGLIST} | ${SORT} >> ${TMPPLIST}
818		@cd ${FAKE_DESTDIR}${TRUE_PREFIX}/${_RELLIBDIR}; \
819		${FIND} -d . -type d ! -name .  | ${SED} -e 's:^\./:@dirrmtry ${_RELLIBDIR}/:' >> ${TMPPLIST};
820
821.  else
822.    if ${PYTHON_REL} >= 30200 && defined(_PYTHON_FEATURE_PY3KPLIST)
823# When Python version is 3.2+ we rewrite all the filenames
824# of TMPPLIST that end with .py[co], so that they conform
825# to PEP 3147 (see https://www.python.org/dev/peps/pep-3147/)
826_PYMAGICTAG=		${PYTHON_CMD} -c 'import sys; print(sys.implementation.cache_tag)'
827_USES_fake+=	935:add-plist-python
828add-plist-python:
829	@${AWK} '\
830		/\.py[co]$$/ && !($$0 ~ "/" pc "/") {id = match($$0, /\/[^\/]+\.py[co]$$/); if (id != 0) {d = substr($$0, 1, RSTART - 1); dirs[d] = 1}; sub(/\.pyc$$/,  "." mt "&"); sub(/\.pyo$$/, "." mt "." pyo); sub(/[^\/]+\.py[co]$$/, pc "/&"); print; next} \
831		/^@dirrm / {d = substr($$0, 8); if (d in dirs) {print $$0 "/" pc}; print $$0; next} \
832		/^@dirrmtry / {d = substr($$0, 11); if (d in dirs) {print $$0 "/" pc}; print $$0; next} \
833		{print} \
834		' \
835		pc="__pycache__" mt="$$(${_PYMAGICTAG})" pyo="opt-1.pyc" \
836		${TMPPLIST} > ${TMPPLIST}.pyc_tmp
837	@${MV} ${TMPPLIST}.pyc_tmp ${TMPPLIST}
838.    endif # ${PYTHON_REL} >= 30200 && defined(_PYTHON_FEATURE_PY3KPLIST)
839.  endif # defined(_PYTHON_FEATURE_AUTOPLIST) && (defined(_PYTHON_FEATURE_DISTUTILS) || defined(_PYTHON_FEATURE_PEP517))
840
841# Fix for programs that build python from a GNU auto* environment
842CONFIGURE_ENV+=	PYTHON="${PYTHON_CMD}"
843
844# By default CMake picks up the highest available version of Python package.
845# Enforce the version required by the port or the default.
846CMAKE_ARGS+=	-DPython_ADDITIONAL_VERSIONS=${PYTHON_VER}
847CMAKE_ARGS+=	-DPython_EXECUTABLE:FILEPATH="${PYTHON_CMD}"
848CMAKE_ARGS+=	-DPython${PYTHON_MAJOR_VER}_EXECUTABLE:FILEPATH="${PYTHON_CMD}"
849
850# Python 3rd-party modules
851PYGAME=		${PYTHON_PKGNAMEPREFIX}game>0:devel/py-game@${PY_FLAVOR}
852PYNUMPY=	${PYTHON_PKGNAMEPREFIX}numpy>=1.16:math/py-numpy@${PY_FLAVOR}
853
854.  if defined(_PYTHON_FEATURE_DISTUTILS)
855.    if ${PYTHON_MAJOR_VER} < 3
856PY_SETUPTOOLS=	${PYTHON_PKGNAMEPREFIX}setuptools44>0:devel/py-setuptools44@${PY_FLAVOR}
857.    else
858#PY_SETUPTOOLS=	${PYTHON_PKGNAMEPREFIX}setuptools58>0:devel/py-setuptools58@${PY_FLAVOR}
859PY_SETUPTOOLS=	${PYTHON_PKGNAMEPREFIX}setuptools>0:devel/py-setuptools@${PY_FLAVOR}
860.    endif
861.  else
862PY_SETUPTOOLS=	${PYTHON_PKGNAMEPREFIX}setuptools>0:devel/py-setuptools@${PY_FLAVOR}
863.  endif
864
865# Common Python modules that can be needed but only for some versions of Python.
866.  if ${PYTHON_REL} < 31400
867PY_BACKPORTS.ZSTD=	${PYTHON_PKGNAMEPREFIX}backports.zstd>=1.0.0:devel/py-backports.zstd@${PY_FLAVOR}
868.  endif
869
870.  if ${PYTHON_REL} < 31100
871PY_EXCEPTIONGROUP=	${PYTHON_PKGNAMEPREFIX}exceptiongroup>=1.1.1:devel/py-exceptiongroup@${PY_FLAVOR}
872PY_TOMLI=		${PYTHON_PKGNAMEPREFIX}tomli>=2.3:textproc/py-tomli@${PY_FLAVOR}
873PY_TYPING_EXTENSIONS=	${PYTHON_PKGNAMEPREFIX}typing-extensions>0:devel/py-typing-extensions@${PY_FLAVOR}
874.  endif
875
876.  if ${PYTHON_REL} >= 30000
877PY_PILLOW=	${PYTHON_PKGNAMEPREFIX}pillow>=7.0.0:graphics/py-pillow@${PY_FLAVOR}
878.  endif
879
880.  if ${PYTHON_VER} != ${PYTHON_DEFAULT}
881PY_MERCURIAL=	${PYTHON_PKGNAMEPREFIX}mercurial>=5.9:devel/mercurial@${PY_FLAVOR}
882.  else
883PY_MERCURIAL=	mercurial>=5.9:devel/mercurial@${PY_FLAVOR}
884.  endif
885
886CMAKE_ARGS+=	-DBOOST_PYTHON_SUFFIX:STRING=${PYTHON_SUFFIX}
887PY_BOOST_LIB=	boost_python${PYTHON_SUFFIX}
888PY_BOOST=	lib${PY_BOOST_LIB}.so:devel/boost-python-libs@${PY_FLAVOR}
889
890# dependencies
891.  for _stage in PATCH BUILD RUN TEST
892.    if defined(_PYTHON_${_stage}_DEP)
893${_stage}_DEPENDS+=	${PYTHON_CMD}:${PYTHON_PORTSDIR}
894.    endif
895.  endfor
896
897# set $PREFIX as Python's one
898.  if defined(_PYTHON_FEATURE_PYTHONPREFIX)
899PREFIX=		${PYTHONBASE}
900.  endif
901
902# Substitutions for SUB_FILES
903SUB_LIST+=	PYTHON_INCLUDEDIR=${PYTHONPREFIX_INCLUDEDIR} \
904		PYTHON_LIBDIR=${PYTHONPREFIX_LIBDIR} \
905		PYTHON_PLATFORM=${PYTHON_PLATFORM} \
906		PYTHON_SITELIBDIR=${PYTHONPREFIX_SITELIBDIR} \
907		PYTHON_SUFFIX=${PYTHON_SUFFIX} \
908		PYTHON_BASESUFFIX=${PYTHON_BASESUFFIX} \
909		PYTHON_TAG=${PYTHON_TAG} \
910		PYTHON_SOABI=${PYTHON_SOABI} \
911		PYTHON_VER=${PYTHON_VER} \
912		PYTHON_BASEVER=${PYTHON_BASEVER} \
913		PYTHON_VERSION=${PYTHON_VERSION}
914
915# Substitutions for pkg-plist
916# Use a short form of the PYTHONPREFIX_*DIR variables; we don't need the
917# base directory in the plist file.
918PLIST_SUB+=	PYTHON_INCLUDEDIR=${PYTHONPREFIX_INCLUDEDIR:S;${TRUE_PREFIX}/;;} \
919		PYTHON_LIBDIR=${PYTHONPREFIX_LIBDIR:S;${TRUE_PREFIX}/;;} \
920		PYTHON_PLATFORM=${PYTHON_PLATFORM} \
921		PYTHON_SITELIBDIR=${PYTHONPREFIX_SITELIBDIR:S;${PREFIX}/;;} \
922		PYTHON_SUFFIX=${PYTHON_SUFFIX} \
923		PYTHON_BASESUFFIX=${PYTHON_BASESUFFIX} \
924		PYTHON_TAG=${PYTHON_TAG} \
925		PYTHON_SOABI=${PYTHON_SOABI} \
926		PYTHON_VER=${PYTHON_VER} \
927		PYTHON_BASEVER=${PYTHON_BASEVER} \
928		PYTHON_VERSION=${PYTHON_VERSION}
929.  if ${PYTHON_MAJOR_VER} < 3
930SUB_LIST+=	PYTHON2="" PYTHON3="@comment "
931PLIST_SUB+=	PYTHON2="" PYTHON3="@comment "
932.  else
933SUB_LIST+=	PYTHON2="@comment " PYTHON3=""
934PLIST_SUB+=	PYTHON2="@comment " PYTHON3=""
935.  endif
936
937_USES_POST+=	python
938.endif # _INCLUDE_USES_PYTHON_MK
939
940.if defined(_POSTMKINCLUDED) && !defined(_INCLUDE_USES_PYTHON_POST_MK)
941_INCLUDE_USES_PYTHON_POST_MK=	yes
942
943# py-distutils support
944PYDISTUTILS_CONFIGURE_TARGET?=	config
945PYDISTUTILS_BUILD_TARGET?=	build
946PYDISTUTILS_INSTALL_TARGET?=	install
947
948.  if defined(_PYTHON_FEATURE_DISTUTILS)
949LDSHARED?=	${CC} -shared
950MAKE_ENV+=	LDSHARED="${LDSHARED}" PYTHONDONTWRITEBYTECODE= PYTHONOPTIMIZE=
951
952.    if !target(do-configure) && !defined(HAS_CONFIGURE) && !defined(GNU_CONFIGURE)
953do-configure:
954	@(cd ${BUILD_WRKSRC}; ${SETENVI} ${WRK_ENV} ${MAKE_ENV} ${PYTHON_CMD} ${PYDISTUTILS_SETUP} ${PYDISTUTILS_CONFIGURE_TARGET} ${PYDISTUTILS_CONFIGUREARGS})
955.    endif
956
957.    if !target(do-build)
958do-build:
959	@(cd ${BUILD_WRKSRC}; ${SETENVI} ${WRK_ENV} ${MAKE_ENV} ${PYTHON_CMD} ${PYDISTUTILS_SETUP} ${PYDISTUTILS_BUILD_TARGET} ${PYDISTUTILS_BUILDARGS})
960.    endif
961
962.    if !target(do-install)
963do-install:
964	@(cd ${INSTALL_WRKSRC}; ${SETENVI} ${WRK_ENV} ${MAKE_ENV} ${PYTHON_CMD} ${PYDISTUTILS_SETUP} ${PYDISTUTILS_INSTALL_TARGET} ${PYDISTUTILS_INSTALLARGS})
965.    endif
966.  endif # defined(_PYTHON_FEATURE_DISTUTILS)
967
968.  if defined(_PYTHON_FEATURE_PEP517)
969.    if !empty(PEP517_BUILD_DEPEND)
970BUILD_DEPENDS+=	${PEP517_BUILD_DEPEND}
971.    endif
972.    if !empty(PEP517_INSTALL_DEPEND)
973BUILD_DEPENDS+=	${PEP517_INSTALL_DEPEND}
974.    endif
975
976.    if !target(do-configure) && !defined(HAS_CONFIGURE) && !defined(GNU_CONFIGURE)
977do-configure:
978	@${DO_NADA}
979.    endif
980
981.    if !target(do-build)
982do-build:
983	@cd ${BUILD_WRKSRC} && ${SETENVI} ${WRK_ENV} ${MAKE_ENV} ${PEP517_BUILD_CMD}
984.    endif
985
986.    if !target(do-install)
987do-install:
988	@${MKDIR} ${FAKE_DESTDIR}${PYTHONPREFIX_SITELIBDIR}
989	@cd ${INSTALL_WRKSRC} && ${SETENVI} ${WRK_ENV} ${MAKE_ENV} ${PEP517_INSTALL_CMD}
990	@${PYTHON_CMD} -B ${PORTSDIR}/Mk/scripts/strip_RECORD.py \
991		${FAKE_DESTDIR}${PYTHONPREFIX_SITELIBDIR}/${PORTNAME:C|[-_]+|_|g}-${DISTVERSION}*.dist-info/RECORD >> ${_PYTHONPKGLIST}
992	@${REINPLACE_CMD} \
993		-e '/\.pyc$$/d' \
994		-e 's|^|${PYTHONPREFIX_SITELIBDIR}/|' \
995		-e 's|^${PYTHONPREFIX_SITELIBDIR}/../../../etc/|etc/|' \
996		-e 's|^${PYTHONPREFIX_SITELIBDIR}/../../../bin/|bin/|' \
997		-e 's|^${PYTHONPREFIX_SITELIBDIR}/../../../include/|include/|' \
998		-e 's|^${PYTHONPREFIX_SITELIBDIR}/../../../lib/|lib/|' \
999		-e 's|^${PYTHONPREFIX_SITELIBDIR}/../../../libdata/|libdata/|' \
1000		-e 's|^${PYTHONPREFIX_SITELIBDIR}/../../../libexec/|libexec/|' \
1001		-e 's|^${PYTHONPREFIX_SITELIBDIR}/../../../man/|man/|' \
1002		-e 's|^${PYTHONPREFIX_SITELIBDIR}/../../../sbin/|sbin/|' \
1003		-e 's|^${PYTHONPREFIX_SITELIBDIR}/../../../share/|share/|' \
1004			${_PYTHONPKGLIST}
1005	@cd ${FAKE_DESTDIR}${TRUE_PREFIX} && ${FIND} lib -name '*.pyc' >> ${_PYTHONPKGLIST}
1006.    endif
1007.  endif # defined(_PYTHON_FEATURE_PEP517)
1008
1009.  if defined(_PYTHON_FEATURE_NOSE)
1010.    if !target(do-test)
1011do-test:
1012	cd ${TEST_WRKSRC} && ${SETENVI} ${WRK_ENV} ${TEST_ENV} ${PYTHON_CMD} -m nose ${TEST_ARGS:NDESTDIR=*} -v
1013.    endif
1014.  endif # defined(_PYTHON_FEATURE_NOSE)
1015
1016.  if defined(_PYTHON_FEATURE_NOSE2)
1017.    if !target(do-test)
1018do-test:
1019	cd ${TEST_WRKSRC} && ${SETENVI} ${WRK_ENV} ${TEST_ENV} ${PYTHON_CMD} -m nose2 ${TEST_ARGS:NDESTDIR=*} -v
1020.    endif
1021.  endif # defined(_PYTHON_FEATURE_NOSE2)
1022
1023.  if defined(_PYTHON_FEATURE_PYTEST)
1024.    if !target(do-test)
1025do-test:
1026	cd ${TEST_WRKSRC} && ${SETENVI} ${WRK_ENV} ${TEST_ENV} ${PYTHON_CMD} -m pytest -k '${_PYTEST_FILTER_EXPRESSION}' -rs -v -o addopts= ${TEST_ARGS:NDESTDIR=*}
1027.    endif
1028.  endif # defined(_PYTHON_FEATURE_PYTEST)
1029
1030.  if defined(_PYTHON_FEATURE_UNITTEST)
1031.    if !target(do-test)
1032do-test:
1033	cd ${TEST_WRKSRC} && ${SETENVI} ${WRK_ENV} ${TEST_ENV} ${PYTHON_CMD} -m unittest ${TEST_ARGS:NDESTDIR=*} -v
1034.    endif
1035.  endif # defined(_PYTHON_FEATURE_UNITTEST)
1036
1037.  if defined(_PYTHON_FEATURE_UNITTEST2)
1038.    if !target(do-test)
1039do-test:
1040	cd ${TEST_WRKSRC} && ${SETENVI} ${WRK_ENV} ${TEST_ENV} ${PYTHON_CMD} -m unittest2 ${TEST_ARGS:NDESTDIR=*} -v
1041.    endif
1042.  endif # defined(_PYTHON_FEATURE_UNITTEST2)
1043
1044.endif # defined(_POSTMKINCLUDED) && !defined(_INCLUDE_USES_PYTHON_POST_MK)
1045