Skip to content

Commit 4938157

Browse files
authored
Merge branch 'main' into cleanup/315/remove-cgi-handler-133810
2 parents d55959c + 7a4a6cf commit 4938157

File tree

10 files changed

+410
-186
lines changed

10 files changed

+410
-186
lines changed

Doc/deprecations/pending-removal-in-3.15.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ Pending removal in Python 3.15
5151

5252
* :mod:`platform`:
5353

54-
* :func:`~platform.java_ver` has been deprecated since Python 3.13.
54+
* :func:`!platform.java_ver` has been deprecated since Python 3.13.
5555
This function is only useful for Jython support, has a confusing API,
5656
and is largely untested.
5757

Doc/library/platform.rst

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -188,24 +188,6 @@ Cross platform
188188
:attr:`processor` is resolved late instead of immediately.
189189

190190

191-
Java platform
192-
-------------
193-
194-
195-
.. function:: java_ver(release='', vendor='', vminfo=('','',''), osinfo=('','',''))
196-
197-
Version interface for Jython.
198-
199-
Returns a tuple ``(release, vendor, vminfo, osinfo)`` with *vminfo* being a
200-
tuple ``(vm_name, vm_release, vm_vendor)`` and *osinfo* being a tuple
201-
``(os_name, os_version, os_arch)``. Values which cannot be determined are set to
202-
the defaults given as parameters (which all default to ``''``).
203-
204-
.. deprecated-removed:: 3.13 3.15
205-
It was largely untested, had a confusing API,
206-
and was only useful for Jython support.
207-
208-
209191
Windows platform
210192
----------------
211193

Doc/library/threading.rst

Lines changed: 89 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,52 @@
1111
This module constructs higher-level threading interfaces on top of the lower
1212
level :mod:`_thread` module.
1313

14+
.. include:: ../includes/wasm-notavail.rst
15+
16+
Introduction
17+
------------
18+
19+
The :mod:`!threading` module provides a way to run multiple `threads
20+
<https://en.wikipedia.org/wiki/Thread_(computing)>`_ (smaller
21+
units of a process) concurrently within a single process. It allows for the
22+
creation and management of threads, making it possible to execute tasks in
23+
parallel, sharing memory space. Threads are particularly useful when tasks are
24+
I/O bound, such as file operations or making network requests,
25+
where much of the time is spent waiting for external resources.
26+
27+
A typical use case for :mod:`!threading` includes managing a pool of worker
28+
threads that can process multiple tasks concurrently. Here's a basic example of
29+
creating and starting threads using :class:`~threading.Thread`::
30+
31+
import threading
32+
import time
33+
34+
def crawl(link, delay=3):
35+
print(f"crawl started for {link}")
36+
time.sleep(delay) # Blocking I/O (simulating a network request)
37+
print(f"crawl ended for {link}")
38+
39+
links = [
40+
"https://python.org",
41+
"https://docs.python.org",
42+
"https://peps.python.org",
43+
]
44+
45+
# Start threads for each link
46+
threads = []
47+
for link in links:
48+
# Using `args` to pass positional arguments and `kwargs` for keyword arguments
49+
t = threading.Thread(target=crawl, args=(link,), kwargs={"delay": 2})
50+
threads.append(t)
51+
52+
# Start each thread
53+
for t in threads:
54+
t.start()
55+
56+
# Wait for all threads to finish
57+
for t in threads:
58+
t.join()
59+
1460
.. versionchanged:: 3.7
1561
This module used to be optional, it is now always available.
1662

@@ -45,7 +91,25 @@ level :mod:`_thread` module.
4591
However, threading is still an appropriate model if you want to run
4692
multiple I/O-bound tasks simultaneously.
4793

48-
.. include:: ../includes/wasm-notavail.rst
94+
GIL and performance considerations
95+
----------------------------------
96+
97+
Unlike the :mod:`multiprocessing` module, which uses separate processes to
98+
bypass the :term:`global interpreter lock` (GIL), the threading module operates
99+
within a single process, meaning that all threads share the same memory space.
100+
However, the GIL limits the performance gains of threading when it comes to
101+
CPU-bound tasks, as only one thread can execute Python bytecode at a time.
102+
Despite this, threads remain a useful tool for achieving concurrency in many
103+
scenarios.
104+
105+
As of Python 3.13, experimental :term:`free-threaded <free threading>` builds
106+
can disable the GIL, enabling true parallel execution of threads, but this
107+
feature is not available by default (see :pep:`703`).
108+
109+
.. TODO: At some point this feature will become available by default.
110+
111+
Reference
112+
---------
49113

50114
This module defines the following functions:
51115

@@ -62,7 +126,7 @@ This module defines the following functions:
62126

63127
Return the current :class:`Thread` object, corresponding to the caller's thread
64128
of control. If the caller's thread of control was not created through the
65-
:mod:`threading` module, a dummy thread object with limited functionality is
129+
:mod:`!threading` module, a dummy thread object with limited functionality is
66130
returned.
67131

