Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main' into 44682-Fix-pdb-command…
Browse files Browse the repository at this point in the history
…s-invalid-bpnum
  • Loading branch information
akulakov committed Jul 26, 2021
2 parents 9e61254 + f22737a commit c080ecb
Show file tree
Hide file tree
Showing 15 changed files with 74 additions and 41 deletions.
17 changes: 9 additions & 8 deletions Doc/howto/enum.rst
Expand Up @@ -508,7 +508,7 @@ evaluate to ``True``.
Pickling enums created with the functional API can be tricky as frame stack
implementation details are used to try and figure out which module the
enumeration is being created in (e.g. it will fail if you use a utility
function in separate module, and also may not work on IronPython or Jython).
function in a separate module, and also may not work on IronPython or Jython).
The solution is to specify the module name explicitly as follows::

>>> Animal = Enum('Animal', 'ANT BEE CAT DOG', module=__name__)
Expand Down Expand Up @@ -540,7 +540,7 @@ The complete signature is::

:value: What the new enum class will record as its name.

:names: The enum members. This can be a whitespace or comma separated string
:names: The enum members. This can be a whitespace- or comma-separated string
(values will start at 1 unless otherwise specified)::

'RED GREEN BLUE' | 'RED,GREEN,BLUE' | 'RED, GREEN, BLUE'
Expand Down Expand Up @@ -997,7 +997,7 @@ Plain :class:`Enum` classes always evaluate as :data:`True`.
"""""""""""""""""""""""""""""

If you give your enum subclass extra methods, like the `Planet`_
class above, those methods will show up in a :func:`dir` of the member,
class below, those methods will show up in a :func:`dir` of the member,
but not of the class::

>>> dir(Planet)
Expand Down Expand Up @@ -1083,7 +1083,7 @@ the following are true:
>>> Color(0)
Color.BLACK

- membership / containment checking has changed slightly -- zero valued flags
- membership / containment checking has changed slightly -- zero-valued flags
are never considered to be contained::

>>> Color.BLACK in Color.WHITE
Expand Down Expand Up @@ -1152,7 +1152,7 @@ that can be used directly, or as examples for creating one's own.
Omitting values
^^^^^^^^^^^^^^^

In many use-cases one doesn't care what the actual value of an enumeration
In many use-cases, one doesn't care what the actual value of an enumeration
is. There are several ways to define this type of simple enumeration:

- use instances of :class:`auto` for the value
Expand Down Expand Up @@ -1338,7 +1338,7 @@ alias::
Planet
^^^^^^

If :meth:`__new__` or :meth:`__init__` is defined the value of the enum member
If :meth:`__new__` or :meth:`__init__` is defined, the value of the enum member
will be passed to those methods::

>>> class Planet(Enum):
Expand Down Expand Up @@ -1388,8 +1388,9 @@ An example to show the :attr:`_ignore_` attribute in use::
Conforming input to Flag
^^^^^^^^^^^^^^^^^^^^^^^^

Creating a :class:`Flag` enum that is more resilient out-of-bounds results to
mathematical operations, you can use the :attr:`FlagBoundary.CONFORM` setting::
To create a :class:`Flag` enum that is more resilient to out-of-bounds results
from mathematical operations, you can use the :attr:`FlagBoundary.CONFORM`
setting::

>>> from enum import Flag, CONFORM, auto
>>> class Weekday(Flag, boundary=CONFORM):
Expand Down
3 changes: 2 additions & 1 deletion Doc/library/shelve.rst
Expand Up @@ -60,7 +60,8 @@ lots of shared sub-objects. The keys are ordinary strings.
to load a shelf from an untrusted source. Like with pickle, loading a shelf
can execute arbitrary code.

Shelf objects support all methods supported by dictionaries. This eases the
Shelf objects support most of methods and operations supported by dictionaries
(except copying, constructors and operators ``|`` and ``|=``). This eases the
transition from dictionary based scripts to those requiring persistent storage.

Two additional methods are supported:
Expand Down
8 changes: 4 additions & 4 deletions Doc/library/stdtypes.rst
Expand Up @@ -5040,16 +5040,16 @@ enables cleaner type hinting syntax compared to :data:`typing.Union`.
TypeError: isinstance() argument 2 cannot contain a parameterized generic

The user-exposed type for the union object can be accessed from
:data:`types.Union` and used for :func:`isinstance` checks. An object cannot be
:data:`types.UnionType` and used for :func:`isinstance` checks. An object cannot be
instantiated from the type::

>>> import types
>>> isinstance(int | str, types.Union)
>>> isinstance(int | str, types.UnionType)
True
>>> types.Union()
>>> types.UnionType()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: cannot create 'types.Union' instances
TypeError: cannot create 'types.UnionType' instances

.. note::
The :meth:`__or__` method for type objects was added to support the syntax
Expand Down
2 changes: 1 addition & 1 deletion Doc/library/sysconfig.rst
Expand Up @@ -175,7 +175,7 @@ identifier. Python currently uses eight paths:
If *expand* is set to ``False``, the path will not be expanded using the
variables.

If *name* is not found, return ``None``.
If *name* is not found, raise a :exc:`KeyError`.


.. function:: get_paths([scheme, [vars, [expand]]])
Expand Down
2 changes: 1 addition & 1 deletion Doc/library/types.rst
Expand Up @@ -312,7 +312,7 @@ Standard names are defined for the following types:
This type can now be subclassed.


.. data:: Union
.. data:: UnionType

The type of :ref:`union type expressions<types-union>`.

Expand Down
3 changes: 2 additions & 1 deletion Doc/whatsnew/3.10.rst
Expand Up @@ -747,7 +747,8 @@ and :func:`issubclass`::
See :ref:`types-union` and :pep:`604` for more details.
(Contributed by Maggie Moss and Philippe Prados in :issue:`41428`.)
(Contributed by Maggie Moss and Philippe Prados in :issue:`41428`,
with additions by Yurii Karabas and Serhiy Storchaka in :issue:`44490`.)
PEP 612: Parameter Specification Variables
Expand Down
21 changes: 21 additions & 0 deletions Lib/test/test_complex.py
@@ -1,4 +1,5 @@
import unittest
import sys
from test import support
from test.test_grammar import (VALID_UNDERSCORE_LITERALS,
INVALID_UNDERSCORE_LITERALS)
Expand Down Expand Up @@ -248,6 +249,26 @@ def test_pow(self):
b = 5.1+2.3j
self.assertRaises(ValueError, pow, a, b, 0)

# Check some boundary conditions; some of these used to invoke
# undefined behaviour (https://bugs.python.org/issue44698). We're
# not actually checking the results of these operations, just making
# sure they don't crash (for example when using clang's
# UndefinedBehaviourSanitizer).
values = (sys.maxsize, sys.maxsize+1, sys.maxsize-1,
-sys.maxsize, -sys.maxsize+1, -sys.maxsize+1)
for real in values:
for imag in values:
with self.subTest(real=real, imag=imag):
c = complex(real, imag)
try:
c ** real
except OverflowError:
pass
try:
c ** c
except OverflowError:
pass

def test_boolcontext(self):
for i in range(100):
self.assertTrue(complex(random() + 1e-6, random() + 1e-6))
Expand Down
2 changes: 1 addition & 1 deletion Lib/test/test_typing.py
Expand Up @@ -3090,7 +3090,7 @@ class C(Generic[T]): pass
self.assertIs(get_origin(Callable), collections.abc.Callable)
self.assertIs(get_origin(list[int]), list)
self.assertIs(get_origin(list), None)
self.assertIs(get_origin(list | str), types.Union)
self.assertIs(get_origin(list | str), types.UnionType)
self.assertIs(get_origin(P.args), P)
self.assertIs(get_origin(P.kwargs), P)

Expand Down
3 changes: 1 addition & 2 deletions Lib/types.py
Expand Up @@ -297,9 +297,8 @@ def wrapped(*args, **kwargs):

return wrapped


GenericAlias = type(list[int])
Union = type(int | str)
UnionType = type(int | str)

EllipsisType = type(Ellipsis)
NoneType = type(None)
Expand Down
22 changes: 11 additions & 11 deletions Lib/typing.py
Expand Up @@ -175,7 +175,7 @@ def _type_check(arg, msg, is_argument=True, module=None):
return arg
if isinstance(arg, _SpecialForm) or arg in (Generic, Protocol):
raise TypeError(f"Plain {arg} is not valid as type argument")
if isinstance(arg, (type, TypeVar, ForwardRef, types.Union, ParamSpec)):
if isinstance(arg, (type, TypeVar, ForwardRef, types.UnionType, ParamSpec)):
return arg
if not callable(arg):
raise TypeError(f"{msg} Got {arg!r:.100}.")
Expand Down Expand Up @@ -215,7 +215,7 @@ def _collect_type_vars(types_, typevar_types=None):
for t in types_:
if isinstance(t, typevar_types) and t not in tvars:
tvars.append(t)
if isinstance(t, (_GenericAlias, GenericAlias, types.Union)):
if isinstance(t, (_GenericAlias, GenericAlias, types.UnionType)):
tvars.extend([t for t in t.__parameters__ if t not in tvars])
return tuple(tvars)

Expand Down Expand Up @@ -268,7 +268,7 @@ def _remove_dups_flatten(parameters):
# Flatten out Union[Union[...], ...].
params = []
for p in parameters:
if isinstance(p, (_UnionGenericAlias, types.Union)):
if isinstance(p, (_UnionGenericAlias, types.UnionType)):
params.extend(p.__args__)
elif isinstance(p, tuple) and len(p) > 0 and p[0] is Union:
params.extend(p[1:])
Expand Down Expand Up @@ -322,13 +322,13 @@ def _eval_type(t, globalns, localns, recursive_guard=frozenset()):
"""
if isinstance(t, ForwardRef):
return t._evaluate(globalns, localns, recursive_guard)
if isinstance(t, (_GenericAlias, GenericAlias, types.Union)):
if isinstance(t, (_GenericAlias, GenericAlias, types.UnionType)):
ev_args = tuple(_eval_type(a, globalns, localns, recursive_guard) for a in t.__args__)
if ev_args == t.__args__:
return t
if isinstance(t, GenericAlias):
return GenericAlias(t.__origin__, ev_args)
if isinstance(t, types.Union):
if isinstance(t, types.UnionType):
return functools.reduce(operator.or_, ev_args)
else:
return t.copy_with(ev_args)
Expand Down Expand Up @@ -1038,7 +1038,7 @@ def __getitem__(self, params):
for arg in self.__args__:
if isinstance(arg, self._typevar_types):
arg = subst[arg]
elif isinstance(arg, (_GenericAlias, GenericAlias, types.Union)):
elif isinstance(arg, (_GenericAlias, GenericAlias, types.UnionType)):
subparams = arg.__parameters__
if subparams:
subargs = tuple(subst[x] for x in subparams)
Expand Down Expand Up @@ -1206,7 +1206,7 @@ def copy_with(self, params):
return Union[params]

