Merge branch 'master' of https://github.com/python/cpython into tupleify-ga

This commit is contained in:
Fidget-Spinner 2021-01-04 21:41:30 +08:00
commit 7a3cfa41a9
35 changed files with 1864 additions and 1170 deletions

View File

@ -112,14 +112,15 @@ The module :mod:`curses` defines the following functions:
.. function:: color_content(color_number)
Return the intensity of the red, green, and blue (RGB) components in the color
*color_number*, which must be between ``0`` and :const:`COLORS`. Return a 3-tuple,
*color_number*, which must be between ``0`` and ``COLORS - 1``. Return a 3-tuple,
containing the R,G,B values for the given color, which will be between
``0`` (no component) and ``1000`` (maximum amount of component).
.. function:: color_pair(color_number)
.. function:: color_pair(pair_number)
Return the attribute value for displaying text in the specified color. This
Return the attribute value for displaying text in the specified color pair.
Only the first 256 color pairs are supported. This
attribute value can be combined with :const:`A_STANDOUT`, :const:`A_REVERSE`,
and the other :const:`A_\*` attributes. :func:`pair_number` is the counterpart
to this function.
@ -287,7 +288,7 @@ The module :mod:`curses` defines the following functions:
Change the definition of a color, taking the number of the color to be changed
followed by three RGB values (for the amounts of red, green, and blue
components). The value of *color_number* must be between ``0`` and
:const:`COLORS`. Each of *r*, *g*, *b*, must be a value between ``0`` and
`COLORS - 1`. Each of *r*, *g*, *b*, must be a value between ``0`` and
``1000``. When :func:`init_color` is used, all occurrences of that color on the
screen immediately change to the new definition. This function is a no-op on
most terminals; it is active only if :func:`can_change_color` returns ``True``.
@ -300,7 +301,8 @@ The module :mod:`curses` defines the following functions:
color number. The value of *pair_number* must be between ``1`` and
``COLOR_PAIRS - 1`` (the ``0`` color pair is wired to white on black and cannot
be changed). The value of *fg* and *bg* arguments must be between ``0`` and
:const:`COLORS`. If the color-pair was previously initialized, the screen is
``COLORS - 1``, or, after calling :func:`use_default_colors`, ``-1``.
If the color-pair was previously initialized, the screen is
refreshed and all occurrences of that color-pair are changed to the new
definition.
@ -450,7 +452,7 @@ The module :mod:`curses` defines the following functions:
.. function:: pair_content(pair_number)
Return a tuple ``(fg, bg)`` containing the colors for the requested color pair.
The value of *pair_number* must be between ``1`` and ``COLOR_PAIRS - 1``.
The value of *pair_number* must be between ``0`` and ``COLOR_PAIRS - 1``.
.. function:: pair_number(attr)

View File

@ -198,7 +198,7 @@ However, for reading convenience, most of the examples show sorted sequences.
.. versionadded:: 3.6
.. versionchanged:: 3.8
.. versionchanged:: 3.10
Added support for *weights*.
.. function:: median(data)

View File

@ -426,9 +426,11 @@ Optimizations
average.
(Contributed by Victor Stinner in :issue:`41006`.)
* The ``LOAD_ATTR`` instruction now uses new "per opcode cache" mechanism.
It is about 36% faster now. (Contributed by Pablo Galindo and Yury Selivanov
in :issue:`42093`, based on ideas implemented originally in PyPy and MicroPython.)
* The ``LOAD_ATTR`` instruction now uses new "per opcode cache" mechanism. It
is about 36% faster now. This makes optimized ``LOAD_ATTR`` instructions the
current most performance attribute access method (faster than slots).
(Contributed by Pablo Galindo and Yury Selivanov in :issue:`42093`, based on
ideas implemented originally in PyPy and MicroPython.)
* When building Python with ``--enable-optimizations`` now
``-fno-semantic-interposition`` is added to both the compile and link line.

View File

@ -580,18 +580,23 @@ star_targets[expr_ty]:
| a=star_target !',' { a }
| a=star_target b=(',' c=star_target { c })* [','] {
_Py_Tuple(CHECK(asdl_expr_seq*, _PyPegen_seq_insert_in_front(p, a, b)), Store, EXTRA) }
star_targets_seq[asdl_expr_seq*]: a[asdl_expr_seq*]=','.star_target+ [','] { a }
star_targets_list_seq[asdl_expr_seq*]: a[asdl_expr_seq*]=','.star_target+ [','] { a }
star_targets_tuple_seq[asdl_expr_seq*]:
| a=star_target b=(',' c=star_target { c })+ [','] { (asdl_expr_seq*) _PyPegen_seq_insert_in_front(p, a, b) }
| a=star_target ',' { (asdl_expr_seq*) _PyPegen_singleton_seq(p, a) }
star_target[expr_ty] (memo):
| '*' a=(!'*' star_target) {
_Py_Starred(CHECK(expr_ty, _PyPegen_set_expr_context(p, a, Store)), Store, EXTRA) }
| target_with_star_atom
target_with_star_atom[expr_ty] (memo):
| a=t_primary '.' b=NAME !t_lookahead { _Py_Attribute(a, b->v.Name.id, Store, EXTRA) }
| a=t_primary '[' b=slices ']' !t_lookahead { _Py_Subscript(a, b, Store, EXTRA) }
| star_atom
star_atom[expr_ty]:
| a=NAME { _PyPegen_set_expr_context(p, a, Store) }
| '(' a=star_target ')' { _PyPegen_set_expr_context(p, a, Store) }
| '(' a=[star_targets_seq] ')' { _Py_Tuple(a, Store, EXTRA) }
| '[' a=[star_targets_seq] ']' { _Py_List(a, Store, EXTRA) }
| '(' a=target_with_star_atom ')' { _PyPegen_set_expr_context(p, a, Store) }
| '(' a=[star_targets_tuple_seq] ')' { _Py_Tuple(a, Store, EXTRA) }
| '[' a=[star_targets_list_seq] ']' { _Py_List(a, Store, EXTRA) }
single_target[expr_ty]:
| single_subscript_attribute_target

View File

@ -174,7 +174,7 @@ def libc_ver(executable=None, lib='', version='', chunksize=16384):
The file is read and scanned in chunks of chunksize bytes.
"""
if executable is None:
if not executable:
try:
ver = os.confstr('CS_GNU_LIBC_VERSION')
# parse 'glibc 2.28' as ('glibc', '2.28')

View File

@ -96,6 +96,7 @@ LOG4 = _log(4.0)
SG_MAGICCONST = 1.0 + _log(4.5)
BPF = 53 # Number of bits in a float
RECIP_BPF = 2 ** -BPF
_ONE = 1
class Random(_random.Random):
@ -288,7 +289,7 @@ class Random(_random.Random):
## -------------------- integer methods -------------------
def randrange(self, start, stop=None, step=1):
def randrange(self, start, stop=None, step=_ONE):
"""Choose a random item from range(start, stop[, step]).
This fixes the problem with randint() which includes the
@ -311,7 +312,12 @@ class Random(_random.Random):
_warn('randrange() will raise TypeError in the future',
DeprecationWarning, 2)
raise ValueError("non-integer arg 1 for randrange()")
if stop is None:
# We don't check for "step != 1" because it hasn't been
# type checked and converted to an integer yet.
if step is not _ONE:
raise TypeError('Missing a non-None stop argument')
if istart > 0:
return self._randbelow(istart)
raise ValueError("empty range for randrange()")
@ -345,9 +351,9 @@ class Random(_random.Random):
DeprecationWarning, 2)
raise ValueError("non-integer step for randrange()")
width = istop - istart
if istep == 1 and width > 0:
return istart + self._randbelow(width)
if istep == 1:
if width > 0:
return istart + self._randbelow(width)
raise ValueError("empty range for randrange() (%d, %d, %d)" % (istart, istop, width))
# Non-unit step argument supplied.
@ -357,10 +363,8 @@ class Random(_random.Random):
n = (width + istep + 1) // istep
else:
raise ValueError("zero step for randrange()")
if n <= 0:
raise ValueError("empty range for randrange()")
return istart + istep * self._randbelow(n)
def randint(self, a, b):

View File

