1 # Authors: David Goodger; Garth Kidd
2 # Contact: goodger@users.sourceforge.net
5 # Copyright: This module has been placed in the public domain.
11 - `statemachine` is 'docutils.statemachine'
12 - `nodes` is 'docutils.nodes'
13 - `urischemes` is 'docutils.urischemes'
14 - `utils` is 'docutils.utils'
15 - `transforms` is 'docutils.transforms'
16 - `states` is 'docutils.parsers.rst.states'
17 - `tableparser` is 'docutils.parsers.rst.tableparser'
24 - `TransformTestSuite`
27 - `ParserTransformTestCase`
29 - `PEPParserTestSuite`
30 - `GridTableParserTestCase`
31 - `GridTableParserTestSuite`
32 - `SimpleTableParserTestCase`
33 - `SimpleTableParserTestSuite`
34 - `WriterPublishTestCase`
35 - `LatexWriterPublishTestCase`
36 - `PseudoXMLWriterPublishTestCase`
37 - `HtmlWriterPublishTestCase`
39 - `HtmlFragmentTestSuite`
40 - `DevNull` (output sink)
42 __docformat__
= 'reStructuredText'
47 testroot
= os
.path
.abspath(os
.path
.dirname(__file__
) or os
.curdir
)
49 sys
.path
.insert(0, os
.path
.normpath(os
.path
.join(testroot
, '..')))
50 sys
.path
.insert(0, testroot
)
51 sys
.path
.append(os
.path
.normpath(os
.path
.join(testroot
, '..', 'extras')))
54 import docutils_difflib
56 from pprint
import pformat
57 from types
import UnicodeType
, StringType
58 import package_unittest
61 from docutils
import frontend
, nodes
, statemachine
, urischemes
, utils
62 from docutils
.transforms
import universal
63 from docutils
.parsers
import rst
64 from docutils
.parsers
.rst
import states
, tableparser
, roles
, languages
65 from docutils
.readers
import standalone
, pep
66 from docutils
.statemachine
import StringList
, string2lines
69 from docutils
.readers
.python
import moduleparser
70 from tokenize
import generate_tokens
72 except ImportError: # moduleparser depends on modules added in Python 2.2
81 # Hack to make repr(StringList) look like repr(list):
82 StringList
.__repr
__ = StringList
.__str
__
89 def write(self
, string
):
96 class StandardTestCase(unittest
.TestCase
):
99 Helper class, providing the same interface as unittest.TestCase,
100 but with useful setUp and comparison methods.
106 def failUnlessEqual(self
, first
, second
, msg
=None):
107 """Fail if the two objects are unequal as determined by the '=='
110 if not first
== second
:
111 raise self
.failureException
, \
112 (msg
or '%s != %s' % _format_str(first
, second
))
114 def failIfEqual(self
, first
, second
, msg
=None):
115 """Fail if the two objects are equal as determined by the '=='
119 raise self
.failureException
, \
120 (msg
or '%s == %s' % _format_str(first
, second
))
122 # Synonyms for assertion methods
124 assertEqual
= assertEquals
= failUnlessEqual
126 assertNotEqual
= assertNotEquals
= failIfEqual
129 class CustomTestCase(StandardTestCase
):
132 Helper class, providing extended functionality over unittest.TestCase.
134 The methods failUnlessEqual and failIfEqual have been overwritten
135 to provide better support for multi-line strings. Furthermore,
136 see the compare_output method and the parameter list of __init__.
139 compare
= docutils_difflib
.Differ().compare
140 """Comparison method shared by all subclasses."""
142 def __init__(self
, method_name
, input, expected
, id, run_in_debugger
=0,
143 suite_settings
=None):
145 Initialise the CustomTestCase.
149 method_name -- name of test method to run.
150 input -- input to the parser.
151 expected -- expected output from the parser.
152 id -- unique test identifier, used by the test framework.
153 run_in_debugger -- if true, run this test under the pdb debugger.
154 suite_settings -- settings overrides for this test suite.
158 self
.expected
= expected
159 self
.run_in_debugger
= run_in_debugger
160 self
.suite_settings
= suite_settings
or {}
163 unittest
.TestCase
.__init
__(self
, method_name
)
167 Return string conversion. Overridden to give test id, in addition to
170 return '%s; %s' % (self
.id, unittest
.TestCase
.__str
__(self
))
173 return "<%s %s>" % (self
.id, unittest
.TestCase
.__repr
__(self
))
175 def clear_roles(self
):
176 # Language-specific roles and roles added by the
177 # "default-role" and "role" directives are currently stored
178 # globally in the roles._roles dictionary. This workaround
179 # empties that dictionary.
183 StandardTestCase
.setUp(self
)
186 def compare_output(self
, input, output
, expected
):
187 """`input`, `output`, and `expected` should all be strings."""
188 if isinstance(input, UnicodeType
):
189 input = input.encode('raw_unicode_escape')
190 if isinstance(output
, UnicodeType
):
191 output
= output
.encode('raw_unicode_escape')
192 if isinstance(expected
, UnicodeType
):
193 expected
= expected
.encode('raw_unicode_escape')
195 self
.assertEquals(output
, expected
)
196 except AssertionError, error
:
197 print >>sys
.stderr
, '\n%s\ninput:' % (self
,)
198 print >>sys
.stderr
, input
200 comparison
= ''.join(self
.compare(expected
.splitlines(1),
201 output
.splitlines(1)))
202 print >>sys
.stderr
, '-: expected\n+: output'
203 print >>sys
.stderr
, comparison
204 except AttributeError: # expected or output not a string
205 # alternative output for non-strings:
206 print >>sys
.stderr
, 'expected: %r' % expected
207 print >>sys
.stderr
, 'output: %r' % output
211 class CustomTestSuite(unittest
.TestSuite
):
214 A collection of CustomTestCases.
216 Provides test suite ID generation and a method for adding test cases.
220 """Identifier for the TestSuite. Prepended to the
221 TestCase identifiers to make identification easier."""
223 next_test_case_id
= 0
224 """The next identifier to use for non-identified test cases."""
226 def __init__(self
, tests
=(), id=None, suite_settings
=None):
228 Initialize the CustomTestSuite.
232 id -- identifier for the suite, prepended to test cases.
233 suite_settings -- settings overrides for this test suite.
235 unittest
.TestSuite
.__init
__(self
, tests
)
236 self
.suite_settings
= suite_settings
or {}
238 mypath
= os
.path
.abspath(
239 sys
.modules
[CustomTestSuite
.__module
__].__file
__)
240 outerframes
= inspect
.getouterframes(inspect
.currentframe())
241 for outerframe
in outerframes
[1:]:
242 if outerframe
[3] != '__init__':
243 callerpath
= outerframe
[1]
244 if callerpath
is None:
245 # It happens sometimes. Why is a mystery.
246 callerpath
= os
.getcwd()
247 callerpath
= os
.path
.abspath(callerpath
)
249 mydir
, myname
= os
.path
.split(mypath
)
252 if callerpath
.startswith(mydir
):
253 self
.id = callerpath
[len(mydir
) + 1:] # caller's module
259 def addTestCase(self
, test_case_class
, method_name
, input, expected
,
260 id=None, run_in_debugger
=0, **kwargs
):
262 Create a CustomTestCase in the CustomTestSuite.
263 Also return it, just in case.
267 test_case_class -- the CustomTestCase to add
268 method_name -- a string; CustomTestCase.method_name is the test
269 input -- input to the parser.
270 expected -- expected output from the parser.
271 id -- unique test identifier, used by the test framework.
272 run_in_debugger -- if true, run this test under the pdb debugger.
274 if id is None: # generate id if required
275 id = self
.next_test_case_id
276 self
.next_test_case_id
+= 1
277 # test identifier will become suiteid.testid
278 tcid
= '%s: %s' % (self
.id, id)
279 # suite_settings may be passed as a parameter;
280 # if not, set from attribute:
281 kwargs
.setdefault('suite_settings', self
.suite_settings
)
282 # generate and add test case
283 tc
= test_case_class(method_name
, input, expected
, tcid
,
284 run_in_debugger
=run_in_debugger
, **kwargs
)
288 def generate_no_tests(self
, *args
, **kwargs
):
292 class TransformTestCase(CustomTestCase
):
295 Output checker for the transform.
297 Should probably be called TransformOutputChecker, but I can deal with
298 that later when/if someone comes up with a category of transform test
299 cases that have nothing to do with the input and output of the transform.
302 option_parser
= frontend
.OptionParser(components
=(rst
.Parser
,))
303 settings
= option_parser
.get_default_values()
304 settings
.report_level
= 1
305 settings
.halt_level
= 5
306 settings
.debug
= package_unittest
.debug
307 settings
.warning_stream
= DevNull()
308 unknown_reference_resolvers
= ()
310 def __init__(self
, *args
, **kwargs
):
311 self
.transforms
= kwargs
['transforms']
312 """List of transforms to perform for this test case."""
314 self
.parser
= kwargs
['parser']
315 """Input parser for this test case."""
317 del kwargs
['transforms'], kwargs
['parser'] # only wanted here
318 CustomTestCase
.__init
__(self
, *args
, **kwargs
)
320 def supports(self
, format
):
323 def test_transforms(self
):
324 if self
.run_in_debugger
:
326 settings
= self
.settings
.copy()
327 settings
.__dict
__.update(self
.suite_settings
)
328 document
= utils
.new_document('test data', settings
)
329 self
.parser
.parse(self
.input, document
)
330 # Don't do a ``populate_from_components()`` because that would
331 # enable the Transformer's default transforms.
332 document
.transformer
.add_transforms(self
.transforms
)
333 document
.transformer
.add_transform(universal
.TestMessages
)
334 document
.transformer
.components
['writer'] = self
335 document
.transformer
.apply_transforms()
336 output
= document
.pformat()
337 self
.compare_output(self
.input, output
, self
.expected
)
339 def test_transforms_verbosely(self
):
340 if self
.run_in_debugger
:
345 settings
= self
.settings
.copy()
346 settings
.__dict
__.update(self
.suite_settings
)
347 document
= utils
.new_document('test data', settings
)
348 self
.parser
.parse(self
.input, document
)
350 print document
.pformat()
351 for transformClass
in self
.transforms
:
352 transformClass(document
).apply()
353 output
= document
.pformat()
356 self
.compare_output(self
.input, output
, self
.expected
)
359 class TransformTestSuite(CustomTestSuite
):
362 A collection of TransformTestCases.
364 A TransformTestSuite instance manufactures TransformTestCases,
365 keeps track of them, and provides a shared test fixture (a-la
369 def __init__(self
, parser
, suite_settings
=None):
371 """Parser shared by all test cases."""
373 CustomTestSuite
.__init
__(self
, suite_settings
=suite_settings
)
375 def generateTests(self
, dict, dictname
='totest',
376 testmethod
='test_transforms'):
378 Stock the suite with test cases generated from a test data dictionary.
380 Each dictionary key (test type's name) maps to a tuple, whose
381 first item is a list of transform classes and whose second
382 item is a list of tests. Each test is a list: input, expected
383 output, optional modifier. The optional third entry, a
384 behavior modifier, can be 0 (temporarily disable this test) or
385 1 (run this test under the pdb debugger). Tests should be
386 self-documenting and not require external comments.
388 for name
, (transforms
, cases
) in dict.items():
389 for casenum
in range(len(cases
)):
390 case
= cases
[casenum
]
393 # TODO: (maybe) change the 3rd argument to a dict, so it
394 # can handle more cases by keyword ('disable', 'debug',
395 # 'settings'), here and in other generateTests methods.
396 # But there's also the method that
397 # HtmlPublishPartsTestSuite uses <DJG>
403 TransformTestCase
, testmethod
,
404 transforms
=transforms
, parser
=self
.parser
,
405 input=case
[0], expected
=case
[1],
406 id='%s[%r][%s]' % (dictname
, name
, casenum
),
407 run_in_debugger
=run_in_debugger
)
410 class ParserTestCase(CustomTestCase
):
413 Output checker for the parser.
415 Should probably be called ParserOutputChecker, but I can deal with
416 that later when/if someone comes up with a category of parser test
417 cases that have nothing to do with the input and output of the parser.
420 parser
= rst
.Parser()
421 """Parser shared by all ParserTestCases."""
423 option_parser
= frontend
.OptionParser(components
=(rst
.Parser
,))
424 settings
= option_parser
.get_default_values()
425 settings
.report_level
= 5
426 settings
.halt_level
= 5
427 settings
.debug
= package_unittest
.debug
429 def test_parser(self
):
430 if self
.run_in_debugger
:
432 settings
= self
.settings
.copy()
433 settings
.__dict
__.update(self
.suite_settings
)
434 document
= utils
.new_document('test data', settings
)
435 self
.parser
.parse(self
.input, document
)
436 output
= document
.pformat()
437 self
.compare_output(self
.input, output
, self
.expected
)
440 class ParserTestSuite(CustomTestSuite
):
443 A collection of ParserTestCases.
445 A ParserTestSuite instance manufactures ParserTestCases,
446 keeps track of them, and provides a shared test fixture (a-la
450 test_case_class
= ParserTestCase
452 def generateTests(self
, dict, dictname
='totest'):
454 Stock the suite with test cases generated from a test data dictionary.
456 Each dictionary key (test type name) maps to a list of tests. Each
457 test is a list: input, expected output, optional modifier. The
458 optional third entry, a behavior modifier, can be 0 (temporarily
459 disable this test) or 1 (run this test under the pdb debugger). Tests
460 should be self-documenting and not require external comments.
462 for name
, cases
in dict.items():
463 for casenum
in range(len(cases
)):
464 case
= cases
[casenum
]
472 self
.test_case_class
, 'test_parser',
473 input=case
[0], expected
=case
[1],
474 id='%s[%r][%s]' % (dictname
, name
, casenum
),
475 run_in_debugger
=run_in_debugger
)
478 class PEPParserTestCase(ParserTestCase
):
480 """PEP-specific parser test case."""
482 parser
= rst
.Parser(rfc2822
=1, inliner
=rst
.states
.Inliner())
483 """Parser shared by all PEPParserTestCases."""
485 option_parser
= frontend
.OptionParser(components
=(rst
.Parser
, pep
.Reader
))
486 settings
= option_parser
.get_default_values()
487 settings
.report_level
= 5
488 settings
.halt_level
= 5
489 settings
.debug
= package_unittest
.debug
492 class PEPParserTestSuite(ParserTestSuite
):
494 """A collection of PEPParserTestCases."""
496 test_case_class
= PEPParserTestCase
499 class GridTableParserTestCase(CustomTestCase
):
501 parser
= tableparser
.GridTableParser()
503 def test_parse_table(self
):
504 self
.parser
.setup(StringList(string2lines(self
.input), 'test data'))
506 self
.parser
.find_head_body_sep()
507 self
.parser
.parse_table()
508 output
= self
.parser
.cells
509 except Exception, details
:
510 output
= '%s: %s' % (details
.__class
__.__name
__, details
)
511 self
.compare_output(self
.input, pformat(output
) + '\n',
512 pformat(self
.expected
) + '\n')
514 def test_parse(self
):
516 output
= self
.parser
.parse(StringList(string2lines(self
.input),
518 except Exception, details
:
519 output
= '%s: %s' % (details
.__class
__.__name
__, details
)
520 self
.compare_output(self
.input, pformat(output
) + '\n',
521 pformat(self
.expected
) + '\n')
524 class GridTableParserTestSuite(CustomTestSuite
):
527 A collection of GridTableParserTestCases.
529 A GridTableParserTestSuite instance manufactures GridTableParserTestCases,
530 keeps track of them, and provides a shared test fixture (a-la setUp and
534 test_case_class
= GridTableParserTestCase
536 def generateTests(self
, dict, dictname
='totest'):
538 Stock the suite with test cases generated from a test data dictionary.
540 Each dictionary key (test type name) maps to a list of tests. Each
541 test is a list: an input table, expected output from parse_table(),
542 expected output from parse(), optional modifier. The optional fourth
543 entry, a behavior modifier, can be 0 (temporarily disable this test)
544 or 1 (run this test under the pdb debugger). Tests should be
545 self-documenting and not require external comments.
547 for name
, cases
in dict.items():
548 for casenum
in range(len(cases
)):
549 case
= cases
[casenum
]
556 self
.addTestCase(self
.test_case_class
, 'test_parse_table',
557 input=case
[0], expected
=case
[1],
558 id='%s[%r][%s]' % (dictname
, name
, casenum
),
559 run_in_debugger
=run_in_debugger
)
560 self
.addTestCase(self
.test_case_class
, 'test_parse',
561 input=case
[0], expected
=case
[2],
562 id='%s[%r][%s]' % (dictname
, name
, casenum
),
563 run_in_debugger
=run_in_debugger
)
566 class SimpleTableParserTestCase(GridTableParserTestCase
):
568 parser
= tableparser
.SimpleTableParser()
571 class SimpleTableParserTestSuite(CustomTestSuite
):
574 A collection of SimpleTableParserTestCases.
577 test_case_class
= SimpleTableParserTestCase
579 def generateTests(self
, dict, dictname
='totest'):
581 Stock the suite with test cases generated from a test data dictionary.
583 Each dictionary key (test type name) maps to a list of tests. Each
584 test is a list: an input table, expected output from parse(), optional
585 modifier. The optional third entry, a behavior modifier, can be 0
586 (temporarily disable this test) or 1 (run this test under the pdb
587 debugger). Tests should be self-documenting and not require external
590 for name
, cases
in dict.items():
591 for casenum
in range(len(cases
)):
592 case
= cases
[casenum
]
599 self
.addTestCase(self
.test_case_class
, 'test_parse',
600 input=case
[0], expected
=case
[1],
601 id='%s[%r][%s]' % (dictname
, name
, casenum
),
602 run_in_debugger
=run_in_debugger
)
605 class PythonModuleParserTestCase(CustomTestCase
):
607 def test_parser(self
):
608 if self
.run_in_debugger
:
610 module
= moduleparser
.parse_module(self
.input, 'test data').pformat()
612 self
.compare_output(self
.input, output
, self
.expected
)
614 def test_token_parser_rhs(self
):
615 if self
.run_in_debugger
:
617 tr
= moduleparser
.TokenParser(self
.input)
619 self
.compare_output(self
.input, output
, self
.expected
)
622 class PythonModuleParserTestSuite(CustomTestSuite
):
625 A collection of PythonModuleParserTestCase.
630 def __init__(self
, *args
, **kwargs
):
631 if moduleparser
is None:
632 if not self
.notified
:
633 print ('Tests of docutils.readers.python skipped; '
634 'Python 2.2 or higher required.')
635 PythonModuleParserTestSuite
.notified
= 1
636 self
.generateTests
= self
.generate_no_tests
637 CustomTestSuite
.__init
__(self
, *args
, **kwargs
)
639 def generateTests(self
, dict, dictname
='totest',
640 testmethod
='test_parser'):
642 Stock the suite with test cases generated from a test data dictionary.
644 Each dictionary key (test type's name) maps to a list of tests. Each
645 test is a list: input, expected output, optional modifier. The
646 optional third entry, a behavior modifier, can be 0 (temporarily
647 disable this test) or 1 (run this test under the pdb debugger). Tests
648 should be self-documenting and not require external comments.
650 for name
, cases
in dict.items():
651 for casenum
in range(len(cases
)):
652 case
= cases
[casenum
]
660 PythonModuleParserTestCase
, testmethod
,
661 input=case
[0], expected
=case
[1],
662 id='%s[%r][%s]' % (dictname
, name
, casenum
),
663 run_in_debugger
=run_in_debugger
)
666 class WriterPublishTestCase(CustomTestCase
, docutils
.SettingsSpec
):
669 Test case for publish.
672 settings_default_overrides
= {'_disable_config': 1,
674 writer_name
= '' # set in subclasses or constructor
676 def __init__(self
, *args
, **kwargs
):
677 if kwargs
.has_key('writer_name'):
678 self
.writer_name
= kwargs
['writer_name']
679 del kwargs
['writer_name']
680 CustomTestCase
.__init
__(self
, *args
, **kwargs
)
682 def test_publish(self
):
683 if self
.run_in_debugger
:
685 output
= docutils
.core
.publish_string(
687 reader_name
='standalone',
688 parser_name
='restructuredtext',
689 writer_name
=self
.writer_name
,
691 settings_overrides
=self
.suite_settings
)
692 self
.compare_output(self
.input, output
, self
.expected
)
695 class PublishTestSuite(CustomTestSuite
):
697 def __init__(self
, writer_name
, suite_settings
=None):
699 `writer_name` is the name of the writer to use.
701 CustomTestSuite
.__init
__(self
, suite_settings
=suite_settings
)
702 self
.test_class
= WriterPublishTestCase
703 self
.writer_name
= writer_name
705 def generateTests(self
, dict, dictname
='totest'):
706 for name
, cases
in dict.items():
707 for casenum
in range(len(cases
)):
708 case
= cases
[casenum
]
716 self
.test_class
, 'test_publish',
717 input=case
[0], expected
=case
[1],
718 id='%s[%r][%s]' % (dictname
, name
, casenum
),
719 run_in_debugger
=run_in_debugger
,
720 # Passed to constructor of self.test_class:
721 writer_name
=self
.writer_name
)
724 class HtmlPublishPartsTestSuite(CustomTestSuite
):
726 def generateTests(self
, dict, dictname
='totest'):
727 for name
, (settings_overrides
, cases
) in dict.items():
728 settings
= self
.suite_settings
.copy()
729 settings
.update(settings_overrides
)
730 for casenum
in range(len(cases
)):
731 case
= cases
[casenum
]
739 HtmlWriterPublishPartsTestCase
, 'test_publish',
740 input=case
[0], expected
=case
[1],
741 id='%s[%r][%s]' % (dictname
, name
, casenum
),
742 run_in_debugger
=run_in_debugger
,
743 suite_settings
=settings
)
746 class HtmlWriterPublishPartsTestCase(WriterPublishTestCase
):
749 Test case for HTML writer via the publish_parts interface.
754 settings_default_overrides
= \
755 WriterPublishTestCase
.settings_default_overrides
.copy()
756 settings_default_overrides
['stylesheet'] = ''
758 def test_publish(self
):
759 if self
.run_in_debugger
:
761 parts
= docutils
.core
.publish_parts(
763 reader_name
='standalone',
764 parser_name
='restructuredtext',
765 writer_name
=self
.writer_name
,
767 settings_overrides
=self
.suite_settings
)
768 output
= self
.format_output(parts
)
769 # interpolate standard variables:
770 expected
= self
.expected
% {'version': docutils
.__version
__}
771 self
.compare_output(self
.input, output
, expected
)
774 standard_content_type_template
= ('<meta http-equiv="Content-Type"'
775 ' content="text/html; charset=%s" />\n')
776 standard_generator_template
= (
777 '<meta name="generator"'
778 ' content="Docutils %s: http://docutils.sourceforge.net/" />\n')
779 standard_html_meta_value
= (
780 standard_content_type_template
781 + standard_generator_template
% docutils
.__version
__)
782 standard_meta_value
= standard_html_meta_value
% 'utf-8'
783 standard_html_prolog
= """\
784 <?xml version="1.0" encoding="%s" ?>
785 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
788 def format_output(self
, parts
):
789 """Minimize & standardize the output."""
790 # remove redundant parts:
792 assert parts
['body'] == parts
['fragment']
794 # remove standard portions:
795 parts
['meta'] = parts
['meta'].replace(self
.standard_meta_value
, '')
796 parts
['html_head'] = parts
['html_head'].replace(
797 self
.standard_html_meta_value
, '...')
798 parts
['html_prolog'] = parts
['html_prolog'].replace(
799 self
.standard_html_prolog
, '')
800 # remove empty values:
801 for key
in parts
.keys():
804 # standard output format:
809 output
.append("%r: '''%s'''"
810 % (key
, parts
[key
].encode('raw_unicode_escape')))
811 if output
[-1].endswith("\n'''"):
812 output
[-1] = output
[-1][:-4] + "\\n'''"
813 return '{' + ',\n '.join(output
) + '}\n'
816 def exception_data(code
):
818 Execute `code` and return the resulting exception, the exception arguments,
819 and the formatted exception string.
823 except Exception, detail
:
824 return (detail
, detail
.args
,
825 '%s: %s' % (detail
.__class
__.__name
__, detail
))
828 def _format_str(*args
):
830 Return a tuple containing representations of all args.
832 Same as map(repr, args) except that it returns multi-line
833 representations for strings containing newlines, e.g.::
845 This is a helper function for CustomTestCase.
851 if ( (isinstance(i
, StringType
) or isinstance(i
, UnicodeType
))
854 if isinstance(i
, UnicodeType
):
855 # stripped = 'u' or 'U'
858 # quote_char = "'" or '"'
860 assert quote_char
in ("'", '"')
863 r
= (stripped
+ 3 * quote_char
+ '\\\n' +
864 re
.sub(r
'(?<!\\)((\\\\)*)\\n', r
'\1\n', r
) +
866 r
= re
.sub(r
' \n', r
' \\n\\\n', r
)
867 return_tuple
.append(r
)
868 return tuple(return_tuple
)