Skip to content

Commit 150cea1

Browse files
authored
Merge branch 'main' into multi_inputs
2 parents ba26b80 + 81a9b53 commit 150cea1

14 files changed

+531
-136
lines changed

Doc/library/multiprocessing.rst

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -380,35 +380,40 @@ However, if you really do need to use some shared data then
380380
proxies.
381381

382382
A manager returned by :func:`Manager` will support types
383-
:class:`list`, :class:`dict`, :class:`~managers.Namespace`, :class:`Lock`,
383+
:class:`list`, :class:`dict`, :class:`set`, :class:`~managers.Namespace`, :class:`Lock`,
384384
:class:`RLock`, :class:`Semaphore`, :class:`BoundedSemaphore`,
385385
:class:`Condition`, :class:`Event`, :class:`Barrier`,
386386
:class:`Queue`, :class:`Value` and :class:`Array`. For example, ::
387387

388388
from multiprocessing import Process, Manager
389389

390-
def f(d, l):
390+
def f(d, l, s):
391391
d[1] = '1'
392392
d['2'] = 2
393393
d[0.25] = None
394394
l.reverse()
395+
s.add('a')
396+
s.add('b')
395397

396398
if __name__ == '__main__':
397399
with Manager() as manager:
398400
d = manager.dict()
399401
l = manager.list(range(10))
402+
s = manager.set()
400403

401-
p = Process(target=f, args=(d, l))
404+
p = Process(target=f, args=(d, l, s))
402405
p.start()
403406
p.join()
404407

405408
print(d)
406409
print(l)
410+
print(s)
407411

408412
will print ::
409413

410414
{0.25: None, 1: '1', '2': 2}
411415
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
416+
{'a', 'b'}
412417

413418
Server process managers are more flexible than using shared memory objects
414419
because they can be made to support arbitrary object types. Also, a single
@@ -1942,6 +1947,15 @@ their parent process exits. The manager classes are defined in the
19421947

19431948
Create a shared :class:`list` object and return a proxy for it.
19441949

1950+
.. method:: set()
1951+
set(sequence)
1952+
set(mapping)
1953+
1954+
Create a shared :class:`set` object and return a proxy for it.
1955+
1956+
.. versionadded:: next
1957+
:class:`set` support was added.
1958+
19451959
.. versionchanged:: 3.6
19461960
Shared objects are capable of being nested. For example, a shared
19471961
container object such as a shared list can contain other shared objects

Doc/whatsnew/3.14.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -700,6 +700,11 @@ multiprocessing
700700

701701
(Contributed by Roy Hyunjin Han for :gh:`103134`.)
702702

703+
* Add support for shared :class:`set` objects via
704+
:meth:`SyncManager.set() <multiprocessing.managers.SyncManager.set>`.
705+
The :func:`set` in :func:`multiprocessing.Manager` method is now available.
706+
(Contributed by Mingyu Park in :gh:`129949`.)
707+
703708

704709
operator
705710
--------

Lib/_pydatetime.py

Lines changed: 23 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
__all__ = ("date", "datetime", "time", "timedelta", "timezone", "tzinfo",
44
"MINYEAR", "MAXYEAR", "UTC")
55

6+
__name__ = "datetime"
7+
68

79
import time as _time
810
import math as _math
@@ -14,10 +16,10 @@ def _cmp(x, y):
1416

1517
def _get_class_module(self):
1618
module_name = self.__class__.__module__
17-
if module_name == '_pydatetime':
18-
return 'datetime'
19+
if module_name == 'datetime':
20+
return 'datetime.'
1921
else:
20-
return module_name
22+
return ''
2123

2224
MINYEAR = 1
2325
MAXYEAR = 9999
@@ -767,9 +769,9 @@ def __repr__(self):
767769
args.append("microseconds=%d" % self._microseconds)
768770
if not args:
769771
args.append('0')
770-
return "%s.%s(%s)" % (_get_class_module(self),
771-
self.__class__.__qualname__,
772-
', '.join(args))
772+
return "%s%s(%s)" % (_get_class_module(self),
773+
self.__class__.__qualname__,
774+
', '.join(args))
773775