@ -69,6 +69,10 @@ def count_opcode(code, pickle):
return n
def identity(x):
return x
class UnseekableIO(io.BytesIO):
def peek(self, *args):
raise NotImplementedError
@ -138,11 +142,12 @@ class E(C):
def __getinitargs__(self):
return ()
class H(object):
# Simple mutable object.
class Object:
pass
# Hashable mutable key
class K(object):
# Hashable immutable key object containing unheshable mutable data.
class K:
def __init__(self, value):
self.value = value
@ -157,10 +162,6 @@ __main__.D = D
D.__module__ = "__main__"
__main__.E = E
E.__module__ = "__main__"
__main__.H = H
H.__module__ = "__main__"
__main__.K = K
K.__module__ = "__main__"
class myint(int):
def __init__(self, x):
@ -1496,54 +1497,182 @@ class AbstractPickleTests(unittest.TestCase):
got = filelike.getvalue()
self.assertEqual(expected, got)
def test_recursive_list(self):
l = []
def _test_recursive_list(self, cls, aslist=identity, minprotocol=0):
# List containing itself.
l = cls()
l.append(l)
for proto in protocols:
for proto in range(minprotocol, pickle.HIGHEST_PROTOCOL + 1):
s = self.dumps(l, proto)
x = self.loads(s)
self.assertIsInstance(x, list)
self.assertEqual(len(x), 1)
self.assertIs(x[0], x)
self.assertIsInstance(x, cls)
y = aslist(x)
self.assertEqual(len(y), 1)
self.assertIs(y[0], x)
def test_recursive_tuple_and_list(self):
t = ([],)
def test_recursive_list(self):
self._test_recursive_list(list)
def test_recursive_list_subclass(self):
self._test_recursive_list(MyList, minprotocol=2)
def test_recursive_list_like(self):
self._test_recursive_list(REX_six, aslist=lambda x: x.items)
def _test_recursive_tuple_and_list(self, cls, aslist=identity, minprotocol=0):
# Tuple containing a list containing the original tuple.
t = (cls(),)
t[0].append(t)
for proto in protocols:
for proto in range(minprotocol, pickle.HIGHEST_PROTOCOL + 1):
s = self.dumps(t, proto)
x = self.loads(s)
self.assertIsInstance(x, tuple)
self.assertEqual(len(x), 1)
self.assertIsInstance(x[0], list)
self.assertEqual(len(x[0]), 1)
self.assertIs(x[0][0], x)
self.assertIsInstance(x[0], cls)
y = aslist(x[0])
self.assertEqual(len(y), 1)
self.assertIs(y[0], x)
# List containing a tuple containing the original list.
t, = t
for proto in range(minprotocol, pickle.HIGHEST_PROTOCOL + 1):
s = self.dumps(t, proto)
x = self.loads(s)
self.assertIsInstance(x, cls)
y = aslist(x)
self.assertEqual(len(y), 1)
self.assertIsInstance(y[0], tuple)
self.assertEqual(len(y[0]), 1)
self.assertIs(y[0][0], x)
def test_recursive_tuple_and_list(self):
self._test_recursive_tuple_and_list(list)
def test_recursive_tuple_and_list_subclass(self):
self._test_recursive_tuple_and_list(MyList, minprotocol=2)
def test_recursive_tuple_and_list_like(self):
self._test_recursive_tuple_and_list(REX_six, aslist=lambda x: x.items)
def _test_recursive_dict(self, cls, asdict=identity, minprotocol=0):
# Dict containing itself.
d = cls()
d[1] = d
for proto in range(minprotocol, pickle.HIGHEST_PROTOCOL + 1):
s = self.dumps(d, proto)
x = self.loads(s)
self.assertIsInstance(x, cls)
y = asdict(x)
self.assertEqual(list(y.keys()), [1])
self.assertIs(y[1], x)
def test_recursive_dict(self):
d = {}
d[1] = d
for proto in protocols:
self._test_recursive_dict(dict)
def test_recursive_dict_subclass(self):
self._test_recursive_dict(MyDict, minprotocol=2)
def test_recursive_dict_like(self):
self._test_recursive_dict(REX_seven, asdict=lambda x: x.table)
def _test_recursive_tuple_and_dict(self, cls, asdict=identity, minprotocol=0):
# Tuple containing a dict containing the original tuple.
t = (cls(),)
t[0][1] = t
for proto in range(minprotocol, pickle.HIGHEST_PROTOCOL + 1):
s = self.dumps(t, proto)
x = self.loads(s)
self.assertIsInstance(x, tuple)
self.assertEqual(len(x), 1)
self.assertIsInstance(x[0], cls)
y = asdict(x[0])
self.assertEqual(list(y), [1])
self.assertIs(y[1], x)
# Dict containing a tuple containing the original dict.
t, = t
for proto in range(minprotocol, pickle.HIGHEST_PROTOCOL + 1):
s = self.dumps(t, proto)
x = self.loads(s)
self.assertIsInstance(x, cls)
y = asdict(x)
self.assertEqual(list(y), [1])
self.assertIsInstance(y[1], tuple)
self.assertEqual(len(y[1]), 1)
self.assertIs(y[1][0], x)
def test_recursive_tuple_and_dict(self):
self._test_recursive_tuple_and_dict(dict)
def test_recursive_tuple_and_dict_subclass(self):
self._test_recursive_tuple_and_dict(MyDict, minprotocol=2)
def test_recursive_tuple_and_dict_like(self):
self._test_recursive_tuple_and_dict(REX_seven, asdict=lambda x: x.table)
def _test_recursive_dict_key(self, cls, asdict=identity, minprotocol=0):
# Dict containing an immutable object (as key) containing the original
# dict.
d = cls()
d[K(d)] = 1
for proto in range(minprotocol, pickle.HIGHEST_PROTOCOL + 1):
s = self.dumps(d, proto)
x = self.loads(s)
self.assertIsInstance(x, dict)
self.assertEqual(list(x.keys()), [1])
self.assertIs(x[1], x)
self.assertIsInstance(x, cls)
y = asdict(x)
self.assertEqual(len(y.keys()), 1)
self.assertIsInstance(list(y.keys())[0], K)
self.assertIs(list(y.keys())[0].value, x)
def test_recursive_dict_key(self):
d = {}
k = K(d)
d[k] = 1
for proto in protocols:
s = self.dumps(d, proto)
self._test_recursive_dict_key(dict)
def test_recursive_dict_subclass_key(self):
self._test_recursive_dict_key(MyDict, minprotocol=2)
def test_recursive_dict_like_key(self):
self._test_recursive_dict_key(REX_seven, asdict=lambda x: x.table)
def _test_recursive_tuple_and_dict_key(self, cls, asdict=identity, minprotocol=0):
# Tuple containing a dict containing an immutable object (as key)
# containing the original tuple.
t = (cls(),)
t[0][K(t)] = 1
for proto in range(minprotocol, pickle.HIGHEST_PROTOCOL + 1):
s = self.dumps(t, proto)
x = self.loads(s)
self.assertIsInstance(x, dict)
self.assertEqual(len(x.keys()), 1)
self.assertIsInstance(list(x.keys())[0], K)
self.assertIs(list(x.keys())[0].value, x)
self.assertIsInstance(x, tuple)
self.assertEqual(len(x), 1)
self.assertIsInstance(x[0], cls)
y = asdict(x[0])
self.assertEqual(len(y), 1)
self.assertIsInstance(list(y.keys())[0], K)
self.assertIs(list(y.keys())[0].value, x)
# Dict containing an immutable object (as key) containing a tuple
# containing the original dict.
t, = t
for proto in range(minprotocol, pickle.HIGHEST_PROTOCOL + 1):
s = self.dumps(t, proto)
x = self.loads(s)
self.assertIsInstance(x, cls)
y = asdict(x)
self.assertEqual(len(y), 1)
self.assertIsInstance(list(y.keys())[0], K)
self.assertIs(list(y.keys())[0].value[0], x)
def test_recursive_tuple_and_dict_key(self):
self._test_recursive_tuple_and_dict_key(dict)
def test_recursive_tuple_and_dict_subclass_key(self):
self._test_recursive_tuple_and_dict_key(MyDict, minprotocol=2)
def test_recursive_tuple_and_dict_like_key(self):
self._test_recursive_tuple_and_dict_key(REX_seven, asdict=lambda x: x.table)
def test_recursive_set(self):
# Set containing an immutable object containing the original set.
y = set()
k = K(y)
y.add(k)
y.add(K(y))
for proto in range(4, pickle.HIGHEST_PROTOCOL + 1):
s = self.dumps(y, proto)
x = self.loads(s)
@ -1552,52 +1681,31 @@ class AbstractPickleTests(unittest.TestCase):
self.assertIsInstance(list(x)[0], K)
self.assertIs(list(x)[0].value, x)
def test_recursive_list_subclass(self):
y = MyList()
y.append(y)
for proto in range(2, pickle.HIGHEST_PROTOCOL + 1):
# Immutable object containing a set containing the original object.
y, = y
for proto in range(4, pickle.HIGHEST_PROTOCOL + 1):
s = self.dumps(y, proto)
x = self.loads(s)
self.assertIsInstance(x, MyList)
self.assertEqual(len(x), 1)
self.assertIs(x[0], x)
def test_recursive_dict_subclass(self):
d = MyDict()
d[1] = d
for proto in range(2, pickle.HIGHEST_PROTOCOL + 1):
s = self.dumps(d, proto)
x = self.loads(s)
self.assertIsInstance(x, MyDict)
self.assertEqual(list(x.keys()), [1])
self.assertIs(x[1], x)
def test_recursive_dict_subclass_key(self):
d = MyDict()
k = K(d)
d[k] = 1
for proto in range(2, pickle.HIGHEST_PROTOCOL + 1):
s = self.dumps(d, proto)
x = self.loads(s)
self.assertIsInstance(x, MyDict)
self.assertEqual(len(list(x.keys())), 1)
self.assertIsInstance(list(x.keys())[0], K)
self.assertIs(list(x.keys())[0].value, x)
self.assertIsInstance(x, K)
self.assertIsInstance(x.value, set)
self.assertEqual(len(x.value), 1)
self.assertIs(list(x.value)[0], x)
def test_recursive_inst(self):
i = C()
# Mutable object containing itself.
i = Object()
i.attr = i
for proto in protocols:
s = self.dumps(i, proto)
x = self.loads(s)
self.assertIsInstance(x, C)
self.assertIsInstance(x, Object)
self.assertEqual(dir(x), dir(i))
self.assertIs(x.attr, x)
def test_recursive_multi(self):
l = []
d = {1:l}
i = C()
i = Object()
i.attr = d
l.append(i)
for proto in protocols:
@ -1607,49 +1715,94 @@ class AbstractPickleTests(unittest.TestCase):
self.assertEqual(len(x), 1)
self.assertEqual(dir(x[0]), dir(i))
self.assertEqual(list(x[0].attr.keys()), [1])
self.assertTrue(x[0].attr[1] is x)
self.assertIs(x[0].attr[1], x)
def check_recursive_collection_and_inst(self, factory):
h = H()
y = factory([h])
h.attr = y
def _test_recursive_collection_and_inst(self, factory):
# Mutable object containing a collection containing the original
# object.
o = Object()
o.attr = factory([o])
t = type(o.attr)
for proto in protocols:
s = self.dumps(y, proto)
s = self.dumps(o, proto)
x = self.loads(s)
self.assertIsInstance(x, type(y))
self.assertIsInstance(x.attr, t)
self.assertEqual(len(x.attr), 1)
self.assertIsInstance(list(x.attr)[0], Object)
self.assertIs(list(x.attr)[0], x)
# Collection containing a mutable object containing the original
# collection.
o = o.attr
for proto in protocols:
s = self.dumps(o, proto)
x = self.loads(s)
self.assertIsInstance(x, t)
self.assertEqual(len(x), 1)
self.assertIsInstance(list(x)[0], H)
self.assertIsInstance(list(x)[0], Object)
self.assertIs(list(x)[0].attr, x)
def test_recursive_list_and_inst(self):
self.check_recursive_collection_and_inst(list)
self._test_recursive_collection_and_inst(list)
def test_recursive_tuple_and_inst(self):
self.check_recursive_collection_and_inst(tuple)
self._test_recursive_collection_and_inst(tuple)
def test_recursive_dict_and_inst(self):
self.check_recursive_collection_and_inst(dict.fromkeys)
self._test_recursive_collection_and_inst(dict.fromkeys)
def test_recursive_set_and_inst(self):
self.check_recursive_collection_and_inst(set)
self._test_recursive_collection_and_inst(set)
def test_recursive_frozenset_and_inst(self):
self.check_recursive_collection_and_inst(frozenset)
self._test_recursive_collection_and_inst(frozenset)
def test_recursive_list_subclass_and_inst(self):
self.check_recursive_collection_and_inst(MyList)
self._test_recursive_collection_and_inst(MyList)
def test_recursive_tuple_subclass_and_inst(self):
self.check_recursive_collection_and_inst(MyTuple)
self._test_recursive_collection_and_inst(MyTuple)
def test_recursive_dict_subclass_and_inst(self):
self.check_recursive_collection_and_inst(MyDict.fromkeys)
self._test_recursive_collection_and_inst(MyDict.fromkeys)
def test_recursive_set_subclass_and_inst(self):
self.check_recursive_collection_and_inst(MySet)
self._test_recursive_collection_and_inst(MySet)
def test_recursive_frozenset_subclass_and_inst(self):
self.check_recursive_collection_and_inst(MyFrozenSet)
self._test_recursive_collection_and_inst(MyFrozenSet)
def test_recursive_inst_state(self):
# Mutable object containing itself.
y = REX_state()
y.state = y
for proto in protocols:
s = self.dumps(y, proto)
x = self.loads(s)
self.assertIsInstance(x, REX_state)
self.assertIs(x.state, x)
def test_recursive_tuple_and_inst_state(self):
# Tuple containing a mutable object containing the original tuple.
t = (REX_state(),)
t[0].state = t
for proto in protocols:
s = self.dumps(t, proto)
x = self.loads(s)
self.assertIsInstance(x, tuple)
self.assertEqual(len(x), 1)
self.assertIsInstance(x[0], REX_state)
self.assertIs(x[0].state, x)
# Mutable object containing a tuple containing the object.
t, = t
for proto in protocols:
s = self.dumps(t, proto)
x = self.loads(s)
self.assertIsInstance(x, REX_state)
self.assertIsInstance(x.state, tuple)
self.assertEqual(len(x.state), 1)
self.assertIs(x.state[0], x)
def test_unicode(self):
endcases = ['', '<\\u>', '<\\\u1234>', '<\n>',
@ -3062,6 +3215,19 @@ class REX_seven(object):
def __reduce__(self):
return type(self), (), None, None, iter(self.table.items())
class REX_state(object):
"""This class is used to check the 3th argument (state) of
the reduce protocol.
"""
def __init__(self, state=None):
self.state = state
def __eq__(self, other):
return type(self) is type(other) and self.state == other.state
def __setstate__(self, state):
self.state = state
def __reduce__(self):
return type(self), (), self.state
# Test classes for newobj

View File

@ -4,8 +4,7 @@
# This script doesn't actually display anything very coherent. but it
# does call (nearly) every method and function.
#
# Functions not tested: {def,reset}_{shell,prog}_mode, getch(), getstr(),
# init_color()
# Functions not tested: {def,reset}_{shell,prog}_mode, getch(), getstr()
# Only called, not tested: getmouse(), ungetmouse()
#
@ -13,6 +12,7 @@ import os
import string
import sys
import tempfile
import functools
import unittest
from test.support import requires, verbose, SaveSignals
@ -37,6 +37,15 @@ def requires_curses_func(name):
return unittest.skipUnless(hasattr(curses, name),
'requires curses.%s' % name)
def requires_colors(test):
@functools.wraps(test)
def wrapped(self, *args, **kwargs):
if not curses.has_colors():
self.skipTest('requires colors support')
curses.start_color()
test(self, *args, **kwargs)
return wrapped
term = os.environ.get('TERM')
# If newterm was supported we could use it instead of initscr and not exit
@ -48,37 +57,59 @@ class TestCurses(unittest.TestCase):
@classmethod
def setUpClass(cls):
if not sys.__stdout__.isatty():
# Temporary skip tests on non-tty
raise unittest.SkipTest('sys.__stdout__ is not a tty')
cls.tmp = tempfile.TemporaryFile()
fd = cls.tmp.fileno()
else:
cls.tmp = None
fd = sys.__stdout__.fileno()
if verbose:
print(f'TERM={term}', file=sys.stderr, flush=True)
# testing setupterm() inside initscr/endwin
# causes terminal breakage
curses.setupterm(fd=fd)
@classmethod
def tearDownClass(cls):
if cls.tmp:
cls.tmp.close()
del cls.tmp
stdout_fd = sys.__stdout__.fileno()
curses.setupterm(fd=stdout_fd)
def setUp(self):
self.isatty = True
self.output = sys.__stdout__
stdout_fd = sys.__stdout__.fileno()
if not sys.__stdout__.isatty():
# initstr() unconditionally uses C stdout.
# If it is redirected to file or pipe, try to attach it
# to terminal.
# First, save a copy of the file descriptor of stdout, so it
# can be restored after finishing the test.
dup_fd = os.dup(stdout_fd)
self.addCleanup(os.close, dup_fd)
self.addCleanup(os.dup2, dup_fd, stdout_fd)
if sys.__stderr__.isatty():
# If stderr is connected to terminal, use it.
tmp = sys.__stderr__
self.output = sys.__stderr__
else:
try:
# Try to open the terminal device.
tmp = open('/dev/tty', 'wb', buffering=0)
except OSError:
# As a fallback, use regular file to write control codes.
# Some functions (like savetty) will not work, but at
# least the garbage control sequences will not be mixed
# with the testing report.
tmp = tempfile.TemporaryFile(mode='wb', buffering=0)
self.isatty = False
self.addCleanup(tmp.close)
self.output = None
os.dup2(tmp.fileno(), stdout_fd)
self.save_signals = SaveSignals()
self.save_signals.save()
if verbose:
self.addCleanup(self.save_signals.restore)
if verbose and self.output is not None:
# just to make the test output a little more readable
print()
sys.stderr.flush()
sys.stdout.flush()
print(file=self.output, flush=True)
self.stdscr = curses.initscr()
curses.savetty()
def tearDown(self):
curses.resetty()
curses.endwin()
self.save_signals.restore()
if self.isatty:
curses.savetty()
self.addCleanup(curses.endwin)
self.addCleanup(curses.resetty)
def test_window_funcs(self):
"Test the methods of windows"
@ -96,7 +127,7 @@ class TestCurses(unittest.TestCase):
for meth in [stdscr.clear, stdscr.clrtobot,
stdscr.clrtoeol, stdscr.cursyncup, stdscr.delch,
stdscr.deleteln, stdscr.erase, stdscr.getbegyx,
stdscr.getbkgd, stdscr.getkey, stdscr.getmaxyx,
stdscr.getbkgd, stdscr.getmaxyx,
stdscr.getparyx, stdscr.getyx, stdscr.inch,
stdscr.insertln, stdscr.instr, stdscr.is_wintouched,
win.noutrefresh, stdscr.redrawwin, stdscr.refresh,
@ -207,6 +238,11 @@ class TestCurses(unittest.TestCase):
if hasattr(stdscr, 'enclose'):
stdscr.enclose(10, 10)
with tempfile.TemporaryFile() as f:
self.stdscr.putwin(f)
f.seek(0)
curses.getwin(f)
self.assertRaises(ValueError, stdscr.getstr, -400)
self.assertRaises(ValueError, stdscr.getstr, 2, 3, -400)
self.assertRaises(ValueError, stdscr.instr, -2)
@ -225,17 +261,20 @@ class TestCurses(unittest.TestCase):
def test_module_funcs(self):
"Test module-level functions"
for func in [curses.baudrate, curses.beep, curses.can_change_color,
curses.cbreak, curses.def_prog_mode, curses.doupdate,
curses.flash, curses.flushinp,
curses.doupdate, curses.flash, curses.flushinp,
curses.has_colors, curses.has_ic, curses.has_il,
curses.isendwin, curses.killchar, curses.longname,
curses.nocbreak, curses.noecho, curses.nonl,
curses.noqiflush, curses.noraw,
curses.reset_prog_mode, curses.termattrs,
curses.termname, curses.erasechar,
curses.noecho, curses.nonl, curses.noqiflush,
curses.termattrs, curses.termname, curses.erasechar,
curses.has_extended_color_support]:
with self.subTest(func=func.__qualname__):
func()
if self.isatty:
for func in [curses.cbreak, curses.def_prog_mode,
curses.nocbreak, curses.noraw,
curses.reset_prog_mode]:
with self.subTest(func=func.__qualname__):
func()
if hasattr(curses, 'filter'):
curses.filter()
if hasattr(curses, 'getsyx'):
@ -247,13 +286,9 @@ class TestCurses(unittest.TestCase):
curses.delay_output(1)
curses.echo() ; curses.echo(1)
with tempfile.TemporaryFile() as f:
self.stdscr.putwin(f)
f.seek(0)
curses.getwin(f)
curses.halfdelay(1)
curses.intrflush(1)
if self.isatty:
curses.intrflush(1)
curses.meta(1)
curses.napms(100)
curses.newpad(50,50)
@ -262,7 +297,8 @@ class TestCurses(unittest.TestCase):
curses.nl() ; curses.nl(1)
curses.putp(b'abc')
curses.qiflush()
curses.raw() ; curses.raw(1)
if self.isatty:
curses.raw() ; curses.raw(1)
curses.set_escdelay(25)
self.assertEqual(curses.get_escdelay(), 25)
curses.set_tabsize(4)
@ -281,31 +317,101 @@ class TestCurses(unittest.TestCase):
curses.use_env(1)
# Functions only available on a few platforms
def test_colors_funcs(self):
if not curses.has_colors():
self.skipTest('requires colors support')
curses.start_color()
curses.init_pair(2, 1,1)
curses.color_content(1)
curses.color_pair(2)
def bad_colors(self):
return (-1, curses.COLORS, -2**31 - 1, 2**31, -2**63 - 1, 2**63, 2**64)
def bad_colors2(self):
return (curses.COLORS, 2**31, 2**63, 2**64)
def bad_pairs(self):
return (-1, -2**31 - 1, 2**31, -2**63 - 1, 2**63, 2**64)
@requires_colors
def test_color_content(self):
self.assertEqual(curses.color_content(curses.COLOR_BLACK), (0, 0, 0))
curses.color_content(0)
curses.color_content(curses.COLORS - 1)
for color in self.bad_colors():
self.assertRaises(ValueError, curses.color_content, color)
@requires_colors
def test_init_color(self):
if not curses.can_change_color:
self.skipTest('cannot change color')
old = curses.color_content(0)
try:
curses.init_color(0, *old)
except curses.error:
self.skipTest('cannot change color (init_color() failed)')
self.addCleanup(curses.init_color, 0, *old)
curses.init_color(0, 0, 0, 0)
self.assertEqual(curses.color_content(0), (0, 0, 0))
curses.init_color(0, 1000, 1000, 1000)
self.assertEqual(curses.color_content(0), (1000, 1000, 1000))
old = curses.color_content(curses.COLORS - 1)
curses.init_color(curses.COLORS - 1, *old)
self.addCleanup(curses.init_color, curses.COLORS - 1, *old)
curses.init_color(curses.COLORS - 1, 0, 500, 1000)
self.assertEqual(curses.color_content(curses.COLORS - 1), (0, 500, 1000))
for color in self.bad_colors():
self.assertRaises(ValueError, curses.init_color, color, 0, 0, 0)
for comp in (-1, 1001):
self.assertRaises(ValueError, curses.init_color, 0, comp, 0, 0)
self.assertRaises(ValueError, curses.init_color, 0, 0, comp, 0)
self.assertRaises(ValueError, curses.init_color, 0, 0, 0, comp)
@requires_colors
def test_pair_content(self):
if not hasattr(curses, 'use_default_colors'):
self.assertEqual(curses.pair_content(0),
(curses.COLOR_WHITE, curses.COLOR_BLACK))
curses.pair_content(0)
curses.pair_content(curses.COLOR_PAIRS - 1)
curses.pair_number(0)
if hasattr(curses, 'use_default_colors'):
curses.use_default_colors()
for pair in self.bad_pairs():
self.assertRaises(ValueError, curses.pair_content, pair)
self.assertRaises(ValueError, curses.color_content, -1)
self.assertRaises(ValueError, curses.color_content, curses.COLORS + 1)
self.assertRaises(ValueError, curses.color_content, -2**31 - 1)
self.assertRaises(ValueError, curses.color_content, 2**31)
self.assertRaises(ValueError, curses.color_content, -2**63 - 1)
self.assertRaises(ValueError, curses.color_content, 2**63 - 1)
self.assertRaises(ValueError, curses.pair_content, -1)
self.assertRaises(ValueError, curses.pair_content, curses.COLOR_PAIRS)
self.assertRaises(ValueError, curses.pair_content, -2**31 - 1)
self.assertRaises(ValueError, curses.pair_content, 2**31)
self.assertRaises(ValueError, curses.pair_content, -2**63 - 1)
self.assertRaises(ValueError, curses.pair_content, 2**63 - 1)
@requires_colors
def test_init_pair(self):
old = curses.pair_content(1)
curses.init_pair(1, *old)
self.addCleanup(curses.init_pair, 1, *old)
curses.init_pair(1, 0, 0)
self.assertEqual(curses.pair_content(1), (0, 0))
curses.init_pair(1, curses.COLORS - 1, curses.COLORS - 1)
self.assertEqual(curses.pair_content(1),
(curses.COLORS - 1, curses.COLORS - 1))
curses.init_pair(curses.COLOR_PAIRS - 1, 2, 3)
self.assertEqual(curses.pair_content(curses.COLOR_PAIRS - 1), (2, 3))
for pair in self.bad_pairs():
self.assertRaises(ValueError, curses.init_pair, pair, 0, 0)
for color in self.bad_colors2():
self.assertRaises(ValueError, curses.init_pair, 1, color, 0)
self.assertRaises(ValueError, curses.init_pair, 1, 0, color)
@requires_colors
def test_color_attrs(self):
for pair in 0, 1, 255:
attr = curses.color_pair(pair)
self.assertEqual(curses.pair_number(attr), pair, attr)
self.assertEqual(curses.pair_number(attr | curses.A_BOLD), pair)
self.assertEqual(curses.color_pair(0), 0)
self.assertEqual(curses.pair_number(0), 0)
@requires_curses_func('use_default_colors')
@requires_colors
def test_use_default_colors(self):
self.assertIn(curses.pair_content(0),
((curses.COLOR_WHITE, curses.COLOR_BLACK), (-1, -1)))
curses.use_default_colors()
self.assertEqual(curses.pair_content(0), (-1, -1))
@requires_curses_func('keyname')
def test_keyname(self):
@ -373,7 +479,6 @@ class TestCurses(unittest.TestCase):
@requires_curses_func('resizeterm')
def test_resizeterm(self):
stdscr = self.stdscr
lines, cols = curses.LINES, curses.COLS
new_lines = lines - 1
new_cols = cols + 1

View File

@ -332,6 +332,59 @@ non-important content
self.assertEqual(binop.left.col_offset, 4)
self.assertEqual(binop.right.col_offset, 7)
def test_ast_line_numbers_with_parentheses(self):
expr = """
x = (
f" {test(t)}"
)"""
t = ast.parse(expr)
self.assertEqual(type(t), ast.Module)
self.assertEqual(len(t.body), 1)
# check the test(t) location
call = t.body[0].value.values[1].value
self.assertEqual(type(call), ast.Call)
self.assertEqual(call.lineno, 3)
self.assertEqual(call.end_lineno, 3)
self.assertEqual(call.col_offset, 8)
self.assertEqual(call.end_col_offset, 15)
expr = """
x = (
'PERL_MM_OPT', (
f'wat'
f'some_string={f(x)} '
f'wat'
),
)
"""
t = ast.parse(expr)
self.assertEqual(type(t), ast.Module)
self.assertEqual(len(t.body), 1)
# check the fstring
fstring = t.body[0].value.elts[1]
self.assertEqual(type(fstring), ast.JoinedStr)
self.assertEqual(len(fstring.values), 3)
wat1, middle, wat2 = fstring.values
# check the first wat
self.assertEqual(type(wat1), ast.Constant)
self.assertEqual(wat1.lineno, 4)
self.assertEqual(wat1.end_lineno, 6)
self.assertEqual(wat1.col_offset, 12)
self.assertEqual(wat1.end_col_offset, 18)
# check the call
call = middle.value
self.assertEqual(type(call), ast.Call)
self.assertEqual(call.lineno, 5)
self.assertEqual(call.end_lineno, 5)
self.assertEqual(call.col_offset, 27)
self.assertEqual(call.end_col_offset, 31)
# check the second wat
self.assertEqual(type(wat2), ast.Constant)
self.assertEqual(wat2.lineno, 4)
self.assertEqual(wat2.end_lineno, 6)
self.assertEqual(wat2.col_offset, 12)
self.assertEqual(wat2.end_col_offset, 18)
def test_docstring(self):
def f():
f'''Not a docstring'''

View File

@ -562,6 +562,14 @@ class SystemRandom_TestBasicOps(TestBasicOps, unittest.TestCase):
with self.assertRaises(ValueError):
randrange(10, 20, 1.5)
def test_randrange_step(self):
# bpo-42772: When stop is None, the step argument was being ignored.
randrange = self.gen.randrange
with self.assertRaises(TypeError):
randrange(1000, step=100)
with self.assertRaises(TypeError):
randrange(1000, None, step=100)
def test_randbelow_logic(self, _log=log, int=int):
# check bitcount transition points: 2**i and 2**(i+1)-1
# show that: k = int(1.001 + _log(n, 2))

View File

@ -737,6 +737,16 @@ class TypesTests(unittest.TestCase):
with self.assertRaises(ZeroDivisionError):
list[int] | list[bt]
union_ga = (int | list[str], int | collections.abc.Callable[..., str],
int | d)
# Raise error when isinstance(type, type | genericalias)
for type_ in union_ga:
with self.subTest(f"check isinstance/issubclass is invalid for {type_}"):
with self.assertRaises(TypeError):
isinstance(list, type_)
with self.assertRaises(TypeError):
issubclass(list, type_)
def test_ellipsis_type(self):
self.assertIsInstance(Ellipsis, types.EllipsisType)

View File

@ -346,6 +346,31 @@ Now some general starred expressions (all fail).
...
SyntaxError: can't use starred expression here
>>> (*x),y = 1, 2 # doctest:+ELLIPSIS
Traceback (most recent call last):
...
SyntaxError: can't use starred expression here
>>> (((*x))),y = 1, 2 # doctest:+ELLIPSIS
Traceback (most recent call last):
...
SyntaxError: can't use starred expression here
>>> z,(*x),y = 1, 2, 4 # doctest:+ELLIPSIS
Traceback (most recent call last):
...
SyntaxError: can't use starred expression here
>>> z,(*x) = 1, 2 # doctest:+ELLIPSIS
Traceback (most recent call last):
...
SyntaxError: can't use starred expression here
>>> ((*x),y) = 1, 2 # doctest:+ELLIPSIS
Traceback (most recent call last):
...
SyntaxError: can't use starred expression here
Some size constraints (all fail.)
>>> s = ", ".join("a%d" % i for i in range(1<<8)) + ", *rest = range(1<<8 + 1)"

View File

@ -242,15 +242,12 @@ def library_recipes():
result.extend([
dict(
name="OpenSSL 1.1.1g",
url="https://www.openssl.org/source/openssl-1.1.1g.tar.gz",
checksum='76766e98997660138cdaf13a187bd234',
name="OpenSSL 1.1.1i",
url="https://www.openssl.org/source/openssl-1.1.1i.tar.gz",
checksum='08987c3cf125202e2b0840035efb392c',
buildrecipe=build_universal_openssl,
configure=None,
install=None,
patches=[
"openssl-mac-arm64.patch",
],
),
])
@ -263,10 +260,10 @@ def library_recipes():
tk_patches = ['tk868_on_10_8_10_9.patch']
else:
tcl_tk_ver='8.6.10'
tcl_checksum='97c55573f8520bcab74e21bfd8d0aadc'
tcl_tk_ver='8.6.11'
tcl_checksum='8a4c004f48984a03a7747e9ba06e4da4'
tk_checksum='602a47ad9ecac7bf655ada729d140a94'
tk_checksum='c7ee71a2d05bba78dfffd76528dc17c6'
tk_patches = [ ]
@ -357,9 +354,9 @@ def library_recipes():
),
),
dict(
name="SQLite 3.33.0",
url="https://sqlite.org/2020/sqlite-autoconf-3330000.tar.gz",
checksum='842a8a100d7b01b09e543deb2b7951dd',
name="SQLite 3.34.0",
url="https://sqlite.org/2020/sqlite-autoconf-3340000.tar.gz",
checksum='7f33c9db7b713957fcb9271fe9049fef',
extra_cflags=('-Os '
'-DSQLITE_ENABLE_FTS5 '
'-DSQLITE_ENABLE_FTS4 '
@ -1138,7 +1135,6 @@ def buildPythonDocs():
if not os.path.exists(htmlDir):
# Create virtual environment for docs builds with blurb and sphinx
runCommand('make venv')
runCommand('venv/bin/python3 -m pip install -U Sphinx==2.3.1')
runCommand('make html PYTHON=venv/bin/python')
os.rename(htmlDir, docdir)
os.chdir(curDir)
@ -1615,7 +1611,7 @@ def buildDMG():
if os.path.exists(outdir):
shutil.rmtree(outdir)
# We used to use the deployment target as the last characters of the
# We used to use the deployment target as the last characters of the
# installer file name. With the introduction of weaklinked installer
# variants, we may have two variants with the same file name, i.e.
# both ending in '10.9'. To avoid this, we now use the major/minor

View File

@ -1,41 +0,0 @@
diff -ur openssl-1.1.1g-orig/Configurations/10-main.conf openssl-1.1.1g/Configurations/10-main.conf
--- openssl-1.1.1g-orig/Configurations/10-main.conf 2020-04-21 14:22:39.000000000 +0200
+++ openssl-1.1.1g/Configurations/10-main.conf 2020-07-26 12:21:32.000000000 +0200
@@ -1557,6 +1557,14 @@
bn_ops => "SIXTY_FOUR_BIT_LONG",
perlasm_scheme => "macosx",
},
+ "darwin64-arm64-cc" => {
+ inherit_from => [ "darwin-common", asm("aarch64_asm") ],
+ CFLAGS => add("-Wall"),
+ cflags => add("-arch arm64"),
+ lib_cppflags => add("-DL_ENDIAN"),
+ bn_ops => "SIXTY_FOUR_BIT_LONG",
+ perlasm_scheme => "ios64",
+ },
##### GNU Hurd
"hurd-x86" => {
diff -ur openssl-1.1.1g-orig/config openssl-1.1.1g/config
--- openssl-1.1.1g-orig/config 2020-04-21 14:22:39.000000000 +0200
+++ openssl-1.1.1g/config 2020-07-26 12:21:59.000000000 +0200
@@ -255,6 +255,9 @@
;;
x86_64)
echo "x86_64-apple-darwin${VERSION}"
+ ;;
+ arm64)
+ echo "arm64-apple-darwin${VERSION}"
;;
*)
echo "i686-apple-darwin${VERSION}"
@@ -497,6 +500,9 @@
else
OUT="darwin64-x86_64-cc"
fi ;;
+ x86_64-apple-darwin*)
+ OUT="darwin64-arm64-cc"
+ ;;
armv6+7-*-iphoneos)
__CNF_CFLAGS="$__CNF_CFLAGS -arch armv6 -arch armv7"
__CNF_CXXFLAGS="$__CNF_CXXFLAGS -arch armv6 -arch armv7"

