Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Doc/library/array.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
--------------

This module defines an object type which can compactly represent an array of
basic values: characters, integers, floating-point numbers. Arrays are sequence
basic values: characters, integers, floating-point numbers. Arrays are mutable :term:`sequence`
types and behave very much like lists, except that the type of objects stored in
them is constrained. The type is specified at object creation time by using a
:dfn:`type code`, which is a single character. The following type codes are
Expand Down Expand Up @@ -93,7 +93,7 @@ The module defines the following type:
otherwise, the initializer's iterator is passed to the :meth:`extend` method
to add initial items to the array.

Array objects support the ordinary sequence operations of indexing, slicing,
Array objects support the ordinary :ref:`mutable <typesseq-mutable>` :term:`sequence` operations of indexing, slicing,
concatenation, and multiplication. When using slice assignment, the assigned
value must be an array object with the same type code; in all other cases,
:exc:`TypeError` is raised. Array objects also implement the buffer interface,
Expand Down
13 changes: 8 additions & 5 deletions Doc/library/stdtypes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1093,11 +1093,14 @@ Notes:
still ``0``.

(4)
The slice of *s* from *i* to *j* is defined as the sequence of items with index
*k* such that ``i <= k < j``. If *i* or *j* is greater than ``len(s)``, use
``len(s)``. If *i* is omitted or ``None``, use ``0``. If *j* is omitted or
``None``, use ``len(s)``. If *i* is greater than or equal to *j*, the slice is
empty.
The slice of *s* from *i* to *j* is defined as the sequence of items with
index *k* such that ``i <= k < j``.

* If *i* is omitted or ``None``, use ``0``.
* If *j* is omitted or ``None``, use ``len(s)``.
* If *i* or *j* is less than ``-len(s)``, use ``0``.
* If *i* or *j* is greater than ``len(s)``, use ``len(s)``.
* If *i* is greater than or equal to *j*, the slice is empty.

(5)
The slice of *s* from *i* to *j* with step *k* is defined as the sequence of
Expand Down
14 changes: 11 additions & 3 deletions Doc/library/typing.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2369,7 +2369,7 @@ These functions and classes should not be used directly as annotations.
Their intended purpose is to be building blocks for creating and declaring
types.

.. class:: NamedTuple
.. function:: NamedTuple

Typed version of :func:`collections.namedtuple`.

Expand Down Expand Up @@ -2442,6 +2442,10 @@ types.
Removed the ``_field_types`` attribute in favor of the more
standard ``__annotations__`` attribute which has the same information.

.. versionchanged:: 3.9
``NamedTuple`` is now a function rather than a class.
It can still be used as a class base, as described above.

.. versionchanged:: 3.11
Added support for generic namedtuples.

Expand Down Expand Up @@ -2585,10 +2589,10 @@ types.
for more details.


.. class:: TypedDict(dict)
.. function:: TypedDict

Special construct to add type hints to a dictionary.
At runtime it is a plain :class:`dict`.
At runtime ":class:`!TypedDict` instances" are simply :class:`dicts <dict>`.

``TypedDict`` declares a dictionary type that expects all of its
instances to have a certain set of keys, where each key is
Expand Down Expand Up @@ -2811,6 +2815,10 @@ types.

.. versionadded:: 3.8

.. versionchanged:: 3.9
``TypedDict`` is now a function rather than a class.
It can still be used as a class base, as described above.

.. versionchanged:: 3.11
Added support for marking individual keys as :data:`Required` or :data:`NotRequired`.
See :pep:`655`.
Expand Down
44 changes: 42 additions & 2 deletions Lib/test/test_pickle.py
Original file line number Diff line number Diff line change
Expand Up @@ -419,6 +419,46 @@ def test_issue18339(self):
unpickler.memo = {-1: None}
unpickler.memo = {1: None}