68132
The function ``currentThread`` is a deprecated alias for this function.
@@ -157,13 +221,13 @@ This module defines the following functions:
157221

158222
.. index:: single: trace function
159223

160-
Set a trace function for all threads started from the :mod:`threading` module.
224+
Set a trace function for all threads started from the :mod:`!threading` module.
161225
The *func* will be passed to :func:`sys.settrace` for each thread, before its
162226
:meth:`~Thread.run` method is called.
163227

164228
.. function:: settrace_all_threads(func)
165229

166-
Set a trace function for all threads started from the :mod:`threading` module
230+
Set a trace function for all threads started from the :mod:`!threading` module
167231
and all Python threads that are currently executing.
168232

169233
The *func* will be passed to :func:`sys.settrace` for each thread, before its
@@ -186,13 +250,13 @@ This module defines the following functions:
186250

187251
.. index:: single: profile function
188252

189-
Set a profile function for all threads started from the :mod:`threading` module.
253+
Set a profile function for all threads started from the :mod:`!threading` module.
190254
The *func* will be passed to :func:`sys.setprofile` for each thread, before its
191255
:meth:`~Thread.run` method is called.
192256

193257
.. function:: setprofile_all_threads(func)
194258

195-
Set a profile function for all threads started from the :mod:`threading` module
259+
Set a profile function for all threads started from the :mod:`!threading` module
196260
and all Python threads that are currently executing.
197261

198262
The *func* will be passed to :func:`sys.setprofile` for each thread, before its
@@ -257,8 +321,8 @@ when implemented, are mapped to module-level functions.
257321
All of the methods described below are executed atomically.
258322

259323

260-
Thread-Local Data
261-
-----------------
324+
Thread-local data
325+
^^^^^^^^^^^^^^^^^
262326

263327
Thread-local data is data whose values are thread specific. If you
264328
have data that you want to be local to a thread, create a
@@ -389,8 +453,8 @@ affects what we see::
389453

390454
.. _thread-objects:
391455

392-
Thread Objects
393-
--------------
456+
Thread objects
457+
^^^^^^^^^^^^^^
394458

395459
The :class:`Thread` class represents an activity that is run in a separate
396460
thread of control. There are two ways to specify the activity: by passing a
@@ -645,8 +709,8 @@ since it is impossible to detect the termination of alien threads.
645709

646710
.. _lock-objects:
647711

648-
Lock Objects
649-
------------
712+
Lock objects
713+
^^^^^^^^^^^^
650714

651715
A primitive lock is a synchronization primitive that is not owned by a
652716
particular thread when locked. In Python, it is currently the lowest level
@@ -738,8 +802,8 @@ All methods are executed atomically.
738802

739803
.. _rlock-objects:
740804

741-
RLock Objects
742-
-------------
805+
RLock objects
806+
^^^^^^^^^^^^^
743807

744808
A reentrant lock is a synchronization primitive that may be acquired multiple
745809
times by the same thread. Internally, it uses the concepts of "owning thread"
@@ -848,8 +912,8 @@ call release as many times the lock has been acquired can lead to deadlock.
848912

849913
.. _condition-objects:
850914

851-
Condition Objects
852-
-----------------
915+
Condition objects
916+
^^^^^^^^^^^^^^^^^
853917

854918
A condition variable is always associated with some kind of lock; this can be
855919
passed in or one will be created by default. Passing one in is useful when
@@ -1026,8 +1090,8 @@ item to the buffer only needs to wake up one consumer thread.
10261090

10271091
.. _semaphore-objects:
10281092

1029-
Semaphore Objects
1030-
-----------------
1093+
Semaphore objects
1094+
^^^^^^^^^^^^^^^^^
10311095

