diff options
-rw-r--r-- | Doc/c-api/typeobj.rst | 5 | ||||
-rw-r--r-- | Doc/library/logging.config.rst | 25 | ||||
-rw-r--r-- | Lib/calendar.py | 11 | ||||
-rw-r--r-- | Lib/test/pickletester.py | 13 | ||||
-rw-r--r-- | Lib/test/test_calendar.py | 7 | ||||
-rw-r--r-- | Misc/NEWS | 5 | ||||
-rw-r--r-- | Modules/_pickle.c | 3 |
7 files changed, 63 insertions, 6 deletions
diff --git a/Doc/c-api/typeobj.rst b/Doc/c-api/typeobj.rst index 4a6335c..68ca9ad 100644 --- a/Doc/c-api/typeobj.rst +++ b/Doc/c-api/typeobj.rst @@ -745,6 +745,11 @@ type objects) *must* have the :attr:`ob_size` field. This field is not inherited by subtypes (though the attributes defined in here are inherited through a different mechanism). + .. warning:: + + It is not safe to use :c:func:`PyDict_SetItem` on or otherwise modify + :attr:`tp_dict` with the dictionary C-API. + .. c:member:: descrgetfunc PyTypeObject.tp_descr_get diff --git a/Doc/library/logging.config.rst b/Doc/library/logging.config.rst index bb80a7f..b2dd71e 100644 --- a/Doc/library/logging.config.rst +++ b/Doc/library/logging.config.rst @@ -513,6 +513,31 @@ the system will attempt to retrieve the value from to ``config_dict['handlers']['myhandler']['mykey']['123']`` if that fails. + +.. _logging-import-resolution: + +Import resolution and custom importers +"""""""""""""""""""""""""""""""""""""" + +Import resolution, by default, uses the builtin :func:`__import__` function +to do its importing. You may want to replace this with your own importing +mechanism: if so, you can replace the :attr:`importer` attribute of the +:class:`DictConfigurator` or its superclass, the +:class:`BaseConfigurator` class. However, you need to be +careful because of the way functions are accessed from classes via +descriptors. If you are using a Python callable to do your imports, and you +want to define it at class level rather than instance level, you need to wrap +it with :func:`staticmethod`. For example:: + + from importlib import import_module + from logging.config import BaseConfigurator + + BaseConfigurator.importer = staticmethod(import_module) + +You don't need to wrap with :func:`staticmethod` if you're setting the import +callable on a configurator *instance*. + + .. _logging-config-fileformat: Configuration file format diff --git a/Lib/calendar.py b/Lib/calendar.py index 84aa3a4..0301d6b 100644 --- a/Lib/calendar.py +++ b/Lib/calendar.py @@ -636,7 +636,7 @@ def main(args): parser.add_option( "-e", "--encoding", dest="encoding", default=None, - help="Encoding to use for output" + help="Encoding to use for output." ) parser.add_option( "-t", "--type", @@ -662,10 +662,11 @@ def main(args): if encoding is None: encoding = sys.getdefaultencoding() optdict = dict(encoding=encoding, css=options.css) + write = sys.stdout.buffer.write if len(args) == 1: - print(cal.formatyearpage(datetime.date.today().year, **optdict)) + write(cal.formatyearpage(datetime.date.today().year, **optdict)) elif len(args) == 2: - print(cal.formatyearpage(int(args[1]), **optdict)) + write(cal.formatyearpage(int(args[1]), **optdict)) else: parser.error("incorrect number of arguments") sys.exit(1) @@ -687,9 +688,11 @@ def main(args): else: parser.error("incorrect number of arguments") sys.exit(1) + write = sys.stdout.write if options.encoding: result = result.encode(options.encoding) - print(result) + write = sys.stdout.buffer.write + write(result) if __name__ == "__main__": diff --git a/Lib/test/pickletester.py b/Lib/test/pickletester.py index a843486..e4ab0dd 100644 --- a/Lib/test/pickletester.py +++ b/Lib/test/pickletester.py @@ -1418,6 +1418,19 @@ class AbstractPicklerUnpicklerObjectTests(unittest.TestCase): def test_multiple_unpicklings_unseekable(self): self._check_multiple_unpicklings(UnseekableIO) + def test_unpickling_buffering_readline(self): + # Issue #12687: the unpickler's buffering logic could fail with + # text mode opcodes. + data = list(range(10)) + for proto in protocols: + for buf_size in range(1, 11): + f = io.BufferedRandom(io.BytesIO(), buffer_size=buf_size) + pickler = self.pickler_class(f, protocol=proto) + pickler.dump(data) + f.seek(0) + unpickler = self.unpickler_class(f) + self.assertEqual(unpickler.load(), data) + if __name__ == "__main__": # Print some stuff that can be used to rewrite DATA{0,1,2} diff --git a/Lib/test/test_calendar.py b/Lib/test/test_calendar.py index 4bd758b..d3093ac 100644 --- a/Lib/test/test_calendar.py +++ b/Lib/test/test_calendar.py @@ -2,6 +2,7 @@ import calendar import unittest from test import support +from test.script_helper import assert_python_ok import time import locale @@ -451,6 +452,11 @@ class LeapdaysTestCase(unittest.TestCase): self.assertEqual(calendar.leapdays(1997,2020), 5) +class ConsoleOutputTestCase(unittest.TestCase): + def test_outputs_bytes(self): + (return_code, stdout, stderr) = assert_python_ok('-m', 'calendar', '--type=html', '2010') + self.assertEqual(stdout[:6], b'<?xml ') + def test_main(): support.run_unittest( OutputTestCase, @@ -460,6 +466,7 @@ def test_main(): TimegmTestCase, MonthRangeTestCase, LeapdaysTestCase, + ConsoleOutputTestCase ) @@ -41,6 +41,11 @@ Core and Builtins Library ------- +- Issue #12687: Fix a possible buffering bug when unpickling text mode + (protocol 0, mostly) pickles. + +- Issue #10087: Fix the html output format of the calendar module. + - Issue #12540: Prevent zombie IDLE processes on Windows due to changes in os.kill(). diff --git a/Modules/_pickle.c b/Modules/_pickle.c index 287f0a3..001360b 100644 --- a/Modules/_pickle.c +++ b/Modules/_pickle.c @@ -1034,9 +1034,8 @@ _Unpickler_Readline(UnpicklerObject *self, char **result) num_read = _Unpickler_ReadFromFile(self, READ_WHOLE_LINE); if (num_read < 0) return -1; - *result = self->input_buffer; self->next_read_idx = num_read; - return num_read; + return _Unpickler_CopyLine(self, self->input_buffer, num_read, result); } /* If we get here, we've run off the end of the input string. Return the |