def test_concurrent_pickler_dump(self):
f = io.BytesIO()
pickler = self.pickler_class(f)
class X:
def __reduce__(slf):
self.assertRaises(RuntimeError, pickler.dump, 42)
return list, ()
pickler.dump(X()) # should not crash
self.assertEqual(pickle.loads(f.getvalue()), [])

def test_concurrent_pickler_dump_and_init(self):
f = io.BytesIO()
pickler = self.pickler_class(f)
class X:
def __reduce__(slf):
self.assertRaises(RuntimeError, pickler.__init__, f)
return list, ()
pickler.dump([X()]) # should not fail
self.assertEqual(pickle.loads(f.getvalue()), [[]])

def test_concurrent_unpickler_load(self):
global reducer
def reducer():
self.assertRaises(RuntimeError, unpickler.load)
return 42
f = io.BytesIO(b'(c%b\nreducer\n(tRl.' % (__name__.encode(),))
unpickler = self.unpickler_class(f)
unpickled = unpickler.load() # should not fail
self.assertEqual(unpickled, [42])

def test_concurrent_unpickler_load_and_init(self):
global reducer
def reducer():
self.assertRaises(RuntimeError, unpickler.__init__, f)
return 42
f = io.BytesIO(b'(c%b\nreducer\n(tRl.' % (__name__.encode(),))
unpickler = self.unpickler_class(f)
unpickled = unpickler.load() # should not crash
self.assertEqual(unpickled, [42])

class CDispatchTableTests(AbstractDispatchTableTests, unittest.TestCase):
pickler_class = pickle.Pickler
def get_dispatch_table(self):
Expand Down Expand Up @@ -467,7 +507,7 @@ class SizeofTests(unittest.TestCase):
check_sizeof = support.check_sizeof

def test_pickler(self):
basesize = support.calcobjsize('7P2n3i2n3i2P')
basesize = support.calcobjsize('7P2n3i2n4i2P')
p = _pickle.Pickler(io.BytesIO())
self.assertEqual(object.__sizeof__(p), basesize)
MT_size = struct.calcsize('3nP0n')
Expand All @@ -484,7 +524,7 @@ def test_pickler(self):
0) # Write buffer is cleared after every dump().

def test_unpickler(self):
basesize = support.calcobjsize('2P2n3P 2P2n2i5P 2P3n8P2n2i')
basesize = support.calcobjsize('2P2n3P 2P2n2i5P 2P3n8P2n3i')
unpickler = _pickle.Unpickler
P = struct.calcsize('P') # Size of memo table entry.
n = struct.calcsize('n') # Size of mark table entry.
Expand Down
12 changes: 12 additions & 0 deletions Lib/test/test_struct.py
Original file line number Diff line number Diff line change
Expand Up @@ -816,6 +816,18 @@ def test_endian_table_init_subinterpreters(self):
results = executor.map(exec, [code] * 5)
self.assertListEqual(list(results), [None] * 5)

def test_operations_on_half_initialized_Struct(self):
S = struct.Struct.__new__(struct.Struct)

spam = array.array('b', b' ')
self.assertRaises(RuntimeError, S.iter_unpack, spam)
self.assertRaises(RuntimeError, S.pack, 1)
self.assertRaises(RuntimeError, S.pack_into, spam, 1)
self.assertRaises(RuntimeError, S.unpack, spam)
self.assertRaises(RuntimeError, S.unpack_from, spam)
self.assertRaises(RuntimeError, getattr, S, 'format')
self.assertEqual(S.size, -1)


class UnpackIteratorTest(unittest.TestCase):
"""
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Raise :exc:`RuntimeError`'s when user attempts to call methods on
half-initialized :class:`~struct.Struct` objects, For example, created by
``Struct.__new__(Struct)``. Patch by Sergey B Kirpichev.
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Forbid reentrant calls of the :class:`pickle.Pickler` and
:class:`pickle.Unpickler` methods for the C implementation. Previously, this
could cause crash or data corruption, now concurrent calls of methods of the
same object raise :exc:`RuntimeError`.
Loading
Loading