From a6dc531063efe3a8d47ff4639729060c72a3688c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Delfino?= Date: Fri, 26 Oct 2018 11:56:57 -0300 Subject: [PATCH] bpo-34789: make xml.sax.make_parser accept iterables of all types (GH-9576) --- Doc/library/xml.sax.rst | 5 +++- Lib/test/test_sax.py | 28 +++++++++++++++++++ Lib/xml/sax/__init__.py | 8 +++--- .../2018-09-25-15-48-50.bpo-34789.rPOEj5.rst | 2 ++ 4 files changed, 38 insertions(+), 5 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2018-09-25-15-48-50.bpo-34789.rPOEj5.rst diff --git a/Doc/library/xml.sax.rst b/Doc/library/xml.sax.rst index aa3ea9bfc55a98..0b6973b8c8a8b3 100644 --- a/Doc/library/xml.sax.rst +++ b/Doc/library/xml.sax.rst @@ -40,10 +40,13 @@ The convenience functions are: Create and return a SAX :class:`~xml.sax.xmlreader.XMLReader` object. The first parser found will - be used. If *parser_list* is provided, it must be a sequence of strings which + be used. If *parser_list* is provided, it must be an iterable of strings which name modules that have a function named :func:`create_parser`. Modules listed in *parser_list* will be used before modules in the default list of parsers. + .. versionchanged:: 3.8 + The *parser_list* argument can be any iterable, not just a list. + .. function:: parse(filename_or_stream, handler, error_handler=handler.ErrorHandler()) diff --git a/Lib/test/test_sax.py b/Lib/test/test_sax.py index 3044960a0ed165..894d86ac71f03c 100644 --- a/Lib/test/test_sax.py +++ b/Lib/test/test_sax.py @@ -254,6 +254,34 @@ def test_make_parser2(self): from xml.sax import make_parser p = make_parser() + def test_make_parser3(self): + # Testing that make_parser can handle different types of + # iterables. + make_parser(['module']) + make_parser(('module', )) + make_parser({'module'}) + make_parser(frozenset({'module'})) + make_parser({'module': None}) + make_parser(iter(['module'])) + + def test_make_parser4(self): + # Testing that make_parser can handle empty iterables. + make_parser([]) + make_parser(tuple()) + make_parser(set()) + make_parser(frozenset()) + make_parser({}) + make_parser(iter([])) + + def test_make_parser5(self): + # Testing that make_parser can handle iterables with more than + # one item. + make_parser(['module1', 'module2']) + make_parser(('module1', 'module2')) + make_parser({'module1', 'module2'}) + make_parser(frozenset({'module1', 'module2'})) + make_parser({'module1': None, 'module2': None}) + make_parser(iter(['module1', 'module2'])) # =========================================================================== # diff --git a/Lib/xml/sax/__init__.py b/Lib/xml/sax/__init__.py index 13f6cf58d0d2f2..a0f5d40b2000ce 100644 --- a/Lib/xml/sax/__init__.py +++ b/Lib/xml/sax/__init__.py @@ -67,15 +67,15 @@ def parseString(string, handler, errorHandler=ErrorHandler()): default_parser_list = sys.registry.getProperty(_key).split(",") -def make_parser(parser_list = []): +def make_parser(parser_list=()): """Creates and returns a SAX parser. Creates the first parser it is able to instantiate of the ones - given in the list created by doing parser_list + - default_parser_list. The lists must contain the names of Python + given in the iterable created by chaining parser_list and + default_parser_list. The iterables must contain the names of Python modules containing both a SAX parser and a create_parser function.""" - for parser_name in parser_list + default_parser_list: + for parser_name in list(parser_list) + default_parser_list: try: return _create_parser(parser_name) except ImportError as e: diff --git a/Misc/NEWS.d/next/Library/2018-09-25-15-48-50.bpo-34789.rPOEj5.rst b/Misc/NEWS.d/next/Library/2018-09-25-15-48-50.bpo-34789.rPOEj5.rst new file mode 100644 index 00000000000000..28f15c3f41225f --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-09-25-15-48-50.bpo-34789.rPOEj5.rst @@ -0,0 +1,2 @@ +:func:`xml.sax.make_parser` now accepts any iterable as its *parser_list* +argument. Patch by Andrés Delfino.