View File

@ -0,0 +1 @@
Fix __builtin_available check on older compilers. Patch by Joshua Root.

View File

@ -0,0 +1 @@
Convert :mod:`array` to use heap types, and establish module state for these.

View File

@ -0,0 +1,2 @@
Fix regression where a single parenthesized starred expression was a valid
assignment target.

View File

@ -0,0 +1,2 @@
Fix the column offsets for f-strings :mod:`ast` nodes surrounded by
parentheses and for nodes that spawn multiple lines. Patch by Pablo Galindo.

View File

@ -0,0 +1 @@
Fix undefined behavior in ``Objects/genericaliasobject.c``.

View File

@ -0,0 +1 @@
Fixed range checks for color and pair numbers in :mod:`curses`.

View File

@ -0,0 +1,2 @@
randrange() now raises a TypeError when step is specified without a stop
argument. Formerly, it silently ignored the step argument.

View File

@ -0,0 +1 @@
Handle empty string in variable executable in platform.libc_ver()

View File

@ -0,0 +1 @@
Update macOS installer to use SQLite 3.34.0.

View File

@ -0,0 +1 @@
Update macOS installer build to use OpenSSL 1.1.1i.

View File

@ -0,0 +1,2 @@
Update macOS installer build to use Tcl/Tk 8.6.11 (rc2, expected to be final
release).

