Skip to content

Commit

Permalink
Merge branch 'main' into inlinecomp2
Browse files Browse the repository at this point in the history
* main: (37 commits)
  pythongh-102192: Replace PyErr_Fetch/Restore etc by more efficient alternatives in sub interpreters module (python#102472)
  pythongh-95672: Fix versionadded indentation of get_pagesize in test.rst (pythongh-102455)
  pythongh-102416: Do not memoize incorrectly loop rules in the parser (python#102467)
  pythonGH-101362: Optimise PurePath(PurePath(...)) (pythonGH-101667)
  pythonGH-101362: Check pathlib.Path flavour compatibility at import time (pythonGH-101664)
  pythonGH-101362: Call join() only when >1 argument supplied to pathlib.PurePath() (python#101665)
  pythongh-102444: Fix minor bugs in `test_typing` highlighted by pyflakes (python#102445)
  pythonGH-102341: Improve the test function for pow (python#102342)
  Fix unused classes in a typing test (pythonGH-102437)
  pythongh-101979: argparse: fix a bug where parentheses in metavar argument of add_argument() were dropped (python#102318)
  pythongh-102356: Add thrashcan macros to filter object dealloc (python#102426)
  Move around example in to_bytes() to avoid confusion (python#101595)
  pythonGH-97546: fix flaky asyncio `test_wait_for_race_condition` test (python#102421)
  pythongh-96821: Add config option `--with-strict-overflow` (python#96823)
  pythongh-101992: update pstlib module documentation (python#102133)
  pythongh-63301: Set exit code when tabnanny CLI exits on error (python#7699)
  pythongh-101863: Fix wrong comments in EUC-KR codec (pythongh-102417)
  pythongh-102302 Micro-optimize `inspect.Parameter.__hash__` (python#102303)
  pythongh-102179: Fix `os.dup2` error reporting for negative fds (python#102180)
  pythongh-101892: Fix `SystemError` when a callable iterator call exhausts the iterator (python#101896)
  ...
  • Loading branch information
carljm committed Mar 6, 2023
2 parents 73dc0ed + f105fe4 commit ecb313c
Show file tree
Hide file tree
Showing 74 changed files with 891 additions and 760 deletions.
2 changes: 1 addition & 1 deletion Doc/c-api/buffer.rst
Original file line number Diff line number Diff line change
Expand Up @@ -499,7 +499,7 @@ Buffer-related functions
This function fails if *len* != *src->len*.
.. c:function:: int PyObject_CopyData(Py_buffer *dest, Py_buffer *src)
.. c:function:: int PyObject_CopyData(PyObject *dest, PyObject *src)
Copy data from *src* to *dest* buffer. Can convert between C-style and
or Fortran-style buffers.
Expand Down
6 changes: 3 additions & 3 deletions Doc/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,7 @@
ogp_site_name = 'Python documentation'
ogp_image = '_static/og-image.png'
ogp_custom_meta_tags = [
'<meta property="og:image:width" content="200">',
'<meta property="og:image:height" content="200">',
'<meta name="theme-color" content="#3776ab">',
'<meta property="og:image:width" content="200" />',
'<meta property="og:image:height" content="200" />',
'<meta name="theme-color" content="#3776ab" />',
]
9 changes: 6 additions & 3 deletions Doc/library/itertools.rst
Original file line number Diff line number Diff line change
Expand Up @@ -886,9 +886,12 @@ which incur interpreter overhead.
except AttributeError:
# Slow path for general iterables
it = islice(iterable, start, None)
for i, element in enumerate(it, start):
if element is value or element == value:
yield i
i = start - 1
try:
while True:
yield (i := i + operator.indexOf(it, value) + 1)
except ValueError:
pass
else:
# Fast path for sequences
i = start - 1
Expand Down
5 changes: 5 additions & 0 deletions Doc/library/os.rst
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,11 @@ process and user.
``'surrogateescape'`` error handler. Use :data:`environb` if you would like
to use a different encoding.

On Windows, the keys are converted to uppercase. This also applies when
getting, setting, or deleting an item. For example,
``environ['monty'] = 'python'`` maps the key ``'MONTY'`` to the value
``'python'``.

.. note::

Calling :func:`putenv` directly does not change :data:`os.environ`, so it's better
Expand Down
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
2 changes: 1 addition & 1 deletion Doc/library/sqlite3.rst
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ including `cursors`_ and `transactions`_.

First, we need to create a new database and open
a database connection to allow :mod:`!sqlite3` to work with it.
Call :func:`sqlite3.connect` to to create a connection to
Call :func:`sqlite3.connect` to create a connection to
the database :file:`tutorial.db` in the current working directory,
implicitly creating it if it does not exist:

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
7 changes: 7 additions & 0 deletions Doc/library/test.rst
Original file line number Diff line number Diff line change
Expand Up @@ -536,6 +536,13 @@ The :mod:`test.support` module defines the following functions:
:func:`doctest.testmod`.


.. function:: get_pagesize()

Get size of a page in bytes.

.. versionadded:: 3.12


.. function:: setswitchinterval(interval)

Set the :func:`sys.setswitchinterval` to the given *interval*. Defines
Expand Down
2 changes: 1 addition & 1 deletion Doc/library/typing.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1345,7 +1345,7 @@ These are not used in annotations. They are building blocks for creating generic

x: Ts # Not valid
x: tuple[Ts] # Not valid
x: tuple[*Ts] # The correct way to to do it
x: tuple[*Ts] # The correct way to do it

Type variable tuples can be used in the same contexts as normal type
variables. For example, in class definitions, arguments, and return types::
Expand Down
1 change: 1 addition & 0 deletions Doc/library/unittest.mock.rst
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ available, and then make assertions about how they have been used:
:attr:`side_effect` allows you to perform side effects, including raising an
exception when a mock is called:

>>> from unittest.mock import Mock
>>> mock = Mock(side_effect=KeyError('foo'))
>>> mock()
Traceback (most recent call last):
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
6 changes: 0 additions & 6 deletions Include/internal/pycore_compile.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,6 @@ PyAPI_FUNC(PyCodeObject*) _PyAST_Compile(
int optimize,
struct _arena *arena);

int _PyFuture_FromAST(
struct _mod * mod,
PyObject *filename,
PyFutureFeatures* futures);

extern PyObject* _Py_Mangle(PyObject *p, PyObject *name);

typedef struct {
int optimize;
Expand Down
15 changes: 0 additions & 15 deletions Include/internal/pycore_pymath.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,21 +56,6 @@ static inline void _Py_ADJUST_ERANGE2(double x, double y)
}
}

// Return the maximum value of integral type *type*.
#define _Py_IntegralTypeMax(type) \
(_Py_IS_TYPE_SIGNED(type) ? (((((type)1 << (sizeof(type)*CHAR_BIT - 2)) - 1) << 1) + 1) : ~(type)0)

// Return the minimum value of integral type *type*.
#define _Py_IntegralTypeMin(type) \
(_Py_IS_TYPE_SIGNED(type) ? -_Py_IntegralTypeMax(type) - 1 : 0)

// Check whether *v* is in the range of integral type *type*. This is most
// useful if *v* is floating-point, since demoting a floating-point *v* to an
// integral type that cannot represent *v*'s integral part is undefined
// behavior.
#define _Py_InIntegralTypeRange(type, v) \
(_Py_IntegralTypeMin(type) <= v && v <= _Py_IntegralTypeMax(type))


//--- HAVE_PY_SET_53BIT_PRECISION macro ------------------------------------
//
Expand Down
7 changes: 7 additions & 0 deletions Include/internal/pycore_symtable.h
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,8 @@ PyAPI_FUNC(PySTEntryObject *) PySymtable_Lookup(struct symtable *, void *);

extern void _PySymtable_Free(struct symtable *);

extern PyObject* _Py_Mangle(PyObject *p, PyObject *name);

/* Flags for def-use information */

#define DEF_GLOBAL 1 /* global stmt */
Expand Down Expand Up @@ -129,6 +131,11 @@ extern struct symtable* _Py_SymtableStringObjectFlags(
int start,
PyCompilerFlags *flags);

int _PyFuture_FromAST(
struct _mod * mod,
PyObject *filename,
PyFutureFeatures* futures);

#ifdef __cplusplus
}
#endif
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
2 changes: 1 addition & 1 deletion Lib/inspect.py
Original file line number Diff line number Diff line change
Expand Up @@ -2805,7 +2805,7 @@ def __repr__(self):
return '<{} "{}">'.format(self.__class__.__name__, self)

def __hash__(self):
return hash((self.name, self.kind, self.annotation, self.default))
return hash((self._name, self._kind, self._annotation, self._default))

def __eq__(self, other):
if self is other:
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
Loading

0 comments on commit ecb313c

Please sign in to comment.