1SUMMARY="An interpreted, interactive, object-oriented programming language"
2DESCRIPTION="Python is a programming language that lets you work more quickly \
3and integrate your systems more effectively. You can learn to use Python and \
4see almost immediate gains in productivity and lower maintenance costs.
5Python runs on Windows, Linux/Unix, Mac OS X, and has been ported to the Java \
6and .NET virtual machines.
7Python is free to use, even for commercial products, because of its \
8OSI-approved open source license."
9HOMEPAGE="https://www.python.org"
10LICENSE="Python"
11COPYRIGHT="1990-2023 Python Software Foundation"
12REVISION="1"
13SOURCE_URI="https://www.python.org/ftp/python/$portVersion/Python-$portVersion.tar.xz"
14CHECKSUM_SHA256="01597db0132c1cf7b331eff68ae09b5a235a3c3caa9c944c29cac7d1c4c4c00a"
15SOURCE_DIR="Python-$portVersion"
16PATCHES="python3.9-$portVersion.patchset"
17if [ "$secondaryArchSuffix" = _x86 ] ; then
18	PATCHES+="
19		python3.9_x86-$portVersion.patchset
20	"
21fi
22
23ARCHITECTURES="all !x86_gcc2 ?x86"
24SECONDARY_ARCHITECTURES="x86"
25
26# On x86_gcc2 we don't want to install the commands in bin/<arch>/, but in bin/.
27commandSuffix=$secondaryArchSuffix
28commandBinDir=$binDir
29if [ "$targetArchitecture" = x86_gcc2 ]; then
30	commandSuffix=
31	commandBinDir=$prefix/bin
32fi
33
34PROVIDES="
35	python3.9$secondaryArchSuffix = $portVersion compat >= 3.9
36	python39$secondaryArchSuffix = $portVersion compat >= 3.9
37	cmd:2to3_3.9 = $portVersion compat >= 3.9
38	cmd:idle3.9 = $portVersion compat >= 3.9
39	cmd:pydoc3.9 = $portVersion compat >= 3.9
40	cmd:python3.9 = $portVersion compat >= 3.9
41	cmd:python3.9_config = $portVersion compat >= 3.9
42	devel:libpython3.9$secondaryArchSuffix = 1.0
43	lib:libpython3.9$secondaryArchSuffix = 1.0
44	"
45REQUIRES="
46	haiku$secondaryArchSuffix
47	cmd:file
48	lib:libbz2$secondaryArchSuffix
49	lib:libedit$secondaryArchSuffix
50	lib:libexpat$secondaryArchSuffix
51	lib:libffi$secondaryArchSuffix
52	lib:libintl$secondaryArchSuffix
53	lib:liblzma$secondaryArchSuffix
54	lib:libncurses$secondaryArchSuffix
55	lib:libsqlite3$secondaryArchSuffix
56	lib:libssl$secondaryArchSuffix
57	lib:libz$secondaryArchSuffix
58	"
59BUILD_REQUIRES="
60	haiku${secondaryArchSuffix}_devel
61	devel:libbz2$secondaryArchSuffix
62	devel:libedit$secondaryArchSuffix
63	devel:libexpat$secondaryArchSuffix
64	devel:libffi$secondaryArchSuffix
65	devel:liblzma$secondaryArchSuffix
66	devel:libncurses$secondaryArchSuffix
67	devel:libsqlite3$secondaryArchSuffix
68	devel:libssl$secondaryArchSuffix
69	devel:libtclstub8.6$secondaryArchSuffix
70	devel:libtk8.6$secondaryArchSuffix
71	devel:libz$secondaryArchSuffix
72	"
73BUILD_PREREQUIRES="
74	autoconf_archive
75	cmd:aclocal
76	cmd:autoconf
77	cmd:find
78	cmd:gcc$secondaryArchSuffix
79	cmd:ld$secondaryArchSuffix
80	cmd:libtoolize$secondaryArchSuffix
81	cmd:make
82	cmd:pkg_config$secondaryArchSuffix
83	"
84
85GLOBAL_WRITABLE_FILES="
86	non-packaged/lib/python3.9/site-packages directory keep-old
87	"
88
89BUILD()
90{
91	autoreconf -fi
92
93	# From ./configure:
94	# "compiler flags are generated in two sets, BASECFLAGS and OPT.  OPT is just
95	# for debug/optimization stuff.  BASECFLAGS is for flags that are required
96	# just to get things to compile and link."
97	export BASECFLAGS="-D_BSD_SOURCE"
98
99	# Not exporting OPT ends up with "-g -fwrapv -O3 -Wall" being used,
100	# and using OPT="" means the build ends up being "-O0".
101	export OPT="-fwrapv -O3 -Wall"
102
103	runConfigure --omit-dirs binDir,includeDir ./configure \
104		--bindir=$commandBinDir \
105		--includedir=$developDir/headers \
106		--enable-optimizations \
107		--enable-shared \
108		--with-ensurepip=no \
109		--with-system-expat \
110		--with-system-ffi
111		# "configure: WARNING: --with(out)-system-ffi is ignored on this platform"
112
113	# prevent make from rebuilding stuff that requires python
114	touch Parser/asdl* Python/Python-ast.c Include/Python-ast.h
115
116	rm -f python
117
118	# NOTE: When using "--enable-optimizations" above, using "make $jobArgs" might be unreliable.
119	# make clean # Uncomment when doing repeated builds (for testing different flags/options).
120	make $jobArgs
121}
122
123INSTALL()
124{
125	# altinstall avoids clobbering $prefix/bin/{2to3,idle3,pydoc3,python3,python3-config}
126	make altinstall
127
128	rm $libDir/libpython3.so
129
130	if [ "$targetArchitecture" = x86_gcc2 ]; then
131		# On x86_gcc2, move lib-dynload to lib/python3.x/
132		mv $libDir/python3.9/lib-dynload $prefix/lib/python3.9/
133	fi
134	prepareInstalledDevelLibs libpython3.9
135	fixPkgconfig
136	if [ "$targetArchitecture" = x86_gcc2 ]; then
137		# fix pkgconfig to match configure flags
138		sed -i -e 's,headers/x86,headers,' $developLibDir/pkgconfig/python*.pc
139	fi
140
141	mkdir -p $prefix/lib/python3.9/vendor-packages
142	echo 'This directory contains packaged python modules.' \
143		>$prefix/lib/python3.9/vendor-packages/README
144
145	mkdir -p $prefix/non-packaged/lib/python3.9
146	mv $prefix/lib/python3.9/site-packages $prefix/non-packaged/lib/python3.9/
147
148	# drop testsuite altogether; move to a separate package if needed
149	cd $prefix/lib/python3.9
150	rm -rf ctypes/test distutils/tests idlelib/idle_test lib2to3/tests \
151		sqlite3/test test tkinter/test unittest/test
152}
153
154# Some of the test will crash, invoking the crash dialog, and will hang waiting for
155# user's interaction. To avoid that, make sure to configure your system by adding
156# the following lines in the file "~/config/settings/system/debug_server/settings":
157##---
158# executable_actions {
159#	/sources/Python-$portVersion/python kill
160# }
161##---
162# Replace $portVersion as necessary.
163
164# For some tests that purposefully crash, it would make sense to add support for
165# crash-report suppression (as done for other platforms) on "tests/support/__init__,py"'s
166# SuppressCrashReport class.
167# But that needs support from Haiku's debug_server, as we can't change settings from
168# the recipe's building environment at the moment (https://dev.haiku-os.org/ticket/10301)
169
170TEST()
171{
172	# Remove tests data left-overs, if any
173	rm -f -r /boot/system/cache/tmp/
174	rm -f -d -r build/test_python*
175
176	cd Lib/test
177
178	# distutils is deprecated, and will be removed on 3.12.
179	rm -f test_distutils.py
180
181	# The following tests invoke the crash dialog, and unless your configure
182	# debug_server default action to "kill" or "report", they will hang waiting for
183	# user input. See comment above TEST().
184	rm -f test_asyncio/test_futures.py # Crashes: Exception (Segment violation)
185	rm -f test_faulthandler.py
186	rm -f test_subprocess.py # tends to hang.
187	rm -f test_threading.py # tends to hang.
188
189	# Many of the tests hang/stall. We have two options:
190	#
191	# 1- Manually remove the problematic test-cases.
192	# 2- Set a TIMEOUT.
193	#
194	# Option 1: Works, but requires manual identification/mainteinance.
195	#
196	# Option 2: Doesn't requires maintaining a list of stalling tests, but:
197	# - Causes errors at the end of the run:
198	#	"unmounting failed: Device/File/Resource Busy"
199	# - Leaves dangling threads running when the tests timeout:
200	#	"Warning -- threading_cleanup() failed to cleanup 0 threads (count: 0, dangling: 2)"
201	# - The time it takes to run the full suite goes from 14 to 30+ minutes,
202	#
203	# For Option 2, use: export EXTRATESTOPTS="--timeout=300"
204	# before calling "make $jobArgs test".
205	#
206	# Let's use Option 1, for now at least:
207
208	# These hang reliably.
209	# You might want then to manually restore them on re-runs, use:
210	# > git checkout -- Lib/test/
211	rm -f test__xxsubinterpreters.py
212	rm -f test_asynchat.py
213	rm -f test_concurrent_futures.py
214	rm -f test_importlib/test_threaded_import.py
215	rm -f test_interpreters.py
216	rm -f test_multiprocessing_fork.py
217	rm -f test_multiprocessing_forkserver.py
218	rm -f test_multiprocessing_main_handling.py
219	rm -f test_multiprocessing_spawn.py
220	rm -f test_multiprocessing.py
221	rm -f test_socketserver.py
222
223	# "test_asyncio" doesn't seems to runs reliably, even after individually skipping
224	# all the problematic test-cases that could be identify by running them one by one.
225	rm -f -r test_asyncio
226#	rm -f test_asyncio/test_base_events.py
227#	rm -f test_asyncio/test_buffered_proto.py # Exception on Exception handler.
228#	rm -f test_asyncio/test_events.py
229#	rm -f test_asyncio/test_sendfile.py
230#	rm -f test_asyncio/test_server.py # Exception on Exception handler.
231#	rm -f test_asyncio/test_sslproto.py # Exception on Exception handler.
232#	rm -f test_asyncio/test_streams.py
233
234	# These not always hang/stall, but they do it enough to warrant skipping for now.
235	rm -f test_imaplib.py
236	rm -f test_signal.py
237	rm -f test_socket.py
238	rm -f test_ssl.py
239	rm -f test_urllib2_localnet.py
240
241	cd ../..
242
243	# These allows to change what resources tests can use:
244	# export EXTRATESTOPTS="-uall,-largefile,-audio,-gui,-network,-cpu,-urlfetch,-tzdata"
245
246	# Occasionally, some test fails seemingly due to the racy nature of tempfile.mktemp().
247	# Even the help for that function says to NOT use it, but some tests still do.
248	#
249	# If you find some strange "��" suffix on temp dirnames, ej:
250	#    "cwd: /sources/Python-3.10.12/build/test_python_10324��"
251	# That's due to usages of os_helper.FS_NONASCII.
252	make $jobArgs test
253}
254