774776
def __str__(self):
775777
mm, ss = divmod(self._seconds, 60)
@@ -1082,11 +1084,11 @@ def __repr__(self):
10821084
>>> repr(d)
10831085
'datetime.date(2010, 1, 1)'
10841086
"""
1085-
return "%s.%s(%d, %d, %d)" % (_get_class_module(self),
1086-
self.__class__.__qualname__,
1087-
self._year,
1088-
self._month,
1089-
self._day)
1087+
return "%s%s(%d, %d, %d)" % (_get_class_module(self),
1088+
self.__class__.__qualname__,
1089+
self._year,
1090+
self._month,
1091+
self._day)
10901092
# XXX These shouldn't depend on time.localtime(), because that
10911093
# clips the usable dates to [1970 .. 2038). At least ctime() is
10921094
# easily done without using strftime() -- that's better too because
@@ -1586,7 +1588,7 @@ def __repr__(self):
15861588
s = ", %d" % self._second
15871589
else:
15881590
s = ""
1589-
s= "%s.%s(%d, %d%s)" % (_get_class_module(self),
1591+
s = "%s%s(%d, %d%s)" % (_get_class_module(self),
15901592
self.__class__.__qualname__,
15911593
self._hour, self._minute, s)
15921594
if self._tzinfo is not None:
@@ -2162,9 +2164,9 @@ def __repr__(self):
21622164
del L[-1]
21632165
if L[-1] == 0:
21642166
del L[-1]
2165-
s = "%s.%s(%s)" % (_get_class_module(self),
2166-
self.__class__.__qualname__,
2167-
", ".join(map(str, L)))
2167+
s = "%s%s(%s)" % (_get_class_module(self),
2168+
self.__class__.__qualname__,
2169+
", ".join(map(str, L)))
21682170
if self._tzinfo is not None:
21692171
assert s[-1:] == ")"
21702172
s = s[:-1] + ", tzinfo=%r" % self._tzinfo + ")"
@@ -2461,12 +2463,12 @@ def __repr__(self):
24612463
if self is self.utc:
24622464
return 'datetime.timezone.utc'
24632465
if self._name is None:
2464-
return "%s.%s(%r)" % (_get_class_module(self),
2465-
self.__class__.__qualname__,
2466-
self._offset)
2467-
return "%s.%s(%r, %r)" % (_get_class_module(self),
2468-
self.__class__.__qualname__,
2469-
self._offset, self._name)
2466+
return "%s%s(%r)" % (_get_class_module(self),
2467+
self.__class__.__qualname__,
2468+
self._offset)
2469+
return "%s%s(%r, %r)" % (_get_class_module(self),
2470+
self.__class__.__qualname__,
2471+
self._offset, self._name)
24702472

24712473
def __str__(self):
24722474
return self.tzname(None)

Lib/_pyrepl/base_eventqueue.py

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
# Copyright 2000-2008 Michael Hudson-Doyle <[email protected]>
2+
# Armin Rigo
3+
#
4+
# All Rights Reserved
5+
#
6+
#
7+
# Permission to use, copy, modify, and distribute this software and
8+
# its documentation for any purpose is hereby granted without fee,
9+
# provided that the above copyright notice appear in all copies and
10+
# that both that copyright notice and this permission notice appear in
11+
# supporting documentation.
12+
#
13+
# THE AUTHOR MICHAEL HUDSON DISCLAIMS ALL WARRANTIES WITH REGARD TO
14+
# THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
15+
# AND FITNESS, IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL,
16+
# INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
17+
# RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
18+
# CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
19+
# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
20+
21+
"""
22+
OS-independent base for an event and VT sequence scanner
23+
24+
See unix_eventqueue and windows_eventqueue for subclasses.
25+
"""
26+
27+
from collections import deque
28+
29+
from . import keymap
30+
from .console import Event
31+
from .trace import trace
32+
33+
class BaseEventQueue:
34+
def __init__(self, encoding: str, keymap_dict: dict[bytes, str]) -> None:
35+
self.compiled_keymap = keymap.compile_keymap(keymap_dict)
36+
self.keymap = self.compiled_keymap
37+
trace("keymap {k!r}", k=self.keymap)
38+
self.encoding = encoding
39+
self.events: deque[Event] = deque()
40+
self.buf = bytearray()
41+
42+
def get(self) -> Event | None:
43+
"""
44+
Retrieves the next event from the queue.
45+
"""
46+
if self.events:
47+
return self.events.popleft()
48+
else:
49+
return None
50+
51+
def empty(self) -> bool:
52+
"""
53+
Checks if the queue is empty.
54+
"""
55+
return not self.events
56+
57+
def flush_buf(self) -> bytearray:
58+
"""
59+
Flushes the buffer and returns its contents.
60+
"""
61+
old = self.buf
62+
self.buf = bytearray()
63+
return old
64+
65+
def insert(self, event: Event) -> None:
66+
"""
67+
Inserts an event into the queue.
68+
"""
69+
trace('added event {event}', event=event)
70+
self.events.append(event)
71+
72+
def push(self, char: int | bytes) -> None:
73+
"""
74+
Processes a character by updating the buffer and handling special key mappings.
75+
"""
76+
ord_char = char if isinstance(char, int) else ord(char)
77+
char = bytes(bytearray((ord_char,)))
78+
self.buf.append(ord_char)
79+
if char in self.keymap:
80+
if self.keymap is self.compiled_keymap:
81+
# sanity check, buffer is empty when a special key comes
82+
assert len(self.buf) == 1
83+
k = self.keymap[char]
84+
trace('found map {k!r}', k=k)
85+
if isinstance(k, dict):
86+
self.keymap = k
87+
else:
88+
self.insert(Event('key', k, self.flush_buf()))
89+
self.keymap = self.compiled_keymap
90+
91+
elif self.buf and self.buf[0] == 27: # escape
92+
# escape sequence not recognized by our keymap: propagate it
93+
# outside so that i can be recognized as an M-... key (see also
94+
# the docstring in keymap.py
95+
trace('unrecognized escape sequence, propagating...')
96+
self.keymap = self.compiled_keymap
97+
self.insert(Event('key', '\033', bytearray(b'\033')))
98+
for _c in self.flush_buf()[1:]:
99+
self.push(_c)
100+
101+
else:
102+
try:
103+
decoded = bytes(self.buf).decode(self.encoding)
104+
except UnicodeError:
105+
return
106+
else:
107+
self.insert(Event('key', decoded, self.flush_buf()))
108+
self.keymap = self.compiled_keymap

Lib/_pyrepl/unix_eventqueue.py

Lines changed: 5 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,9 @@
1818
# CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
1919
# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
2020

21-
from collections import deque
22-
23-
from . import keymap
24-
from .console import Event
2521
from . import curses
2622
from .trace import trace
23+
from .base_eventqueue import BaseEventQueue
2724
from termios import tcgetattr, VERASE
2825
import os
2926

@@ -70,83 +67,10 @@ def get_terminal_keycodes() -> dict[bytes, str]:
7067
keycodes.update(CTRL_ARROW_KEYCODES)
7168
return keycodes
7269

73-
class EventQueue:
70+
class EventQueue(BaseEventQueue):
7471
def __init__(self, fd: int, encoding: str) -> None:
75-
self.keycodes = get_terminal_keycodes()
72+
keycodes = get_terminal_keycodes()
7673
if os.isatty(fd):
7774
backspace = tcgetattr(fd)[6][VERASE]
78-
self.keycodes[backspace] = "backspace"
79-
self.compiled_keymap = keymap.compile_keymap(self.keycodes)
80-
self.keymap = self.compiled_keymap
81-
trace("keymap {k!r}", k=self.keymap)
82-
self.encoding = encoding
83-
self.events: deque[Event] = deque()
84-
self.buf = bytearray()
85-
86-
def get(self) -> Event | None:
87-
"""
88-
Retrieves the next event from the queue.
89-
"""
90-
if self.events:
91-
return self.events.popleft()
92-
else:
93-
return None
94-
95-
def empty(self) -> bool:
96-
"""
97-
Checks if the queue is empty.
98-
"""
99-
return not self.events
100-
101-
def flush_buf(self) -> bytearray:
102-
"""
103-
Flushes the buffer and returns its contents.
104-
"""
105-
old = self.buf
106-
self.buf = bytearray()
107-
return old
108-
109-
def insert(self, event: Event) -> None:
110-
"""
111-
Inserts an event into the queue.
112-
"""
113-
trace('added event {event}', event=event)
114-
self.events.append(event)
115-
116-
def push(self, char: int | bytes) -> None:
117-
"""
118-
Processes a character by updating the buffer and handling special key mappings.
119-
"""
120-
ord_char = char if isinstance(char, int) else ord(char)
121-
char = bytes(bytearray((ord_char,)))
122-
self.buf.append(ord_char)
123-
if char in self.keymap:
124-
if self.keymap is self.compiled_keymap:
125-
#sanity check, buffer is empty when a special key comes
126-
assert len(self.buf) == 1
127-
k = self.keymap[char]
128-
trace('found map {k!r}', k=k)
129-
if isinstance(k, dict):
130-
self.keymap = k
131-
else:
132-
self.insert(Event('key', k, self.flush_buf()))
133-
self.keymap = self.compiled_keymap
134-
135-
elif self.buf and self.buf[0] == 27: # escape
136-
# escape sequence not recognized by our keymap: propagate it
137-
# outside so that i can be recognized as an M-... key (see also
138-
# the docstring in keymap.py
139-
trace('unrecognized escape sequence, propagating...')
140-
self.keymap = self.compiled_keymap
141-
self.insert(Event('key', '\033', bytearray(b'\033')))
142-
for _c in self.flush_buf()[1:]:
143-
self.push(_c)
144-
145-
else:
146-
try:
147-
decoded = bytes(self.buf).decode(self.encoding)
148-
except UnicodeError:
149-
return
150-
else:
151-
self.insert(Event('key', decoded, self.flush_buf()))
152-
self.keymap = self.compiled_keymap
75+
keycodes[backspace] = "backspace"
76+
BaseEventQueue.__init__(self, encoding, keycodes)

0 commit comments

Comments
 (0)