Skip to content

Commit 7554a69

Browse files
Merge branch 'main' into polish_simplequeue_put
2 parents 3714ac6 + 398d7e1 commit 7554a69

25 files changed

Lines changed: 388 additions & 73 deletions

Doc/library/dataclasses.rst

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -418,7 +418,7 @@ Module contents
418418
:func:`!astuple` raises :exc:`TypeError` if *obj* is not a dataclass
419419
instance.
420420

421-
.. function:: make_dataclass(cls_name, fields, *, bases=(), namespace=None, init=True, repr=True, eq=True, order=False, unsafe_hash=False, frozen=False, match_args=True, kw_only=False, slots=False, weakref_slot=False, module=None, decorator=dataclass)
421+
.. function:: make_dataclass(cls_name, fields, *, bases=(), namespace=None, init=True, repr=True, eq=True, order=False, unsafe_hash=False, frozen=False, match_args=True, kw_only=False, slots=False, weakref_slot=False, module=None, qualname=None, decorator=dataclass)
422422

423423
Creates a new dataclass with name *cls_name*, fields as defined
424424
in *fields*, base classes as given in *bases*, and initialized
@@ -434,6 +434,9 @@ Module contents
434434
of the dataclass is set to that value.
435435
By default, it is set to the module name of the caller.
436436

437+
If *qualname* is defined, the :attr:`~type.__qualname__` attribute of the dataclass
438+
is set to that value. By default, it is set to the value passed to *cls_name*.
439+
437440
The *decorator* parameter is a callable that will be used to create the dataclass.
438441
It should take the class object as a first argument and the same keyword arguments
439442
as :deco:`dataclass`. By default, the :deco:`dataclass`
@@ -464,6 +467,8 @@ Module contents
464467

465468
.. versionadded:: 3.14
466469
Added the *decorator* parameter.
470+
.. versionadded:: next
471+
Added the *qualname* parameter.
467472

468473
.. function:: replace(obj, /, **changes)
469474

Doc/library/inspect.rst

Lines changed: 42 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -424,24 +424,63 @@ attributes (see :ref:`import-mod-attrs` for module attributes):
424424

425425
Return ``True`` if the object is a bound method written in Python.
426426

427+
.. note::
427428

428-
.. function:: ispackage(object)
429+
For example, given this class::
429430

430-
Return ``True`` if the object is a :term:`package`.
431+
>>> class Greeter:
432+
... def say_hello(self):
433+
... print('hello!')
431434

432-
.. versionadded:: 3.14
435+
A bound method (also known as an *instance method*) is created when
436+
accessing ``say_hello`` (a :term:`function` defined in the
437+
``Greeter`` namespace) through an instance of the ``Greeter`` class::
438+
439+
>>> instance = Greeter()
440+
441+
>>> instance.say_hello
442+
<bound method Greeter.say_hello of <__main__.Greeter object ...>>
443+
>>> ismethod(instance.say_hello)
444+
True
445+
>>> isfunction(instance.say_hello)
446+
False
447+
448+
Accessing ``say_hello`` through the ``Greeter`` class will return the
449+
function itself. For this function, :func:`ismethod` will return
450+
``False``, but :func:`isfunction` will return ``True``::
451+
452+
>>> Greeter.say_hello
453+
<function Greeter.say_hello at 0x7f7503854a90>
454+
>>> ismethod(Greeter.say_hello)
455+
False
456+
>>> isfunction(Greeter.say_hello)
457+
True
458+
459+
See :ref:`typesmethods` for details.
433460

434461

435462
.. function:: isfunction(object)
436463

437464
Return ``True`` if the object is a Python function, which includes functions
438465
created by a :term:`lambda` expression.
439466

467+
See the note for :func:`~inspect.ismethod` for an example.
468+
469+
470+
.. function:: ispackage(object)
471+
472+
Return ``True`` if the object is a :term:`package`.
473+
474+
.. versionadded:: 3.14
475+
440476

441477
.. function:: isgeneratorfunction(object)
442478

443479
Return ``True`` if the object is a Python generator function.
444480

481+
It also returns ``True`` for bound methods created from Python generator functions
482+
(see :ref:`typesmethods` for more information).
483+
445484
.. versionchanged:: 3.8
446485
Functions wrapped in :func:`functools.partial` now return ``True`` if the
447486
wrapped function is a Python generator function.

Doc/library/os.rst

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2549,7 +2549,8 @@ features:
25492549
Windows now handles a *mode* of ``0o700``.
25502550

25512551

2552-
.. function:: makedirs(name, mode=0o777, exist_ok=False)
2552+
.. function:: makedirs(name, mode=0o777, exist_ok=False, *, \
2553+
parent_mode=None)
25532554

