Skip to content

Commit

Permalink
Merge branch 'main' into typewatch
Browse files Browse the repository at this point in the history
* main:
  Minor edits to the Descriptor HowTo Guide (pythonGH-24901)
  Fix link to Lifecycle of a Pull Request in CONTRIBUTING (python#98102)
  pythonGH-94597: deprecate `SafeChildWatcher`, `FastChildWatcher` and `MultiLoopChildWatcher` child watchers  (python#98089)
  Auto-cancel old builds when new commit pushed to branch (python#98009)
  pythongh-95011: Migrate syslog module to Argument Clinic (pythonGH-95012)
  • Loading branch information
carljm committed Oct 9, 2022
2 parents 4783e07 + 2d2e01a commit 71d48c1
Show file tree
Hide file tree
Showing 17 changed files with 483 additions and 117 deletions.
2 changes: 1 addition & 1 deletion .github/CONTRIBUTING.rst
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ also suggestions on how you can most effectively help the project.

Please be aware that our workflow does deviate slightly from the typical GitHub
project. Details on how to properly submit a pull request are covered in
`Lifecycle of a Pull Request <https://devguide.python.org/pullrequest/>`_.
`Lifecycle of a Pull Request <https://devguide.python.org/getting-started/pull-request-lifecycle.html>`_.
We utilize various bots and status checks to help with this, so do follow the
comments they leave and their "Details" links, respectively. The key points of
our workflow that are not covered by a bot or status check are:
Expand Down
4 changes: 4 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ on:
permissions:
contents: read

concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
cancel-in-progress: true

jobs:
check_source:
name: 'Check for source changes'
Expand Down
4 changes: 4 additions & 0 deletions .github/workflows/build_msi.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ on:
permissions:
contents: read

concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
cancel-in-progress: true

jobs:
build:
name: Windows Installer
Expand Down
4 changes: 4 additions & 0 deletions .github/workflows/doc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@ on:
permissions:
contents: read

concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
cancel-in-progress: true

jobs:
build_doc:
name: 'Docs'
Expand Down
4 changes: 4 additions & 0 deletions .github/workflows/verify-ensurepip-wheels.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ on:
permissions:
contents: read

concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
cancel-in-progress: true

jobs:
verify:
runs-on: ubuntu-latest
Expand Down
14 changes: 8 additions & 6 deletions Doc/howto/descriptor.rst
Original file line number Diff line number Diff line change
Expand Up @@ -847,7 +847,7 @@ afterwards, :meth:`__set_name__` will need to be called manually.
ORM example
-----------

The following code is simplified skeleton showing how data descriptors could
The following code is a simplified skeleton showing how data descriptors could
be used to implement an `object relational mapping
<https://en.wikipedia.org/wiki/Object%E2%80%93relational_mapping>`_.

Expand Down Expand Up @@ -1535,6 +1535,8 @@ by member descriptors:
def __get__(self, obj, objtype=None):
'Emulate member_get() in Objects/descrobject.c'
# Also see PyMember_GetOne() in Python/structmember.c
if obj is None:
return self
value = obj._slotvalues[self.offset]
if value is null:
raise AttributeError(self.name)
Expand Down Expand Up @@ -1563,13 +1565,13 @@ variables:
class Type(type):
'Simulate how the type metaclass adds member objects for slots'

def __new__(mcls, clsname, bases, mapping):
def __new__(mcls, clsname, bases, mapping, **kwargs):
'Emulate type_new() in Objects/typeobject.c'
# type_new() calls PyTypeReady() which calls add_methods()
slot_names = mapping.get('slot_names', [])
for offset, name in enumerate(slot_names):
mapping[name] = Member(name, clsname, offset)
return type.__new__(mcls, clsname, bases, mapping)
return type.__new__(mcls, clsname, bases, mapping, **kwargs)
The :meth:`object.__new__` method takes care of creating instances that have
slots instead of an instance dictionary. Here is a rough simulation in pure
Expand All @@ -1580,7 +1582,7 @@ Python:
class Object:
'Simulate how object.__new__() allocates memory for __slots__'

def __new__(cls, *args):
def __new__(cls, *args, **kwargs):
'Emulate object_new() in Objects/typeobject.c'
inst = super().__new__(cls)
if hasattr(cls, 'slot_names'):
Expand All @@ -1593,7 +1595,7 @@ Python:
cls = type(self)
if hasattr(cls, 'slot_names') and name not in cls.slot_names:
raise AttributeError(
f'{type(self).__name__!r} object has no attribute {name!r}'
f'{cls.__name__!r} object has no attribute {name!r}'
)
super().__setattr__(name, value)

Expand All @@ -1602,7 +1604,7 @@ Python:
cls = type(self)
if hasattr(cls, 'slot_names') and name not in cls.slot_names:
raise AttributeError(
f'{type(self).__name__!r} object has no attribute {name!r}'
f'{cls.__name__!r} object has no attribute {name!r}'
)
super().__delattr__(name)

Expand Down
18 changes: 18 additions & 0 deletions Doc/whatsnew/3.12.rst
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,24 @@ New Modules
Improved Modules
================

asyncio
-------

* On Linux, :mod:`asyncio` uses :class:`~asyncio.PidfdChildWatcher` by default
if :func:`os.pidfd_open` is available and functional instead of
:class:`~asyncio.ThreadedChildWatcher`.
(Contributed by Kumar Aditya in :gh:`98024`.)

* The child watcher classes :class:`~asyncio.MultiLoopChildWatcher`,
:class:`~asyncio.FastChildWatcher` and
:class:`~asyncio.SafeChildWatcher` are deprecated and
will be removed in Python 3.14. It is recommended to not manually
configure a child watcher as the event loop now uses the best available
child watcher for each platform (:class:`~asyncio.PidfdChildWatcher`
if supported and :class:`~asyncio.ThreadedChildWatcher` otherwise).
(Contributed by Kumar Aditya in :gh:`94597`.)


pathlib
-------

Expand Down
3 changes: 3 additions & 0 deletions Include/internal/pycore_global_strings.h
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,7 @@ struct _Py_global_strings {
STRUCT_FOR_ID(exception)
STRUCT_FOR_ID(exp)
STRUCT_FOR_ID(extend)
STRUCT_FOR_ID(facility)
STRUCT_FOR_ID(factory)
STRUCT_FOR_ID(family)
STRUCT_FOR_ID(fanout)
Expand Down Expand Up @@ -392,6 +393,7 @@ struct _Py_global_strings {
STRUCT_FOR_ID(hi)
STRUCT_FOR_ID(hook)
STRUCT_FOR_ID(id)
STRUCT_FOR_ID(ident)
STRUCT_FOR_ID(ignore)
STRUCT_FOR_ID(imag)
STRUCT_FOR_ID(importlib)
Expand Down Expand Up @@ -447,6 +449,7 @@ struct _Py_global_strings {
STRUCT_FOR_ID(lo)
STRUCT_FOR_ID(locale)
STRUCT_FOR_ID(locals)
STRUCT_FOR_ID(logoption)
STRUCT_FOR_ID(loop)
STRUCT_FOR_ID(mapping)
STRUCT_FOR_ID(match)
Expand Down
21 changes: 21 additions & 0 deletions Include/internal/pycore_runtime_init_generated.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 15 additions & 0 deletions Lib/asyncio/unix_events.py
Original file line number Diff line number Diff line change
Expand Up @@ -1022,6 +1022,13 @@ class SafeChildWatcher(BaseChildWatcher):
big number of children (O(n) each time SIGCHLD is raised)
"""

def __init__(self):
super().__init__()
warnings._deprecated("SafeChildWatcher",
"{name!r} is deprecated as of Python 3.12 and will be "
"removed in Python {remove}.",
remove=(3, 14))

def close(self):
self._callbacks.clear()
super().close()
Expand Down Expand Up @@ -1100,6 +1107,10 @@ def __init__(self):
self._lock = threading.Lock()
self._zombies = {}
self._forks = 0
warnings._deprecated("FastChildWatcher",
"{name!r} is deprecated as of Python 3.12 and will be "
"removed in Python {remove}.",
remove=(3, 14))

def close(self):
self._callbacks.clear()
Expand Down Expand Up @@ -1212,6 +1223,10 @@ class MultiLoopChildWatcher(AbstractChildWatcher):
def __init__(self):
self._callbacks = {}
self._saved_sighandler = None
warnings._deprecated("MultiLoopChildWatcher",
"{name!r} is deprecated as of Python 3.12 and will be "
"removed in Python {remove}.",
remove=(3, 14))

def is_active(self):
return self._saved_sighandler is not None
Expand Down
10 changes: 7 additions & 3 deletions Lib/test/test_asyncio/test_events.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
import unittest
from unittest import mock
import weakref

import warnings
if sys.platform not in ('win32', 'vxworks'):
import tty

Expand Down Expand Up @@ -2055,7 +2055,9 @@ def test_remove_fds_after_closing(self):
class UnixEventLoopTestsMixin(EventLoopTestsMixin):
def setUp(self):
super().setUp()
watcher = asyncio.SafeChildWatcher()
with warnings.catch_warnings():
warnings.simplefilter('ignore', DeprecationWarning)
watcher = asyncio.SafeChildWatcher()
watcher.attach_loop(self.loop)
asyncio.set_child_watcher(watcher)

Expand Down Expand Up @@ -2652,7 +2654,9 @@ def setUp(self):
asyncio.set_event_loop(self.loop)

if sys.platform != 'win32':
watcher = asyncio.SafeChildWatcher()
with warnings.catch_warnings():
warnings.simplefilter('ignore', DeprecationWarning)
watcher = asyncio.SafeChildWatcher()
watcher.attach_loop(self.loop)
asyncio.set_child_watcher(watcher)

Expand Down
6 changes: 4 additions & 2 deletions Lib/test/test_asyncio/test_streams.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import threading
import unittest
from unittest import mock
import warnings
from test.support import socket_helper
try:
import ssl
Expand Down Expand Up @@ -791,8 +792,9 @@ def test_read_all_from_pipe_reader(self):
protocol = asyncio.StreamReaderProtocol(reader, loop=self.loop)
transport, _ = self.loop.run_until_complete(
self.loop.connect_read_pipe(lambda: protocol, pipe))

watcher = asyncio.SafeChildWatcher()
with warnings.catch_warnings():
warnings.simplefilter('ignore', DeprecationWarning)
watcher = asyncio.SafeChildWatcher()
watcher.attach_loop(self.loop)
try:
asyncio.set_child_watcher(watcher)
Expand Down
Loading

0 comments on commit 71d48c1

Please sign in to comment.