Skip to content

Commit f60f9ec

Browse files
authored
Merge branch 'main' into fix-opt-default
2 parents e712a28 + f87eb4d commit f60f9ec

File tree

14 files changed

+2177
-1026
lines changed

14 files changed

+2177
-1026
lines changed

Doc/c-api/descriptor.rst

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,46 @@ found in the dictionary of type objects.
2121
.. c:function:: PyObject* PyDescr_NewMember(PyTypeObject *type, struct PyMemberDef *meth)
2222
2323
24+
.. c:var:: PyTypeObject PyMemberDescr_Type
25+
26+
The type object for member descriptor objects created from
27+
:c:type:`PyMemberDef` structures. These descriptors expose fields of a
28+
C struct as attributes on a type, and correspond
29+
to :class:`types.MemberDescriptorType` objects in Python.
30+
31+
32+
33+
.. c:var:: PyTypeObject PyGetSetDescr_Type
34+
35+
The type object for get/set descriptor objects created from
36+
:c:type:`PyGetSetDef` structures. These descriptors implement attributes
37+
whose value is computed by C getter and setter functions, and are used
38+
for many built-in type attributes.
39+
40+
2441
.. c:function:: PyObject* PyDescr_NewMethod(PyTypeObject *type, struct PyMethodDef *meth)
2542
2643
44+
.. c:var:: PyTypeObject PyMethodDescr_Type
45+
46+
The type object for method descriptor objects created from
47+
:c:type:`PyMethodDef` structures. These descriptors expose C functions as
48+
methods on a type, and correspond to :class:`types.MemberDescriptorType`
49+
objects in Python.
50+
51+
2752
.. c:function:: PyObject* PyDescr_NewWrapper(PyTypeObject *type, struct wrapperbase *wrapper, void *wrapped)
2853
2954
55+
.. c:var:: PyTypeObject PyWrapperDescr_Type
56+
57+
The type object for wrapper descriptor objects created by
58+
:c:func:`PyDescr_NewWrapper` and :c:func:`PyWrapper_New`. Wrapper
59+
descriptors are used internally to expose special methods implemented
60+
via wrapper structures, and appear in Python as
61+
:class:`types.WrapperDescriptorType` objects.
62+
63+
3064
.. c:function:: PyObject* PyDescr_NewClassMethod(PyTypeObject *type, PyMethodDef *method)
3165
3266
@@ -55,6 +89,14 @@ Built-in descriptors
5589
:class:`classmethod` in the Python layer.
5690
5791
92+
.. c:var:: PyTypeObject PyClassMethodDescr_Type
93+
94+
The type object for C-level class method descriptor objects.
95+
This is the type of the descriptors created for :func:`classmethod` defined in
96+
C extension types, and is the same object as :class:`classmethod`
97+
in Python.
98+
99+
58100
.. c:function:: PyObject *PyClassMethod_New(PyObject *callable)
59101
60102
Create a new :class:`classmethod` object wrapping *callable*.

Doc/c-api/dict.rst

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,17 @@ Dictionary Objects
4343
prevent modification of the dictionary for non-dynamic class types.
4444
4545
46+
.. c:var:: PyTypeObject PyDictProxy_Type
47+
48+
The type object for mapping proxy objects created by
49+
:c:func:`PyDictProxy_New` and for the read-only ``__dict__`` attribute
50+
of many built-in types. A :c:type:`PyDictProxy_Type` instance provides a
51+
dynamic, read-only view of an underlying dictionary: changes to the
52+
underlying dictionary are reflected in the proxy, but the proxy itself
53+
does not support mutation operations. This corresponds to
54+
:class:`types.MappingProxyType` in Python.
55+
56+
4657
.. c:function:: void PyDict_Clear(PyObject *p)
4758
4859
Empty an existing dictionary of all key-value pairs.

Lib/http/client.py

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,11 @@
111111
_MAXLINE = 65536
112112
_MAXHEADERS = 100
113113

