Skip to content

Commit

Permalink
Merge branch 'main' into remove-imp
Browse files Browse the repository at this point in the history
  • Loading branch information
warsaw committed Mar 7, 2023
2 parents 8e4893f + 54060ae commit c240e08
Show file tree
Hide file tree
Showing 48 changed files with 848 additions and 658 deletions.
5 changes: 3 additions & 2 deletions Doc/library/pathlib.rst
Original file line number Diff line number Diff line change
Expand Up @@ -105,8 +105,9 @@ we also call *flavours*:
PurePosixPath('setup.py')

Each element of *pathsegments* can be either a string representing a
path segment, an object implementing the :class:`os.PathLike` interface
which returns a string, or another path object::
path segment, or an object implementing the :class:`os.PathLike` interface
where the :meth:`~os.PathLike.__fspath__` method returns a string,
such as another path object::

>>> PurePath('foo', 'some/path', 'bar')
PurePosixPath('foo/some/path/bar')
Expand Down
6 changes: 4 additions & 2 deletions Doc/library/stdtypes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -530,12 +530,14 @@ class`. In addition, it provides a few more methods:
is ``False``.

The default values can be used to conveniently turn an integer into a
single byte object. However, when using the default arguments, don't try
to convert a value greater than 255 or you'll get an :exc:`OverflowError`::
single byte object::

>>> (65).to_bytes()
b'A'

However, when using the default arguments, don't try
to convert a value greater than 255 or you'll get an :exc:`OverflowError`.

Equivalent to::

def to_bytes(n, length=1, byteorder='big', signed=False):
Expand Down
2 changes: 1 addition & 1 deletion Doc/library/test.rst
Original file line number Diff line number Diff line change
Expand Up @@ -540,7 +540,7 @@ The :mod:`test.support` module defines the following functions:

Get size of a page in bytes.

.. versionadded:: 3.12
.. versionadded:: 3.12


.. function:: setswitchinterval(interval)
Expand Down
7 changes: 4 additions & 3 deletions Doc/tools/extensions/c_annotations.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
from docutils.parsers.rst import directives
from docutils.parsers.rst import Directive
from docutils.statemachine import StringList
from sphinx.locale import _ as sphinx_gettext
import csv

from sphinx import addnodes
Expand Down Expand Up @@ -168,11 +169,11 @@ def add_annotations(self, app, doctree):
elif not entry.result_type.endswith("Object*"):
continue
if entry.result_refs is None:
rc = 'Return value: Always NULL.'
rc = sphinx_gettext('Return value: Always NULL.')
elif entry.result_refs:
rc = 'Return value: New reference.'
rc = sphinx_gettext('Return value: New reference.')
else:
rc = 'Return value: Borrowed reference.'
rc = sphinx_gettext('Return value: Borrowed reference.')
node.insert(0, nodes.emphasis(rc, rc, classes=['refcount']))


Expand Down
5 changes: 5 additions & 0 deletions Doc/tools/templates/dummy.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@
{% trans %}Deprecated since version {deprecated}, will be removed in version {removed}{% endtrans %}
{% trans %}Deprecated since version {deprecated}, removed in version {removed}{% endtrans %}

In extensions/c_annotations.py:

{% trans %}Return value: Always NULL.{% endtrans %}
{% trans %}Return value: New reference.{% endtrans %}
{% trans %}Return value: Borrowed reference.{% endtrans %}

In docsbuild-scripts, when rewriting indexsidebar.html with actual versions:

Expand Down
5 changes: 5 additions & 0 deletions Doc/using/configure.rst
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,11 @@ also be used to improve performance.

Enable C-level code profiling with ``gprof`` (disabled by default).

.. cmdoption:: --with-strict-overflow

Add ``-fstrict-overflow`` to the C compiler flags (by default we add
``-fno-strict-overflow`` instead).


.. _debug-build:

Expand Down
208 changes: 116 additions & 92 deletions Doc/whatsnew/3.11.rst

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions Include/internal/pycore_global_objects.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ struct _Py_interp_static_objects {
// hamt_empty is here instead of global because of its weakreflist.
_PyGC_Head_UNUSED _hamt_empty_gc_not_used;
PyHamtObject hamt_empty;
PyBaseExceptionObject last_resort_memory_error;
} singletons;
};

Expand Down
4 changes: 2 additions & 2 deletions Include/internal/pycore_intrinsics.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,6 @@
typedef PyObject *(*instrinsic_func1)(PyThreadState* tstate, PyObject *value);
typedef PyObject *(*instrinsic_func2)(PyThreadState* tstate, PyObject *value1, PyObject *value2);

extern instrinsic_func1 _PyIntrinsics_UnaryFunctions[];
extern instrinsic_func2 _PyIntrinsics_BinaryFunctions[];
extern const instrinsic_func1 _PyIntrinsics_UnaryFunctions[];
extern const instrinsic_func2 _PyIntrinsics_BinaryFunctions[];

6 changes: 6 additions & 0 deletions Include/internal/pycore_runtime_init.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ extern "C" {
#include "pycore_obmalloc_init.h"


extern PyTypeObject _PyExc_MemoryError;


/* The static initializers defined here should only be used
in the runtime init code (in pystate.c and pylifecycle.c). */

Expand Down Expand Up @@ -120,6 +123,9 @@ extern "C" {
.ob_base = _PyObject_IMMORTAL_INIT(&_PyHamt_Type), \
.h_root = (PyHamtNode*)&_Py_SINGLETON(hamt_bitmap_node_empty), \
}, \
.last_resort_memory_error = { \
_PyObject_IMMORTAL_INIT(&_PyExc_MemoryError), \
}, \
}, \
}, \
._initial_thread = _PyThreadState_INIT, \
Expand Down
13 changes: 10 additions & 3 deletions Lib/argparse.py
Original file line number Diff line number Diff line change
Expand Up @@ -403,10 +403,18 @@ def _format_actions_usage(self, actions, groups):
except ValueError:
continue
else:
end = start + len(group._group_actions)
group_action_count = len(group._group_actions)
end = start + group_action_count
if actions[start:end] == group._group_actions:

suppressed_actions_count = 0
for action in group._group_actions:
group_actions.add(action)
if action.help is SUPPRESS:
suppressed_actions_count += 1

exposed_actions_count = group_action_count - suppressed_actions_count

if not group.required:
if start in inserts:
inserts[start] += ' ['
Expand All @@ -416,7 +424,7 @@ def _format_actions_usage(self, actions, groups):
inserts[end] += ']'
else:
inserts[end] = ']'
else:
elif exposed_actions_count > 1:
if start in inserts:
inserts[start] += ' ('
else:
Expand Down Expand Up @@ -490,7 +498,6 @@ def _format_actions_usage(self, actions, groups):
text = _re.sub(r'(%s) ' % open, r'\1', text)
text = _re.sub(r' (%s)' % close, r'\1', text)
text = _re.sub(r'%s *%s' % (open, close), r'', text)
text = _re.sub(r'\(([^|]*)\)', r'\1', text)
text = text.strip()

# return the text
Expand Down
8 changes: 2 additions & 6 deletions Lib/asyncio/tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -630,10 +630,6 @@ def ensure_future(coro_or_future, *, loop=None):
If the argument is a Future, it is returned directly.
"""
return _ensure_future(coro_or_future, loop=loop)


def _ensure_future(coro_or_future, *, loop=None):
if futures.isfuture(coro_or_future):
if loop is not None and loop is not futures._get_loop(coro_or_future):
raise ValueError('The future belongs to a different loop than '
Expand Down Expand Up @@ -798,7 +794,7 @@ def _done_callback(fut):
outer = None # bpo-46672
for arg in coros_or_futures:
if arg not in arg_to_fut:
fut = _ensure_future(arg, loop=loop)
fut = ensure_future(arg, loop=loop)
if loop is None:
loop = futures._get_loop(fut)
if fut is not arg:
Expand Down Expand Up @@ -855,7 +851,7 @@ def shield(arg):
weak references to tasks. A task that isn't referenced elsewhere
may get garbage collected at any time, even before it's done.
"""
inner = _ensure_future(arg)
inner = ensure_future(arg)
if inner.done():
# Shortcut.
return inner
Expand Down
57 changes: 26 additions & 31 deletions Lib/pathlib.py
Original file line number Diff line number Diff line change
Expand Up @@ -275,9 +275,20 @@ def __reduce__(self):
def _parse_parts(cls, parts):
if not parts:
return '', '', []
elif len(parts) == 1:
path = os.fspath(parts[0])
else:
path = cls._flavour.join(*parts)
sep = cls._flavour.sep
altsep = cls._flavour.altsep
path = cls._flavour.join(*parts)
if isinstance(path, str):
# Force-cast str subclasses to str (issue #21127)
path = str(path)
else:
raise TypeError(
"argument should be a str or an os.PathLike "
"object where __fspath__ returns a str, "
f"not {type(path).__name__!r}")
if altsep:
path = path.replace(altsep, sep)
drv, root, rel = cls._flavour.splitroot(path)
Expand All @@ -288,32 +299,10 @@ def _parse_parts(cls, parts):
parsed = [sys.intern(x) for x in unfiltered_parsed if x and x != '.']
return drv, root, parsed

@classmethod
def _parse_args(cls, args):
# This is useful when you don't want to create an instance, just
# canonicalize some constructor arguments.
parts = []
for a in args:
if isinstance(a, PurePath):
parts += a._parts
else:
a = os.fspath(a)
if isinstance(a, str):
# Force-cast str subclasses to str (issue #21127)
parts.append(str(a))
else:
raise TypeError(
"argument should be a str object or an os.PathLike "
"object returning str, not %r"
% type(a))
return cls._parse_parts(parts)

@classmethod
def _from_parts(cls, args):
# We need to call _parse_args on the instance, so as to get the
# right flavour.
self = object.__new__(cls)
drv, root, parts = self._parse_args(args)
drv, root, parts = self._parse_parts(args)
self._drv = drv
self._root = root
self._parts = parts
Expand Down Expand Up @@ -572,7 +561,7 @@ def joinpath(self, *args):
anchored).
"""
drv1, root1, parts1 = self._drv, self._root, self._parts
drv2, root2, parts2 = self._parse_args(args)
drv2, root2, parts2 = self._parse_parts(args)
if root2:
if not drv2 and drv1:
return self._from_parsed_parts(drv1, root2, [drv1 + root2] + parts2[1:])
Expand Down Expand Up @@ -659,7 +648,7 @@ def match(self, path_pattern):
return True

# Can't subclass os.PathLike from PurePath and keep the constructor
# optimizations in PurePath._parse_args().
# optimizations in PurePath.__slots__.
os.PathLike.register(PurePath)


Expand Down Expand Up @@ -704,11 +693,7 @@ def __new__(cls, *args, **kwargs):
warnings._deprecated("pathlib.PurePath(**kwargs)", msg, remove=(3, 14))
if cls is Path:
cls = WindowsPath if os.name == 'nt' else PosixPath
self = cls._from_parts(args)
if self._flavour is not os.path:
raise NotImplementedError("cannot instantiate %r on your system"
% (cls.__name__,))
return self
return cls._from_parts(args)

def _make_child_relpath(self, part):
# This is an optimization used for dir walking. `part` must be
Expand Down Expand Up @@ -1258,9 +1243,19 @@ class PosixPath(Path, PurePosixPath):
"""
__slots__ = ()

if os.name == 'nt':
def __new__(cls, *args, **kwargs):
raise NotImplementedError(
f"cannot instantiate {cls.__name__!r} on your system")

class WindowsPath(Path, PureWindowsPath):
"""Path subclass for Windows systems.
On a Windows system, instantiating a Path should return this object.
"""
__slots__ = ()

if os.name != 'nt':
def __new__(cls, *args, **kwargs):
raise NotImplementedError(
f"cannot instantiate {cls.__name__!r} on your system")
23 changes: 16 additions & 7 deletions Lib/plistlib.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,29 +21,38 @@
Generate Plist example:
import datetime
import plistlib
pl = dict(
aString = "Doodah",
aList = ["A", "B", 12, 32.1, [1, 2, 3]],
aFloat = 0.1,
anInt = 728,
aDict = dict(
anotherString = "<hello & hi there!>",
aUnicodeValue = "M\xe4ssig, Ma\xdf",
aThirdString = "M\xe4ssig, Ma\xdf",
aTrueValue = True,
aFalseValue = False,
),
someData = b"<binary gunk>",
someMoreData = b"<lots of binary gunk>" * 10,
aDate = datetime.datetime.fromtimestamp(time.mktime(time.gmtime())),
aDate = datetime.datetime.now()
)
with open(fileName, 'wb') as fp:
dump(pl, fp)
print(plistlib.dumps(pl).decode())
Parse Plist example:
with open(fileName, 'rb') as fp:
pl = load(fp)
print(pl["aKey"])
import plistlib
plist = b'''<plist version="1.0">
<dict>
<key>foo</key>
<string>bar</string>
</dict>
</plist>'''
pl = plistlib.loads(plist)
print(pl["foo"])
"""
__all__ = [
"InvalidFileException", "FMT_XML", "FMT_BINARY", "load", "dump", "loads", "dumps", "UID"
Expand Down
3 changes: 1 addition & 2 deletions Lib/tabnanny.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ def errprint(*args):
sys.stderr.write(sep + str(arg))
sep = " "
sys.stderr.write("\n")
sys.exit(1)

def main():
import getopt
Expand All @@ -44,15 +45,13 @@ def main():
opts, args = getopt.getopt(sys.argv[1:], "qv")
except getopt.error as msg:
errprint(msg)
return
for o, a in opts:
if o == '-q':
filename_only = filename_only + 1
if o == '-v':
verbose = verbose + 1
if not args:
errprint("Usage:", sys.argv[0], "[-v] file_or_directory ...")
return
for arg in args:
check(arg)

Expand Down
22 changes: 22 additions & 0 deletions Lib/test/test_argparse.py
Original file line number Diff line number Diff line change
Expand Up @@ -3764,6 +3764,28 @@ class TestHelpUsage(HelpTestCase):
version = ''


class TestHelpUsageWithParentheses(HelpTestCase):
parser_signature = Sig(prog='PROG')
argument_signatures = [
Sig('positional', metavar='(example) positional'),
Sig('-p', '--optional', metavar='{1 (option A), 2 (option B)}'),
]

usage = '''\
usage: PROG [-h] [-p {1 (option A), 2 (option B)}] (example) positional
'''
help = usage + '''\
positional arguments:
(example) positional
options:
-h, --help show this help message and exit
-p {1 (option A), 2 (option B)}, --optional {1 (option A), 2 (option B)}
'''
version = ''


class TestHelpOnlyUserGroups(HelpTestCase):
"""Test basic usage messages"""

Expand Down
Loading

0 comments on commit c240e08

Please sign in to comment.