def __eq__(self, other):
if not isinstance(other, (_UnionGenericAlias, types.Union)):
if not isinstance(other, (_UnionGenericAlias, types.UnionType)):
return NotImplemented
return set(self.__args__) == set(other.__args__)

Expand Down Expand Up @@ -1810,7 +1810,7 @@ def _strip_annotations(t):
if stripped_args == t.__args__:
return t
return GenericAlias(t.__origin__, stripped_args)
if isinstance(t, types.Union):
if isinstance(t, types.UnionType):
stripped_args = tuple(_strip_annotations(a) for a in t.__args__)
if stripped_args == t.__args__:
return t
Expand Down Expand Up @@ -1841,8 +1841,8 @@ def get_origin(tp):
return tp.__origin__
if tp is Generic:
return Generic
if isinstance(tp, types.Union):
return types.Union
if isinstance(tp, types.UnionType):
return types.UnionType
return None


Expand All @@ -1866,7 +1866,7 @@ def get_args(tp):
or isinstance(res[0], (ParamSpec, _ConcatenateGenericAlias)))):
res = (list(res[:-1]), res[-1])
return res
if isinstance(tp, types.Union):
if isinstance(tp, types.UnionType):
return tp.__args__
return ()

Expand Down
@@ -0,0 +1 @@
Fix undefined behaviour in complex object exponentiation.
@@ -0,0 +1 @@
Rename ``types.Union`` to ``types.UnionType``.
@@ -0,0 +1 @@
Fix documentation for the return type of :func:`sysconfig.get_path`.
23 changes: 15 additions & 8 deletions Objects/complexobject.c
Expand Up @@ -514,8 +514,6 @@ static PyObject *
complex_pow(PyObject *v, PyObject *w, PyObject *z)
{
Py_complex p;
Py_complex exponent;
long int_exponent;
Py_complex a, b;
TO_COMPLEX(v, a);
TO_COMPLEX(w, b);
Expand All @@ -525,12 +523,21 @@ complex_pow(PyObject *v, PyObject *w, PyObject *z)
return NULL;
}
errno = 0;
exponent = b;
int_exponent = (long)exponent.real;
if (exponent.imag == 0. && exponent.real == int_exponent)
p = c_powi(a, int_exponent);
else
p = _Py_c_pow(a, exponent);
// Check if w is an integer value that fits inside a C long, so we can
// use a faster algorithm. TO_COMPLEX(w, b), above, already handled the
// conversion from larger longs, as well as other types.
if (PyLong_Check(w)) {
int overflow = 0;
long int_exponent = PyLong_AsLongAndOverflow(w, &overflow);
if (int_exponent == -1 && PyErr_Occurred())
return NULL;
if (overflow == 0)
p = c_powi(a, int_exponent);
else
p = _Py_c_pow(a, b);
} else {
p = _Py_c_pow(a, b);
}