View File

@ -155,10 +155,8 @@ typedef chtype attr_t; /* No attr_t type is available */
#define _CURSES_PAIR_NUMBER_FUNC pair_content
#endif /* _NCURSES_EXTENDED_COLOR_FUNCS */
#define _CURSES_FUNC_NAME_STR(s) #s
#define _CURSES_INIT_COLOR_FUNC_NAME _CURSES_FUNC_NAME_STR(_CURSES_INIT_COLOR_FUNC)
#define _CURSES_INIT_PAIR_FUNC_NAME _CURSES_FUNC_NAME_STR(_CURSES_INIT_PAIR_FUNC)
#define _CURSES_INIT_COLOR_FUNC_NAME Py_STRINGIFY(_CURSES_INIT_COLOR_FUNC)
#define _CURSES_INIT_PAIR_FUNC_NAME Py_STRINGIFY(_CURSES_INIT_PAIR_FUNC)
/*[clinic input]
module _curses
@ -202,18 +200,6 @@ static char *screen_encoding = NULL;
/* Utility Functions */
static inline int
color_pair_to_attr(short color_number)
{
return ((int)color_number << 8);
}
static inline short
attr_to_color_pair(int attr)
{
return (short)((attr & A_COLOR) >> 8);
}
/*
* Check the return code from a curses function and return None
* or raise an exception as appropriate. These are exported using the
@ -414,7 +400,7 @@ PyCurses_ConvertToString(PyCursesWindowObject *win, PyObject *obj,
}
static int
color_converter(PyObject *arg, void *ptr)
color_allow_default_converter(PyObject *arg, void *ptr)
{
long color_number;
int overflow;
@ -423,19 +409,31 @@ color_converter(PyObject *arg, void *ptr)
if (color_number == -1 && PyErr_Occurred())
return 0;
if (overflow > 0 || color_number > COLORS) {
if (overflow > 0 || color_number >= COLORS) {
PyErr_Format(PyExc_ValueError,
"Color number is greater than COLORS (%d).",
COLORS);
"Color number is greater than COLORS-1 (%d).",
COLORS - 1);
return 0;
}
else if (overflow < 0 || color_number < 0) {
color_number = -1;
}
*(int *)ptr = (int)color_number;
return 1;
}
static int
color_converter(PyObject *arg, void *ptr)
{
if (!color_allow_default_converter(arg, ptr)) {
return 0;
}
if (*(int *)ptr < 0) {
PyErr_SetString(PyExc_ValueError,
"Color number is less than 0.");
return 0;
}
*(int *)ptr = (int)color_number;
return 1;
}
@ -446,6 +444,13 @@ class color_converter(CConverter):
[python start generated code]*/
/*[python end generated code: output=da39a3ee5e6b4b0d input=4260d2b6e66b3709]*/
/*[python input]
class color_allow_default_converter(CConverter):
type = 'int'
converter = 'color_allow_default_converter'
[python start generated code]*/
/*[python end generated code: output=da39a3ee5e6b4b0d input=975602bc058a872d]*/
static int
pair_converter(PyObject *arg, void *ptr)
{
@ -456,15 +461,24 @@ pair_converter(PyObject *arg, void *ptr)
if (pair_number == -1 && PyErr_Occurred())
return 0;
if (overflow > 0 || pair_number > COLOR_PAIRS - 1) {
#if _NCURSES_EXTENDED_COLOR_FUNCS
if (overflow > 0 || pair_number > INT_MAX) {
PyErr_Format(PyExc_ValueError,
"Color pair is greater than maximum (%d).",
INT_MAX);
return 0;
}
#else
if (overflow > 0 || pair_number >= COLOR_PAIRS) {
PyErr_Format(PyExc_ValueError,
"Color pair is greater than COLOR_PAIRS-1 (%d).",
COLOR_PAIRS - 1);
return 0;
}
else if (overflow < 0 || pair_number < 1) {
#endif
else if (overflow < 0 || pair_number < 0) {
PyErr_SetString(PyExc_ValueError,
"Color pair is less than 1.");
"Color pair is less than 0.");
return 0;
}
@ -742,7 +756,7 @@ _curses_window_addch_impl(PyCursesWindowObject *self, int group_left_1,
if (type == 2) {
funcname = "add_wch";
wstr[1] = L'\0';
setcchar(&wcval, wstr, attr, attr_to_color_pair(attr), NULL);
setcchar(&wcval, wstr, attr, PAIR_NUMBER(attr), NULL);
if (coordinates_group)
rtn = mvwadd_wch(self->win,y,x, &wcval);
else {
@ -2710,7 +2724,7 @@ NoArgOrFlagNoReturnFunctionBody(cbreak, flag)
_curses.color_content
color_number: color
The number of the color (0 - COLORS).
The number of the color (0 - (COLORS-1)).
/
Return the red, green, and blue (RGB) components of the specified color.
@ -2721,7 +2735,7 @@ which will be between 0 (no component) and 1000 (maximum amount of component).
static PyObject *
_curses_color_content_impl(PyObject *module, int color_number)
/*[clinic end generated code: output=17b466df7054e0de input=c10ef58f694b13ee]*/
/*[clinic end generated code: output=17b466df7054e0de input=03b5ed0472662aea]*/
{
_NCURSES_COLOR_VAL_TYPE r,g,b;
@ -2740,8 +2754,8 @@ _curses_color_content_impl(PyObject *module, int color_number)
/*[clinic input]
_curses.color_pair
color_number: color
The number of the color (0 - COLORS).
pair_number: int
The number of the color pair.
/
Return the attribute value for displaying text in the specified color.
@ -2751,13 +2765,13 @@ other A_* attributes. pair_number() is the counterpart to this function.
[clinic start generated code]*/
static PyObject *
_curses_color_pair_impl(PyObject *module, int color_number)
/*[clinic end generated code: output=3fd752e8e24c93fb input=b049033819ab4ef5]*/
_curses_color_pair_impl(PyObject *module, int pair_number)
/*[clinic end generated code: output=60718abb10ce9feb input=6034e9146f343802]*/
{
PyCursesInitialised;
PyCursesInitialisedColor;
return PyLong_FromLong(color_pair_to_attr(color_number));
return PyLong_FromLong(COLOR_PAIR(pair_number));
}
/*[clinic input]
@ -3152,7 +3166,7 @@ _curses_has_key_impl(PyObject *module, int key)
_curses.init_color
color_number: color
The number of the color to be changed (0 - COLORS).
The number of the color to be changed (0 - (COLORS-1)).
r: component
Red component (0 - 1000).
g: component
@ -3165,13 +3179,13 @@ Change the definition of a color.
When init_color() is used, all occurrences of that color on the screen
immediately change to the new definition. This function is a no-op on
most terminals; it is active only if can_change_color() returns 1.
most terminals; it is active only if can_change_color() returns true.
[clinic start generated code]*/
static PyObject *
_curses_init_color_impl(PyObject *module, int color_number, short r, short g,
short b)
/*[clinic end generated code: output=d7ed71b2d818cdf2 input=8a2fe94ca9204aa5]*/
/*[clinic end generated code: output=d7ed71b2d818cdf2 input=ae2b8bea0f152c80]*/
{
PyCursesInitialised;
PyCursesInitialisedColor;
@ -3184,10 +3198,10 @@ _curses.init_pair
pair_number: pair
The number of the color-pair to be changed (1 - (COLOR_PAIRS-1)).
fg: color
Foreground color number (0 - COLORS).
bg: color
Background color number (0 - COLORS).
fg: color_allow_default
Foreground color number (-1 - (COLORS-1)).
bg: color_allow_default
Background color number (-1 - (COLORS-1)).
/
Change the definition of a color-pair.
@ -3198,7 +3212,7 @@ all occurrences of that color-pair are changed to the new definition.
static PyObject *
_curses_init_pair_impl(PyObject *module, int pair_number, int fg, int bg)
/*[clinic end generated code: output=a0bba03d2bbc3ee6 input=b865583a18061c1f]*/
/*[clinic end generated code: output=a0bba03d2bbc3ee6 input=54b421b44c12c389]*/
{
PyCursesInitialised;
PyCursesInitialisedColor;
@ -3821,7 +3835,7 @@ NoArgNoReturnFunctionBody(noraw)
_curses.pair_content
pair_number: pair
The number of the color pair (1 - (COLOR_PAIRS-1)).
The number of the color pair (0 - (COLOR_PAIRS-1)).
/
Return a tuple (fg, bg) containing the colors for the requested color pair.
@ -3829,7 +3843,7 @@ Return a tuple (fg, bg) containing the colors for the requested color pair.
static PyObject *
_curses_pair_content_impl(PyObject *module, int pair_number)
/*[clinic end generated code: output=4a726dd0e6885f3f input=b42eacf8a4103852]*/
/*[clinic end generated code: output=4a726dd0e6885f3f input=03970f840fc7b739]*/
{
_NCURSES_COLOR_VAL_TYPE f, b;
@ -3838,7 +3852,7 @@ _curses_pair_content_impl(PyObject *module, int pair_number)
if (_CURSES_PAIR_NUMBER_FUNC(pair_number, &f, &b)==ERR) {
PyErr_SetString(PyCursesError,
"Argument 1 was out of range. (1..COLOR_PAIRS-1)");
"Argument 1 was out of range. (0..COLOR_PAIRS-1)");
return NULL;
}
@ -3863,7 +3877,7 @@ _curses_pair_number_impl(PyObject *module, int attr)
PyCursesInitialised;
PyCursesInitialisedColor;
return PyLong_FromLong(attr_to_color_pair(attr));
return PyLong_FromLong(PAIR_NUMBER(attr));
}
/*[clinic input]

View File

@ -5,6 +5,7 @@
#define PY_SSIZE_T_CLEAN
#include "Python.h"
#include "structmember.h" // PyMemberDef
#include <stddef.h> // offsetof()
#ifdef STDC_HEADERS
@ -21,6 +22,7 @@ module array
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=7d1b8d7f5958fd83]*/
struct arrayobject; /* Forward */
static struct PyModuleDef arraymodule;
/* All possible arraydescr values are defined in the vector "descriptors"
* below. That's defined later because the appropriate get and set
@ -46,8 +48,6 @@ typedef struct arrayobject {
Py_ssize_t ob_exports; /* Number of exported buffers */
} arrayobject;
static PyTypeObject Arraytype;
typedef struct {
PyObject_HEAD
Py_ssize_t index;
@ -55,9 +55,21 @@ typedef struct {
PyObject* (*getitem)(struct arrayobject *, Py_ssize_t);
} arrayiterobject;
static PyTypeObject PyArrayIter_Type;
typedef struct {
PyTypeObject *ArrayType;
PyTypeObject *ArrayIterType;
} array_state;
#define PyArrayIter_Check(op) PyObject_TypeCheck(op, &PyArrayIter_Type)
static array_state *
get_array_state(PyObject *module)
{
return (array_state *)PyModule_GetState(module);
}
#define find_array_state_by_type(tp) \
(get_array_state(_PyType_GetModuleByDef(tp, &arraymodule)))
#define get_array_state_by_class(cls) \
(get_array_state(PyType_GetModule(cls)))
enum machine_format_code {
UNKNOWN_FORMAT = -1,
@ -105,8 +117,7 @@ enum machine_format_code {
*/
#include "clinic/arraymodule.c.h"
#define array_Check(op) PyObject_TypeCheck(op, &Arraytype)
#define array_CheckExact(op) Py_IS_TYPE(op, &Arraytype)
#define array_Check(op, state) PyObject_TypeCheck(op, state->ArrayType)
static int
array_resize(arrayobject *self, Py_ssize_t newsize)
@ -562,9 +573,9 @@ static const struct arraydescr descriptors[] = {
Implementations of array object methods.
****************************************************************************/
/*[clinic input]
class array.array "arrayobject *" "&Arraytype"
class array.array "arrayobject *" "ArrayType"
[clinic start generated code]*/
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=ad43d37e942a8854]*/
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=a5c29edf59f176a3]*/
static PyObject *
newarrayobject(PyTypeObject *type, Py_ssize_t size, const struct arraydescr *descr)
@ -607,8 +618,11 @@ newarrayobject(PyTypeObject *type, Py_ssize_t size, const struct arraydescr *des
static PyObject *
getarrayitem(PyObject *op, Py_ssize_t i)
{
#ifndef NDEBUG
array_state *state = find_array_state_by_type(Py_TYPE(op));
assert(array_Check(op, state));
#endif
arrayobject *ap;
assert(array_Check(op));
ap = (arrayobject *)op;
assert(i>=0 && i<Py_SIZE(ap));
return (*ap->ob_descr->getitem)(ap, i);
@ -649,23 +663,27 @@ ins1(arrayobject *self, Py_ssize_t where, PyObject *v)
static void
array_dealloc(arrayobject *op)
{
PyTypeObject *tp = Py_TYPE(op);
if (op->weakreflist != NULL)
PyObject_ClearWeakRefs((PyObject *) op);
if (op->ob_item != NULL)
PyMem_Free(op->ob_item);
Py_TYPE(op)->tp_free((PyObject *)op);
tp->tp_free(op);
Py_DECREF(tp);
}
static PyObject *
array_richcompare(PyObject *v, PyObject *w, int op)
{
array_state *state = find_array_state_by_type(Py_TYPE(v));
arrayobject *va, *wa;
PyObject *vi = NULL;
PyObject *wi = NULL;
Py_ssize_t i, k;
PyObject *res;
if (!array_Check(v) || !array_Check(w))
if (!array_Check(v, state) || !array_Check(w, state))
Py_RETURN_NOTIMPLEMENTED;
va = (arrayobject *)v;
@ -787,7 +805,9 @@ array_item(arrayobject *a, Py_ssize_t i)
static PyObject *
array_slice(arrayobject *a, Py_ssize_t ilow, Py_ssize_t ihigh)
{
array_state *state = find_array_state_by_type(Py_TYPE(a));
arrayobject *np;
if (ilow < 0)
ilow = 0;
else if (ilow > Py_SIZE(a))
@ -798,7 +818,7 @@ array_slice(arrayobject *a, Py_ssize_t ilow, Py_ssize_t ihigh)
ihigh = ilow;
else if (ihigh > Py_SIZE(a))
ihigh = Py_SIZE(a);
np = (arrayobject *) newarrayobject(&Arraytype, ihigh - ilow, a->ob_descr);
np = (arrayobject *) newarrayobject(state->ArrayType, ihigh - ilow, a->ob_descr);
if (np == NULL)
return NULL;
if (ihigh > ilow) {
@ -841,9 +861,10 @@ array_array___deepcopy__(arrayobject *self, PyObject *unused)
static PyObject *
array_concat(arrayobject *a, PyObject *bb)
{
array_state *state = find_array_state_by_type(Py_TYPE(a));
Py_ssize_t size;
arrayobject *np;
if (!array_Check(bb)) {
if (!array_Check(bb, state)) {
PyErr_Format(PyExc_TypeError,
"can only append array (not \"%.200s\") to array",
Py_TYPE(bb)->tp_name);
@ -858,7 +879,7 @@ array_concat(arrayobject *a, PyObject *bb)
return PyErr_NoMemory();
}
size = Py_SIZE(a) + Py_SIZE(b);
np = (arrayobject *) newarrayobject(&Arraytype, size, a->ob_descr);
np = (arrayobject *) newarrayobject(state->ArrayType, size, a->ob_descr);
if (np == NULL) {
return NULL;
}
@ -876,6 +897,7 @@ array_concat(arrayobject *a, PyObject *bb)
static PyObject *
array_repeat(arrayobject *a, Py_ssize_t n)
{
array_state *state = find_array_state_by_type(Py_TYPE(a));
Py_ssize_t size;
arrayobject *np;
Py_ssize_t oldbytes, newbytes;
@ -885,7 +907,7 @@ array_repeat(arrayobject *a, Py_ssize_t n)
return PyErr_NoMemory();
}
size = Py_SIZE(a) * n;
np = (arrayobject *) newarrayobject(&Arraytype, size, a->ob_descr);
np = (arrayobject *) newarrayobject(state->ArrayType, size, a->ob_descr);
if (np == NULL)
return NULL;
if (size == 0)
@ -958,7 +980,10 @@ array_ass_item(arrayobject *a, Py_ssize_t i, PyObject *v)
static int
setarrayitem(PyObject *a, Py_ssize_t i, PyObject *v)
{
assert(array_Check(a));
#ifndef NDEBUG
array_state *state = find_array_state_by_type(Py_TYPE(a));
assert(array_Check(a, state));
#endif
return array_ass_item((arrayobject *)a, i, v);
}
@ -986,11 +1011,11 @@ array_iter_extend(arrayobject *self, PyObject *bb)
}
static int
array_do_extend(arrayobject *self, PyObject *bb)
array_do_extend(array_state *state, arrayobject *self, PyObject *bb)
{
Py_ssize_t size, oldsize, bbsize;
if (!array_Check(bb))
if (!array_Check(bb, state))
return array_iter_extend(self, bb);
#define b ((arrayobject *)bb)
if (self->ob_descr != b->ob_descr) {
@ -1021,13 +1046,15 @@ array_do_extend(arrayobject *self, PyObject *bb)
static PyObject *
array_inplace_concat(arrayobject *self, PyObject *bb)
{
if (!array_Check(bb)) {
array_state *state = find_array_state_by_type(Py_TYPE(self));
if (!array_Check(bb, state)) {
PyErr_Format(PyExc_TypeError,
"can only extend array with array (not \"%.200s\")",
Py_TYPE(bb)->tp_name);
return NULL;
}
if (array_do_extend(self, bb) == -1)
if (array_do_extend(state, self, bb) == -1)
return NULL;
Py_INCREF(self);
return (PyObject *)self;
@ -1232,6 +1259,7 @@ array_array_pop_impl(arrayobject *self, Py_ssize_t i)
/*[clinic input]
array.array.extend
cls: defining_class
bb: object
/
@ -1239,10 +1267,12 @@ Append items to the end of the array.
[clinic start generated code]*/
static PyObject *
array_array_extend(arrayobject *self, PyObject *bb)
/*[clinic end generated code: output=bbddbc8e8bef871d input=43be86aba5c31e44]*/
array_array_extend_impl(arrayobject *self, PyTypeObject *cls, PyObject *bb)
/*[clinic end generated code: output=e65eb7588f0bc266 input=8eb6817ec4d2cb62]*/
{
if (array_do_extend(self, bb) == -1)
array_state *state = get_array_state_by_class(cls);
if (array_do_extend(state, self, bb) == -1)
return NULL;
Py_RETURN_NONE;
}
@ -1928,6 +1958,7 @@ array__array_reconstructor_impl(PyObject *module, PyTypeObject *arraytype,
PyObject *items)
/*[clinic end generated code: output=e05263141ba28365 input=2464dc8f4c7736b5]*/
{
array_state *state = get_array_state(module);
PyObject *converted_items;
PyObject *result;
const struct arraydescr *descr;
@ -1938,10 +1969,10 @@ array__array_reconstructor_impl(PyObject *module, PyTypeObject *arraytype,
Py_TYPE(arraytype)->tp_name);
return NULL;
}
if (!PyType_IsSubtype(arraytype, &Arraytype)) {
if (!PyType_IsSubtype(arraytype, state->ArrayType)) {
PyErr_Format(PyExc_TypeError,
"%.200s is not a subtype of %.200s",
arraytype->tp_name, Arraytype.tp_name);
arraytype->tp_name, state->ArrayType->tp_name);
return NULL;
}
for (descr = descriptors; descr->typecode != '\0'; descr++) {
@ -2287,6 +2318,8 @@ array_repr(arrayobject *a)
static PyObject*
array_subscr(arrayobject* self, PyObject* item)
{
array_state *state = find_array_state_by_type(Py_TYPE(self));
if (PyIndex_Check(item)) {
Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
if (i==-1 && PyErr_Occurred()) {
@ -2310,10 +2343,10 @@ array_subscr(arrayobject* self, PyObject* item)
step);
if (slicelength <= 0) {
return newarrayobject(&Arraytype, 0, self->ob_descr);
return newarrayobject(state->ArrayType, 0, self->ob_descr);
}
else if (step == 1) {
PyObject *result = newarrayobject(&Arraytype,
PyObject *result = newarrayobject(state->ArrayType,
slicelength, self->ob_descr);
if (result == NULL)
return NULL;
@ -2323,7 +2356,7 @@ array_subscr(arrayobject* self, PyObject* item)
return result;
}
else {
result = newarrayobject(&Arraytype, slicelength, self->ob_descr);
result = newarrayobject(state->ArrayType, slicelength, self->ob_descr);
if (!result) return NULL;
ar = (arrayobject*)result;
@ -2349,6 +2382,7 @@ static int
array_ass_subscr(arrayobject* self, PyObject* item, PyObject* value)
{
Py_ssize_t start, stop, step, slicelength, needed;
array_state* state = find_array_state_by_type(Py_TYPE(self));
arrayobject* other;
int itemsize;
@ -2390,7 +2424,7 @@ array_ass_subscr(arrayobject* self, PyObject* item, PyObject* value)
other = NULL;
needed = 0;
}
else if (array_Check(value)) {
else if (array_Check(value, state)) {
other = (arrayobject *)value;
needed = Py_SIZE(other);
if (self == other) {
@ -2502,12 +2536,6 @@ array_ass_subscr(arrayobject* self, PyObject* item, PyObject* value)
}
}
static PyMappingMethods array_as_mapping = {
(lenfunc)array_length,
(binaryfunc)array_subscr,
(objobjargproc)array_ass_subscr
};
static const void *emptybuf = "";
@ -2558,32 +2586,15 @@ array_buffer_relbuf(arrayobject *self, Py_buffer *view)
self->ob_exports--;
}
static PySequenceMethods array_as_sequence = {
(lenfunc)array_length, /*sq_length*/
(binaryfunc)array_concat, /*sq_concat*/
(ssizeargfunc)array_repeat, /*sq_repeat*/
(ssizeargfunc)array_item, /*sq_item*/
0, /*sq_slice*/
(ssizeobjargproc)array_ass_item, /*sq_ass_item*/
0, /*sq_ass_slice*/
(objobjproc)array_contains, /*sq_contains*/
(binaryfunc)array_inplace_concat, /*sq_inplace_concat*/
(ssizeargfunc)array_inplace_repeat /*sq_inplace_repeat*/
};
static PyBufferProcs array_as_buffer = {
(getbufferproc)array_buffer_getbuf,
(releasebufferproc)array_buffer_relbuf
};
static PyObject *
array_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
array_state *state = find_array_state_by_type(type);
int c;
PyObject *initial = NULL, *it = NULL;
const struct arraydescr *descr;
if (type == &Arraytype && !_PyArg_NoKeywords("array.array", kwds))
if (type == state->ArrayType && !_PyArg_NoKeywords("array.array", kwds))
return NULL;
if (!PyArg_ParseTuple(args, "C|O:array", &c, &initial))
@ -2600,7 +2611,7 @@ array_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
"an array with typecode '%c'", c);
return NULL;
}
else if (array_Check(initial) &&
else if (array_Check(initial, state) &&
((arrayobject*)initial)->ob_descr->typecode == 'u') {
PyErr_Format(PyExc_TypeError, "cannot use a unicode array to "
"initialize an array with typecode '%c'", c);
@ -2613,7 +2624,7 @@ array_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
|| PyBytes_Check(initial)
|| PyTuple_Check(initial)
|| ((c=='u') && PyUnicode_Check(initial))
|| (array_Check(initial)
|| (array_Check(initial, state)
&& c == ((arrayobject*)initial)->ob_descr->typecode))) {
it = PyObject_GetIter(initial);
if (it == NULL)
@ -2634,7 +2645,7 @@ array_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
len = 0;
else if (PyList_Check(initial))
len = PyList_GET_SIZE(initial);
else if (PyTuple_Check(initial) || array_Check(initial))
else if (PyTuple_Check(initial) || array_Check(initial, state))
len = Py_SIZE(initial);
else
len = 0;
@ -2643,7 +2654,7 @@ array_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
if (a == NULL)
return NULL;
if (len > 0 && !array_Check(initial)) {
if (len > 0 && !array_Check(initial, state)) {
Py_ssize_t i;
for (i = 0; i < len; i++) {
PyObject *v =
@ -2688,7 +2699,7 @@ array_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
self->allocated = n;
}
}
else if (initial != NULL && array_Check(initial) && len > 0) {
else if (initial != NULL && array_Check(initial, state) && len > 0) {
arrayobject *self = (arrayobject *)a;
arrayobject *other = (arrayobject *)initial;
memcpy(self->ob_item, other->ob_item, len * other->ob_descr->itemsize);
@ -2777,67 +2788,73 @@ itemsize -- the length in bytes of one array item\n\
static PyObject *array_iter(arrayobject *ao);
static PyTypeObject Arraytype = {
PyVarObject_HEAD_INIT(NULL, 0)
"array.array",
sizeof(arrayobject),
0,
(destructor)array_dealloc, /* tp_dealloc */
0, /* tp_vectorcall_offset */
0, /* tp_getattr */
0, /* tp_setattr */
0, /* tp_as_async */
(reprfunc)array_repr, /* tp_repr */
0, /* tp_as_number*/
&array_as_sequence, /* tp_as_sequence*/
&array_as_mapping, /* tp_as_mapping*/
0, /* tp_hash */
0, /* tp_call */
0, /* tp_str */
PyObject_GenericGetAttr, /* tp_getattro */
0, /* tp_setattro */
&array_as_buffer, /* tp_as_buffer*/
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
arraytype_doc, /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
array_richcompare, /* tp_richcompare */
offsetof(arrayobject, weakreflist), /* tp_weaklistoffset */
(getiterfunc)array_iter, /* tp_iter */
0, /* tp_iternext */
array_methods, /* tp_methods */
0, /* tp_members */
array_getsets, /* tp_getset */
0, /* tp_base */
0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
0, /* tp_init */
PyType_GenericAlloc, /* tp_alloc */
array_new, /* tp_new */
PyObject_Del, /* tp_free */
static struct PyMemberDef array_members[] = {
{"__weaklistoffset__", T_PYSSIZET, offsetof(arrayobject, weakreflist), READONLY},
{NULL},
};
static PyType_Slot array_slots[] = {
{Py_tp_dealloc, array_dealloc},
{Py_tp_repr, array_repr},
{Py_tp_getattro, PyObject_GenericGetAttr},
{Py_tp_doc, (void *)arraytype_doc},
{Py_tp_richcompare, array_richcompare},
{Py_tp_iter, array_iter},
{Py_tp_methods, array_methods},
{Py_tp_members, array_members},
{Py_tp_getset, array_getsets},
{Py_tp_alloc, PyType_GenericAlloc},
{Py_tp_new, array_new},
{Py_tp_free, PyObject_Del},
/* as sequence */
{Py_sq_length, array_length},
{Py_sq_concat, array_concat},
{Py_sq_repeat, array_repeat},
{Py_sq_item, array_item},
{Py_sq_ass_item, array_ass_item},
{Py_sq_contains, array_contains},
{Py_sq_inplace_concat, array_inplace_concat},
{Py_sq_inplace_repeat, array_inplace_repeat},
/* as mapping */
{Py_mp_length, array_length},
{Py_mp_subscript, array_subscr},
{Py_mp_ass_subscript, array_ass_subscr},
/* as buffer */
{Py_bf_getbuffer, array_buffer_getbuf},
{Py_bf_releasebuffer, array_buffer_relbuf},
{0, NULL},
};
static PyType_Spec array_spec = {
.name = "array.array",
.basicsize = sizeof(arrayobject),
.flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
.slots = array_slots,
};
/*********************** Array Iterator **************************/
/*[clinic input]
class array.arrayiterator "arrayiterobject *" "&PyArrayIter_Type"
class array.arrayiterator "arrayiterobject *" "find_array_state_by_type(type)->ArrayIterType"
[clinic start generated code]*/
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=5aefd2d74d8c8e30]*/
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=fb46d5ef98dd95ff]*/
static PyObject *
array_iter(arrayobject *ao)
{
array_state *state = find_array_state_by_type(Py_TYPE(ao));
arrayiterobject *it;
if (!array_Check(ao)) {
if (!array_Check(ao, state)) {
PyErr_BadInternalCall();
return NULL;
}
it = PyObject_GC_New(arrayiterobject, &PyArrayIter_Type);
it = PyObject_GC_New(arrayiterobject, state->ArrayIterType);
if (it == NULL)
return NULL;
@ -2855,12 +2872,17 @@ arrayiter_next(arrayiterobject *it)
arrayobject *ao;
assert(it != NULL);
assert(PyArrayIter_Check(it));
#ifndef NDEBUG
array_state *state = find_array_state_by_type(Py_TYPE(it));
assert(PyObject_TypeCheck(it, state->ArrayIterType));
#endif
ao = it->ao;
if (ao == NULL) {
return NULL;
}
assert(array_Check(ao));
#ifndef NDEBUG
assert(array_Check(ao, state));
#endif
if (it->index < Py_SIZE(ao)) {
return (*it->getitem)(ao, it->index++);
}
@ -2872,9 +2894,12 @@ arrayiter_next(arrayiterobject *it)
static void
arrayiter_dealloc(arrayiterobject *it)
{
PyTypeObject *tp = Py_TYPE(it);
PyObject_GC_UnTrack(it);
Py_XDECREF(it->ao);
PyObject_GC_Del(it);
Py_DECREF(tp);
}
static int
@ -2932,86 +2957,103 @@ static PyMethodDef arrayiter_methods[] = {
{NULL, NULL} /* sentinel */
};
static PyTypeObject PyArrayIter_Type = {
PyVarObject_HEAD_INIT(NULL, 0)
"arrayiterator", /* tp_name */
sizeof(arrayiterobject), /* tp_basicsize */
0, /* tp_itemsize */
/* methods */
(destructor)arrayiter_dealloc, /* tp_dealloc */
0, /* tp_vectorcall_offset */
0, /* tp_getattr */
0, /* tp_setattr */
0, /* tp_as_async */
0, /* tp_repr */
0, /* tp_as_number */
0, /* tp_as_sequence */
0, /* tp_as_mapping */
0, /* tp_hash */
0, /* tp_call */
0, /* tp_str */
PyObject_GenericGetAttr, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
0, /* tp_doc */
(traverseproc)arrayiter_traverse, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
PyObject_SelfIter, /* tp_iter */
(iternextfunc)arrayiter_next, /* tp_iternext */
arrayiter_methods, /* tp_methods */
static PyType_Slot arrayiter_slots[] = {
{Py_tp_dealloc, arrayiter_dealloc},
{Py_tp_getattro, PyObject_GenericGetAttr},
{Py_tp_traverse, arrayiter_traverse},
{Py_tp_iter, PyObject_SelfIter},
{Py_tp_iternext, arrayiter_next},
{Py_tp_methods, arrayiter_methods},
{0, NULL},
};
static PyType_Spec arrayiter_spec = {
.name = "array.arrayiterator",
.basicsize = sizeof(arrayiterobject),
.flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
.slots = arrayiter_slots,
};
/*********************** Install Module **************************/
static int
array_traverse(PyObject *module, visitproc visit, void *arg)
{
array_state *state = get_array_state(module);
Py_VISIT(state->ArrayType);
Py_VISIT(state->ArrayIterType);
return 0;
}
static int
array_clear(PyObject *module)
{
array_state *state = get_array_state(module);
Py_CLEAR(state->ArrayType);
Py_CLEAR(state->ArrayIterType);
return 0;
}
static void
array_free(void *module)
{
array_clear((PyObject *)module);
}
/* No functions in array module. */
static PyMethodDef a_methods[] = {
ARRAY__ARRAY_RECONSTRUCTOR_METHODDEF
{NULL, NULL, 0, NULL} /* Sentinel */
};
#define CREATE_TYPE(module, type, spec) \
do { \
type = (PyTypeObject *)PyType_FromModuleAndSpec(module, spec, NULL); \
if (type == NULL) { \
return -1; \
} \
} while (0)
static int
array_modexec(PyObject *m)
{
array_state *state = get_array_state(m);
char buffer[Py_ARRAY_LENGTH(descriptors)], *p;
PyObject *typecodes;
const struct arraydescr *descr;
if (PyType_Ready(&Arraytype) < 0)
return -1;
Py_SET_TYPE(&PyArrayIter_Type, &PyType_Type);
CREATE_TYPE(m, state->ArrayType, &array_spec);
CREATE_TYPE(m, state->ArrayIterType, &arrayiter_spec);
Py_SET_TYPE(state->ArrayIterType, &PyType_Type);
Py_INCREF((PyObject *)&Arraytype);
if (PyModule_AddObject(m, "ArrayType", (PyObject *)&Arraytype) < 0) {
Py_DECREF((PyObject *)&Arraytype);
Py_INCREF((PyObject *)state->ArrayType);
if (PyModule_AddObject(m, "ArrayType", (PyObject *)state->ArrayType) < 0) {
Py_DECREF((PyObject *)state->ArrayType);
return -1;
}
PyObject *abc_mod = PyImport_ImportModule("collections.abc");
if (!abc_mod) {
Py_DECREF((PyObject *)&Arraytype);
Py_DECREF((PyObject *)state->ArrayType);
return -1;
}
PyObject *mutablesequence = PyObject_GetAttrString(abc_mod, "MutableSequence");
Py_DECREF(abc_mod);
if (!mutablesequence) {
Py_DECREF((PyObject *)&Arraytype);
Py_DECREF((PyObject *)state->ArrayType);
return -1;
}
PyObject *res = PyObject_CallMethod(mutablesequence, "register", "O", (PyObject *)&Arraytype);
PyObject *res = PyObject_CallMethod(mutablesequence, "register", "O",
(PyObject *)state->ArrayType);
Py_DECREF(mutablesequence);
if (!res) {
Py_DECREF((PyObject *)&Arraytype);
Py_DECREF((PyObject *)state->ArrayType);
return -1;
}
Py_DECREF(res);
Py_INCREF((PyObject *)&Arraytype);
if (PyModule_AddObject(m, "array", (PyObject *)&Arraytype) < 0) {
Py_DECREF((PyObject *)&Arraytype);
if (PyModule_AddType(m, state->ArrayType) < 0) {
return -1;
}
@ -3035,15 +3077,15 @@ static PyModuleDef_Slot arrayslots[] = {
static struct PyModuleDef arraymodule = {
PyModuleDef_HEAD_INIT,
"array",
module_doc,
0,
a_methods,
arrayslots,
NULL,
NULL,
NULL
.m_base = PyModuleDef_HEAD_INIT,
.m_name = "array",
.m_size = sizeof(array_state),
.m_doc = module_doc,
.m_methods = a_methods,
.m_slots = arrayslots,
.m_traverse = array_traverse,
.m_clear = array_clear,
.m_free = array_free,
};

View File

@ -1958,7 +1958,7 @@ PyDoc_STRVAR(_curses_color_content__doc__,
"Return the red, green, and blue (RGB) components of the specified color.\n"
"\n"
" color_number\n"
" The number of the color (0 - COLORS).\n"
" The number of the color (0 - (COLORS-1)).\n"
"\n"
"A 3-tuple is returned, containing the R, G, B values for the given color,\n"
"which will be between 0 (no component) and 1000 (maximum amount of component).");
@ -1985,13 +1985,13 @@ exit:
}
PyDoc_STRVAR(_curses_color_pair__doc__,
"color_pair($module, color_number, /)\n"
"color_pair($module, pair_number, /)\n"
"--\n"
"\n"
"Return the attribute value for displaying text in the specified color.\n"
"\n"
" color_number\n"
" The number of the color (0 - COLORS).\n"
" pair_number\n"
" The number of the color pair.\n"
"\n"
"This attribute value can be combined with A_STANDOUT, A_REVERSE, and the\n"
"other A_* attributes. pair_number() is the counterpart to this function.");
@ -2000,18 +2000,19 @@ PyDoc_STRVAR(_curses_color_pair__doc__,
{"color_pair", (PyCFunction)_curses_color_pair, METH_O, _curses_color_pair__doc__},
static PyObject *
_curses_color_pair_impl(PyObject *module, int color_number);
_curses_color_pair_impl(PyObject *module, int pair_number);
static PyObject *
_curses_color_pair(PyObject *module, PyObject *arg)
{
PyObject *return_value = NULL;
int color_number;
int pair_number;
if (!color_converter(arg, &color_number)) {
pair_number = _PyLong_AsInt(arg);
if (pair_number == -1 && PyErr_Occurred()) {
goto exit;
}
return_value = _curses_color_pair_impl(module, color_number);
return_value = _curses_color_pair_impl(module, pair_number);
exit:
return return_value;
@ -2542,7 +2543,7 @@ PyDoc_STRVAR(_curses_init_color__doc__,
"Change the definition of a color.\n"
"\n"
" color_number\n"
" The number of the color to be changed (0 - COLORS).\n"
" The number of the color to be changed (0 - (COLORS-1)).\n"
" r\n"
" Red component (0 - 1000).\n"
" g\n"
@ -2552,7 +2553,7 @@ PyDoc_STRVAR(_curses_init_color__doc__,
"\n"
"When init_color() is used, all occurrences of that color on the screen\n"
"immediately change to the new definition. This function is a no-op on\n"
"most terminals; it is active only if can_change_color() returns 1.");
"most terminals; it is active only if can_change_color() returns true.");
#define _CURSES_INIT_COLOR_METHODDEF \
{"init_color", (PyCFunction)(void(*)(void))_curses_init_color, METH_FASTCALL, _curses_init_color__doc__},
@ -2600,9 +2601,9 @@ PyDoc_STRVAR(_curses_init_pair__doc__,
" pair_number\n"
" The number of the color-pair to be changed (1 - (COLOR_PAIRS-1)).\n"
" fg\n"
" Foreground color number (0 - COLORS).\n"
" Foreground color number (-1 - (COLORS-1)).\n"
" bg\n"
" Background color number (0 - COLORS).\n"
" Background color number (-1 - (COLORS-1)).\n"
"\n"
"If the color-pair was previously initialized, the screen is refreshed and\n"
"all occurrences of that color-pair are changed to the new definition.");
@ -2627,10 +2628,10 @@ _curses_init_pair(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
if (!pair_converter(args[0], &pair_number)) {
goto exit;
}
if (!color_converter(args[1], &fg)) {
if (!color_allow_default_converter(args[1], &fg)) {
goto exit;
}
if (!color_converter(args[2], &bg)) {
if (!color_allow_default_converter(args[2], &bg)) {
goto exit;
}
return_value = _curses_init_pair_impl(module, pair_number, fg, bg);
@ -3403,7 +3404,7 @@ PyDoc_STRVAR(_curses_pair_content__doc__,
"Return a tuple (fg, bg) containing the colors for the requested color pair.\n"
"\n"
" pair_number\n"
" The number of the color pair (1 - (COLOR_PAIRS-1)).");
" The number of the color pair (0 - (COLOR_PAIRS-1)).");
#define _CURSES_PAIR_CONTENT_METHODDEF \
{"pair_content", (PyCFunction)_curses_pair_content, METH_O, _curses_pair_content__doc__},
@ -4288,4 +4289,4 @@ _curses_has_extended_color_support(PyObject *module, PyObject *Py_UNUSED(ignored
#ifndef _CURSES_USE_DEFAULT_COLORS_METHODDEF
#define _CURSES_USE_DEFAULT_COLORS_METHODDEF
#endif /* !defined(_CURSES_USE_DEFAULT_COLORS_METHODDEF) */
/*[clinic end generated code: output=92bad2172fef9747 input=a9049054013a1b77]*/
/*[clinic end generated code: output=ae6559aa61200289 input=a9049054013a1b77]*/

View File

@ -108,7 +108,28 @@ PyDoc_STRVAR(array_array_extend__doc__,
"Append items to the end of the array.");
#define ARRAY_ARRAY_EXTEND_METHODDEF \
{"extend", (PyCFunction)array_array_extend, METH_O, array_array_extend__doc__},
{"extend", (PyCFunction)(void(*)(void))array_array_extend, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, array_array_extend__doc__},
static PyObject *
array_array_extend_impl(arrayobject *self, PyTypeObject *cls, PyObject *bb);
static PyObject *
array_array_extend(arrayobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
{
PyObject *return_value = NULL;
static const char * const _keywords[] = {"", NULL};
static _PyArg_Parser _parser = {"O:extend", _keywords, 0};
PyObject *bb;
if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser,
&bb)) {
goto exit;
}
return_value = array_array_extend_impl(self, cls, bb);
exit:
return return_value;
}
PyDoc_STRVAR(array_array_insert__doc__,
"insert($self, i, v, /)\n"
@ -514,4 +535,4 @@ PyDoc_STRVAR(array_arrayiterator___setstate____doc__,
#define ARRAY_ARRAYITERATOR___SETSTATE___METHODDEF \
{"__setstate__", (PyCFunction)array_arrayiterator___setstate__, METH_O, array_arrayiterator___setstate____doc__},
/*[clinic end generated code: output=91c1cded65a1285f input=a9049054013a1b77]*/
/*[clinic end generated code: output=a7f71a18b994c88f input=a9049054013a1b77]*/

View File

@ -61,7 +61,13 @@
*/
#if defined(__APPLE__)
#if defined(__has_builtin) && __has_builtin(__builtin_available)
#if defined(__has_builtin)
#if __has_builtin(__builtin_available)
#define HAVE_BUILTIN_AVAILABLE 1
#endif
#endif
#ifdef HAVE_BUILTIN_AVAILABLE
# define HAVE_FSTATAT_RUNTIME __builtin_available(macOS 10.10, iOS 8.0, *)
# define HAVE_FACCESSAT_RUNTIME __builtin_available(macOS 10.10, iOS 8.0, *)
# define HAVE_FCHMODAT_RUNTIME __builtin_available(macOS 10.10, iOS 8.0, *)

View File

@ -1836,6 +1836,13 @@ error:
}
#endif
static void
pyexpat_destructor(PyObject *op)
{
void *p = PyCapsule_GetPointer(op, PyExpat_CAPSULE_NAME);
PyMem_Free(p);
}
static int
pyexpat_exec(PyObject *mod)
{
@ -1921,40 +1928,46 @@ pyexpat_exec(PyObject *mod)
MYCONST(XML_PARAM_ENTITY_PARSING_ALWAYS);
#undef MYCONST
static struct PyExpat_CAPI capi;
struct PyExpat_CAPI *capi = PyMem_Calloc(1, sizeof(struct PyExpat_CAPI));
if (capi == NULL) {
PyErr_NoMemory();
return -1;
}
/* initialize pyexpat dispatch table */
capi.size = sizeof(capi);
capi.magic = PyExpat_CAPI_MAGIC;
capi.MAJOR_VERSION = XML_MAJOR_VERSION;
capi.MINOR_VERSION = XML_MINOR_VERSION;
capi.MICRO_VERSION = XML_MICRO_VERSION;
capi.ErrorString = XML_ErrorString;
capi.GetErrorCode = XML_GetErrorCode;
capi.GetErrorColumnNumber = XML_GetErrorColumnNumber;
capi.GetErrorLineNumber = XML_GetErrorLineNumber;
capi.Parse = XML_Parse;
capi.ParserCreate_MM = XML_ParserCreate_MM;
capi.ParserFree = XML_ParserFree;
capi.SetCharacterDataHandler = XML_SetCharacterDataHandler;
capi.SetCommentHandler = XML_SetCommentHandler;
capi.SetDefaultHandlerExpand = XML_SetDefaultHandlerExpand;
capi.SetElementHandler = XML_SetElementHandler;
capi.SetNamespaceDeclHandler = XML_SetNamespaceDeclHandler;
capi.SetProcessingInstructionHandler = XML_SetProcessingInstructionHandler;
capi.SetUnknownEncodingHandler = XML_SetUnknownEncodingHandler;
capi.SetUserData = XML_SetUserData;
capi.SetStartDoctypeDeclHandler = XML_SetStartDoctypeDeclHandler;
capi.SetEncoding = XML_SetEncoding;
capi.DefaultUnknownEncodingHandler = PyUnknownEncodingHandler;
capi->size = sizeof(*capi);
capi->magic = PyExpat_CAPI_MAGIC;
capi->MAJOR_VERSION = XML_MAJOR_VERSION;
capi->MINOR_VERSION = XML_MINOR_VERSION;
capi->MICRO_VERSION = XML_MICRO_VERSION;
capi->ErrorString = XML_ErrorString;
capi->GetErrorCode = XML_GetErrorCode;
capi->GetErrorColumnNumber = XML_GetErrorColumnNumber;
capi->GetErrorLineNumber = XML_GetErrorLineNumber;
capi->Parse = XML_Parse;
capi->ParserCreate_MM = XML_ParserCreate_MM;
capi->ParserFree = XML_ParserFree;
capi->SetCharacterDataHandler = XML_SetCharacterDataHandler;
capi->SetCommentHandler = XML_SetCommentHandler;
capi->SetDefaultHandlerExpand = XML_SetDefaultHandlerExpand;
capi->SetElementHandler = XML_SetElementHandler;
capi->SetNamespaceDeclHandler = XML_SetNamespaceDeclHandler;
capi->SetProcessingInstructionHandler = XML_SetProcessingInstructionHandler;
capi->SetUnknownEncodingHandler = XML_SetUnknownEncodingHandler;
capi->SetUserData = XML_SetUserData;
capi->SetStartDoctypeDeclHandler = XML_SetStartDoctypeDeclHandler;
capi->SetEncoding = XML_SetEncoding;
capi->DefaultUnknownEncodingHandler = PyUnknownEncodingHandler;
#if XML_COMBINED_VERSION >= 20100
capi.SetHashSalt = XML_SetHashSalt;
capi->SetHashSalt = XML_SetHashSalt;
#else
capi.SetHashSalt = NULL;
capi->SetHashSalt = NULL;
#endif
/* export using capsule */
PyObject *capi_object = PyCapsule_New(&capi, PyExpat_CAPSULE_NAME, NULL);
PyObject *capi_object = PyCapsule_New(capi, PyExpat_CAPSULE_NAME,
pyexpat_destructor);
if (capi_object == NULL) {
PyMem_Free(capi);
return -1;
}

View File

@ -174,6 +174,7 @@ is_typing_name(PyObject *obj, int num, ...)
break;
}
}
va_end(names);
if (!hit) {
return 0;
}
@ -185,7 +186,6 @@ is_typing_name(PyObject *obj, int num, ...)
&& _PyUnicode_EqualToASCIIString(module, "typing");
Py_DECREF(module);
va_end(names);
return res;
}

View File

@ -34,7 +34,7 @@ is_generic_alias_in_args(PyObject *args) {
Py_ssize_t nargs = PyTuple_GET_SIZE(args);
for (Py_ssize_t iarg = 0; iarg < nargs; iarg++) {
PyObject *arg = PyTuple_GET_ITEM(args, iarg);
if (Py_TYPE(arg) == &Py_GenericAliasType) {
if (PyObject_TypeCheck(arg, &Py_GenericAliasType)) {
return 0;
}
}

File diff suppressed because it is too large Load Diff

View File

@ -405,7 +405,7 @@ fstring_compile_expr(Parser *p, const char *expr_start, const char *expr_end,
Parser *p2 = _PyPegen_Parser_New(tok, Py_fstring_input, p->flags, p->feature_version,
NULL, p->arena);
p2->starting_lineno = t->lineno + lines - 1;
p2->starting_col_offset = p->tok->first_lineno == p->tok->lineno ? t->col_offset + cols : cols;
p2->starting_col_offset = t->col_offset + cols;
expr = _PyPegen_run_parser(p2);