114+
# Data larger than this will be read in chunks, to prevent extreme
115+
# overallocation.
116+
_MIN_READ_BUF_SIZE = 1 << 20
117+
118+
114119
# Header name/value ABNF (http://tools.ietf.org/html/rfc7230#section-3.2)
115120
#
116121
# VCHAR = %x21-7E
@@ -642,10 +647,25 @@ def _safe_read(self, amt):
642647
reading. If the bytes are truly not available (due to EOF), then the
643648
IncompleteRead exception can be used to detect the problem.
644649
"""
645-
data = self.fp.read(amt)
646-
if len(data) < amt:
647-
raise IncompleteRead(data, amt-len(data))
648-
return data
650+
cursize = min(amt, _MIN_READ_BUF_SIZE)
651+
data = self.fp.read(cursize)
652+
if len(data) >= amt:
653+
return data
654+
if len(data) < cursize:
655+
raise IncompleteRead(data, amt - len(data))
656+
657+
data = io.BytesIO(data)
658+
data.seek(0, 2)
659+
while True:
660+
# This is a geometric increase in read size (never more than
661+
# doubling out the current length of data per loop iteration).
662+
delta = min(cursize, amt - cursize)
663+
data.write(self.fp.read(delta))
664+
if data.tell() >= amt:
665+
return data.getvalue()
666+
cursize += delta
667+
if data.tell() < cursize:
668+
raise IncompleteRead(data.getvalue(), amt - data.tell())
649669

650670
def _safe_readinto(self, b):
651671
"""Same as _safe_read, but for reading into a buffer."""

Lib/plistlib.py

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,9 @@
7373
PlistFormat = enum.Enum('PlistFormat', 'FMT_XML FMT_BINARY', module=__name__)
7474
globals().update(PlistFormat.__members__)
7575

76+
# Data larger than this will be read in chunks, to prevent extreme
77+
# overallocation.
78+
_MIN_READ_BUF_SIZE = 1 << 20
7679

7780
class UID:
7881
def __init__(self, data):
@@ -508,12 +511,24 @@ def _get_size(self, tokenL):
508511

509512
return tokenL
510513

514+
def _read(self, size):
515+
cursize = min(size, _MIN_READ_BUF_SIZE)
516+
data = self._fp.read(cursize)
517+
while True:
518+
if len(data) != cursize:
519+
raise InvalidFileException
520+
if cursize == size:
521+
return data
522+
delta = min(cursize, size - cursize)
523+
data += self._fp.read(delta)
524+
cursize += delta
525+
511526
def _read_ints(self, n, size):
512-
data = self._fp.read(size * n)
527+
data = self._read(size * n)
513528
if size in _BINARY_FORMAT:
514529
return struct.unpack(f'>{n}{_BINARY_FORMAT[size]}', data)
515530
else:
516-
if not size or len(data) != size * n:
531+
if not size:
517532
raise InvalidFileException()
518533
return tuple(int.from_bytes(data[i: i + size], 'big')
519534
for i in range(0, size * n, size))
@@ -573,22 +588,16 @@ def _read_object(self, ref):
573588

574589
elif tokenH == 0x40: # data
575590
s = self._get_size(tokenL)
576-
result = self._fp.read(s)
577-
if len(result) != s:
578-
raise InvalidFileException()
591+
result = self._read(s)
579592

580593
elif tokenH == 0x50: # ascii string
581594
s = self._get_size(tokenL)
582-
data = self._fp.read(s)
583-
if len(data) != s:
584-
raise InvalidFileException()
595+
data = self._read(s)
585596
result = data.decode('ascii')
586597

587598
elif tokenH == 0x60: # unicode string
588599
s = self._get_size(tokenL) * 2
589-
data = self._fp.read(s)
590-
if len(data) != s:
591-
raise InvalidFileException()
600+
data = self._read(s)
592601
result = data.decode('utf-16be')
593602

594603
elif tokenH == 0x80: # UID

0 commit comments

Comments
 (0)