Py_ADJUST_ERANGE2(p.real, p.imag);
if (errno == EDOM) {
Expand Down
6 changes: 3 additions & 3 deletions Objects/unionobject.c
@@ -1,4 +1,4 @@
// types.Union -- used to represent e.g. Union[int, str], int | str
// types.UnionType -- used to represent e.g. Union[int, str], int | str
#include "Python.h"
#include "pycore_object.h" // _PyObject_GC_TRACK/UNTRACK
#include "pycore_unionobject.h"
Expand Down Expand Up @@ -414,7 +414,7 @@ union_parameters(PyObject *self, void *Py_UNUSED(unused))
}

static PyGetSetDef union_properties[] = {
{"__parameters__", union_parameters, (setter)NULL, "Type variables in the types.Union.", NULL},
{"__parameters__", union_parameters, (setter)NULL, "Type variables in the types.UnionType.", NULL},
{0}
};

Expand All @@ -424,7 +424,7 @@ static PyNumberMethods union_as_number = {

PyTypeObject _PyUnion_Type = {
PyVarObject_HEAD_INIT(&PyType_Type, 0)
.tp_name = "types.Union",
.tp_name = "types.UnionType",
.tp_doc = "Represent a PEP 604 union type\n"
"\n"
"E.g. for int | str",
Expand Down

0 comments on commit c080ecb

Please sign in to comment.