25542555
.. index::
25552556
single: directory; creating
@@ -2567,6 +2568,12 @@ features:
25672568
If *exist_ok* is ``False`` (the default), a :exc:`FileExistsError` is
25682569
raised if the target directory already exists.
25692570

2571+
If *parent_mode* is not ``None``, it is used as the mode for any
2572+
newly-created, intermediate-level directories. Like *mode*, it is
2573+
combined with the process's umask value; see :ref:`the mkdir()
2574+
description <mkdir_modebits>`. Otherwise, intermediate directories are
2575+
created with the default mode, which is also subject to the umask.
2576+
25702577
.. note::
25712578

25722579
:func:`makedirs` will become confused if the path elements to create
@@ -2593,6 +2600,11 @@ features:
25932600
The *mode* argument no longer affects the file permission bits of
25942601
newly created intermediate-level directories.
25952602

2603+
.. versionadded:: 3.15
2604+
The *parent_mode* parameter. To match the behavior from Python 3.6 and
2605+
earlier (where *mode* was applied to all created directories), pass
2606+
``parent_mode=mode``.
2607+
25962608

25972609
.. function:: mkfifo(path, mode=0o666, *, dir_fd=None)
25982610

Doc/library/pathlib.rst

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1518,7 +1518,8 @@ Creating files and directories
15181518
:meth:`~Path.write_bytes` methods are often used to create files.
15191519

15201520

1521-
.. method:: Path.mkdir(mode=0o777, parents=False, exist_ok=False)
1521+
.. method:: Path.mkdir(mode=0o777, parents=False, exist_ok=False, *, \
1522+
parent_mode=None)
15221523

15231524
Create a new directory at this given path. If *mode* is given, it is
15241525
combined with the process's ``umask`` value to determine the file mode
@@ -1529,6 +1530,12 @@ Creating files and directories
15291530
as needed; they are created with the default permissions without taking
15301531
*mode* into account (mimicking the POSIX ``mkdir -p`` command).
15311532

1533+
If *parent_mode* is not ``None``, it is used as the mode for any
1534+
newly-created, intermediate-level directories when *parents* is true.
1535+
Like *mode*, it is combined with the process's ``umask`` value.
1536+
Otherwise, intermediate directories are created with the default
1537+
permissions (also subject to the umask).
1538+
15321539
If *parents* is false (the default), a missing parent raises
15331540
:exc:`FileNotFoundError`.
15341541

@@ -1542,6 +1549,9 @@ Creating files and directories
15421549
.. versionchanged:: 3.5
15431550
The *exist_ok* parameter was added.
15441551

1552+
.. versionadded:: 3.15
1553+
The *parent_mode* parameter.
1554+
15451555

15461556
.. method:: Path.symlink_to(target, target_is_directory=False)
15471557

Doc/whatsnew/3.15.rst

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1285,6 +1285,10 @@ os
12851285
glibc versions 2.28 and later.
12861286
(Contributed by Jeffrey Bosboom and Victor Stinner in :gh:`83714`.)
12871287

1288+
* :func:`os.makedirs` function now has a *parent_mode* parameter that allows
1289+
specifying the mode for intermediate directories. This can be used to match
1290+
the behavior from Python 3.6 and earlier by passing ``parent_mode=mode``.
1291+
(Contributed by Zackery Spytz and Gregory P. Smith in :gh:`86533`.)
12881292

12891293
os.path
12901294
-------
@@ -2057,6 +2061,10 @@ importlib.resources
20572061
pathlib
20582062
-------
20592063

2064+
* :meth:`pathlib.Path.mkdir` now has a *parent_mode* parameter that allows
2065+
specifying the mode for intermediate directories when ``parents=True``.
2066+
(Contributed by Gregory P. Smith in :gh:`86533`.)
2067+
20602068
* Removed deprecated :meth:`!pathlib.PurePath.is_reserved`.
20612069
Use :func:`os.path.isreserved` to detect reserved paths on Windows.
20622070
(Contributed by Nikita Sobolev in :gh:`133875`.)

Lib/dataclasses.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1644,7 +1644,7 @@ def _astuple_inner(obj, tuple_factory):
16441644
def make_dataclass(cls_name, fields, *, bases=(), namespace=None, init=True,
16451645
repr=True, eq=True, order=False, unsafe_hash=False,
16461646
frozen=False, match_args=True, kw_only=False, slots=False,
1647-
weakref_slot=False, module=None, decorator=dataclass):
1647+
weakref_slot=False, module=None, qualname=None, decorator=dataclass):
16481648
"""Return a new dynamically created dataclass.
16491649
16501650
The dataclass name will be 'cls_name'. 'fields' is an iterable
@@ -1669,6 +1669,9 @@ class C(Base):
16691669
16701670
If module parameter is defined, the '__module__' attribute of the dataclass is
16711671
set to that value.
1672+
1673+
If qualname parameter is defined, the '__qualname__' attribute of the dataclass is set
1674+
to that value.
16721675
"""
16731676

16741677
if namespace is None:
@@ -1758,6 +1761,9 @@ def exec_body_callback(ns):
17581761
if module is not None:
17591762
cls.__module__ = module
17601763

1764+
if qualname:
1765+
cls.__qualname__ = qualname
1766+
17611767
# Apply the normal provided decorator.
17621768
cls = decorator(cls, init=init, repr=repr, eq=eq, order=order,
17631769
unsafe_hash=unsafe_hash, frozen=frozen,

Lib/multiprocessing/connection.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@
5050
default_family = 'AF_INET'
5151
families = ['AF_INET']
5252

53-
if hasattr(socket, 'AF_UNIX'):
53+
if hasattr(socket, 'AF_UNIX') and sys.platform != 'cygwin':
5454
default_family = 'AF_UNIX'
5555
families += ['AF_UNIX']
5656

Lib/multiprocessing/context.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -326,8 +326,10 @@ def _check_available(self):
326326
_concrete_contexts = {
327327
'fork': ForkContext(),
328328
'spawn': SpawnContext(),
329-
'forkserver': ForkServerContext(),
330329
}
330+
if reduction.HAVE_SEND_HANDLE:
331+
_concrete_contexts['forkserver'] = ForkServerContext()
332+
331333
# bpo-33725: running arbitrary code after fork() is no longer reliable
332334
# on macOS since macOS 10.14 (Mojave). Use spawn by default instead.
333335
# gh-84559: We changed everyones default to a thread safeish one in 3.14.

Lib/os.py

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -219,22 +219,29 @@ def _add(str, fn):
219219
# Super directory utilities.
220220
# (Inspired by Eric Raymond; the doc strings are mostly his)
221221

222-
def makedirs(name, mode=0o777, exist_ok=False):
223-
"""makedirs(name [, mode=0o777][, exist_ok=False])
222+
def makedirs(name, mode=0o777, exist_ok=False, *, parent_mode=None):
223+
"""makedirs(name [, mode=0o777][, exist_ok=False][, parent_mode=None])
224224
225225
Super-mkdir; create a leaf directory and all intermediate ones. Works like
226226
mkdir, except that any intermediate path segment (not just the rightmost)
227227
will be created if it does not exist. If the target directory already
228228
exists, raise an OSError if exist_ok is False. Otherwise no exception is
229-
raised. This is recursive.
229+
raised. If parent_mode is not None, it will be used as the mode for any
230+
newly-created, intermediate-level directories. Otherwise, intermediate
231+
directories are created with the default permissions (respecting umask).
232+
This is recursive.
230233
231234
"""
232235
head, tail = path.split(name)
233236
if not tail:
234237
head, tail = path.split(head)
235238
if head and tail and not path.exists(head):
236239
try:
237-
makedirs(head, exist_ok=exist_ok)
240+
if parent_mode is not None:
241+
makedirs(head, mode=parent_mode, exist_ok=exist_ok,
242+
parent_mode=parent_mode)
243+
else:
244+
makedirs(head, exist_ok=exist_ok)
238245
except FileExistsError:
239246
# Defeats race condition when another thread created the path
240247
pass

Lib/pathlib/__init__.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1204,7 +1204,7 @@ def touch(self, mode=0o666, exist_ok=True):
12041204
fd = os.open(self, flags, mode)
12051205
os.close(fd)
12061206

1207-
def mkdir(self, mode=0o777, parents=False, exist_ok=False):
1207+
def mkdir(self, mode=0o777, parents=False, exist_ok=False, *, parent_mode=None):
12081208
"""
12091209
Create a new directory at this given path.
12101210
"""
@@ -1213,7 +1213,11 @@ def mkdir(self, mode=0o777, parents=False, exist_ok=False):
12131213
except FileNotFoundError:
12141214
if not parents or self.parent == self:
12151215
raise
1216-
self.parent.mkdir(parents=True, exist_ok=True)
1216+
if parent_mode is not None:
1217+
self.parent.mkdir(mode=parent_mode, parents=True, exist_ok=True,
1218+
parent_mode=parent_mode)
1219+
else:
1220+
self.parent.mkdir(parents=True, exist_ok=True)
12171221
self.mkdir(mode, parents=False, exist_ok=exist_ok)
12181222
except OSError:
12191223
# Cannot rely on checking for EEXIST, since the operating system

0 commit comments

Comments
 (0)