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
5 changes: 4 additions & 1 deletion Doc/library/json.rst
Original file line number Diff line number Diff line change
Expand Up @@ -486,7 +486,7 @@ Encoders and Decoders
+----------------------------------------+---------------+
| Python | JSON |
+========================================+===============+
| dict | object |
| dict, frozendict | object |
+----------------------------------------+---------------+
| list, tuple | array |
+----------------------------------------+---------------+
Expand All @@ -504,6 +504,9 @@ Encoders and Decoders
.. versionchanged:: 3.4
Added support for int- and float-derived Enum classes.

.. versionchanged:: 3.15
Added support for :class:`frozendict`.

To extend this to recognize other objects, subclass and implement a
:meth:`~JSONEncoder.default` method with another method that returns a serializable object
for ``o`` if possible, otherwise it should call the superclass implementation
Expand Down
4 changes: 2 additions & 2 deletions Lib/calendar.py
Original file line number Diff line number Diff line change
Expand Up @@ -609,11 +609,11 @@ def formatyearpage(self, theyear, width=3, css='calendar.css', encoding=None):
content = self.formatyear(theyear, width)
return self._format_html_page(theyear, content, css, encoding)

def formatmonthpage(self, theyear, themonth, width=3, css='calendar.css', encoding=None):
def formatmonthpage(self, theyear, themonth, *, css='calendar.css', encoding=None):
"""
Return a formatted month as a complete HTML page.
"""
content = self.formatmonth(theyear, themonth, width)
content = self.formatmonth(theyear, themonth)
return self._format_html_page(theyear, content, css, encoding)


Expand Down
6 changes: 6 additions & 0 deletions Lib/test/test_calendar.py
Original file line number Diff line number Diff line change
Expand Up @@ -545,6 +545,12 @@ def test_format_html_year_with_month(self):
result_2009_6_html
)

def test_formatmonthpage_no_width(self):
# gh-140212: formatmonthpage must not accept a 'width' argument.
cal = calendar.HTMLCalendar()
self.assertIn(b'class="month">June 2009', cal.formatmonthpage(2009, 6))
self.assertRaises(TypeError, cal.formatmonthpage, 2009, 6, width=3)


class CalendarTestCase(unittest.TestCase):

Expand Down
10 changes: 10 additions & 0 deletions Lib/test/test_marshal.py
Original file line number Diff line number Diff line change
Expand Up @@ -386,6 +386,16 @@ def test_reference_loop_frozendict(self):
for v in range(marshal.version + 1):
self.assertRaises(ValueError, marshal.dumps, a, v)

def test_shared_reference_frozendict(self):
# A frozendict referenced more than once must round-trip with the
# shared identity preserved, like frozenset.
fd = frozendict({'a': 1, 'b': 2})
out = marshal.loads(marshal.dumps([fd, fd]))
self.assertEqual(out[0], fd)
self.assertIs(out[0], out[1])
nested = marshal.loads(marshal.dumps(frozendict({'x': fd, 'y': fd})))
self.assertIs(nested['x'], nested['y'])

def test_loads_reference_loop_list(self):
data = b'\xdb\x01\x00\x00\x00r\x00\x00\x00\x00' # [<R>]
a = marshal.loads(data)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Fix :mod:`marshal` so that a ``frozendict`` referenced more than once in the
serialized data round-trips correctly, instead of failing to load with
:exc:`ValueError`. Patch by tonghuaroot.
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Remove the erroneous *width* argument of
:meth:`!calendar.HTMLCalendar.formatmonthpage`, which could drop the year from
the heading.
9 changes: 3 additions & 6 deletions Modules/_sre/sre.c
Original file line number Diff line number Diff line change
Expand Up @@ -1273,8 +1273,7 @@ _sre_SRE_Pattern_split_impl(PatternObject *self, PyObject *string,
);
if (!item)
goto error;
status = PyList_Append(list, item);
Py_DECREF(item);
status = _PyList_AppendTakeRef((PyListObject *)list, item);
if (status < 0)
goto error;

Expand All @@ -1283,8 +1282,7 @@ _sre_SRE_Pattern_split_impl(PatternObject *self, PyObject *string,
item = state_getslice(&state, i+1, string, 0);
if (!item)
goto error;
status = PyList_Append(list, item);
Py_DECREF(item);
status = _PyList_AppendTakeRef((PyListObject *)list, item);
if (status < 0)
goto error;
}
Expand All @@ -1301,8 +1299,7 @@ _sre_SRE_Pattern_split_impl(PatternObject *self, PyObject *string,
);
if (!item)
goto error;
status = PyList_Append(list, item);
Py_DECREF(item);
status = _PyList_AppendTakeRef((PyListObject *)list, item);
if (status < 0)
goto error;

Expand Down
16 changes: 5 additions & 11 deletions Objects/stringlib/split.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
#error must include "stringlib/fastsearch.h" before including this module
#endif

#include "pycore_list.h" // _PyList_AppendTakeRef()

/* Overallocate the initial list to reduce the number of reallocs for small
split sizes. Eg, "A A A A A A A A A A".split() (10 elements) has three
resizes, to sizes 4, 8, then 16. Most observed string splits are for human
Expand All @@ -22,12 +24,8 @@
(right) - (left)); \
if (sub == NULL) \
goto onError; \
if (PyList_Append(list, sub)) { \
Py_DECREF(sub); \
goto onError; \
} \
else \
Py_DECREF(sub);
if (_PyList_AppendTakeRef((PyListObject *)list, sub)) \
goto onError;

#define SPLIT_ADD(data, left, right) { \
sub = STRINGLIB_NEW((data) + (left), \
Expand All @@ -37,12 +35,8 @@
if (count < MAX_PREALLOC) { \
PyList_SET_ITEM(list, count, sub); \
} else { \
if (PyList_Append(list, sub)) { \
Py_DECREF(sub); \
if (_PyList_AppendTakeRef((PyListObject *)list, sub)) \
goto onError; \
} \
else \
Py_DECREF(sub); \
} \
count++; }

Expand Down
1 change: 1 addition & 0 deletions Python/marshal.c
Original file line number Diff line number Diff line change
Expand Up @@ -1505,6 +1505,7 @@ r_object(RFILE *p)
}
if (type == TYPE_FROZENDICT && v != NULL) {
Py_SETREF(v, PyFrozenDict_New(v));
v = r_ref_insert(v, idx, flag, p);
}
retval = v;
break;
Expand Down
Loading