10321096
This is one of the oldest synchronization primitives in the history of computer
10331097
science, invented by the early Dutch computer scientist Edsger W. Dijkstra (he
@@ -1107,7 +1171,7 @@ Semaphores also support the :ref:`context management protocol <with-locks>`.
11071171

11081172
.. _semaphore-examples:
11091173

1110-
:class:`Semaphore` Example
1174+
:class:`Semaphore` example
11111175
^^^^^^^^^^^^^^^^^^^^^^^^^^
11121176

11131177
Semaphores are often used to guard resources with limited capacity, for example,
@@ -1135,8 +1199,8 @@ causes the semaphore to be released more than it's acquired will go undetected.
11351199

11361200
.. _event-objects:
11371201

1138-
Event Objects
1139-
-------------
1202+
Event objects
1203+
^^^^^^^^^^^^^
11401204

11411205
This is one of the simplest mechanisms for communication between threads: one
11421206
thread signals an event and other threads wait for it.
@@ -1192,8 +1256,8 @@ method. The :meth:`~Event.wait` method blocks until the flag is true.
11921256

11931257
.. _timer-objects:
11941258

1195-
Timer Objects
1196-
-------------
1259+
Timer objects
1260+
^^^^^^^^^^^^^
11971261

11981262
This class represents an action that should be run only after a certain amount
11991263
of time has passed --- a timer. :class:`Timer` is a subclass of :class:`Thread`
@@ -1230,8 +1294,8 @@ For example::
12301294
only work if the timer is still in its waiting stage.
12311295

12321296

1233-
Barrier Objects
1234-
---------------
1297+
Barrier objects
1298+
^^^^^^^^^^^^^^^
12351299

12361300
.. versionadded:: 3.2
12371301

Doc/whatsnew/3.13.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1908,7 +1908,7 @@ New Deprecations
19081908

19091909
* :mod:`platform`:
19101910

1911-
* Deprecate :func:`~platform.java_ver`,
1911+
* Deprecate :func:`!platform.java_ver`,
19121912
to be removed in Python 3.15.
19131913
This function is only useful for Jython support, has a confusing API,
19141914
and is largely untested.

Doc/whatsnew/3.15.rst

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,14 @@ http.server
130130
(Contributed by Bénédikt Tran in :gh:`133810`.)
131131

132132

133+
platform
134+
--------
135+
136+
* Removed the :func:`!platform.java_ver` function,
137+
which was deprecated since Python 3.13.
138+
(Contributed by Alexey Makridenko in :gh:`133604`.)
139+
140+
133141
sysconfig
134142
---------
135143

Lib/platform.py

Lines changed: 2 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
#
3030
# History:
3131
#
32-
# <see CVS and SVN checkin messages for history>
32+
# <see checkin messages for history>
3333
#
3434
# 1.0.9 - added invalidate_caches() function to invalidate cached values
3535
# 1.0.8 - changed Windows support to read version from kernel32.dll
@@ -110,7 +110,7 @@
110110
111111
"""
112112

113-
__version__ = '1.0.9'
113+
__version__ = '1.1.0'
114114

115115
import collections
116116
import os
@@ -528,53 +528,6 @@ def ios_ver(system="", release="", model="", is_simulator=False):
528528
return IOSVersionInfo(system, release, model, is_simulator)
529529

530530

531-
def _java_getprop(name, default):
532-
"""This private helper is deprecated in 3.13 and will be removed in 3.15"""
533-
from java.lang import System
534-
try:
535-
value = System.getProperty(name)
536-
if value is None:
537-
return default
538-
return value
539-
except AttributeError:
540-
return default
541-
542-
def java_ver(release='', vendor='', vminfo=('', '', ''), osinfo=('', '', '')):
543-
544-
""" Version interface for Jython.
545-
546-
Returns a tuple (release, vendor, vminfo, osinfo) with vminfo being
547-
a tuple (vm_name, vm_release, vm_vendor) and osinfo being a
548-
tuple (os_name, os_version, os_arch).
549-
550-
Values which cannot be determined are set to the defaults
551-
given as parameters (which all default to '').
552-
553-
"""
554-
import warnings
555-
warnings._deprecated('java_ver', remove=(3, 15))
556-
# Import the needed APIs
557-
try:
558-
import java.lang # noqa: F401
559-
except ImportError:
560-
return release, vendor, vminfo, osinfo
561-
562-
vendor = _java_getprop('java.vendor', vendor)
563-
release = _java_getprop('java.version', release)
564-
vm_name, vm_release, vm_vendor = vminfo
565-
vm_name = _java_getprop('java.vm.name', vm_name)
566-
vm_vendor = _java_getprop('java.vm.vendor', vm_vendor)
567-
vm_release = _java_getprop('java.vm.version', vm_release)
568-
vminfo = vm_name, vm_release, vm_vendor
569-
os_name, os_version, os_arch = osinfo
570-
os_arch = _java_getprop('java.os.arch', os_arch)
571-
os_name = _java_getprop('java.os.name', os_name)
572-
os_version = _java_getprop('java.os.version', os_version)
573-
osinfo = os_name, os_version, os_arch
574-
575-
return release, vendor, vminfo, osinfo
576-
577-
578531
AndroidVer = collections.namedtuple(
579532
"AndroidVer", "release api_level manufacturer model device is_emulator")
580533

@@ -1034,13 +987,6 @@ def uname():
1034987
version = '16bit'
1035988
system = 'Windows'
1036989

1037-
elif system[:4] == 'java':
1038-
release, vendor, vminfo, osinfo = java_ver()
1039-
system = 'Java'
1040-
version = ', '.join(vminfo)
1041-
if not version:
1042-
version = vendor
1043-
1044990
# System specific extensions
1045991
if system == 'OpenVMS':
1046992
# OpenVMS seems to have release and version mixed up
@@ -1370,15 +1316,6 @@ def platform(aliased=False, terse=False):
13701316
platform = _platform(system, release, machine, processor,
13711317
'with',
13721318
libcname+libcversion)
1373-
elif system == 'Java':
1374-
# Java platforms
1375-
r, v, vminfo, (os_name, os_version, os_arch) = java_ver()
1376-
if terse or not os_name:
1377-
platform = _platform(system, release, version)
1378-
else:
1379-
platform = _platform(system, release, version,
1380-
'on',
1381-
os_name, os_version, os_arch)
13821319

13831320
else:
13841321
# Generic handler

0 commit comments

Comments
 (0)