diff --git a/transpiler/src/main/scala/org/polystat/py2eo/transpiler/MarkUnsupportedConstructions.scala b/transpiler/src/main/scala/org/polystat/py2eo/transpiler/MarkUnsupportedConstructions.scala index 4018fdc18..89e19bc80 100644 --- a/transpiler/src/main/scala/org/polystat/py2eo/transpiler/MarkUnsupportedConstructions.scala +++ b/transpiler/src/main/scala/org/polystat/py2eo/transpiler/MarkUnsupportedConstructions.scala @@ -26,7 +26,7 @@ object MarkUnsupportedConstructions { val e1 = e match { case CallIndex(isCall, _, args, _) if !isCall || args.exists(x => x._1.nonEmpty) => inner(e) - case StringLiteral(value, ann) if value.exists( + case StringLiteral(value, ann) if value.length > 1 || value.exists( s => (s.head != '\'' && s.head != '"') || "\\\\[^\"'\\\\]".r.findFirstMatchIn(s).nonEmpty ) => inner(e) case ImagLiteral(_, _) => inner(e) diff --git a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/README.md b/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/README.md deleted file mode 100644 index 797977f60..000000000 --- a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/README.md +++ /dev/null @@ -1,2 +0,0 @@ -This directory contains some slightly modified regression tests from [cpython 3.8.10](https://github.com/python/cpython/tree/v3.8.10/Lib/test). -They are used to test the python parser and printer. diff --git a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test___future__.yaml b/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test___future__.yaml deleted file mode 100644 index b1373b1c9..000000000 --- a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test___future__.yaml +++ /dev/null @@ -1,62 +0,0 @@ -python: | - import unittest - import __future__ - - GOOD_SERIALS = ("alpha", "beta", "candidate", "final") - - features = __future__.all_feature_names - - class FutureTest(unittest.TestCase): - - def test_names(self): - # Verify that all_feature_names appears correct. - given_feature_names = features[:] - for name in dir(__future__): - obj = getattr(__future__, name, None) - if obj is not None and isinstance(obj, __future__._Feature): - self.assertTrue( - name in given_feature_names, - "%r should have been in all_feature_names" % name - ) - given_feature_names.remove(name) - self.assertEqual(len(given_feature_names), 0, - "all_feature_names has too much: %r" % given_feature_names) - - def test_attributes(self): - for feature in features: - value = getattr(__future__, feature) - - optional = value.getOptionalRelease() - mandatory = value.getMandatoryRelease() - - a = self.assertTrue - e = self.assertEqual - def check(t, name): - a(isinstance(t, tuple), "%s isn't tuple" % name) - e(len(t), 5, "%s isn't 5-tuple" % name) - (major, minor, micro, level, serial) = t - a(isinstance(major, int), "%s major isn't int" % name) - a(isinstance(minor, int), "%s minor isn't int" % name) - a(isinstance(micro, int), "%s micro isn't int" % name) - a(isinstance(level, str), - "%s level isn't string" % name) - a(level in GOOD_SERIALS, - "%s level string has unknown value" % name) - a(isinstance(serial, int), "%s serial isn't int" % name) - - check(optional, "optional") - if mandatory is not None: - check(mandatory, "mandatory") - a(optional < mandatory, - "optional not less than mandatory, and mandatory not None") - - a(hasattr(value, "compiler_flag"), - "feature is missing a .compiler_flag attr") - # Make sure the compile accepts the flag. - compile("", "", "exec", value.compiler_flag) - a(isinstance(getattr(value, "compiler_flag"), int), - ".compiler_flag isn't int") - - - if __name__ == "__main__": - unittest.main() diff --git a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test__locale.yaml b/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test__locale.yaml deleted file mode 100644 index 9dcd50bc4..000000000 --- a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test__locale.yaml +++ /dev/null @@ -1,198 +0,0 @@ -python: | - from _locale import (setlocale, LC_ALL, LC_CTYPE, LC_NUMERIC, localeconv, Error) - try: - from _locale import (RADIXCHAR, THOUSEP, nl_langinfo) - except ImportError: - nl_langinfo = None - - import locale - import sys - import unittest - from platform import uname - - if uname().system == "Darwin": - maj, min, mic = [int(part) for part in uname().release.split(".")] - if (maj, min, mic) < (8, 0, 0): - raise unittest.SkipTest("locale support broken for OS X < 10.4") - - candidate_locales = ['es_UY', 'fr_FR', 'fi_FI', 'es_CO', 'pt_PT', 'it_IT', - 'et_EE', 'es_PY', 'no_NO', 'nl_NL', 'lv_LV', 'el_GR', 'be_BY', 'fr_BE', - 'ro_RO', 'ru_UA', 'ru_RU', 'es_VE', 'ca_ES', 'se_NO', 'es_EC', 'id_ID', - 'ka_GE', 'es_CL', 'wa_BE', 'hu_HU', 'lt_LT', 'sl_SI', 'hr_HR', 'es_AR', - 'es_ES', 'oc_FR', 'gl_ES', 'bg_BG', 'is_IS', 'mk_MK', 'de_AT', 'pt_BR', - 'da_DK', 'nn_NO', 'cs_CZ', 'de_LU', 'es_BO', 'sq_AL', 'sk_SK', 'fr_CH', - 'de_DE', 'sr_YU', 'br_FR', 'nl_BE', 'sv_FI', 'pl_PL', 'fr_CA', 'fo_FO', - 'bs_BA', 'fr_LU', 'kl_GL', 'fa_IR', 'de_BE', 'sv_SE', 'it_CH', 'uk_UA', - 'eu_ES', 'vi_VN', 'af_ZA', 'nb_NO', 'en_DK', 'tg_TJ', 'ps_AF', 'en_US', - 'fr_FR.ISO8859-1', 'fr_FR.UTF-8', 'fr_FR.ISO8859-15@euro', - 'ru_RU.KOI8-R', 'ko_KR.eucKR'] - - def setUpModule(): - global candidate_locales - # Issue #13441: Skip some locales (e.g. cs_CZ and hu_HU) on Solaris to - # workaround a mbstowcs() bug. For example, on Solaris, the hu_HU locale uses - # the locale encoding ISO-8859-2, the thousauds separator is b'\xA0' and it is - # decoded as U+30000020 (an invalid character) by mbstowcs(). - if sys.platform == 'sunos5': - old_locale = locale.setlocale(locale.LC_ALL) - try: - locales = [] - for loc in candidate_locales: - try: - locale.setlocale(locale.LC_ALL, loc) - except Error: - continue - encoding = locale.getpreferredencoding(False) - try: - localeconv() - except Exception as err: - print("WARNING: Skip locale %s (encoding %s): [%s] %s" - % (loc, encoding, type(err), err)) - else: - locales.append(loc) - candidate_locales = locales - finally: - locale.setlocale(locale.LC_ALL, old_locale) - - # Workaround for MSVC6(debug) crash bug - if "MSC v.1200" in sys.version: - def accept(loc): - a = loc.split(".") - return not(len(a) == 2 and len(a[-1]) >= 9) - candidate_locales = [loc for loc in candidate_locales if accept(loc)] - - # List known locale values to test against when available. - # Dict formatted as `` : (, )``. If a - # value is not known, use '' . - known_numerics = { - 'en_US': ('.', ','), - 'de_DE' : (',', '.'), - # The French thousands separator may be a breaking or non-breaking space - # depending on the platform, so do not test it - 'fr_FR' : (',', ''), - 'ps_AF': ('\u066b', '\u066c'), - } - - if sys.platform == 'win32': - # ps_AF doesn't work on Windows: see bpo-38324 (msg361830) - del known_numerics['ps_AF'] - - class _LocaleTests(unittest.TestCase): - - def setUp(self): - self.oldlocale = setlocale(LC_ALL) - - def tearDown(self): - setlocale(LC_ALL, self.oldlocale) - - # Want to know what value was calculated, what it was compared against, - # what function was used for the calculation, what type of data was used, - # the locale that was supposedly set, and the actual locale that is set. - lc_numeric_err_msg = "%s != %s (%s for %s; set to %s, using %s)" - - def numeric_tester(self, calc_type, calc_value, data_type, used_locale): - """Compare calculation against known value, if available""" - try: - set_locale = setlocale(LC_NUMERIC) - except Error: - set_locale = "" - known_value = known_numerics.get(used_locale, - ('', ''))[data_type == 'thousands_sep'] - if known_value and calc_value: - self.assertEqual(calc_value, known_value, - self.lc_numeric_err_msg % ( - calc_value, known_value, - calc_type, data_type, set_locale, - used_locale)) - return True - - @unittest.skipUnless(nl_langinfo, "nl_langinfo is not available") - def test_lc_numeric_nl_langinfo(self): - # Test nl_langinfo against known values - tested = False - for loc in candidate_locales: - try: - setlocale(LC_NUMERIC, loc) - setlocale(LC_CTYPE, loc) - except Error: - continue - for li, lc in ((RADIXCHAR, "decimal_point"), - (THOUSEP, "thousands_sep")): - if self.numeric_tester('nl_langinfo', nl_langinfo(li), lc, loc): - tested = True - if not tested: - self.skipTest('no suitable locales') - - def test_lc_numeric_localeconv(self): - # Test localeconv against known values - tested = False - for loc in candidate_locales: - try: - setlocale(LC_NUMERIC, loc) - setlocale(LC_CTYPE, loc) - except Error: - continue - formatting = localeconv() - for lc in ("decimal_point", - "thousands_sep"): - if self.numeric_tester('localeconv', formatting[lc], lc, loc): - tested = True - if not tested: - self.skipTest('no suitable locales') - - @unittest.skipUnless(nl_langinfo, "nl_langinfo is not available") - def test_lc_numeric_basic(self): - # Test nl_langinfo against localeconv - tested = False - for loc in candidate_locales: - try: - setlocale(LC_NUMERIC, loc) - setlocale(LC_CTYPE, loc) - except Error: - continue - for li, lc in ((RADIXCHAR, "decimal_point"), - (THOUSEP, "thousands_sep")): - nl_radixchar = nl_langinfo(li) - li_radixchar = localeconv()[lc] - try: - set_locale = setlocale(LC_NUMERIC) - except Error: - set_locale = "" - self.assertEqual(nl_radixchar, li_radixchar, - "%s (nl_langinfo) != %s (localeconv) " - "(set to %s, using %s)" % ( - nl_radixchar, li_radixchar, - loc, set_locale)) - tested = True - if not tested: - self.skipTest('no suitable locales') - - def test_float_parsing(self): - # Bug #1391872: Test whether float parsing is okay on European - # locales. - tested = False - for loc in candidate_locales: - try: - setlocale(LC_NUMERIC, loc) - setlocale(LC_CTYPE, loc) - except Error: - continue - - # Ignore buggy locale databases. (Mac OS 10.4 and some other BSDs) - if loc == 'eu_ES' and localeconv()['decimal_point'] == "' ": - continue - - self.assertEqual(int(eval('3.14') * 100), 314, - "using eval('3.14') failed for %s" % loc) - self.assertEqual(int(float('3.14') * 100), 314, - "using float('3.14') failed for %s" % loc) - if localeconv()['decimal_point'] != '.': - self.assertRaises(ValueError, float, - localeconv()['decimal_point'].join(['1', '23'])) - tested = True - if not tested: - self.skipTest('no suitable locales') - - - if __name__ == '__main__': - unittest.main() diff --git a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test__opcode.yaml b/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test__opcode.yaml deleted file mode 100644 index 7e27bf3bd..000000000 --- a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test__opcode.yaml +++ /dev/null @@ -1,69 +0,0 @@ -python: | - import dis - from test.support import import_module - import unittest - - _opcode = import_module("_opcode") - from _opcode import stack_effect - - - class OpcodeTests(unittest.TestCase): - - def test_stack_effect(self): - self.assertEqual(stack_effect(dis.opmap['POP_TOP']), -1) - self.assertEqual(stack_effect(dis.opmap['DUP_TOP_TWO']), 2) - self.assertEqual(stack_effect(dis.opmap['BUILD_SLICE'], 0), -1) - self.assertEqual(stack_effect(dis.opmap['BUILD_SLICE'], 1), -1) - self.assertEqual(stack_effect(dis.opmap['BUILD_SLICE'], 3), -2) - self.assertRaises(ValueError, stack_effect, 30000) - self.assertRaises(ValueError, stack_effect, dis.opmap['BUILD_SLICE']) - self.assertRaises(ValueError, stack_effect, dis.opmap['POP_TOP'], 0) - # All defined opcodes - for name, code in dis.opmap.items(): - with self.subTest(opname=name): - if code < dis.HAVE_ARGUMENT: - stack_effect(code) - self.assertRaises(ValueError, stack_effect, code, 0) - else: - stack_effect(code, 0) - self.assertRaises(ValueError, stack_effect, code) - # All not defined opcodes - for code in set(range(256)) - set(dis.opmap.values()): - with self.subTest(opcode=code): - self.assertRaises(ValueError, stack_effect, code) - self.assertRaises(ValueError, stack_effect, code, 0) - - def test_stack_effect_jump(self): - JUMP_IF_TRUE_OR_POP = dis.opmap['JUMP_IF_TRUE_OR_POP'] - self.assertEqual(stack_effect(JUMP_IF_TRUE_OR_POP, 0), 0) - self.assertEqual(stack_effect(JUMP_IF_TRUE_OR_POP, 0, jump=True), 0) - self.assertEqual(stack_effect(JUMP_IF_TRUE_OR_POP, 0, jump=False), -1) - FOR_ITER = dis.opmap['FOR_ITER'] - self.assertEqual(stack_effect(FOR_ITER, 0), 1) - self.assertEqual(stack_effect(FOR_ITER, 0, jump=True), -1) - self.assertEqual(stack_effect(FOR_ITER, 0, jump=False), 1) - JUMP_FORWARD = dis.opmap['JUMP_FORWARD'] - self.assertEqual(stack_effect(JUMP_FORWARD, 0), 0) - self.assertEqual(stack_effect(JUMP_FORWARD, 0, jump=True), 0) - self.assertEqual(stack_effect(JUMP_FORWARD, 0, jump=False), 0) - # All defined opcodes - has_jump = dis.hasjabs + dis.hasjrel - for name, code in dis.opmap.items(): - with self.subTest(opname=name): - if code < dis.HAVE_ARGUMENT: - common = stack_effect(code) - jump = stack_effect(code, jump=True) - nojump = stack_effect(code, jump=False) - else: - common = stack_effect(code, 0) - jump = stack_effect(code, 0, jump=True) - nojump = stack_effect(code, 0, jump=False) - if code in has_jump: - self.assertEqual(common, max(jump, nojump)) - else: - self.assertEqual(jump, common) - self.assertEqual(nojump, common) - - - if __name__ == "__main__": - unittest.main() diff --git a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test__osx_support.yaml b/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test__osx_support.yaml deleted file mode 100644 index c5c93004a..000000000 --- a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test__osx_support.yaml +++ /dev/null @@ -1,328 +0,0 @@ -python: | - """ - Test suite for _osx_support: shared OS X support functions. - """ - - import os - import platform - import stat - import sys - import unittest - - import test.support - - import _osx_support - - @unittest.skipUnless(sys.platform.startswith("darwin"), "requires OS X") - class Test_OSXSupport(unittest.TestCase): - - def setUp(self): - self.maxDiff = None - self.prog_name = 'bogus_program_xxxx' - self.temp_path_dir = os.path.abspath(os.getcwd()) - self.env = test.support.EnvironmentVarGuard() - self.addCleanup(self.env.__exit__) - for cv in ('CFLAGS', 'LDFLAGS', 'CPPFLAGS', - 'BASECFLAGS', 'BLDSHARED', 'LDSHARED', 'CC', - 'CXX', 'PY_CFLAGS', 'PY_LDFLAGS', 'PY_CPPFLAGS', - 'PY_CORE_CFLAGS', 'PY_CORE_LDFLAGS'): - if cv in self.env: - self.env.unset(cv) - - def add_expected_saved_initial_values(self, config_vars, expected_vars): - # Ensure that the initial values for all modified config vars - # are also saved with modified keys. - expected_vars.update(('_OSX_SUPPORT_INITIAL_'+ k, - config_vars[k]) for k in config_vars - if config_vars[k] != expected_vars[k]) - - def test__find_executable(self): - if self.env['PATH']: - self.env['PATH'] = self.env['PATH'] + ':' - self.env['PATH'] = self.env['PATH'] + os.path.abspath(self.temp_path_dir) - test.support.unlink(self.prog_name) - self.assertIsNone(_osx_support._find_executable(self.prog_name)) - self.addCleanup(test.support.unlink, self.prog_name) - with open(self.prog_name, 'w') as f: - f.write("#!/bin/sh\n/bin/echo OK\n") - os.chmod(self.prog_name, stat.S_IRWXU) - self.assertEqual(self.prog_name, - _osx_support._find_executable(self.prog_name)) - - def test__read_output(self): - if self.env['PATH']: - self.env['PATH'] = self.env['PATH'] + ':' - self.env['PATH'] = self.env['PATH'] + os.path.abspath(self.temp_path_dir) - test.support.unlink(self.prog_name) - self.addCleanup(test.support.unlink, self.prog_name) - with open(self.prog_name, 'w') as f: - f.write("#!/bin/sh\n/bin/echo ExpectedOutput\n") - os.chmod(self.prog_name, stat.S_IRWXU) - self.assertEqual('ExpectedOutput', - _osx_support._read_output(self.prog_name)) - - def test__find_build_tool(self): - out = _osx_support._find_build_tool('cc') - self.assertTrue(os.path.isfile(out), - 'cc not found - check xcode-select') - - def test__get_system_version(self): - self.assertTrue(platform.mac_ver()[0].startswith( - _osx_support._get_system_version())) - - def test__remove_original_values(self): - config_vars = { - 'CC': 'gcc-test -pthreads', - } - expected_vars = { - 'CC': 'clang -pthreads', - } - cv = 'CC' - newvalue = 'clang -pthreads' - _osx_support._save_modified_value(config_vars, cv, newvalue) - self.assertNotEqual(expected_vars, config_vars) - _osx_support._remove_original_values(config_vars) - self.assertEqual(expected_vars, config_vars) - - def test__save_modified_value(self): - config_vars = { - 'CC': 'gcc-test -pthreads', - } - expected_vars = { - 'CC': 'clang -pthreads', - } - self.add_expected_saved_initial_values(config_vars, expected_vars) - cv = 'CC' - newvalue = 'clang -pthreads' - _osx_support._save_modified_value(config_vars, cv, newvalue) - self.assertEqual(expected_vars, config_vars) - - def test__save_modified_value_unchanged(self): - config_vars = { - 'CC': 'gcc-test -pthreads', - } - expected_vars = config_vars.copy() - cv = 'CC' - newvalue = 'gcc-test -pthreads' - _osx_support._save_modified_value(config_vars, cv, newvalue) - self.assertEqual(expected_vars, config_vars) - - def test__supports_universal_builds(self): - import platform - mac_ver_tuple = tuple(int(i) for i in - platform.mac_ver()[0].split('.')[0:2]) - self.assertEqual(mac_ver_tuple >= (10, 4), - _osx_support._supports_universal_builds()) - - def test__find_appropriate_compiler(self): - compilers = ( - ('gcc-test', 'i686-apple-darwin11-llvm-gcc-4.2'), - ('clang', 'clang version 3.1'), - ) - config_vars = { - 'CC': 'gcc-test -pthreads', - 'CXX': 'cc++-test', - 'CFLAGS': '-fno-strict-aliasing -g -O3 -arch ppc -arch i386 ', - 'LDFLAGS': '-arch ppc -arch i386 -g', - 'CPPFLAGS': '-I. -isysroot /Developer/SDKs/MacOSX10.4u.sdk', - 'BLDSHARED': 'gcc-test -bundle -arch ppc -arch i386 -g', - 'LDSHARED': 'gcc-test -bundle -arch ppc -arch i386 ' - '-isysroot /Developer/SDKs/MacOSX10.4u.sdk -g', - } - expected_vars = { - 'CC': 'clang -pthreads', - 'CXX': 'clang++', - 'CFLAGS': '-fno-strict-aliasing -g -O3 -arch ppc -arch i386 ', - 'LDFLAGS': '-arch ppc -arch i386 -g', - 'CPPFLAGS': '-I. -isysroot /Developer/SDKs/MacOSX10.4u.sdk', - 'BLDSHARED': 'clang -bundle -arch ppc -arch i386 -g', - 'LDSHARED': 'clang -bundle -arch ppc -arch i386 ' - '-isysroot /Developer/SDKs/MacOSX10.4u.sdk -g', - } - self.add_expected_saved_initial_values(config_vars, expected_vars) - - suffix = (':' + self.env['PATH']) if self.env['PATH'] else '' - self.env['PATH'] = os.path.abspath(self.temp_path_dir) + suffix - for c_name, c_output in compilers: - test.support.unlink(c_name) - self.addCleanup(test.support.unlink, c_name) - with open(c_name, 'w') as f: - f.write("#!/bin/sh\n/bin/echo " + c_output) - os.chmod(c_name, stat.S_IRWXU) - self.assertEqual(expected_vars, - _osx_support._find_appropriate_compiler( - config_vars)) - - def test__remove_universal_flags(self): - config_vars = { - 'CFLAGS': '-fno-strict-aliasing -g -O3 -arch ppc -arch i386 ', - 'LDFLAGS': '-arch ppc -arch i386 -g', - 'CPPFLAGS': '-I. -isysroot /Developer/SDKs/MacOSX10.4u.sdk', - 'BLDSHARED': 'gcc-4.0 -bundle -arch ppc -arch i386 -g', - 'LDSHARED': 'gcc-4.0 -bundle -arch ppc -arch i386 ' - '-isysroot /Developer/SDKs/MacOSX10.4u.sdk -g', - } - expected_vars = { - 'CFLAGS': '-fno-strict-aliasing -g -O3 ', - 'LDFLAGS': ' -g', - 'CPPFLAGS': '-I. ', - 'BLDSHARED': 'gcc-4.0 -bundle -g', - 'LDSHARED': 'gcc-4.0 -bundle -g', - } - self.add_expected_saved_initial_values(config_vars, expected_vars) - - self.assertEqual(expected_vars, - _osx_support._remove_universal_flags( - config_vars)) - - def test__remove_universal_flags_alternate(self): - # bpo-38360: also test the alternate single-argument form of -isysroot - config_vars = { - 'CFLAGS': '-fno-strict-aliasing -g -O3 -arch ppc -arch i386 ', - 'LDFLAGS': '-arch ppc -arch i386 -g', - 'CPPFLAGS': '-I. -isysroot/Developer/SDKs/MacOSX10.4u.sdk', - 'BLDSHARED': 'gcc-4.0 -bundle -arch ppc -arch i386 -g', - 'LDSHARED': 'gcc-4.0 -bundle -arch ppc -arch i386 ' - '-isysroot/Developer/SDKs/MacOSX10.4u.sdk -g', - } - expected_vars = { - 'CFLAGS': '-fno-strict-aliasing -g -O3 ', - 'LDFLAGS': ' -g', - 'CPPFLAGS': '-I. ', - 'BLDSHARED': 'gcc-4.0 -bundle -g', - 'LDSHARED': 'gcc-4.0 -bundle -g', - } - self.add_expected_saved_initial_values(config_vars, expected_vars) - - self.assertEqual(expected_vars, - _osx_support._remove_universal_flags( - config_vars)) - - def test__remove_unsupported_archs(self): - config_vars = { - 'CC': 'clang', - 'CFLAGS': '-fno-strict-aliasing -g -O3 -arch ppc -arch i386 ', - 'LDFLAGS': '-arch ppc -arch i386 -g', - 'CPPFLAGS': '-I. -isysroot /Developer/SDKs/MacOSX10.4u.sdk', - 'BLDSHARED': 'gcc-4.0 -bundle -arch ppc -arch i386 -g', - 'LDSHARED': 'gcc-4.0 -bundle -arch ppc -arch i386 ' - '-isysroot /Developer/SDKs/MacOSX10.4u.sdk -g', - } - expected_vars = { - 'CC': 'clang', - 'CFLAGS': '-fno-strict-aliasing -g -O3 -arch i386 ', - 'LDFLAGS': ' -arch i386 -g', - 'CPPFLAGS': '-I. -isysroot /Developer/SDKs/MacOSX10.4u.sdk', - 'BLDSHARED': 'gcc-4.0 -bundle -arch i386 -g', - 'LDSHARED': 'gcc-4.0 -bundle -arch i386 ' - '-isysroot /Developer/SDKs/MacOSX10.4u.sdk -g', - } - self.add_expected_saved_initial_values(config_vars, expected_vars) - - suffix = (':' + self.env['PATH']) if self.env['PATH'] else '' - self.env['PATH'] = os.path.abspath(self.temp_path_dir) + suffix - c_name = 'clang' - test.support.unlink(c_name) - self.addCleanup(test.support.unlink, c_name) - # exit status 255 means no PPC support in this compiler chain - with open(c_name, 'w') as f: - f.write("#!/bin/sh\nexit 255") - os.chmod(c_name, stat.S_IRWXU) - self.assertEqual(expected_vars, - _osx_support._remove_unsupported_archs( - config_vars)) - - def test__override_all_archs(self): - self.env['ARCHFLAGS'] = '-arch x86_64' - config_vars = { - 'CC': 'clang', - 'CFLAGS': '-fno-strict-aliasing -g -O3 -arch ppc -arch i386 ', - 'LDFLAGS': '-arch ppc -arch i386 -g', - 'CPPFLAGS': '-I. -isysroot /Developer/SDKs/MacOSX10.4u.sdk', - 'BLDSHARED': 'gcc-4.0 -bundle -arch ppc -arch i386 -g', - 'LDSHARED': 'gcc-4.0 -bundle -arch ppc -arch i386 ' - '-isysroot /Developer/SDKs/MacOSX10.4u.sdk -g', - } - expected_vars = { - 'CC': 'clang', - 'CFLAGS': '-fno-strict-aliasing -g -O3 -arch x86_64', - 'LDFLAGS': ' -g -arch x86_64', - 'CPPFLAGS': '-I. -isysroot /Developer/SDKs/MacOSX10.4u.sdk', - 'BLDSHARED': 'gcc-4.0 -bundle -g -arch x86_64', - 'LDSHARED': 'gcc-4.0 -bundle -isysroot ' - '/Developer/SDKs/MacOSX10.4u.sdk -g -arch x86_64', - } - self.add_expected_saved_initial_values(config_vars, expected_vars) - - self.assertEqual(expected_vars, - _osx_support._override_all_archs( - config_vars)) - - def test__check_for_unavailable_sdk(self): - config_vars = { - 'CC': 'clang', - 'CFLAGS': '-fno-strict-aliasing -g -O3 -arch ppc -arch i386 ' - '-isysroot /Developer/SDKs/MacOSX10.1.sdk', - 'LDFLAGS': '-arch ppc -arch i386 -g', - 'CPPFLAGS': '-I. -isysroot /Developer/SDKs/MacOSX10.1.sdk', - 'BLDSHARED': 'gcc-4.0 -bundle -arch ppc -arch i386 -g', - 'LDSHARED': 'gcc-4.0 -bundle -arch ppc -arch i386 ' - '-isysroot /Developer/SDKs/MacOSX10.1.sdk -g', - } - expected_vars = { - 'CC': 'clang', - 'CFLAGS': '-fno-strict-aliasing -g -O3 -arch ppc -arch i386 ' - ' ', - 'LDFLAGS': '-arch ppc -arch i386 -g', - 'CPPFLAGS': '-I. ', - 'BLDSHARED': 'gcc-4.0 -bundle -arch ppc -arch i386 -g', - 'LDSHARED': 'gcc-4.0 -bundle -arch ppc -arch i386 ' - ' -g', - } - self.add_expected_saved_initial_values(config_vars, expected_vars) - - self.assertEqual(expected_vars, - _osx_support._check_for_unavailable_sdk( - config_vars)) - - def test__check_for_unavailable_sdk_alternate(self): - # bpo-38360: also test the alternate single-argument form of -isysroot - config_vars = { - 'CC': 'clang', - 'CFLAGS': '-fno-strict-aliasing -g -O3 -arch ppc -arch i386 ' - '-isysroot/Developer/SDKs/MacOSX10.1.sdk', - 'LDFLAGS': '-arch ppc -arch i386 -g', - 'CPPFLAGS': '-I. -isysroot/Developer/SDKs/MacOSX10.1.sdk', - 'BLDSHARED': 'gcc-4.0 -bundle -arch ppc -arch i386 -g', - 'LDSHARED': 'gcc-4.0 -bundle -arch ppc -arch i386 ' - '-isysroot/Developer/SDKs/MacOSX10.1.sdk -g', - } - expected_vars = { - 'CC': 'clang', - 'CFLAGS': '-fno-strict-aliasing -g -O3 -arch ppc -arch i386 ' - ' ', - 'LDFLAGS': '-arch ppc -arch i386 -g', - 'CPPFLAGS': '-I. ', - 'BLDSHARED': 'gcc-4.0 -bundle -arch ppc -arch i386 -g', - 'LDSHARED': 'gcc-4.0 -bundle -arch ppc -arch i386 ' - ' -g', - } - self.add_expected_saved_initial_values(config_vars, expected_vars) - - self.assertEqual(expected_vars, - _osx_support._check_for_unavailable_sdk( - config_vars)) - - def test_get_platform_osx(self): - # Note, get_platform_osx is currently tested more extensively - # indirectly by test_sysconfig and test_distutils - config_vars = { - 'CFLAGS': '-fno-strict-aliasing -g -O3 -arch ppc -arch i386 ' - '-isysroot /Developer/SDKs/MacOSX10.1.sdk', - 'MACOSX_DEPLOYMENT_TARGET': '10.6', - } - result = _osx_support.get_platform_osx(config_vars, ' ', ' ', ' ') - self.assertEqual(('macosx', '10.6', 'fat'), result) - - if __name__ == "__main__": - unittest.main() diff --git a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test__xxsubinterpreters.yaml b/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test__xxsubinterpreters.yaml deleted file mode 100644 index 51c4b85ee..000000000 --- a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test__xxsubinterpreters.yaml +++ /dev/null @@ -1,2125 +0,0 @@ -python: | - from collections import namedtuple - import contextlib - import itertools - import os - import pickle - import sys - from textwrap import dedent - import threading - import time - import unittest - - from test import support - from test.support import script_helper - - - interpreters = support.import_module('_xxsubinterpreters') - - - ################################## - # helpers - - def powerset(*sets): - return itertools.chain.from_iterable( - combinations(sets, r) - for r in range(len(sets)+1)) - - - def _captured_script(script): - r, w = os.pipe() - indented = script.replace('\n', '\n ') - wrapped = dedent(f""" - import contextlib - with open({w}, 'w') as spipe: - with contextlib.redirect_stdout(spipe): - {indented} - """) - return wrapped, open(r) - - - def _run_output(interp, request, shared=None): - script, rpipe = _captured_script(request) - with rpipe: - interpreters.run_string(interp, script, shared) - return rpipe.read() - - - @contextlib.contextmanager - def _running(interp): - r, w = os.pipe() - def run(): - interpreters.run_string(interp, dedent(f""" - # wait for "signal" - with open({r}) as rpipe: - rpipe.read() - """)) - - t = threading.Thread(target=run) - t.start() - - yield - - with open(w, 'w') as spipe: - spipe.write('done') - t.join() - - - #@contextmanager - #def run_threaded(id, source, **shared): - # def run(): - # run_interp(id, source, **shared) - # t = threading.Thread(target=run) - # t.start() - # yield - # t.join() - - - def run_interp(id, source, **shared): - _run_interp(id, source, shared) - - - def _run_interp(id, source, shared, _mainns={}): - source = dedent(source) - main = interpreters.get_main() - if main == id: - if interpreters.get_current() != main: - raise RuntimeError - # XXX Run a func? - exec(source, _mainns) - else: - interpreters.run_string(id, source, shared) - - - def run_interp_threaded(id, source, **shared): - def run(): - _run(id, source, shared) - t = threading.Thread(target=run) - t.start() - t.join() - - - class Interpreter(namedtuple('Interpreter', 'name id')): - - @classmethod - def from_raw(cls, raw): - if isinstance(raw, cls): - return raw - elif isinstance(raw, str): - return cls(raw) - else: - raise NotImplementedError - - def __new__(cls, name=None, id=None): - main = interpreters.get_main() - if id == main: - if not name: - name = 'main' - elif name != 'main': - raise ValueError( - 'name mismatch (expected "main", got "{}")'.format(name)) - id = main - elif id is not None: - if not name: - name = 'interp' - elif name == 'main': - raise ValueError('name mismatch (unexpected "main")') - if not isinstance(id, interpreters.InterpreterID): - id = interpreters.InterpreterID(id) - elif not name or name == 'main': - name = 'main' - id = main - else: - id = interpreters.create() - self = super().__new__(cls, name, id) - return self - - - # XXX expect_channel_closed() is unnecessary once we improve exc propagation. - - @contextlib.contextmanager - def expect_channel_closed(): - try: - yield - except interpreters.ChannelClosedError: - pass - else: - assert False, 'channel not closed' - - - class ChannelAction(namedtuple('ChannelAction', 'action end interp')): - - def __new__(cls, action, end=None, interp=None): - if not end: - end = 'both' - if not interp: - interp = 'main' - self = super().__new__(cls, action, end, interp) - return self - - def __init__(self, *args, **kwargs): - if self.action == 'use': - if self.end not in ('same', 'opposite', 'send', 'recv'): - raise ValueError(self.end) - elif self.action in ('close', 'force-close'): - if self.end not in ('both', 'same', 'opposite', 'send', 'recv'): - raise ValueError(self.end) - else: - raise ValueError(self.action) - if self.interp not in ('main', 'same', 'other', 'extra'): - raise ValueError(self.interp) - - def resolve_end(self, end): - if self.end == 'same': - return end - elif self.end == 'opposite': - return 'recv' if end == 'send' else 'send' - else: - return self.end - - def resolve_interp(self, interp, other, extra): - if self.interp == 'same': - return interp - elif self.interp == 'other': - if other is None: - raise RuntimeError - return other - elif self.interp == 'extra': - if extra is None: - raise RuntimeError - return extra - elif self.interp == 'main': - if interp.name == 'main': - return interp - elif other and other.name == 'main': - return other - else: - raise RuntimeError - # Per __init__(), there aren't any others. - - - class ChannelState(namedtuple('ChannelState', 'pending closed')): - - def __new__(cls, pending=0, *, closed=False): - self = super().__new__(cls, pending, closed) - return self - - def incr(self): - return type(self)(self.pending + 1, closed=self.closed) - - def decr(self): - return type(self)(self.pending - 1, closed=self.closed) - - def close(self, *, force=True): - if self.closed: - if not force or self.pending == 0: - return self - return type(self)(0 if force else self.pending, closed=True) - - - def run_action(cid, action, end, state, *, hideclosed=True): - if state.closed: - if action == 'use' and end == 'recv' and state.pending: - expectfail = False - else: - expectfail = True - else: - expectfail = False - - try: - result = _run_action(cid, action, end, state) - except interpreters.ChannelClosedError: - if not hideclosed and not expectfail: - raise - result = state.close() - else: - if expectfail: - raise ... # XXX - return result - - - def _run_action(cid, action, end, state): - if action == 'use': - if end == 'send': - interpreters.channel_send(cid, b'spam') - return state.incr() - elif end == 'recv': - if not state.pending: - try: - interpreters.channel_recv(cid) - except interpreters.ChannelEmptyError: - return state - else: - raise Exception('expected ChannelEmptyError') - else: - interpreters.channel_recv(cid) - return state.decr() - else: - raise ValueError(end) - elif action == 'close': - kwargs = {} - if end in ('recv', 'send'): - kwargs[end] = True - interpreters.channel_close(cid, **kwargs) - return state.close() - elif action == 'force-close': - kwargs = { - 'force': True, - } - if end in ('recv', 'send'): - kwargs[end] = True - interpreters.channel_close(cid, **kwargs) - return state.close(force=True) - else: - raise ValueError(action) - - - def clean_up_interpreters(): - for id in interpreters.list_all(): - if id == 0: # main - continue - try: - interpreters.destroy(id) - except RuntimeError: - pass # already destroyed - - - def clean_up_channels(): - for cid in interpreters.channel_list_all(): - try: - interpreters.channel_destroy(cid) - except interpreters.ChannelNotFoundError: - pass # already destroyed - - - class TestBase(unittest.TestCase): - - def tearDown(self): - clean_up_interpreters() - clean_up_channels() - - - ################################## - # misc. tests - - class IsShareableTests(unittest.TestCase): - - def test_default_shareables(self): - shareables = [ - # singletons - None, - # builtin objects - b'spam', - 'spam', - 10, - -10, - ] - for obj in shareables: - with self.subTest(obj): - self.assertTrue( - interpreters.is_shareable(obj)) - - def test_not_shareable(self): - class Cheese: - def __init__(self, name): - self.name = name - def __str__(self): - return self.name - - class SubBytes(bytes): - """A subclass of a shareable type.""" - - not_shareables = [ - # singletons - True, - False, - NotImplemented, - ..., - # builtin types and objects - type, - object, - object(), - Exception(), - 100.0, - # user-defined types and objects - Cheese, - Cheese('Wensleydale'), - SubBytes(b'spam'), - ] - for obj in not_shareables: - with self.subTest(repr(obj)): - self.assertFalse( - interpreters.is_shareable(obj)) - - - class ShareableTypeTests(unittest.TestCase): - - def setUp(self): - super().setUp() - self.cid = interpreters.channel_create() - - def tearDown(self): - interpreters.channel_destroy(self.cid) - super().tearDown() - - def _assert_values(self, values): - for obj in values: - with self.subTest(obj): - interpreters.channel_send(self.cid, obj) - got = interpreters.channel_recv(self.cid) - - self.assertEqual(got, obj) - self.assertIs(type(got), type(obj)) - # XXX Check the following in the channel tests? - #self.assertIsNot(got, obj) - - def test_singletons(self): - for obj in [None]: - with self.subTest(obj): - interpreters.channel_send(self.cid, obj) - got = interpreters.channel_recv(self.cid) - - # XXX What about between interpreters? - self.assertIs(got, obj) - - def test_types(self): - self._assert_values([ - b'spam', - 9999, - self.cid, - ]) - - def test_bytes(self): - self._assert_values(i.to_bytes(2, 'little', signed=True) - for i in range(-1, 258)) - - def test_strs(self): - self._assert_values(['hello world', '你好世界', '']) - - def test_int(self): - self._assert_values(itertools.chain(range(-1, 258), - [sys.maxsize, -sys.maxsize - 1])) - - def test_non_shareable_int(self): - ints = [ - sys.maxsize + 1, - -sys.maxsize - 2, - 2**1000, - ] - for i in ints: - with self.subTest(i): - with self.assertRaises(OverflowError): - interpreters.channel_send(self.cid, i) - - - ################################## - # interpreter tests - - class ListAllTests(TestBase): - - def test_initial(self): - main = interpreters.get_main() - ids = interpreters.list_all() - self.assertEqual(ids, [main]) - - def test_after_creating(self): - main = interpreters.get_main() - first = interpreters.create() - second = interpreters.create() - ids = interpreters.list_all() - self.assertEqual(ids, [main, first, second]) - - def test_after_destroying(self): - main = interpreters.get_main() - first = interpreters.create() - second = interpreters.create() - interpreters.destroy(first) - ids = interpreters.list_all() - self.assertEqual(ids, [main, second]) - - - class GetCurrentTests(TestBase): - - def test_main(self): - main = interpreters.get_main() - cur = interpreters.get_current() - self.assertEqual(cur, main) - self.assertIsInstance(cur, interpreters.InterpreterID) - - def test_subinterpreter(self): - main = interpreters.get_main() - interp = interpreters.create() - out = _run_output(interp, dedent(""" - import _xxsubinterpreters as _interpreters - cur = _interpreters.get_current() - print(cur) - assert isinstance(cur, _interpreters.InterpreterID) - """)) - cur = int(out.strip()) - _, expected = interpreters.list_all() - self.assertEqual(cur, expected) - self.assertNotEqual(cur, main) - - - class GetMainTests(TestBase): - - def test_from_main(self): - [expected] = interpreters.list_all() - main = interpreters.get_main() - self.assertEqual(main, expected) - self.assertIsInstance(main, interpreters.InterpreterID) - - def test_from_subinterpreter(self): - [expected] = interpreters.list_all() - interp = interpreters.create() - out = _run_output(interp, dedent(""" - import _xxsubinterpreters as _interpreters - main = _interpreters.get_main() - print(main) - assert isinstance(main, _interpreters.InterpreterID) - """)) - main = int(out.strip()) - self.assertEqual(main, expected) - - - class IsRunningTests(TestBase): - - def test_main(self): - main = interpreters.get_main() - self.assertTrue(interpreters.is_running(main)) - - def test_subinterpreter(self): - interp = interpreters.create() - self.assertFalse(interpreters.is_running(interp)) - - with _running(interp): - self.assertTrue(interpreters.is_running(interp)) - self.assertFalse(interpreters.is_running(interp)) - - def test_from_subinterpreter(self): - interp = interpreters.create() - out = _run_output(interp, dedent(f""" - import _xxsubinterpreters as _interpreters - if _interpreters.is_running({interp}): - print(True) - else: - print(False) - """)) - self.assertEqual(out.strip(), 'True') - - def test_already_destroyed(self): - interp = interpreters.create() - interpreters.destroy(interp) - with self.assertRaises(RuntimeError): - interpreters.is_running(interp) - - def test_does_not_exist(self): - with self.assertRaises(RuntimeError): - interpreters.is_running(1_000_000) - - def test_bad_id(self): - with self.assertRaises(ValueError): - interpreters.is_running(-1) - - - class InterpreterIDTests(TestBase): - - def test_with_int(self): - id = interpreters.InterpreterID(10, force=True) - - self.assertEqual(int(id), 10) - - def test_coerce_id(self): - class Int(str): - def __index__(self): - return 10 - - id = interpreters.InterpreterID(Int(), force=True) - self.assertEqual(int(id), 10) - - def test_bad_id(self): - self.assertRaises(TypeError, interpreters.InterpreterID, object()) - self.assertRaises(TypeError, interpreters.InterpreterID, 10.0) - self.assertRaises(TypeError, interpreters.InterpreterID, '10') - self.assertRaises(TypeError, interpreters.InterpreterID, b'10') - self.assertRaises(ValueError, interpreters.InterpreterID, -1) - self.assertRaises(OverflowError, interpreters.InterpreterID, 2**64) - - def test_does_not_exist(self): - id = interpreters.channel_create() - with self.assertRaises(RuntimeError): - interpreters.InterpreterID(int(id) + 1) # unforced - - def test_str(self): - id = interpreters.InterpreterID(10, force=True) - self.assertEqual(str(id), '10') - - def test_repr(self): - id = interpreters.InterpreterID(10, force=True) - self.assertEqual(repr(id), 'InterpreterID(10)') - - def test_equality(self): - id1 = interpreters.create() - id2 = interpreters.InterpreterID(int(id1)) - id3 = interpreters.create() - - self.assertTrue(id1 == id1) - self.assertTrue(id1 == id2) - self.assertTrue(id1 == int(id1)) - self.assertTrue(int(id1) == id1) - self.assertTrue(id1 == float(int(id1))) - self.assertTrue(float(int(id1)) == id1) - self.assertFalse(id1 == float(int(id1)) + 0.1) - self.assertFalse(id1 == str(int(id1))) - self.assertFalse(id1 == 2**1000) - self.assertFalse(id1 == float('inf')) - self.assertFalse(id1 == 'spam') - self.assertFalse(id1 == id3) - - self.assertFalse(id1 != id1) - self.assertFalse(id1 != id2) - self.assertTrue(id1 != id3) - - - class CreateTests(TestBase): - - def test_in_main(self): - id = interpreters.create() - self.assertIsInstance(id, interpreters.InterpreterID) - - self.assertIn(id, interpreters.list_all()) - - @unittest.skip('enable this test when working on pystate.c') - def test_unique_id(self): - seen = set() - for _ in range(100): - id = interpreters.create() - interpreters.destroy(id) - seen.add(id) - - self.assertEqual(len(seen), 100) - - def test_in_thread(self): - lock = threading.Lock() - id = None - def f(): - nonlocal id - id = interpreters.create() - lock.acquire() - lock.release() - - t = threading.Thread(target=f) - with lock: - t.start() - t.join() - self.assertIn(id, interpreters.list_all()) - - def test_in_subinterpreter(self): - main, = interpreters.list_all() - id1 = interpreters.create() - out = _run_output(id1, dedent(""" - import _xxsubinterpreters as _interpreters - id = _interpreters.create() - print(id) - assert isinstance(id, _interpreters.InterpreterID) - """)) - id2 = int(out.strip()) - - self.assertEqual(set(interpreters.list_all()), {main, id1, id2}) - - def test_in_threaded_subinterpreter(self): - main, = interpreters.list_all() - id1 = interpreters.create() - id2 = None - def f(): - nonlocal id2 - out = _run_output(id1, dedent(""" - import _xxsubinterpreters as _interpreters - id = _interpreters.create() - print(id) - """)) - id2 = int(out.strip()) - - t = threading.Thread(target=f) - t.start() - t.join() - - self.assertEqual(set(interpreters.list_all()), {main, id1, id2}) - - def test_after_destroy_all(self): - before = set(interpreters.list_all()) - # Create 3 subinterpreters. - ids = [] - for _ in range(3): - id = interpreters.create() - ids.append(id) - # Now destroy them. - for id in ids: - interpreters.destroy(id) - # Finally, create another. - id = interpreters.create() - self.assertEqual(set(interpreters.list_all()), before | {id}) - - def test_after_destroy_some(self): - before = set(interpreters.list_all()) - # Create 3 subinterpreters. - id1 = interpreters.create() - id2 = interpreters.create() - id3 = interpreters.create() - # Now destroy 2 of them. - interpreters.destroy(id1) - interpreters.destroy(id3) - # Finally, create another. - id = interpreters.create() - self.assertEqual(set(interpreters.list_all()), before | {id, id2}) - - - class DestroyTests(TestBase): - - def test_one(self): - id1 = interpreters.create() - id2 = interpreters.create() - id3 = interpreters.create() - self.assertIn(id2, interpreters.list_all()) - interpreters.destroy(id2) - self.assertNotIn(id2, interpreters.list_all()) - self.assertIn(id1, interpreters.list_all()) - self.assertIn(id3, interpreters.list_all()) - - def test_all(self): - before = set(interpreters.list_all()) - ids = set() - for _ in range(3): - id = interpreters.create() - ids.add(id) - self.assertEqual(set(interpreters.list_all()), before | ids) - for id in ids: - interpreters.destroy(id) - self.assertEqual(set(interpreters.list_all()), before) - - def test_main(self): - main, = interpreters.list_all() - with self.assertRaises(RuntimeError): - interpreters.destroy(main) - - def f(): - with self.assertRaises(RuntimeError): - interpreters.destroy(main) - - t = threading.Thread(target=f) - t.start() - t.join() - - def test_already_destroyed(self): - id = interpreters.create() - interpreters.destroy(id) - with self.assertRaises(RuntimeError): - interpreters.destroy(id) - - def test_does_not_exist(self): - with self.assertRaises(RuntimeError): - interpreters.destroy(1_000_000) - - def test_bad_id(self): - with self.assertRaises(ValueError): - interpreters.destroy(-1) - - def test_from_current(self): - main, = interpreters.list_all() - id = interpreters.create() - script = dedent(f""" - import _xxsubinterpreters as _interpreters - try: - _interpreters.destroy({id}) - except RuntimeError: - pass - """) - - interpreters.run_string(id, script) - self.assertEqual(set(interpreters.list_all()), {main, id}) - - def test_from_sibling(self): - main, = interpreters.list_all() - id1 = interpreters.create() - id2 = interpreters.create() - script = dedent(f""" - import _xxsubinterpreters as _interpreters - _interpreters.destroy({id2}) - """) - interpreters.run_string(id1, script) - - self.assertEqual(set(interpreters.list_all()), {main, id1}) - - def test_from_other_thread(self): - id = interpreters.create() - def f(): - interpreters.destroy(id) - - t = threading.Thread(target=f) - t.start() - t.join() - - def test_still_running(self): - main, = interpreters.list_all() - interp = interpreters.create() - with _running(interp): - self.assertTrue(interpreters.is_running(interp), - msg=f"Interp {interp} should be running before destruction.") - - with self.assertRaises(RuntimeError, - msg=f"Should not be able to destroy interp {interp} while it's still running."): - interpreters.destroy(interp) - self.assertTrue(interpreters.is_running(interp)) - - - class RunStringTests(TestBase): - - SCRIPT = dedent(""" - with open('{}', 'w') as out: - out.write('{}') - """) - FILENAME = 'spam' - - def setUp(self): - super().setUp() - self.id = interpreters.create() - self._fs = None - - def tearDown(self): - if self._fs is not None: - self._fs.close() - super().tearDown() - - @property - def fs(self): - if self._fs is None: - self._fs = FSFixture(self) - return self._fs - - def test_success(self): - script, file = _captured_script('print("it worked!", end="")') - with file: - interpreters.run_string(self.id, script) - out = file.read() - - self.assertEqual(out, 'it worked!') - - def test_in_thread(self): - script, file = _captured_script('print("it worked!", end="")') - with file: - def f(): - interpreters.run_string(self.id, script) - - t = threading.Thread(target=f) - t.start() - t.join() - out = file.read() - - self.assertEqual(out, 'it worked!') - - def test_create_thread(self): - script, file = _captured_script(""" - import threading - def f(): - print('it worked!', end='') - - t = threading.Thread(target=f) - t.start() - t.join() - """) - with file: - interpreters.run_string(self.id, script) - out = file.read() - - self.assertEqual(out, 'it worked!') - - @unittest.skipUnless(hasattr(os, 'fork'), "test needs os.fork()") - def test_fork(self): - import tempfile - with tempfile.NamedTemporaryFile('w+') as file: - file.write('') - file.flush() - - expected = 'spam spam spam spam spam' - script = dedent(f""" - import os - try: - os.fork() - except RuntimeError: - with open('{file.name}', 'w') as out: - out.write('{expected}') - """) - interpreters.run_string(self.id, script) - - file.seek(0) - content = file.read() - self.assertEqual(content, expected) - - def test_already_running(self): - with _running(self.id): - with self.assertRaises(RuntimeError): - interpreters.run_string(self.id, 'print("spam")') - - def test_does_not_exist(self): - id = 0 - while id in interpreters.list_all(): - id += 1 - with self.assertRaises(RuntimeError): - interpreters.run_string(id, 'print("spam")') - - def test_error_id(self): - with self.assertRaises(ValueError): - interpreters.run_string(-1, 'print("spam")') - - def test_bad_id(self): - with self.assertRaises(TypeError): - interpreters.run_string('spam', 'print("spam")') - - def test_bad_script(self): - with self.assertRaises(TypeError): - interpreters.run_string(self.id, 10) - - def test_bytes_for_script(self): - with self.assertRaises(TypeError): - interpreters.run_string(self.id, b'print("spam")') - - @contextlib.contextmanager - def assert_run_failed(self, exctype, msg=None): - with self.assertRaises(interpreters.RunFailedError) as caught: - yield - if msg is None: - self.assertEqual(str(caught.exception).split(':')[0], - str(exctype)) - else: - self.assertEqual(str(caught.exception), - "{}: {}".format(exctype, msg)) - - def test_invalid_syntax(self): - with self.assert_run_failed(SyntaxError): - # missing close paren - interpreters.run_string(self.id, 'print("spam"') - - def test_failure(self): - with self.assert_run_failed(Exception, 'spam'): - interpreters.run_string(self.id, 'raise Exception("spam")') - - def test_SystemExit(self): - with self.assert_run_failed(SystemExit, '42'): - interpreters.run_string(self.id, 'raise SystemExit(42)') - - def test_sys_exit(self): - with self.assert_run_failed(SystemExit): - interpreters.run_string(self.id, dedent(""" - import sys - sys.exit() - """)) - - with self.assert_run_failed(SystemExit, '42'): - interpreters.run_string(self.id, dedent(""" - import sys - sys.exit(42) - """)) - - def test_with_shared(self): - r, w = os.pipe() - - shared = { - 'spam': b'ham', - 'eggs': b'-1', - 'cheddar': None, - } - script = dedent(f""" - eggs = int(eggs) - spam = 42 - result = spam + eggs - - ns = dict(vars()) - del ns['__builtins__'] - import pickle - with open({w}, 'wb') as chan: - pickle.dump(ns, chan) - """) - interpreters.run_string(self.id, script, shared) - with open(r, 'rb') as chan: - ns = pickle.load(chan) - - self.assertEqual(ns['spam'], 42) - self.assertEqual(ns['eggs'], -1) - self.assertEqual(ns['result'], 41) - self.assertIsNone(ns['cheddar']) - - def test_shared_overwrites(self): - interpreters.run_string(self.id, dedent(""" - spam = 'eggs' - ns1 = dict(vars()) - del ns1['__builtins__'] - """)) - - shared = {'spam': b'ham'} - script = dedent(f""" - ns2 = dict(vars()) - del ns2['__builtins__'] - """) - interpreters.run_string(self.id, script, shared) - - r, w = os.pipe() - script = dedent(f""" - ns = dict(vars()) - del ns['__builtins__'] - import pickle - with open({w}, 'wb') as chan: - pickle.dump(ns, chan) - """) - interpreters.run_string(self.id, script) - with open(r, 'rb') as chan: - ns = pickle.load(chan) - - self.assertEqual(ns['ns1']['spam'], 'eggs') - self.assertEqual(ns['ns2']['spam'], b'ham') - self.assertEqual(ns['spam'], b'ham') - - def test_shared_overwrites_default_vars(self): - r, w = os.pipe() - - shared = {'__name__': b'not __main__'} - script = dedent(f""" - spam = 42 - - ns = dict(vars()) - del ns['__builtins__'] - import pickle - with open({w}, 'wb') as chan: - pickle.dump(ns, chan) - """) - interpreters.run_string(self.id, script, shared) - with open(r, 'rb') as chan: - ns = pickle.load(chan) - - self.assertEqual(ns['__name__'], b'not __main__') - - def test_main_reused(self): - r, w = os.pipe() - interpreters.run_string(self.id, dedent(f""" - spam = True - - ns = dict(vars()) - del ns['__builtins__'] - import pickle - with open({w}, 'wb') as chan: - pickle.dump(ns, chan) - del ns, pickle, chan - """)) - with open(r, 'rb') as chan: - ns1 = pickle.load(chan) - - r, w = os.pipe() - interpreters.run_string(self.id, dedent(f""" - eggs = False - - ns = dict(vars()) - del ns['__builtins__'] - import pickle - with open({w}, 'wb') as chan: - pickle.dump(ns, chan) - """)) - with open(r, 'rb') as chan: - ns2 = pickle.load(chan) - - self.assertIn('spam', ns1) - self.assertNotIn('eggs', ns1) - self.assertIn('eggs', ns2) - self.assertIn('spam', ns2) - - def test_execution_namespace_is_main(self): - r, w = os.pipe() - - script = dedent(f""" - spam = 42 - - ns = dict(vars()) - ns['__builtins__'] = str(ns['__builtins__']) - import pickle - with open({w}, 'wb') as chan: - pickle.dump(ns, chan) - """) - interpreters.run_string(self.id, script) - with open(r, 'rb') as chan: - ns = pickle.load(chan) - - ns.pop('__builtins__') - ns.pop('__loader__') - self.assertEqual(ns, { - '__name__': '__main__', - '__annotations__': {}, - '__doc__': None, - '__package__': None, - '__spec__': None, - 'spam': 42, - }) - - # XXX Fix this test! - @unittest.skip('blocking forever') - def test_still_running_at_exit(self): - script = dedent(f""" - from textwrap import dedent - import threading - import _xxsubinterpreters as _interpreters - id = _interpreters.create() - def f(): - _interpreters.run_string(id, dedent(''' - import time - # Give plenty of time for the main interpreter to finish. - time.sleep(1_000_000) - ''')) - - t = threading.Thread(target=f) - t.start() - """) - with support.temp_dir() as dirname: - filename = script_helper.make_script(dirname, 'interp', script) - with script_helper.spawn_python(filename) as proc: - retcode = proc.wait() - - self.assertEqual(retcode, 0) - - - ################################## - # channel tests - - class ChannelIDTests(TestBase): - - def test_default_kwargs(self): - cid = interpreters._channel_id(10, force=True) - - self.assertEqual(int(cid), 10) - self.assertEqual(cid.end, 'both') - - def test_with_kwargs(self): - cid = interpreters._channel_id(10, send=True, force=True) - self.assertEqual(cid.end, 'send') - - cid = interpreters._channel_id(10, send=True, recv=False, force=True) - self.assertEqual(cid.end, 'send') - - cid = interpreters._channel_id(10, recv=True, force=True) - self.assertEqual(cid.end, 'recv') - - cid = interpreters._channel_id(10, recv=True, send=False, force=True) - self.assertEqual(cid.end, 'recv') - - cid = interpreters._channel_id(10, send=True, recv=True, force=True) - self.assertEqual(cid.end, 'both') - - def test_coerce_id(self): - class Int(str): - def __index__(self): - return 10 - - cid = interpreters._channel_id(Int(), force=True) - self.assertEqual(int(cid), 10) - - def test_bad_id(self): - self.assertRaises(TypeError, interpreters._channel_id, object()) - self.assertRaises(TypeError, interpreters._channel_id, 10.0) - self.assertRaises(TypeError, interpreters._channel_id, '10') - self.assertRaises(TypeError, interpreters._channel_id, b'10') - self.assertRaises(ValueError, interpreters._channel_id, -1) - self.assertRaises(OverflowError, interpreters._channel_id, 2**64) - - def test_bad_kwargs(self): - with self.assertRaises(ValueError): - interpreters._channel_id(10, send=False, recv=False) - - def test_does_not_exist(self): - cid = interpreters.channel_create() - with self.assertRaises(interpreters.ChannelNotFoundError): - interpreters._channel_id(int(cid) + 1) # unforced - - def test_str(self): - cid = interpreters._channel_id(10, force=True) - self.assertEqual(str(cid), '10') - - def test_repr(self): - cid = interpreters._channel_id(10, force=True) - self.assertEqual(repr(cid), 'ChannelID(10)') - - cid = interpreters._channel_id(10, send=True, force=True) - self.assertEqual(repr(cid), 'ChannelID(10, send=True)') - - cid = interpreters._channel_id(10, recv=True, force=True) - self.assertEqual(repr(cid), 'ChannelID(10, recv=True)') - - cid = interpreters._channel_id(10, send=True, recv=True, force=True) - self.assertEqual(repr(cid), 'ChannelID(10)') - - def test_equality(self): - cid1 = interpreters.channel_create() - cid2 = interpreters._channel_id(int(cid1)) - cid3 = interpreters.channel_create() - - self.assertTrue(cid1 == cid1) - self.assertTrue(cid1 == cid2) - self.assertTrue(cid1 == int(cid1)) - self.assertTrue(int(cid1) == cid1) - self.assertTrue(cid1 == float(int(cid1))) - self.assertTrue(float(int(cid1)) == cid1) - self.assertFalse(cid1 == float(int(cid1)) + 0.1) - self.assertFalse(cid1 == str(int(cid1))) - self.assertFalse(cid1 == 2**1000) - self.assertFalse(cid1 == float('inf')) - self.assertFalse(cid1 == 'spam') - self.assertFalse(cid1 == cid3) - - self.assertFalse(cid1 != cid1) - self.assertFalse(cid1 != cid2) - self.assertTrue(cid1 != cid3) - - - class ChannelTests(TestBase): - - def test_create_cid(self): - cid = interpreters.channel_create() - self.assertIsInstance(cid, interpreters.ChannelID) - - def test_sequential_ids(self): - before = interpreters.channel_list_all() - id1 = interpreters.channel_create() - id2 = interpreters.channel_create() - id3 = interpreters.channel_create() - after = interpreters.channel_list_all() - - self.assertEqual(id2, int(id1) + 1) - self.assertEqual(id3, int(id2) + 1) - self.assertEqual(set(after) - set(before), {id1, id2, id3}) - - def test_ids_global(self): - id1 = interpreters.create() - out = _run_output(id1, dedent(""" - import _xxsubinterpreters as _interpreters - cid = _interpreters.channel_create() - print(cid) - """)) - cid1 = int(out.strip()) - - id2 = interpreters.create() - out = _run_output(id2, dedent(""" - import _xxsubinterpreters as _interpreters - cid = _interpreters.channel_create() - print(cid) - """)) - cid2 = int(out.strip()) - - self.assertEqual(cid2, int(cid1) + 1) - - #################### - - def test_send_recv_main(self): - cid = interpreters.channel_create() - orig = b'spam' - interpreters.channel_send(cid, orig) - obj = interpreters.channel_recv(cid) - - self.assertEqual(obj, orig) - self.assertIsNot(obj, orig) - - def test_send_recv_same_interpreter(self): - id1 = interpreters.create() - out = _run_output(id1, dedent(""" - import _xxsubinterpreters as _interpreters - cid = _interpreters.channel_create() - orig = b'spam' - _interpreters.channel_send(cid, orig) - obj = _interpreters.channel_recv(cid) - assert obj is not orig - assert obj == orig - """)) - - def test_send_recv_different_interpreters(self): - cid = interpreters.channel_create() - id1 = interpreters.create() - out = _run_output(id1, dedent(f""" - import _xxsubinterpreters as _interpreters - _interpreters.channel_send({cid}, b'spam') - """)) - obj = interpreters.channel_recv(cid) - - self.assertEqual(obj, b'spam') - - def test_send_recv_different_threads(self): - cid = interpreters.channel_create() - - def f(): - while True: - try: - obj = interpreters.channel_recv(cid) - break - except interpreters.ChannelEmptyError: - time.sleep(0.1) - interpreters.channel_send(cid, obj) - t = threading.Thread(target=f) - t.start() - - interpreters.channel_send(cid, b'spam') - t.join() - obj = interpreters.channel_recv(cid) - - self.assertEqual(obj, b'spam') - - def test_send_recv_different_interpreters_and_threads(self): - cid = interpreters.channel_create() - id1 = interpreters.create() - out = None - - def f(): - nonlocal out - out = _run_output(id1, dedent(f""" - import time - import _xxsubinterpreters as _interpreters - while True: - try: - obj = _interpreters.channel_recv({cid}) - break - except _interpreters.ChannelEmptyError: - time.sleep(0.1) - assert(obj == b'spam') - _interpreters.channel_send({cid}, b'eggs') - """)) - t = threading.Thread(target=f) - t.start() - - interpreters.channel_send(cid, b'spam') - t.join() - obj = interpreters.channel_recv(cid) - - self.assertEqual(obj, b'eggs') - - def test_send_not_found(self): - with self.assertRaises(interpreters.ChannelNotFoundError): - interpreters.channel_send(10, b'spam') - - def test_recv_not_found(self): - with self.assertRaises(interpreters.ChannelNotFoundError): - interpreters.channel_recv(10) - - def test_recv_empty(self): - cid = interpreters.channel_create() - with self.assertRaises(interpreters.ChannelEmptyError): - interpreters.channel_recv(cid) - - def test_run_string_arg_unresolved(self): - cid = interpreters.channel_create() - interp = interpreters.create() - - out = _run_output(interp, dedent(""" - import _xxsubinterpreters as _interpreters - print(cid.end) - _interpreters.channel_send(cid, b'spam') - """), - dict(cid=cid.send)) - obj = interpreters.channel_recv(cid) - - self.assertEqual(obj, b'spam') - self.assertEqual(out.strip(), 'send') - - # XXX For now there is no high-level channel into which the - # sent channel ID can be converted... - # Note: this test caused crashes on some buildbots (bpo-33615). - @unittest.skip('disabled until high-level channels exist') - def test_run_string_arg_resolved(self): - cid = interpreters.channel_create() - cid = interpreters._channel_id(cid, _resolve=True) - interp = interpreters.create() - - out = _run_output(interp, dedent(""" - import _xxsubinterpreters as _interpreters - print(chan.id.end) - _interpreters.channel_send(chan.id, b'spam') - """), - dict(chan=cid.send)) - obj = interpreters.channel_recv(cid) - - self.assertEqual(obj, b'spam') - self.assertEqual(out.strip(), 'send') - - # close - - def test_close_single_user(self): - cid = interpreters.channel_create() - interpreters.channel_send(cid, b'spam') - interpreters.channel_recv(cid) - interpreters.channel_close(cid) - - with self.assertRaises(interpreters.ChannelClosedError): - interpreters.channel_send(cid, b'eggs') - with self.assertRaises(interpreters.ChannelClosedError): - interpreters.channel_recv(cid) - - def test_close_multiple_users(self): - cid = interpreters.channel_create() - id1 = interpreters.create() - id2 = interpreters.create() - interpreters.run_string(id1, dedent(f""" - import _xxsubinterpreters as _interpreters - _interpreters.channel_send({cid}, b'spam') - """)) - interpreters.run_string(id2, dedent(f""" - import _xxsubinterpreters as _interpreters - _interpreters.channel_recv({cid}) - """)) - interpreters.channel_close(cid) - with self.assertRaises(interpreters.RunFailedError) as cm: - interpreters.run_string(id1, dedent(f""" - _interpreters.channel_send({cid}, b'spam') - """)) - self.assertIn('ChannelClosedError', str(cm.exception)) - with self.assertRaises(interpreters.RunFailedError) as cm: - interpreters.run_string(id2, dedent(f""" - _interpreters.channel_send({cid}, b'spam') - """)) - self.assertIn('ChannelClosedError', str(cm.exception)) - - def test_close_multiple_times(self): - cid = interpreters.channel_create() - interpreters.channel_send(cid, b'spam') - interpreters.channel_recv(cid) - interpreters.channel_close(cid) - - with self.assertRaises(interpreters.ChannelClosedError): - interpreters.channel_close(cid) - - def test_close_empty(self): - tests = [ - (False, False), - (True, False), - (False, True), - (True, True), - ] - for send, recv in tests: - with self.subTest((send, recv)): - cid = interpreters.channel_create() - interpreters.channel_send(cid, b'spam') - interpreters.channel_recv(cid) - interpreters.channel_close(cid, send=send, recv=recv) - - with self.assertRaises(interpreters.ChannelClosedError): - interpreters.channel_send(cid, b'eggs') - with self.assertRaises(interpreters.ChannelClosedError): - interpreters.channel_recv(cid) - - def test_close_defaults_with_unused_items(self): - cid = interpreters.channel_create() - interpreters.channel_send(cid, b'spam') - interpreters.channel_send(cid, b'ham') - - with self.assertRaises(interpreters.ChannelNotEmptyError): - interpreters.channel_close(cid) - interpreters.channel_recv(cid) - interpreters.channel_send(cid, b'eggs') - - def test_close_recv_with_unused_items_unforced(self): - cid = interpreters.channel_create() - interpreters.channel_send(cid, b'spam') - interpreters.channel_send(cid, b'ham') - - with self.assertRaises(interpreters.ChannelNotEmptyError): - interpreters.channel_close(cid, recv=True) - interpreters.channel_recv(cid) - interpreters.channel_send(cid, b'eggs') - interpreters.channel_recv(cid) - interpreters.channel_recv(cid) - interpreters.channel_close(cid, recv=True) - - def test_close_send_with_unused_items_unforced(self): - cid = interpreters.channel_create() - interpreters.channel_send(cid, b'spam') - interpreters.channel_send(cid, b'ham') - interpreters.channel_close(cid, send=True) - - with self.assertRaises(interpreters.ChannelClosedError): - interpreters.channel_send(cid, b'eggs') - interpreters.channel_recv(cid) - interpreters.channel_recv(cid) - with self.assertRaises(interpreters.ChannelClosedError): - interpreters.channel_recv(cid) - - def test_close_both_with_unused_items_unforced(self): - cid = interpreters.channel_create() - interpreters.channel_send(cid, b'spam') - interpreters.channel_send(cid, b'ham') - - with self.assertRaises(interpreters.ChannelNotEmptyError): - interpreters.channel_close(cid, recv=True, send=True) - interpreters.channel_recv(cid) - interpreters.channel_send(cid, b'eggs') - interpreters.channel_recv(cid) - interpreters.channel_recv(cid) - interpreters.channel_close(cid, recv=True) - - def test_close_recv_with_unused_items_forced(self): - cid = interpreters.channel_create() - interpreters.channel_send(cid, b'spam') - interpreters.channel_send(cid, b'ham') - interpreters.channel_close(cid, recv=True, force=True) - - with self.assertRaises(interpreters.ChannelClosedError): - interpreters.channel_send(cid, b'eggs') - with self.assertRaises(interpreters.ChannelClosedError): - interpreters.channel_recv(cid) - - def test_close_send_with_unused_items_forced(self): - cid = interpreters.channel_create() - interpreters.channel_send(cid, b'spam') - interpreters.channel_send(cid, b'ham') - interpreters.channel_close(cid, send=True, force=True) - - with self.assertRaises(interpreters.ChannelClosedError): - interpreters.channel_send(cid, b'eggs') - with self.assertRaises(interpreters.ChannelClosedError): - interpreters.channel_recv(cid) - - def test_close_both_with_unused_items_forced(self): - cid = interpreters.channel_create() - interpreters.channel_send(cid, b'spam') - interpreters.channel_send(cid, b'ham') - interpreters.channel_close(cid, send=True, recv=True, force=True) - - with self.assertRaises(interpreters.ChannelClosedError): - interpreters.channel_send(cid, b'eggs') - with self.assertRaises(interpreters.ChannelClosedError): - interpreters.channel_recv(cid) - - def test_close_never_used(self): - cid = interpreters.channel_create() - interpreters.channel_close(cid) - - with self.assertRaises(interpreters.ChannelClosedError): - interpreters.channel_send(cid, b'spam') - with self.assertRaises(interpreters.ChannelClosedError): - interpreters.channel_recv(cid) - - def test_close_by_unassociated_interp(self): - cid = interpreters.channel_create() - interpreters.channel_send(cid, b'spam') - interp = interpreters.create() - interpreters.run_string(interp, dedent(f""" - import _xxsubinterpreters as _interpreters - _interpreters.channel_close({cid}, force=True) - """)) - with self.assertRaises(interpreters.ChannelClosedError): - interpreters.channel_recv(cid) - with self.assertRaises(interpreters.ChannelClosedError): - interpreters.channel_close(cid) - - def test_close_used_multiple_times_by_single_user(self): - cid = interpreters.channel_create() - interpreters.channel_send(cid, b'spam') - interpreters.channel_send(cid, b'spam') - interpreters.channel_send(cid, b'spam') - interpreters.channel_recv(cid) - interpreters.channel_close(cid, force=True) - - with self.assertRaises(interpreters.ChannelClosedError): - interpreters.channel_send(cid, b'eggs') - with self.assertRaises(interpreters.ChannelClosedError): - interpreters.channel_recv(cid) - - - class ChannelReleaseTests(TestBase): - - # XXX Add more test coverage a la the tests for close(). - - """ - - main / interp / other - - run in: current thread / new thread / other thread / different threads - - end / opposite - - force / no force - - used / not used (associated / not associated) - - empty / emptied / never emptied / partly emptied - - closed / not closed - - released / not released - - creator (interp) / other - - associated interpreter not running - - associated interpreter destroyed - """ - - """ - use - pre-release - release - after - check - """ - - """ - release in: main, interp1 - creator: same, other (incl. interp2) - - use: None,send,recv,send/recv in None,same,other(incl. interp2),same+other(incl. interp2),all - pre-release: None,send,recv,both in None,same,other(incl. interp2),same+other(incl. interp2),all - pre-release forced: None,send,recv,both in None,same,other(incl. interp2),same+other(incl. interp2),all - - release: same - release forced: same - - use after: None,send,recv,send/recv in None,same,other(incl. interp2),same+other(incl. interp2),all - release after: None,send,recv,send/recv in None,same,other(incl. interp2),same+other(incl. interp2),all - check released: send/recv for same/other(incl. interp2) - check closed: send/recv for same/other(incl. interp2) - """ - - def test_single_user(self): - cid = interpreters.channel_create() - interpreters.channel_send(cid, b'spam') - interpreters.channel_recv(cid) - interpreters.channel_release(cid, send=True, recv=True) - - with self.assertRaises(interpreters.ChannelClosedError): - interpreters.channel_send(cid, b'eggs') - with self.assertRaises(interpreters.ChannelClosedError): - interpreters.channel_recv(cid) - - def test_multiple_users(self): - cid = interpreters.channel_create() - id1 = interpreters.create() - id2 = interpreters.create() - interpreters.run_string(id1, dedent(f""" - import _xxsubinterpreters as _interpreters - _interpreters.channel_send({cid}, b'spam') - """)) - out = _run_output(id2, dedent(f""" - import _xxsubinterpreters as _interpreters - obj = _interpreters.channel_recv({cid}) - _interpreters.channel_release({cid}) - print(repr(obj)) - """)) - interpreters.run_string(id1, dedent(f""" - _interpreters.channel_release({cid}) - """)) - - self.assertEqual(out.strip(), "b'spam'") - - def test_no_kwargs(self): - cid = interpreters.channel_create() - interpreters.channel_send(cid, b'spam') - interpreters.channel_recv(cid) - interpreters.channel_release(cid) - - with self.assertRaises(interpreters.ChannelClosedError): - interpreters.channel_send(cid, b'eggs') - with self.assertRaises(interpreters.ChannelClosedError): - interpreters.channel_recv(cid) - - def test_multiple_times(self): - cid = interpreters.channel_create() - interpreters.channel_send(cid, b'spam') - interpreters.channel_recv(cid) - interpreters.channel_release(cid, send=True, recv=True) - - with self.assertRaises(interpreters.ChannelClosedError): - interpreters.channel_release(cid, send=True, recv=True) - - def test_with_unused_items(self): - cid = interpreters.channel_create() - interpreters.channel_send(cid, b'spam') - interpreters.channel_send(cid, b'ham') - interpreters.channel_release(cid, send=True, recv=True) - - with self.assertRaises(interpreters.ChannelClosedError): - interpreters.channel_recv(cid) - - def test_never_used(self): - cid = interpreters.channel_create() - interpreters.channel_release(cid) - - with self.assertRaises(interpreters.ChannelClosedError): - interpreters.channel_send(cid, b'spam') - with self.assertRaises(interpreters.ChannelClosedError): - interpreters.channel_recv(cid) - - def test_by_unassociated_interp(self): - cid = interpreters.channel_create() - interpreters.channel_send(cid, b'spam') - interp = interpreters.create() - interpreters.run_string(interp, dedent(f""" - import _xxsubinterpreters as _interpreters - _interpreters.channel_release({cid}) - """)) - obj = interpreters.channel_recv(cid) - interpreters.channel_release(cid) - - with self.assertRaises(interpreters.ChannelClosedError): - interpreters.channel_send(cid, b'eggs') - self.assertEqual(obj, b'spam') - - def test_close_if_unassociated(self): - # XXX Something's not right with this test... - cid = interpreters.channel_create() - interp = interpreters.create() - interpreters.run_string(interp, dedent(f""" - import _xxsubinterpreters as _interpreters - obj = _interpreters.channel_send({cid}, b'spam') - _interpreters.channel_release({cid}) - """)) - - with self.assertRaises(interpreters.ChannelClosedError): - interpreters.channel_recv(cid) - - def test_partially(self): - # XXX Is partial close too weird/confusing? - cid = interpreters.channel_create() - interpreters.channel_send(cid, None) - interpreters.channel_recv(cid) - interpreters.channel_send(cid, b'spam') - interpreters.channel_release(cid, send=True) - obj = interpreters.channel_recv(cid) - - self.assertEqual(obj, b'spam') - - def test_used_multiple_times_by_single_user(self): - cid = interpreters.channel_create() - interpreters.channel_send(cid, b'spam') - interpreters.channel_send(cid, b'spam') - interpreters.channel_send(cid, b'spam') - interpreters.channel_recv(cid) - interpreters.channel_release(cid, send=True, recv=True) - - with self.assertRaises(interpreters.ChannelClosedError): - interpreters.channel_send(cid, b'eggs') - with self.assertRaises(interpreters.ChannelClosedError): - interpreters.channel_recv(cid) - - - class ChannelCloseFixture(namedtuple('ChannelCloseFixture', - 'end interp other extra creator')): - - # Set this to True to avoid creating interpreters, e.g. when - # scanning through test permutations without running them. - QUICK = False - - def __new__(cls, end, interp, other, extra, creator): - assert end in ('send', 'recv') - if cls.QUICK: - known = {} - else: - interp = Interpreter.from_raw(interp) - other = Interpreter.from_raw(other) - extra = Interpreter.from_raw(extra) - known = { - interp.name: interp, - other.name: other, - extra.name: extra, - } - if not creator: - creator = 'same' - self = super().__new__(cls, end, interp, other, extra, creator) - self._prepped = set() - self._state = ChannelState() - self._known = known - return self - - @property - def state(self): - return self._state - - @property - def cid(self): - try: - return self._cid - except AttributeError: - creator = self._get_interpreter(self.creator) - self._cid = self._new_channel(creator) - return self._cid - - def get_interpreter(self, interp): - interp = self._get_interpreter(interp) - self._prep_interpreter(interp) - return interp - - def expect_closed_error(self, end=None): - if end is None: - end = self.end - if end == 'recv' and self.state.closed == 'send': - return False - return bool(self.state.closed) - - def prep_interpreter(self, interp): - self._prep_interpreter(interp) - - def record_action(self, action, result): - self._state = result - - def clean_up(self): - clean_up_interpreters() - clean_up_channels() - - # internal methods - - def _new_channel(self, creator): - if creator.name == 'main': - return interpreters.channel_create() - else: - ch = interpreters.channel_create() - run_interp(creator.id, f""" - import _xxsubinterpreters - cid = _xxsubinterpreters.channel_create() - # We purposefully send back an int to avoid tying the - # channel to the other interpreter. - _xxsubinterpreters.channel_send({ch}, int(cid)) - del _xxsubinterpreters - """) - self._cid = interpreters.channel_recv(ch) - return self._cid - - def _get_interpreter(self, interp): - if interp in ('same', 'interp'): - return self.interp - elif interp == 'other': - return self.other - elif interp == 'extra': - return self.extra - else: - name = interp - try: - interp = self._known[name] - except KeyError: - interp = self._known[name] = Interpreter(name) - return interp - - def _prep_interpreter(self, interp): - if interp.id in self._prepped: - return - self._prepped.add(interp.id) - if interp.name == 'main': - return - run_interp(interp.id, f""" - import _xxsubinterpreters as interpreters - import test.test__xxsubinterpreters as helpers - ChannelState = helpers.ChannelState - try: - cid - except NameError: - cid = interpreters._channel_id({self.cid}) - """) - - - @unittest.skip('these tests take several hours to run') - class ExhaustiveChannelTests(TestBase): - - """ - - main / interp / other - - run in: current thread / new thread / other thread / different threads - - end / opposite - - force / no force - - used / not used (associated / not associated) - - empty / emptied / never emptied / partly emptied - - closed / not closed - - released / not released - - creator (interp) / other - - associated interpreter not running - - associated interpreter destroyed - - - close after unbound - """ - - """ - use - pre-close - close - after - check - """ - - """ - close in: main, interp1 - creator: same, other, extra - - use: None,send,recv,send/recv in None,same,other,same+other,all - pre-close: None,send,recv in None,same,other,same+other,all - pre-close forced: None,send,recv in None,same,other,same+other,all - - close: same - close forced: same - - use after: None,send,recv,send/recv in None,same,other,extra,same+other,all - close after: None,send,recv,send/recv in None,same,other,extra,same+other,all - check closed: send/recv for same/other(incl. interp2) - """ - - def iter_action_sets(self): - # - used / not used (associated / not associated) - # - empty / emptied / never emptied / partly emptied - # - closed / not closed - # - released / not released - - # never used - yield [] - - # only pre-closed (and possible used after) - for closeactions in self._iter_close_action_sets('same', 'other'): - yield closeactions - for postactions in self._iter_post_close_action_sets(): - yield closeactions + postactions - for closeactions in self._iter_close_action_sets('other', 'extra'): - yield closeactions - for postactions in self._iter_post_close_action_sets(): - yield closeactions + postactions - - # used - for useactions in self._iter_use_action_sets('same', 'other'): - yield useactions - for closeactions in self._iter_close_action_sets('same', 'other'): - actions = useactions + closeactions - yield actions - for postactions in self._iter_post_close_action_sets(): - yield actions + postactions - for closeactions in self._iter_close_action_sets('other', 'extra'): - actions = useactions + closeactions - yield actions - for postactions in self._iter_post_close_action_sets(): - yield actions + postactions - for useactions in self._iter_use_action_sets('other', 'extra'): - yield useactions - for closeactions in self._iter_close_action_sets('same', 'other'): - actions = useactions + closeactions - yield actions - for postactions in self._iter_post_close_action_sets(): - yield actions + postactions - for closeactions in self._iter_close_action_sets('other', 'extra'): - actions = useactions + closeactions - yield actions - for postactions in self._iter_post_close_action_sets(): - yield actions + postactions - - def _iter_use_action_sets(self, interp1, interp2): - interps = (interp1, interp2) - - # only recv end used - yield [ - ChannelAction('use', 'recv', interp1), - ] - yield [ - ChannelAction('use', 'recv', interp2), - ] - yield [ - ChannelAction('use', 'recv', interp1), - ChannelAction('use', 'recv', interp2), - ] - - # never emptied - yield [ - ChannelAction('use', 'send', interp1), - ] - yield [ - ChannelAction('use', 'send', interp2), - ] - yield [ - ChannelAction('use', 'send', interp1), - ChannelAction('use', 'send', interp2), - ] - - # partially emptied - for interp1 in interps: - for interp2 in interps: - for interp3 in interps: - yield [ - ChannelAction('use', 'send', interp1), - ChannelAction('use', 'send', interp2), - ChannelAction('use', 'recv', interp3), - ] - - # fully emptied - for interp1 in interps: - for interp2 in interps: - for interp3 in interps: - for interp4 in interps: - yield [ - ChannelAction('use', 'send', interp1), - ChannelAction('use', 'send', interp2), - ChannelAction('use', 'recv', interp3), - ChannelAction('use', 'recv', interp4), - ] - - def _iter_close_action_sets(self, interp1, interp2): - ends = ('recv', 'send') - interps = (interp1, interp2) - for force in (True, False): - op = 'force-close' if force else 'close' - for interp in interps: - for end in ends: - yield [ - ChannelAction(op, end, interp), - ] - for recvop in ('close', 'force-close'): - for sendop in ('close', 'force-close'): - for recv in interps: - for send in interps: - yield [ - ChannelAction(recvop, 'recv', recv), - ChannelAction(sendop, 'send', send), - ] - - def _iter_post_close_action_sets(self): - for interp in ('same', 'extra', 'other'): - yield [ - ChannelAction('use', 'recv', interp), - ] - yield [ - ChannelAction('use', 'send', interp), - ] - - def run_actions(self, fix, actions): - for action in actions: - self.run_action(fix, action) - - def run_action(self, fix, action, *, hideclosed=True): - end = action.resolve_end(fix.end) - interp = action.resolve_interp(fix.interp, fix.other, fix.extra) - fix.prep_interpreter(interp) - if interp.name == 'main': - result = run_action( - fix.cid, - action.action, - end, - fix.state, - hideclosed=hideclosed, - ) - fix.record_action(action, result) - else: - _cid = interpreters.channel_create() - run_interp(interp.id, f""" - result = helpers.run_action( - {fix.cid}, - {repr(action.action)}, - {repr(end)}, - {repr(fix.state)}, - hideclosed={hideclosed}, - ) - interpreters.channel_send({_cid}, result.pending.to_bytes(1, 'little')) - interpreters.channel_send({_cid}, b'X' if result.closed else b'') - """) - result = ChannelState( - pending=int.from_bytes(interpreters.channel_recv(_cid), 'little'), - closed=bool(interpreters.channel_recv(_cid)), - ) - fix.record_action(action, result) - - def iter_fixtures(self): - # XXX threads? - interpreters = [ - ('main', 'interp', 'extra'), - ('interp', 'main', 'extra'), - ('interp1', 'interp2', 'extra'), - ('interp1', 'interp2', 'main'), - ] - for interp, other, extra in interpreters: - for creator in ('same', 'other', 'creator'): - for end in ('send', 'recv'): - yield ChannelCloseFixture(end, interp, other, extra, creator) - - def _close(self, fix, *, force): - op = 'force-close' if force else 'close' - close = ChannelAction(op, fix.end, 'same') - if not fix.expect_closed_error(): - self.run_action(fix, close, hideclosed=False) - else: - with self.assertRaises(interpreters.ChannelClosedError): - self.run_action(fix, close, hideclosed=False) - - def _assert_closed_in_interp(self, fix, interp=None): - if interp is None or interp.name == 'main': - with self.assertRaises(interpreters.ChannelClosedError): - interpreters.channel_recv(fix.cid) - with self.assertRaises(interpreters.ChannelClosedError): - interpreters.channel_send(fix.cid, b'spam') - with self.assertRaises(interpreters.ChannelClosedError): - interpreters.channel_close(fix.cid) - with self.assertRaises(interpreters.ChannelClosedError): - interpreters.channel_close(fix.cid, force=True) - else: - run_interp(interp.id, f""" - with helpers.expect_channel_closed(): - interpreters.channel_recv(cid) - """) - run_interp(interp.id, f""" - with helpers.expect_channel_closed(): - interpreters.channel_send(cid, b'spam') - """) - run_interp(interp.id, f""" - with helpers.expect_channel_closed(): - interpreters.channel_close(cid) - """) - run_interp(interp.id, f""" - with helpers.expect_channel_closed(): - interpreters.channel_close(cid, force=True) - """) - - def _assert_closed(self, fix): - self.assertTrue(fix.state.closed) - - for _ in range(fix.state.pending): - interpreters.channel_recv(fix.cid) - self._assert_closed_in_interp(fix) - - for interp in ('same', 'other'): - interp = fix.get_interpreter(interp) - if interp.name == 'main': - continue - self._assert_closed_in_interp(fix, interp) - - interp = fix.get_interpreter('fresh') - self._assert_closed_in_interp(fix, interp) - - def _iter_close_tests(self, verbose=False): - i = 0 - for actions in self.iter_action_sets(): - print() - for fix in self.iter_fixtures(): - i += 1 - if i > 1000: - return - if verbose: - if (i - 1) % 6 == 0: - print() - print(i, fix, '({} actions)'.format(len(actions))) - else: - if (i - 1) % 6 == 0: - print(' ', end='') - print('.', end=''); sys.stdout.flush() - yield i, fix, actions - if verbose: - print('---') - print() - - # This is useful for scanning through the possible tests. - def _skim_close_tests(self): - ChannelCloseFixture.QUICK = True - for i, fix, actions in self._iter_close_tests(): - pass - - def test_close(self): - for i, fix, actions in self._iter_close_tests(): - with self.subTest('{} {} {}'.format(i, fix, actions)): - fix.prep_interpreter(fix.interp) - self.run_actions(fix, actions) - - self._close(fix, force=False) - - self._assert_closed(fix) - # XXX Things slow down if we have too many interpreters. - fix.clean_up() - - def test_force_close(self): - for i, fix, actions in self._iter_close_tests(): - with self.subTest('{} {} {}'.format(i, fix, actions)): - fix.prep_interpreter(fix.interp) - self.run_actions(fix, actions) - - self._close(fix, force=True) - - self._assert_closed(fix) - # XXX Things slow down if we have too many interpreters. - fix.clean_up() - - - if __name__ == '__main__': - unittest.main() diff --git a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_abc.yaml b/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_abc.yaml deleted file mode 100644 index cc7fa1045..000000000 --- a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_abc.yaml +++ /dev/null @@ -1,494 +0,0 @@ -python: | - # Copyright 2007 Google, Inc. All Rights Reserved. - # Licensed to PSF under a Contributor Agreement. - - # Note: each test is run with Python and C versions of ABCMeta. Except for - # test_ABC_helper(), which assures that abc.ABC is an instance of abc.ABCMeta. - - """Unit tests for abc.py.""" - - import unittest - - import abc - import _py_abc - from inspect import isabstract - - def test_factory(abc_ABCMeta, abc_get_cache_token): - class TestLegacyAPI(unittest.TestCase): - - def test_abstractproperty_basics(self): - @abc.abstractproperty - def foo(self): pass - self.assertTrue(foo.__isabstractmethod__) - def bar(self): pass - self.assertFalse(hasattr(bar, "__isabstractmethod__")) - - class C(metaclass=abc_ABCMeta): - @abc.abstractproperty - def foo(self): return 3 - self.assertRaises(TypeError, C) - class D(C): - @property - def foo(self): return super().foo - self.assertEqual(D().foo, 3) - self.assertFalse(getattr(D.foo, "__isabstractmethod__", False)) - - def test_abstractclassmethod_basics(self): - @abc.abstractclassmethod - def foo(cls): pass - self.assertTrue(foo.__isabstractmethod__) - @classmethod - def bar(cls): pass - self.assertFalse(getattr(bar, "__isabstractmethod__", False)) - - class C(metaclass=abc_ABCMeta): - @abc.abstractclassmethod - def foo(cls): return cls.__name__ - self.assertRaises(TypeError, C) - class D(C): - @classmethod - def foo(cls): return super().foo() - self.assertEqual(D.foo(), 'D') - self.assertEqual(D().foo(), 'D') - - def test_abstractstaticmethod_basics(self): - @abc.abstractstaticmethod - def foo(): pass - self.assertTrue(foo.__isabstractmethod__) - @staticmethod - def bar(): pass - self.assertFalse(getattr(bar, "__isabstractmethod__", False)) - - class C(metaclass=abc_ABCMeta): - @abc.abstractstaticmethod - def foo(): return 3 - self.assertRaises(TypeError, C) - class D(C): - @staticmethod - def foo(): return 4 - self.assertEqual(D.foo(), 4) - self.assertEqual(D().foo(), 4) - - - class TestABC(unittest.TestCase): - - def test_ABC_helper(self): - # create an ABC using the helper class and perform basic checks - class C(abc.ABC): - @classmethod - @abc.abstractmethod - def foo(cls): return cls.__name__ - self.assertEqual(type(C), abc.ABCMeta) - self.assertRaises(TypeError, C) - class D(C): - @classmethod - def foo(cls): return super().foo() - self.assertEqual(D.foo(), 'D') - - def test_abstractmethod_basics(self): - @abc.abstractmethod - def foo(self): pass - self.assertTrue(foo.__isabstractmethod__) - def bar(self): pass - self.assertFalse(hasattr(bar, "__isabstractmethod__")) - - def test_abstractproperty_basics(self): - @property - @abc.abstractmethod - def foo(self): pass - self.assertTrue(foo.__isabstractmethod__) - def bar(self): pass - self.assertFalse(getattr(bar, "__isabstractmethod__", False)) - - class C(metaclass=abc_ABCMeta): - @property - @abc.abstractmethod - def foo(self): return 3 - self.assertRaises(TypeError, C) - class D(C): - @C.foo.getter - def foo(self): return super().foo - self.assertEqual(D().foo, 3) - - def test_abstractclassmethod_basics(self): - @classmethod - @abc.abstractmethod - def foo(cls): pass - self.assertTrue(foo.__isabstractmethod__) - @classmethod - def bar(cls): pass - self.assertFalse(getattr(bar, "__isabstractmethod__", False)) - - class C(metaclass=abc_ABCMeta): - @classmethod - @abc.abstractmethod - def foo(cls): return cls.__name__ - self.assertRaises(TypeError, C) - class D(C): - @classmethod - def foo(cls): return super().foo() - self.assertEqual(D.foo(), 'D') - self.assertEqual(D().foo(), 'D') - - def test_abstractstaticmethod_basics(self): - @staticmethod - @abc.abstractmethod - def foo(): pass - self.assertTrue(foo.__isabstractmethod__) - @staticmethod - def bar(): pass - self.assertFalse(getattr(bar, "__isabstractmethod__", False)) - - class C(metaclass=abc_ABCMeta): - @staticmethod - @abc.abstractmethod - def foo(): return 3 - self.assertRaises(TypeError, C) - class D(C): - @staticmethod - def foo(): return 4 - self.assertEqual(D.foo(), 4) - self.assertEqual(D().foo(), 4) - - def test_abstractmethod_integration(self): - for abstractthing in [abc.abstractmethod, abc.abstractproperty, - abc.abstractclassmethod, - abc.abstractstaticmethod]: - class C(metaclass=abc_ABCMeta): - @abstractthing - def foo(self): pass # abstract - def bar(self): pass # concrete - self.assertEqual(C.__abstractmethods__, {"foo"}) - self.assertRaises(TypeError, C) # because foo is abstract - self.assertTrue(isabstract(C)) - class D(C): - def bar(self): pass # concrete override of concrete - self.assertEqual(D.__abstractmethods__, {"foo"}) - self.assertRaises(TypeError, D) # because foo is still abstract - self.assertTrue(isabstract(D)) - class E(D): - def foo(self): pass - self.assertEqual(E.__abstractmethods__, set()) - E() # now foo is concrete, too - self.assertFalse(isabstract(E)) - class F(E): - @abstractthing - def bar(self): pass # abstract override of concrete - self.assertEqual(F.__abstractmethods__, {"bar"}) - self.assertRaises(TypeError, F) # because bar is abstract now - self.assertTrue(isabstract(F)) - - def test_descriptors_with_abstractmethod(self): - class C(metaclass=abc_ABCMeta): - @property - @abc.abstractmethod - def foo(self): return 3 - @foo.setter - @abc.abstractmethod - def foo(self, val): pass - self.assertRaises(TypeError, C) - class D(C): - @C.foo.getter - def foo(self): return super().foo - self.assertRaises(TypeError, D) - class E(D): - @D.foo.setter - def foo(self, val): pass - self.assertEqual(E().foo, 3) - # check that the property's __isabstractmethod__ descriptor does the - # right thing when presented with a value that fails truth testing: - class NotBool(object): - def __bool__(self): - raise ValueError() - __len__ = __bool__ - with self.assertRaises(ValueError): - class F(C): - def bar(self): - pass - bar.__isabstractmethod__ = NotBool() - foo = property(bar) - - - def test_customdescriptors_with_abstractmethod(self): - class Descriptor: - def __init__(self, fget, fset=None): - self._fget = fget - self._fset = fset - def getter(self, callable): - return Descriptor(callable, self._fget) - def setter(self, callable): - return Descriptor(self._fget, callable) - @property - def __isabstractmethod__(self): - return (getattr(self._fget, '__isabstractmethod__', False) - or getattr(self._fset, '__isabstractmethod__', False)) - class C(metaclass=abc_ABCMeta): - @Descriptor - @abc.abstractmethod - def foo(self): return 3 - @foo.setter - @abc.abstractmethod - def foo(self, val): pass - self.assertRaises(TypeError, C) - class D(C): - @C.foo.getter - def foo(self): return super().foo - self.assertRaises(TypeError, D) - class E(D): - @D.foo.setter - def foo(self, val): pass - self.assertFalse(E.foo.__isabstractmethod__) - - def test_metaclass_abc(self): - # Metaclasses can be ABCs, too. - class A(metaclass=abc_ABCMeta): - @abc.abstractmethod - def x(self): - pass - self.assertEqual(A.__abstractmethods__, {"x"}) - class meta(type, A): - def x(self): - return 1 - class C(metaclass=meta): - pass - - def test_registration_basics(self): - class A(metaclass=abc_ABCMeta): - pass - class B(object): - pass - b = B() - self.assertFalse(issubclass(B, A)) - self.assertFalse(issubclass(B, (A,))) - self.assertNotIsInstance(b, A) - self.assertNotIsInstance(b, (A,)) - B1 = A.register(B) - self.assertTrue(issubclass(B, A)) - self.assertTrue(issubclass(B, (A,))) - self.assertIsInstance(b, A) - self.assertIsInstance(b, (A,)) - self.assertIs(B1, B) - class C(B): - pass - c = C() - self.assertTrue(issubclass(C, A)) - self.assertTrue(issubclass(C, (A,))) - self.assertIsInstance(c, A) - self.assertIsInstance(c, (A,)) - - def test_register_as_class_deco(self): - class A(metaclass=abc_ABCMeta): - pass - @A.register - class B(object): - pass - b = B() - self.assertTrue(issubclass(B, A)) - self.assertTrue(issubclass(B, (A,))) - self.assertIsInstance(b, A) - self.assertIsInstance(b, (A,)) - @A.register - class C(B): - pass - c = C() - self.assertTrue(issubclass(C, A)) - self.assertTrue(issubclass(C, (A,))) - self.assertIsInstance(c, A) - self.assertIsInstance(c, (A,)) - self.assertIs(C, A.register(C)) - - def test_isinstance_invalidation(self): - class A(metaclass=abc_ABCMeta): - pass - class B: - pass - b = B() - self.assertFalse(isinstance(b, A)) - self.assertFalse(isinstance(b, (A,))) - token_old = abc_get_cache_token() - A.register(B) - token_new = abc_get_cache_token() - self.assertNotEqual(token_old, token_new) - self.assertTrue(isinstance(b, A)) - self.assertTrue(isinstance(b, (A,))) - - def test_registration_builtins(self): - class A(metaclass=abc_ABCMeta): - pass - A.register(int) - self.assertIsInstance(42, A) - self.assertIsInstance(42, (A,)) - self.assertTrue(issubclass(int, A)) - self.assertTrue(issubclass(int, (A,))) - class B(A): - pass - B.register(str) - class C(str): pass - self.assertIsInstance("", A) - self.assertIsInstance("", (A,)) - self.assertTrue(issubclass(str, A)) - self.assertTrue(issubclass(str, (A,))) - self.assertTrue(issubclass(C, A)) - self.assertTrue(issubclass(C, (A,))) - - def test_registration_edge_cases(self): - class A(metaclass=abc_ABCMeta): - pass - A.register(A) # should pass silently - class A1(A): - pass - self.assertRaises(RuntimeError, A1.register, A) # cycles not allowed - class B(object): - pass - A1.register(B) # ok - A1.register(B) # should pass silently - class C(A): - pass - A.register(C) # should pass silently - self.assertRaises(RuntimeError, C.register, A) # cycles not allowed - C.register(B) # ok - - def test_register_non_class(self): - class A(metaclass=abc_ABCMeta): - pass - self.assertRaisesRegex(TypeError, "Can only register classes", - A.register, 4) - - def test_registration_transitiveness(self): - class A(metaclass=abc_ABCMeta): - pass - self.assertTrue(issubclass(A, A)) - self.assertTrue(issubclass(A, (A,))) - class B(metaclass=abc_ABCMeta): - pass - self.assertFalse(issubclass(A, B)) - self.assertFalse(issubclass(A, (B,))) - self.assertFalse(issubclass(B, A)) - self.assertFalse(issubclass(B, (A,))) - class C(metaclass=abc_ABCMeta): - pass - A.register(B) - class B1(B): - pass - self.assertTrue(issubclass(B1, A)) - self.assertTrue(issubclass(B1, (A,))) - class C1(C): - pass - B1.register(C1) - self.assertFalse(issubclass(C, B)) - self.assertFalse(issubclass(C, (B,))) - self.assertFalse(issubclass(C, B1)) - self.assertFalse(issubclass(C, (B1,))) - self.assertTrue(issubclass(C1, A)) - self.assertTrue(issubclass(C1, (A,))) - self.assertTrue(issubclass(C1, B)) - self.assertTrue(issubclass(C1, (B,))) - self.assertTrue(issubclass(C1, B1)) - self.assertTrue(issubclass(C1, (B1,))) - C1.register(int) - class MyInt(int): - pass - self.assertTrue(issubclass(MyInt, A)) - self.assertTrue(issubclass(MyInt, (A,))) - self.assertIsInstance(42, A) - self.assertIsInstance(42, (A,)) - - def test_issubclass_bad_arguments(self): - class A(metaclass=abc_ABCMeta): - pass - - with self.assertRaises(TypeError): - issubclass({}, A) # unhashable - - with self.assertRaises(TypeError): - issubclass(42, A) # No __mro__ - - # Python version supports any iterable as __mro__. - # But it's implementation detail and don't emulate it in C version. - class C: - __mro__ = 42 # __mro__ is not tuple - - with self.assertRaises(TypeError): - issubclass(C(), A) - - # bpo-34441: Check that issubclass() doesn't crash on bogus - # classes. - bogus_subclasses = [ - None, - lambda x: [], - lambda: 42, - lambda: [42], - ] - - for i, func in enumerate(bogus_subclasses): - class S(metaclass=abc_ABCMeta): - __subclasses__ = func - - with self.subTest(i=i): - with self.assertRaises(TypeError): - issubclass(int, S) - - # Also check that issubclass() propagates exceptions raised by - # __subclasses__. - exc_msg = "exception from __subclasses__" - - def raise_exc(): - raise Exception(exc_msg) - - class S(metaclass=abc_ABCMeta): - __subclasses__ = raise_exc - - with self.assertRaisesRegex(Exception, exc_msg): - issubclass(int, S) - - def test_all_new_methods_are_called(self): - class A(metaclass=abc_ABCMeta): - pass - class B(object): - counter = 0 - def __new__(cls): - B.counter += 1 - return super().__new__(cls) - class C(A, B): - pass - self.assertEqual(B.counter, 0) - C() - self.assertEqual(B.counter, 1) - - def test_ABC_has___slots__(self): - self.assertTrue(hasattr(abc.ABC, '__slots__')) - - def test_tricky_new_works(self): - def with_metaclass(meta, *bases): - class metaclass(type): - def __new__(cls, name, this_bases, d): - return meta(name, bases, d) - return type.__new__(metaclass, 'temporary_class', (), {}) - class A: ... - class B: ... - class C(with_metaclass(abc_ABCMeta, A, B)): - pass - self.assertEqual(C.__class__, abc_ABCMeta) - - - class TestABCWithInitSubclass(unittest.TestCase): - def test_works_with_init_subclass(self): - class abc_ABC(metaclass=abc_ABCMeta): - __slots__ = () - saved_kwargs = {} - class ReceivesClassKwargs: - def __init_subclass__(cls, **kwargs): - super().__init_subclass__() - saved_kwargs.update(kwargs) - class Receiver(ReceivesClassKwargs, abc_ABC, x=1, y=2, z=3): - pass - self.assertEqual(saved_kwargs, dict(x=1, y=2, z=3)) - return TestLegacyAPI, TestABC, TestABCWithInitSubclass - - TestLegacyAPI_Py, TestABC_Py, TestABCWithInitSubclass_Py = test_factory(abc.ABCMeta, - abc.get_cache_token) - TestLegacyAPI_C, TestABC_C, TestABCWithInitSubclass_C = test_factory(_py_abc.ABCMeta, - _py_abc.get_cache_token) - - if __name__ == "__main__": - unittest.main() diff --git a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_abstract_numbers.yaml b/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_abstract_numbers.yaml deleted file mode 100644 index 0cf2852d2..000000000 --- a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_abstract_numbers.yaml +++ /dev/null @@ -1,45 +0,0 @@ -python: | - """Unit tests for numbers.py.""" - - import math - import operator - import unittest - from numbers import Complex, Real, Rational, Integral - - class TestNumbers(unittest.TestCase): - def test_int(self): - self.assertTrue(issubclass(int, Integral)) - self.assertTrue(issubclass(int, Complex)) - - self.assertEqual(7, int(7).real) - self.assertEqual(0, int(7).imag) - self.assertEqual(7, int(7).conjugate()) - self.assertEqual(-7, int(-7).conjugate()) - self.assertEqual(7, int(7).numerator) - self.assertEqual(1, int(7).denominator) - - def test_float(self): - self.assertFalse(issubclass(float, Rational)) - self.assertTrue(issubclass(float, Real)) - - self.assertEqual(7.3, float(7.3).real) - self.assertEqual(0, float(7.3).imag) - self.assertEqual(7.3, float(7.3).conjugate()) - self.assertEqual(-7.3, float(-7.3).conjugate()) - - def test_complex(self): - self.assertFalse(issubclass(complex, Real)) - self.assertTrue(issubclass(complex, Complex)) - - c1, c2 = complex(3, 2), complex(4,1) - # XXX: This is not ideal, but see the comment in math_trunc(). - self.assertRaises(TypeError, math.trunc, c1) - self.assertRaises(TypeError, operator.mod, c1, c2) - self.assertRaises(TypeError, divmod, c1, c2) - self.assertRaises(TypeError, operator.floordiv, c1, c2) - self.assertRaises(TypeError, float, c1) - self.assertRaises(TypeError, int, c1) - - - if __name__ == "__main__": - unittest.main() diff --git a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_aifc.yaml b/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_aifc.yaml deleted file mode 100644 index d57116aca..000000000 --- a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_aifc.yaml +++ /dev/null @@ -1,434 +0,0 @@ -python: | - from test.support import check_no_resource_warning, findfile, TESTFN, unlink - import unittest - from unittest import mock - from test import audiotests - from audioop import byteswap - import io - import sys - import struct - import aifc - - class AifcTest(audiotests.AudioWriteTests, - audiotests.AudioTestsWithSourceFile): - module = aifc - close_fd = True - test_unseekable_read = None - - - class AifcPCM8Test(AifcTest, unittest.TestCase): - sndfilename = 'pluck-pcm8.aiff' - sndfilenframes = 3307 - nchannels = 2 - sampwidth = 1 - framerate = 11025 - nframes = 48 - comptype = b'NONE' - compname = b'not compressed' - frames = bytes.fromhex("""\ - 02FF 4B00 3104 8008 CB06 4803 BF01 03FE B8FA B4F3 29EB 1AE6 \ - EDE4 C6E2 0EE0 EFE0 57E2 FBE8 13EF D8F7 97FB F5FC 08FB DFFB \ - 11FA 3EFB BCFC 66FF CF04 4309 C10E 5112 EE17 8216 7F14 8012 \ - 490E 520D EF0F CE0F E40C 630A 080A 2B0B 510E 8B11 B60E 440A \ - """) - - - class AifcPCM16Test(AifcTest, unittest.TestCase): - sndfilename = 'pluck-pcm16.aiff' - sndfilenframes = 3307 - nchannels = 2 - sampwidth = 2 - framerate = 11025 - nframes = 48 - comptype = b'NONE' - compname = b'not compressed' - frames = bytes.fromhex("""\ - 022EFFEA 4B5D00F6 311804EA 80E10840 CBE106B1 48A903F5 BFE601B2 036CFE7B \ - B858FA3E B4B1F34F 299AEBCA 1A5DE6DA EDFAE491 C628E275 0E09E0B5 EF2AE029 \ - 5758E271 FB35E83F 1376EF86 D82BF727 9790FB76 F5FAFC0F 0867FB9C DF30FB43 \ - 117EFA36 3EE5FB5B BC79FCB1 66D9FF5D CF150412 431D097C C1BA0EC8 512112A1 \ - EEE21753 82071665 7FFF1443 8004128F 49A20EAF 52BB0DBA EFB40F60 CE3C0FBF \ - E4B30CEC 63430A5C 08C80A20 2BBB0B08 514A0E43 8BCF1139 B6F60EEB 44120A5E \ - """) - - - class AifcPCM24Test(AifcTest, unittest.TestCase): - sndfilename = 'pluck-pcm24.aiff' - sndfilenframes = 3307 - nchannels = 2 - sampwidth = 3 - framerate = 11025 - nframes = 48 - comptype = b'NONE' - compname = b'not compressed' - frames = bytes.fromhex("""\ - 022D65FFEB9D 4B5A0F00FA54 3113C304EE2B 80DCD6084303 \ - CBDEC006B261 48A99803F2F8 BFE82401B07D 036BFBFE7B5D \ - B85756FA3EC9 B4B055F3502B 299830EBCB62 1A5CA7E6D99A \ - EDFA3EE491BD C625EBE27884 0E05A9E0B6CF EF2929E02922 \ - 5758D8E27067 FB3557E83E16 1377BFEF8402 D82C5BF7272A \ - 978F16FB7745 F5F865FC1013 086635FB9C4E DF30FCFB40EE \ - 117FE0FA3438 3EE6B8FB5AC3 BC77A3FCB2F4 66D6DAFF5F32 \ - CF13B9041275 431D69097A8C C1BB600EC74E 5120B912A2BA \ - EEDF641754C0 8207001664B7 7FFFFF14453F 8000001294E6 \ - 499C1B0EB3B2 52B73E0DBCA0 EFB2B20F5FD8 CE3CDB0FBE12 \ - E4B49C0CEA2D 6344A80A5A7C 08C8FE0A1FFE 2BB9860B0A0E \ - 51486F0E44E1 8BCC64113B05 B6F4EC0EEB36 4413170A5B48 \ - """) - - - class AifcPCM32Test(AifcTest, unittest.TestCase): - sndfilename = 'pluck-pcm32.aiff' - sndfilenframes = 3307 - nchannels = 2 - sampwidth = 4 - framerate = 11025 - nframes = 48 - comptype = b'NONE' - compname = b'not compressed' - frames = bytes.fromhex("""\ - 022D65BCFFEB9D92 4B5A0F8000FA549C 3113C34004EE2BC0 80DCD680084303E0 \ - CBDEC0C006B26140 48A9980003F2F8FC BFE8248001B07D92 036BFB60FE7B5D34 \ - B8575600FA3EC920 B4B05500F3502BC0 29983000EBCB6240 1A5CA7A0E6D99A60 \ - EDFA3E80E491BD40 C625EB80E27884A0 0E05A9A0E0B6CFE0 EF292940E0292280 \ - 5758D800E2706700 FB3557D8E83E1640 1377BF00EF840280 D82C5B80F7272A80 \ - 978F1600FB774560 F5F86510FC101364 086635A0FB9C4E20 DF30FC40FB40EE28 \ - 117FE0A0FA3438B0 3EE6B840FB5AC3F0 BC77A380FCB2F454 66D6DA80FF5F32B4 \ - CF13B980041275B0 431D6980097A8C00 C1BB60000EC74E00 5120B98012A2BAA0 \ - EEDF64C01754C060 820700001664B780 7FFFFFFF14453F40 800000001294E6E0 \ - 499C1B000EB3B270 52B73E000DBCA020 EFB2B2E00F5FD880 CE3CDB400FBE1270 \ - E4B49CC00CEA2D90 6344A8800A5A7CA0 08C8FE800A1FFEE0 2BB986C00B0A0E00 \ - 51486F800E44E190 8BCC6480113B0580 B6F4EC000EEB3630 441317800A5B48A0 \ - """) - - - class AifcULAWTest(AifcTest, unittest.TestCase): - sndfilename = 'pluck-ulaw.aifc' - sndfilenframes = 3307 - nchannels = 2 - sampwidth = 2 - framerate = 11025 - nframes = 48 - comptype = b'ulaw' - compname = b'' - frames = bytes.fromhex("""\ - 022CFFE8 497C0104 307C04DC 8284083C CB84069C 497C03DC BE8401AC 036CFE74 \ - B684FA24 B684F344 2A7CEC04 19FCE704 EE04E504 C584E204 0E3CE104 EF04DF84 \ - 557CE204 FB24E804 12FCEF04 D784F744 9684FB64 F5C4FC24 083CFBA4 DF84FB24 \ - 11FCFA24 3E7CFB64 BA84FCB4 657CFF5C CF84041C 417C093C C1840EBC 517C12FC \ - EF0416FC 828415FC 7D7C13FC 828412FC 497C0EBC 517C0DBC F0040F3C CD840FFC \ - E5040CBC 617C0A3C 08BC0A3C 2C7C0B3C 517C0E3C 8A8410FC B6840EBC 457C0A3C \ - """) - if sys.byteorder != 'big': - frames = byteswap(frames, 2) - - - class AifcALAWTest(AifcTest, unittest.TestCase): - sndfilename = 'pluck-alaw.aifc' - sndfilenframes = 3307 - nchannels = 2 - sampwidth = 2 - framerate = 11025 - nframes = 48 - comptype = b'alaw' - compname = b'' - frames = bytes.fromhex("""\ - 0230FFE8 4A0000F8 310004E0 82000840 CB0006A0 4A0003F0 BE0001A8 0370FE78 \ - BA00FA20 B600F340 2900EB80 1A80E680 ED80E480 C700E280 0E40E080 EF80E080 \ - 5600E280 FB20E880 1380EF80 D900F740 9600FB60 F5C0FC10 0840FBA0 DF00FB20 \ - 1180FA20 3F00FB60 BE00FCB0 6600FF58 CF000420 42000940 C1000EC0 52001280 \ - EE801780 82001680 7E001480 82001280 4A000EC0 52000DC0 EF800F40 CF000FC0 \ - E4800CC0 62000A40 08C00A40 2B000B40 52000E40 8A001180 B6000EC0 46000A40 \ - """) - if sys.byteorder != 'big': - frames = byteswap(frames, 2) - - - class AifcMiscTest(audiotests.AudioMiscTests, unittest.TestCase): - module = aifc - - def test_skipunknown(self): - #Issue 2245 - #This file contains chunk types aifc doesn't recognize. - self.f = aifc.open(findfile('Sine-1000Hz-300ms.aif')) - - def test_close_opened_files_on_error(self): - non_aifc_file = findfile('pluck-pcm8.wav', subdir='audiodata') - with check_no_resource_warning(self): - with self.assertRaises(aifc.Error): - # Try opening a non-AIFC file, with the expectation that - # `aifc.open` will fail (without raising a ResourceWarning) - self.f = aifc.open(non_aifc_file, 'rb') - - # Aifc_write.initfp() won't raise in normal case. But some errors - # (e.g. MemoryError, KeyboardInterrupt, etc..) can happen. - with mock.patch.object(aifc.Aifc_write, 'initfp', - side_effect=RuntimeError): - with self.assertRaises(RuntimeError): - self.fout = aifc.open(TESTFN, 'wb') - - def test_params_added(self): - f = self.f = aifc.open(TESTFN, 'wb') - f.aiff() - f.setparams((1, 1, 1, 1, b'NONE', b'')) - f.close() - - f = self.f = aifc.open(TESTFN, 'rb') - params = f.getparams() - self.assertEqual(params.nchannels, f.getnchannels()) - self.assertEqual(params.sampwidth, f.getsampwidth()) - self.assertEqual(params.framerate, f.getframerate()) - self.assertEqual(params.nframes, f.getnframes()) - self.assertEqual(params.comptype, f.getcomptype()) - self.assertEqual(params.compname, f.getcompname()) - - def test_write_header_comptype_sampwidth(self): - for comptype in (b'ULAW', b'ulaw', b'ALAW', b'alaw', b'G722'): - fout = aifc.open(io.BytesIO(), 'wb') - fout.setnchannels(1) - fout.setframerate(1) - fout.setcomptype(comptype, b'') - fout.close() - self.assertEqual(fout.getsampwidth(), 2) - fout.initfp(None) - - def test_write_markers_values(self): - fout = aifc.open(io.BytesIO(), 'wb') - self.assertEqual(fout.getmarkers(), None) - fout.setmark(1, 0, b'foo1') - fout.setmark(1, 1, b'foo2') - self.assertEqual(fout.getmark(1), (1, 1, b'foo2')) - self.assertEqual(fout.getmarkers(), [(1, 1, b'foo2')]) - fout.initfp(None) - - def test_read_markers(self): - fout = self.fout = aifc.open(TESTFN, 'wb') - fout.aiff() - fout.setparams((1, 1, 1, 1, b'NONE', b'')) - fout.setmark(1, 0, b'odd') - fout.setmark(2, 0, b'even') - fout.writeframes(b'\x00') - fout.close() - f = self.f = aifc.open(TESTFN, 'rb') - self.assertEqual(f.getmarkers(), [(1, 0, b'odd'), (2, 0, b'even')]) - self.assertEqual(f.getmark(1), (1, 0, b'odd')) - self.assertEqual(f.getmark(2), (2, 0, b'even')) - self.assertRaises(aifc.Error, f.getmark, 3) - - - class AIFCLowLevelTest(unittest.TestCase): - - def test_read_written(self): - def read_written(self, what): - f = io.BytesIO() - getattr(aifc, '_write_' + what)(f, x) - f.seek(0) - return getattr(aifc, '_read_' + what)(f) - for x in (-1, 0, 0.1, 1): - self.assertEqual(read_written(x, 'float'), x) - for x in (float('NaN'), float('Inf')): - self.assertEqual(read_written(x, 'float'), aifc._HUGE_VAL) - for x in (b'', b'foo', b'a' * 255): - self.assertEqual(read_written(x, 'string'), x) - for x in (-0x7FFFFFFF, -1, 0, 1, 0x7FFFFFFF): - self.assertEqual(read_written(x, 'long'), x) - for x in (0, 1, 0xFFFFFFFF): - self.assertEqual(read_written(x, 'ulong'), x) - for x in (-0x7FFF, -1, 0, 1, 0x7FFF): - self.assertEqual(read_written(x, 'short'), x) - for x in (0, 1, 0xFFFF): - self.assertEqual(read_written(x, 'ushort'), x) - - def test_read_raises(self): - f = io.BytesIO(b'\x00') - self.assertRaises(EOFError, aifc._read_ulong, f) - self.assertRaises(EOFError, aifc._read_long, f) - self.assertRaises(EOFError, aifc._read_ushort, f) - self.assertRaises(EOFError, aifc._read_short, f) - - def test_write_long_string_raises(self): - f = io.BytesIO() - with self.assertRaises(ValueError): - aifc._write_string(f, b'too long' * 255) - - def test_wrong_open_mode(self): - with self.assertRaises(aifc.Error): - aifc.open(TESTFN, 'wrong_mode') - - def test_read_wrong_form(self): - b1 = io.BytesIO(b'WRNG' + struct.pack('>L', 0)) - b2 = io.BytesIO(b'FORM' + struct.pack('>L', 4) + b'WRNG') - self.assertRaises(aifc.Error, aifc.open, b1) - self.assertRaises(aifc.Error, aifc.open, b2) - - def test_read_no_comm_chunk(self): - b = io.BytesIO(b'FORM' + struct.pack('>L', 4) + b'AIFF') - self.assertRaises(aifc.Error, aifc.open, b) - - def test_read_no_ssnd_chunk(self): - b = b'FORM' + struct.pack('>L', 4) + b'AIFC' - b += b'COMM' + struct.pack('>LhlhhLL', 38, 1, 0, 8, - 0x4000 | 12, 11025<<18, 0) - b += b'NONE' + struct.pack('B', 14) + b'not compressed' + b'\x00' - with self.assertRaisesRegex(aifc.Error, 'COMM chunk and/or SSND chunk' - ' missing'): - aifc.open(io.BytesIO(b)) - - def test_read_wrong_compression_type(self): - b = b'FORM' + struct.pack('>L', 4) + b'AIFC' - b += b'COMM' + struct.pack('>LhlhhLL', 23, 1, 0, 8, - 0x4000 | 12, 11025<<18, 0) - b += b'WRNG' + struct.pack('B', 0) - self.assertRaises(aifc.Error, aifc.open, io.BytesIO(b)) - - def test_read_wrong_number_of_channels(self): - for nchannels in 0, -1: - b = b'FORM' + struct.pack('>L', 4) + b'AIFC' - b += b'COMM' + struct.pack('>LhlhhLL', 38, nchannels, 0, 8, - 0x4000 | 12, 11025<<18, 0) - b += b'NONE' + struct.pack('B', 14) + b'not compressed' + b'\x00' - b += b'SSND' + struct.pack('>L', 8) + b'\x00' * 8 - with self.assertRaisesRegex(aifc.Error, 'bad # of channels'): - aifc.open(io.BytesIO(b)) - - def test_read_wrong_sample_width(self): - for sampwidth in 0, -1: - b = b'FORM' + struct.pack('>L', 4) + b'AIFC' - b += b'COMM' + struct.pack('>LhlhhLL', 38, 1, 0, sampwidth, - 0x4000 | 12, 11025<<18, 0) - b += b'NONE' + struct.pack('B', 14) + b'not compressed' + b'\x00' - b += b'SSND' + struct.pack('>L', 8) + b'\x00' * 8 - with self.assertRaisesRegex(aifc.Error, 'bad sample width'): - aifc.open(io.BytesIO(b)) - - def test_read_wrong_marks(self): - b = b'FORM' + struct.pack('>L', 4) + b'AIFF' - b += b'COMM' + struct.pack('>LhlhhLL', 18, 1, 0, 8, - 0x4000 | 12, 11025<<18, 0) - b += b'SSND' + struct.pack('>L', 8) + b'\x00' * 8 - b += b'MARK' + struct.pack('>LhB', 3, 1, 1) - with self.assertWarns(UserWarning) as cm: - f = aifc.open(io.BytesIO(b)) - self.assertEqual(str(cm.warning), 'Warning: MARK chunk contains ' - 'only 0 markers instead of 1') - self.assertEqual(f.getmarkers(), None) - - def test_read_comm_kludge_compname_even(self): - b = b'FORM' + struct.pack('>L', 4) + b'AIFC' - b += b'COMM' + struct.pack('>LhlhhLL', 18, 1, 0, 8, - 0x4000 | 12, 11025<<18, 0) - b += b'NONE' + struct.pack('B', 4) + b'even' + b'\x00' - b += b'SSND' + struct.pack('>L', 8) + b'\x00' * 8 - with self.assertWarns(UserWarning) as cm: - f = aifc.open(io.BytesIO(b)) - self.assertEqual(str(cm.warning), 'Warning: bad COMM chunk size') - self.assertEqual(f.getcompname(), b'even') - - def test_read_comm_kludge_compname_odd(self): - b = b'FORM' + struct.pack('>L', 4) + b'AIFC' - b += b'COMM' + struct.pack('>LhlhhLL', 18, 1, 0, 8, - 0x4000 | 12, 11025<<18, 0) - b += b'NONE' + struct.pack('B', 3) + b'odd' - b += b'SSND' + struct.pack('>L', 8) + b'\x00' * 8 - with self.assertWarns(UserWarning) as cm: - f = aifc.open(io.BytesIO(b)) - self.assertEqual(str(cm.warning), 'Warning: bad COMM chunk size') - self.assertEqual(f.getcompname(), b'odd') - - def test_write_params_raises(self): - fout = aifc.open(io.BytesIO(), 'wb') - wrong_params = (0, 0, 0, 0, b'WRNG', '') - self.assertRaises(aifc.Error, fout.setparams, wrong_params) - self.assertRaises(aifc.Error, fout.getparams) - self.assertRaises(aifc.Error, fout.setnchannels, 0) - self.assertRaises(aifc.Error, fout.getnchannels) - self.assertRaises(aifc.Error, fout.setsampwidth, 0) - self.assertRaises(aifc.Error, fout.getsampwidth) - self.assertRaises(aifc.Error, fout.setframerate, 0) - self.assertRaises(aifc.Error, fout.getframerate) - self.assertRaises(aifc.Error, fout.setcomptype, b'WRNG', '') - fout.aiff() - fout.setnchannels(1) - fout.setsampwidth(1) - fout.setframerate(1) - fout.setnframes(1) - fout.writeframes(b'\x00') - self.assertRaises(aifc.Error, fout.setparams, (1, 1, 1, 1, 1, 1)) - self.assertRaises(aifc.Error, fout.setnchannels, 1) - self.assertRaises(aifc.Error, fout.setsampwidth, 1) - self.assertRaises(aifc.Error, fout.setframerate, 1) - self.assertRaises(aifc.Error, fout.setnframes, 1) - self.assertRaises(aifc.Error, fout.setcomptype, b'NONE', '') - self.assertRaises(aifc.Error, fout.aiff) - self.assertRaises(aifc.Error, fout.aifc) - - def test_write_params_singles(self): - fout = aifc.open(io.BytesIO(), 'wb') - fout.aifc() - fout.setnchannels(1) - fout.setsampwidth(2) - fout.setframerate(3) - fout.setnframes(4) - fout.setcomptype(b'NONE', b'name') - self.assertEqual(fout.getnchannels(), 1) - self.assertEqual(fout.getsampwidth(), 2) - self.assertEqual(fout.getframerate(), 3) - self.assertEqual(fout.getnframes(), 0) - self.assertEqual(fout.tell(), 0) - self.assertEqual(fout.getcomptype(), b'NONE') - self.assertEqual(fout.getcompname(), b'name') - fout.writeframes(b'\x00' * 4 * fout.getsampwidth() * fout.getnchannels()) - self.assertEqual(fout.getnframes(), 4) - self.assertEqual(fout.tell(), 4) - - def test_write_params_bunch(self): - fout = aifc.open(io.BytesIO(), 'wb') - fout.aifc() - p = (1, 2, 3, 4, b'NONE', b'name') - fout.setparams(p) - self.assertEqual(fout.getparams(), p) - fout.initfp(None) - - def test_write_header_raises(self): - fout = aifc.open(io.BytesIO(), 'wb') - self.assertRaises(aifc.Error, fout.close) - fout = aifc.open(io.BytesIO(), 'wb') - fout.setnchannels(1) - self.assertRaises(aifc.Error, fout.close) - fout = aifc.open(io.BytesIO(), 'wb') - fout.setnchannels(1) - fout.setsampwidth(1) - self.assertRaises(aifc.Error, fout.close) - - def test_write_header_comptype_raises(self): - for comptype in (b'ULAW', b'ulaw', b'ALAW', b'alaw', b'G722'): - fout = aifc.open(io.BytesIO(), 'wb') - fout.setsampwidth(1) - fout.setcomptype(comptype, b'') - self.assertRaises(aifc.Error, fout.close) - fout.initfp(None) - - def test_write_markers_raises(self): - fout = aifc.open(io.BytesIO(), 'wb') - self.assertRaises(aifc.Error, fout.setmark, 0, 0, b'') - self.assertRaises(aifc.Error, fout.setmark, 1, -1, b'') - self.assertRaises(aifc.Error, fout.setmark, 1, 0, None) - self.assertRaises(aifc.Error, fout.getmark, 1) - fout.initfp(None) - - def test_write_aiff_by_extension(self): - sampwidth = 2 - filename = TESTFN + '.aiff' - fout = self.fout = aifc.open(filename, 'wb') - self.addCleanup(unlink, filename) - fout.setparams((1, sampwidth, 1, 1, b'ULAW', b'')) - frames = b'\x00' * fout.getnchannels() * sampwidth - fout.writeframes(frames) - fout.close() - f = self.f = aifc.open(filename, 'rb') - self.assertEqual(f.getcomptype(), b'NONE') - f.close() - - - if __name__ == "__main__": - unittest.main() diff --git a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_argparse.yaml b/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_argparse.yaml deleted file mode 100644 index 8c544de9a..000000000 --- a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_argparse.yaml +++ /dev/null @@ -1,5312 +0,0 @@ -python: | - # Author: Steven J. Bethard . - - import inspect - import os - import shutil - import stat - import sys - import textwrap - import tempfile - import unittest - import argparse - - from io import StringIO - - from test import support - from unittest import mock - class StdIOBuffer(StringIO): - pass - - class TestCase(unittest.TestCase): - - def setUp(self): - # The tests assume that line wrapping occurs at 80 columns, but this - # behaviour can be overridden by setting the COLUMNS environment - # variable. To ensure that this width is used, set COLUMNS to 80. - env = support.EnvironmentVarGuard() - env['COLUMNS'] = '80' - self.addCleanup(env.__exit__) - - - class TempDirMixin(object): - - def setUp(self): - self.temp_dir = tempfile.mkdtemp() - self.old_dir = os.getcwd() - os.chdir(self.temp_dir) - - def tearDown(self): - os.chdir(self.old_dir) - for root, dirs, files in os.walk(self.temp_dir, topdown=False): - for name in files: - os.chmod(os.path.join(self.temp_dir, name), stat.S_IWRITE) - shutil.rmtree(self.temp_dir, True) - - def create_readonly_file(self, filename): - file_path = os.path.join(self.temp_dir, filename) - with open(file_path, 'w') as file: - file.write(filename) - os.chmod(file_path, stat.S_IREAD) - - class Sig(object): - - def __init__(self, *args, **kwargs): - self.args = args - self.kwargs = kwargs - - - class NS(object): - - def __init__(self, **kwargs): - self.__dict__.update(kwargs) - - def __repr__(self): - sorted_items = sorted(self.__dict__.items()) - kwarg_str = ', '.join(['%s=%r' % tup for tup in sorted_items]) - return '%s(%s)' % (type(self).__name__, kwarg_str) - - def __eq__(self, other): - return vars(self) == vars(other) - - - class ArgumentParserError(Exception): - - def __init__(self, message, stdout=None, stderr=None, error_code=None): - Exception.__init__(self, message, stdout, stderr) - self.message = message - self.stdout = stdout - self.stderr = stderr - self.error_code = error_code - - - def stderr_to_parser_error(parse_args, *args, **kwargs): - # if this is being called recursively and stderr or stdout is already being - # redirected, simply call the function and let the enclosing function - # catch the exception - if isinstance(sys.stderr, StdIOBuffer) or isinstance(sys.stdout, StdIOBuffer): - return parse_args(*args, **kwargs) - - # if this is not being called recursively, redirect stderr and - # use it as the ArgumentParserError message - old_stdout = sys.stdout - old_stderr = sys.stderr - sys.stdout = StdIOBuffer() - sys.stderr = StdIOBuffer() - try: - try: - result = parse_args(*args, **kwargs) - for key in list(vars(result)): - if getattr(result, key) is sys.stdout: - setattr(result, key, old_stdout) - if getattr(result, key) is sys.stderr: - setattr(result, key, old_stderr) - return result - except SystemExit: - code = sys.exc_info()[1].code - stdout = sys.stdout.getvalue() - stderr = sys.stderr.getvalue() - raise ArgumentParserError("SystemExit", stdout, stderr, code) - finally: - sys.stdout = old_stdout - sys.stderr = old_stderr - - - class ErrorRaisingArgumentParser(argparse.ArgumentParser): - - def parse_args(self, *args, **kwargs): - parse_args = super(ErrorRaisingArgumentParser, self).parse_args - return stderr_to_parser_error(parse_args, *args, **kwargs) - - def exit(self, *args, **kwargs): - exit = super(ErrorRaisingArgumentParser, self).exit - return stderr_to_parser_error(exit, *args, **kwargs) - - def error(self, *args, **kwargs): - error = super(ErrorRaisingArgumentParser, self).error - return stderr_to_parser_error(error, *args, **kwargs) - - - class ParserTesterMetaclass(type): - """Adds parser tests using the class attributes. - - Classes of this type should specify the following attributes: - - argument_signatures -- a list of Sig objects which specify - the signatures of Argument objects to be created - failures -- a list of args lists that should cause the parser - to fail - successes -- a list of (initial_args, options, remaining_args) tuples - where initial_args specifies the string args to be parsed, - options is a dict that should match the vars() of the options - parsed out of initial_args, and remaining_args should be any - remaining unparsed arguments - """ - - def __init__(cls, name, bases, bodydict): - if name == 'ParserTestCase': - return - - # default parser signature is empty - if not hasattr(cls, 'parser_signature'): - cls.parser_signature = Sig() - if not hasattr(cls, 'parser_class'): - cls.parser_class = ErrorRaisingArgumentParser - - # --------------------------------------- - # functions for adding optional arguments - # --------------------------------------- - def no_groups(parser, argument_signatures): - """Add all arguments directly to the parser""" - for sig in argument_signatures: - parser.add_argument(*sig.args, **sig.kwargs) - - def one_group(parser, argument_signatures): - """Add all arguments under a single group in the parser""" - group = parser.add_argument_group('foo') - for sig in argument_signatures: - group.add_argument(*sig.args, **sig.kwargs) - - def many_groups(parser, argument_signatures): - """Add each argument in its own group to the parser""" - for i, sig in enumerate(argument_signatures): - group = parser.add_argument_group('foo:%i' % i) - group.add_argument(*sig.args, **sig.kwargs) - - # -------------------------- - # functions for parsing args - # -------------------------- - def listargs(parser, args): - """Parse the args by passing in a list""" - return parser.parse_args(args) - - def sysargs(parser, args): - """Parse the args by defaulting to sys.argv""" - old_sys_argv = sys.argv - sys.argv = [old_sys_argv[0]] + args - try: - return parser.parse_args() - finally: - sys.argv = old_sys_argv - - # class that holds the combination of one optional argument - # addition method and one arg parsing method - class AddTests(object): - - def __init__(self, tester_cls, add_arguments, parse_args): - self._add_arguments = add_arguments - self._parse_args = parse_args - - add_arguments_name = self._add_arguments.__name__ - parse_args_name = self._parse_args.__name__ - for test_func in [self.test_failures, self.test_successes]: - func_name = test_func.__name__ - names = func_name, add_arguments_name, parse_args_name - test_name = '_'.join(names) - - def wrapper(self, test_func=test_func): - test_func(self) - try: - wrapper.__name__ = test_name - except TypeError: - pass - setattr(tester_cls, test_name, wrapper) - - def _get_parser(self, tester): - args = tester.parser_signature.args - kwargs = tester.parser_signature.kwargs - parser = tester.parser_class(*args, **kwargs) - self._add_arguments(parser, tester.argument_signatures) - return parser - - def test_failures(self, tester): - parser = self._get_parser(tester) - for args_str in tester.failures: - args = args_str.split() - with tester.assertRaises(ArgumentParserError, msg=args): - parser.parse_args(args) - - def test_successes(self, tester): - parser = self._get_parser(tester) - for args, expected_ns in tester.successes: - if isinstance(args, str): - args = args.split() - result_ns = self._parse_args(parser, args) - tester.assertEqual(expected_ns, result_ns) - - # add tests for each combination of an optionals adding method - # and an arg parsing method - for add_arguments in [no_groups, one_group, many_groups]: - for parse_args in [listargs, sysargs]: - AddTests(cls, add_arguments, parse_args) - - bases = TestCase, - ParserTestCase = ParserTesterMetaclass('ParserTestCase', bases, {}) - - # =============== - # Optionals tests - # =============== - - class TestOptionalsSingleDash(ParserTestCase): - """Test an Optional with a single-dash option string""" - - argument_signatures = [Sig('-x')] - failures = ['-x', 'a', '--foo', '-x --foo', '-x -y'] - successes = [ - ('', NS(x=None)), - ('-x a', NS(x='a')), - ('-xa', NS(x='a')), - ('-x -1', NS(x='-1')), - ('-x-1', NS(x='-1')), - ] - - - class TestOptionalsSingleDashCombined(ParserTestCase): - """Test an Optional with a single-dash option string""" - - argument_signatures = [ - Sig('-x', action='store_true'), - Sig('-yyy', action='store_const', const=42), - Sig('-z'), - ] - failures = ['a', '--foo', '-xa', '-x --foo', '-x -z', '-z -x', - '-yx', '-yz a', '-yyyx', '-yyyza', '-xyza'] - successes = [ - ('', NS(x=False, yyy=None, z=None)), - ('-x', NS(x=True, yyy=None, z=None)), - ('-za', NS(x=False, yyy=None, z='a')), - ('-z a', NS(x=False, yyy=None, z='a')), - ('-xza', NS(x=True, yyy=None, z='a')), - ('-xz a', NS(x=True, yyy=None, z='a')), - ('-x -za', NS(x=True, yyy=None, z='a')), - ('-x -z a', NS(x=True, yyy=None, z='a')), - ('-y', NS(x=False, yyy=42, z=None)), - ('-yyy', NS(x=False, yyy=42, z=None)), - ('-x -yyy -za', NS(x=True, yyy=42, z='a')), - ('-x -yyy -z a', NS(x=True, yyy=42, z='a')), - ] - - - class TestOptionalsSingleDashLong(ParserTestCase): - """Test an Optional with a multi-character single-dash option string""" - - argument_signatures = [Sig('-foo')] - failures = ['-foo', 'a', '--foo', '-foo --foo', '-foo -y', '-fooa'] - successes = [ - ('', NS(foo=None)), - ('-foo a', NS(foo='a')), - ('-foo -1', NS(foo='-1')), - ('-fo a', NS(foo='a')), - ('-f a', NS(foo='a')), - ] - - - class TestOptionalsSingleDashSubsetAmbiguous(ParserTestCase): - """Test Optionals where option strings are subsets of each other""" - - argument_signatures = [Sig('-f'), Sig('-foobar'), Sig('-foorab')] - failures = ['-f', '-foo', '-fo', '-foo b', '-foob', '-fooba', '-foora'] - successes = [ - ('', NS(f=None, foobar=None, foorab=None)), - ('-f a', NS(f='a', foobar=None, foorab=None)), - ('-fa', NS(f='a', foobar=None, foorab=None)), - ('-foa', NS(f='oa', foobar=None, foorab=None)), - ('-fooa', NS(f='ooa', foobar=None, foorab=None)), - ('-foobar a', NS(f=None, foobar='a', foorab=None)), - ('-foorab a', NS(f=None, foobar=None, foorab='a')), - ] - - - class TestOptionalsSingleDashAmbiguous(ParserTestCase): - """Test Optionals that partially match but are not subsets""" - - argument_signatures = [Sig('-foobar'), Sig('-foorab')] - failures = ['-f', '-f a', '-fa', '-foa', '-foo', '-fo', '-foo b'] - successes = [ - ('', NS(foobar=None, foorab=None)), - ('-foob a', NS(foobar='a', foorab=None)), - ('-foor a', NS(foobar=None, foorab='a')), - ('-fooba a', NS(foobar='a', foorab=None)), - ('-foora a', NS(foobar=None, foorab='a')), - ('-foobar a', NS(foobar='a', foorab=None)), - ('-foorab a', NS(foobar=None, foorab='a')), - ] - - - class TestOptionalsNumeric(ParserTestCase): - """Test an Optional with a short opt string""" - - argument_signatures = [Sig('-1', dest='one')] - failures = ['-1', 'a', '-1 --foo', '-1 -y', '-1 -1', '-1 -2'] - successes = [ - ('', NS(one=None)), - ('-1 a', NS(one='a')), - ('-1a', NS(one='a')), - ('-1-2', NS(one='-2')), - ] - - - class TestOptionalsDoubleDash(ParserTestCase): - """Test an Optional with a double-dash option string""" - - argument_signatures = [Sig('--foo')] - failures = ['--foo', '-f', '-f a', 'a', '--foo -x', '--foo --bar'] - successes = [ - ('', NS(foo=None)), - ('--foo a', NS(foo='a')), - ('--foo=a', NS(foo='a')), - ('--foo -2.5', NS(foo='-2.5')), - ('--foo=-2.5', NS(foo='-2.5')), - ] - - - class TestOptionalsDoubleDashPartialMatch(ParserTestCase): - """Tests partial matching with a double-dash option string""" - - argument_signatures = [ - Sig('--badger', action='store_true'), - Sig('--bat'), - ] - failures = ['--bar', '--b', '--ba', '--b=2', '--ba=4', '--badge 5'] - successes = [ - ('', NS(badger=False, bat=None)), - ('--bat X', NS(badger=False, bat='X')), - ('--bad', NS(badger=True, bat=None)), - ('--badg', NS(badger=True, bat=None)), - ('--badge', NS(badger=True, bat=None)), - ('--badger', NS(badger=True, bat=None)), - ] - - - class TestOptionalsDoubleDashPrefixMatch(ParserTestCase): - """Tests when one double-dash option string is a prefix of another""" - - argument_signatures = [ - Sig('--badger', action='store_true'), - Sig('--ba'), - ] - failures = ['--bar', '--b', '--ba', '--b=2', '--badge 5'] - successes = [ - ('', NS(badger=False, ba=None)), - ('--ba X', NS(badger=False, ba='X')), - ('--ba=X', NS(badger=False, ba='X')), - ('--bad', NS(badger=True, ba=None)), - ('--badg', NS(badger=True, ba=None)), - ('--badge', NS(badger=True, ba=None)), - ('--badger', NS(badger=True, ba=None)), - ] - - - class TestOptionalsSingleDoubleDash(ParserTestCase): - """Test an Optional with single- and double-dash option strings""" - - argument_signatures = [ - Sig('-f', action='store_true'), - Sig('--bar'), - Sig('-baz', action='store_const', const=42), - ] - failures = ['--bar', '-fbar', '-fbaz', '-bazf', '-b B', 'B'] - successes = [ - ('', NS(f=False, bar=None, baz=None)), - ('-f', NS(f=True, bar=None, baz=None)), - ('--ba B', NS(f=False, bar='B', baz=None)), - ('-f --bar B', NS(f=True, bar='B', baz=None)), - ('-f -b', NS(f=True, bar=None, baz=42)), - ('-ba -f', NS(f=True, bar=None, baz=42)), - ] - - - class TestOptionalsAlternatePrefixChars(ParserTestCase): - """Test an Optional with option strings with custom prefixes""" - - parser_signature = Sig(prefix_chars='+:/', add_help=False) - argument_signatures = [ - Sig('+f', action='store_true'), - Sig('::bar'), - Sig('/baz', action='store_const', const=42), - ] - failures = ['--bar', '-fbar', '-b B', 'B', '-f', '--bar B', '-baz', '-h', '--help', '+h', '::help', '/help'] - successes = [ - ('', NS(f=False, bar=None, baz=None)), - ('+f', NS(f=True, bar=None, baz=None)), - ('::ba B', NS(f=False, bar='B', baz=None)), - ('+f ::bar B', NS(f=True, bar='B', baz=None)), - ('+f /b', NS(f=True, bar=None, baz=42)), - ('/ba +f', NS(f=True, bar=None, baz=42)), - ] - - - class TestOptionalsAlternatePrefixCharsAddedHelp(ParserTestCase): - """When ``-`` not in prefix_chars, default operators created for help - should use the prefix_chars in use rather than - or -- - http://bugs.python.org/issue9444""" - - parser_signature = Sig(prefix_chars='+:/', add_help=True) - argument_signatures = [ - Sig('+f', action='store_true'), - Sig('::bar'), - Sig('/baz', action='store_const', const=42), - ] - failures = ['--bar', '-fbar', '-b B', 'B', '-f', '--bar B', '-baz'] - successes = [ - ('', NS(f=False, bar=None, baz=None)), - ('+f', NS(f=True, bar=None, baz=None)), - ('::ba B', NS(f=False, bar='B', baz=None)), - ('+f ::bar B', NS(f=True, bar='B', baz=None)), - ('+f /b', NS(f=True, bar=None, baz=42)), - ('/ba +f', NS(f=True, bar=None, baz=42)) - ] - - - class TestOptionalsAlternatePrefixCharsMultipleShortArgs(ParserTestCase): - """Verify that Optionals must be called with their defined prefixes""" - - parser_signature = Sig(prefix_chars='+-', add_help=False) - argument_signatures = [ - Sig('-x', action='store_true'), - Sig('+y', action='store_true'), - Sig('+z', action='store_true'), - ] - failures = ['-w', - '-xyz', - '+x', - '-y', - '+xyz', - ] - successes = [ - ('', NS(x=False, y=False, z=False)), - ('-x', NS(x=True, y=False, z=False)), - ('+y -x', NS(x=True, y=True, z=False)), - ('+yz -x', NS(x=True, y=True, z=True)), - ] - - - class TestOptionalsShortLong(ParserTestCase): - """Test a combination of single- and double-dash option strings""" - - argument_signatures = [ - Sig('-v', '--verbose', '-n', '--noisy', action='store_true'), - ] - failures = ['--x --verbose', '-N', 'a', '-v x'] - successes = [ - ('', NS(verbose=False)), - ('-v', NS(verbose=True)), - ('--verbose', NS(verbose=True)), - ('-n', NS(verbose=True)), - ('--noisy', NS(verbose=True)), - ] - - - class TestOptionalsDest(ParserTestCase): - """Tests various means of setting destination""" - - argument_signatures = [Sig('--foo-bar'), Sig('--baz', dest='zabbaz')] - failures = ['a'] - successes = [ - ('--foo-bar f', NS(foo_bar='f', zabbaz=None)), - ('--baz g', NS(foo_bar=None, zabbaz='g')), - ('--foo-bar h --baz i', NS(foo_bar='h', zabbaz='i')), - ('--baz j --foo-bar k', NS(foo_bar='k', zabbaz='j')), - ] - - - class TestOptionalsDefault(ParserTestCase): - """Tests specifying a default for an Optional""" - - argument_signatures = [Sig('-x'), Sig('-y', default=42)] - failures = ['a'] - successes = [ - ('', NS(x=None, y=42)), - ('-xx', NS(x='x', y=42)), - ('-yy', NS(x=None, y='y')), - ] - - - class TestOptionalsNargsDefault(ParserTestCase): - """Tests not specifying the number of args for an Optional""" - - argument_signatures = [Sig('-x')] - failures = ['a', '-x'] - successes = [ - ('', NS(x=None)), - ('-x a', NS(x='a')), - ] - - - class TestOptionalsNargs1(ParserTestCase): - """Tests specifying 1 arg for an Optional""" - - argument_signatures = [Sig('-x', nargs=1)] - failures = ['a', '-x'] - successes = [ - ('', NS(x=None)), - ('-x a', NS(x=['a'])), - ] - - - class TestOptionalsNargs3(ParserTestCase): - """Tests specifying 3 args for an Optional""" - - argument_signatures = [Sig('-x', nargs=3)] - failures = ['a', '-x', '-x a', '-x a b', 'a -x', 'a -x b'] - successes = [ - ('', NS(x=None)), - ('-x a b c', NS(x=['a', 'b', 'c'])), - ] - - - class TestOptionalsNargsOptional(ParserTestCase): - """Tests specifying an Optional arg for an Optional""" - - argument_signatures = [ - Sig('-w', nargs='?'), - Sig('-x', nargs='?', const=42), - Sig('-y', nargs='?', default='spam'), - Sig('-z', nargs='?', type=int, const='42', default='84'), - ] - failures = ['2'] - successes = [ - ('', NS(w=None, x=None, y='spam', z=84)), - ('-w', NS(w=None, x=None, y='spam', z=84)), - ('-w 2', NS(w='2', x=None, y='spam', z=84)), - ('-x', NS(w=None, x=42, y='spam', z=84)), - ('-x 2', NS(w=None, x='2', y='spam', z=84)), - ('-y', NS(w=None, x=None, y=None, z=84)), - ('-y 2', NS(w=None, x=None, y='2', z=84)), - ('-z', NS(w=None, x=None, y='spam', z=42)), - ('-z 2', NS(w=None, x=None, y='spam', z=2)), - ] - - - class TestOptionalsNargsZeroOrMore(ParserTestCase): - """Tests specifying args for an Optional that accepts zero or more""" - - argument_signatures = [ - Sig('-x', nargs='*'), - Sig('-y', nargs='*', default='spam'), - ] - failures = ['a'] - successes = [ - ('', NS(x=None, y='spam')), - ('-x', NS(x=[], y='spam')), - ('-x a', NS(x=['a'], y='spam')), - ('-x a b', NS(x=['a', 'b'], y='spam')), - ('-y', NS(x=None, y=[])), - ('-y a', NS(x=None, y=['a'])), - ('-y a b', NS(x=None, y=['a', 'b'])), - ] - - - class TestOptionalsNargsOneOrMore(ParserTestCase): - """Tests specifying args for an Optional that accepts one or more""" - - argument_signatures = [ - Sig('-x', nargs='+'), - Sig('-y', nargs='+', default='spam'), - ] - failures = ['a', '-x', '-y', 'a -x', 'a -y b'] - successes = [ - ('', NS(x=None, y='spam')), - ('-x a', NS(x=['a'], y='spam')), - ('-x a b', NS(x=['a', 'b'], y='spam')), - ('-y a', NS(x=None, y=['a'])), - ('-y a b', NS(x=None, y=['a', 'b'])), - ] - - - class TestOptionalsChoices(ParserTestCase): - """Tests specifying the choices for an Optional""" - - argument_signatures = [ - Sig('-f', choices='abc'), - Sig('-g', type=int, choices=range(5))] - failures = ['a', '-f d', '-fad', '-ga', '-g 6'] - successes = [ - ('', NS(f=None, g=None)), - ('-f a', NS(f='a', g=None)), - ('-f c', NS(f='c', g=None)), - ('-g 0', NS(f=None, g=0)), - ('-g 03', NS(f=None, g=3)), - ('-fb -g4', NS(f='b', g=4)), - ] - - - class TestOptionalsRequired(ParserTestCase): - """Tests an optional action that is required""" - - argument_signatures = [ - Sig('-x', type=int, required=True), - ] - failures = ['a', ''] - successes = [ - ('-x 1', NS(x=1)), - ('-x42', NS(x=42)), - ] - - - class TestOptionalsActionStore(ParserTestCase): - """Tests the store action for an Optional""" - - argument_signatures = [Sig('-x', action='store')] - failures = ['a', 'a -x'] - successes = [ - ('', NS(x=None)), - ('-xfoo', NS(x='foo')), - ] - - - class TestOptionalsActionStoreConst(ParserTestCase): - """Tests the store_const action for an Optional""" - - argument_signatures = [Sig('-y', action='store_const', const=object)] - failures = ['a'] - successes = [ - ('', NS(y=None)), - ('-y', NS(y=object)), - ] - - - class TestOptionalsActionStoreFalse(ParserTestCase): - """Tests the store_false action for an Optional""" - - argument_signatures = [Sig('-z', action='store_false')] - failures = ['a', '-za', '-z a'] - successes = [ - ('', NS(z=True)), - ('-z', NS(z=False)), - ] - - - class TestOptionalsActionStoreTrue(ParserTestCase): - """Tests the store_true action for an Optional""" - - argument_signatures = [Sig('--apple', action='store_true')] - failures = ['a', '--apple=b', '--apple b'] - successes = [ - ('', NS(apple=False)), - ('--apple', NS(apple=True)), - ] - - - class TestOptionalsActionAppend(ParserTestCase): - """Tests the append action for an Optional""" - - argument_signatures = [Sig('--baz', action='append')] - failures = ['a', '--baz', 'a --baz', '--baz a b'] - successes = [ - ('', NS(baz=None)), - ('--baz a', NS(baz=['a'])), - ('--baz a --baz b', NS(baz=['a', 'b'])), - ] - - - class TestOptionalsActionAppendWithDefault(ParserTestCase): - """Tests the append action for an Optional""" - - argument_signatures = [Sig('--baz', action='append', default=['X'])] - failures = ['a', '--baz', 'a --baz', '--baz a b'] - successes = [ - ('', NS(baz=['X'])), - ('--baz a', NS(baz=['X', 'a'])), - ('--baz a --baz b', NS(baz=['X', 'a', 'b'])), - ] - - - class TestOptionalsActionAppendConst(ParserTestCase): - """Tests the append_const action for an Optional""" - - argument_signatures = [ - Sig('-b', action='append_const', const=Exception), - Sig('-c', action='append', dest='b'), - ] - failures = ['a', '-c', 'a -c', '-bx', '-b x'] - successes = [ - ('', NS(b=None)), - ('-b', NS(b=[Exception])), - ('-b -cx -b -cyz', NS(b=[Exception, 'x', Exception, 'yz'])), - ] - - - class TestOptionalsActionAppendConstWithDefault(ParserTestCase): - """Tests the append_const action for an Optional""" - - argument_signatures = [ - Sig('-b', action='append_const', const=Exception, default=['X']), - Sig('-c', action='append', dest='b'), - ] - failures = ['a', '-c', 'a -c', '-bx', '-b x'] - successes = [ - ('', NS(b=['X'])), - ('-b', NS(b=['X', Exception])), - ('-b -cx -b -cyz', NS(b=['X', Exception, 'x', Exception, 'yz'])), - ] - - - class TestOptionalsActionCount(ParserTestCase): - """Tests the count action for an Optional""" - - argument_signatures = [Sig('-x', action='count')] - failures = ['a', '-x a', '-x b', '-x a -x b'] - successes = [ - ('', NS(x=None)), - ('-x', NS(x=1)), - ] - - - class TestOptionalsAllowLongAbbreviation(ParserTestCase): - """Allow long options to be abbreviated unambiguously""" - - argument_signatures = [ - Sig('--foo'), - Sig('--foobaz'), - Sig('--fooble', action='store_true'), - ] - failures = ['--foob 5', '--foob'] - successes = [ - ('', NS(foo=None, foobaz=None, fooble=False)), - ('--foo 7', NS(foo='7', foobaz=None, fooble=False)), - ('--fooba a', NS(foo=None, foobaz='a', fooble=False)), - ('--foobl --foo g', NS(foo='g', foobaz=None, fooble=True)), - ] - - - class TestOptionalsDisallowLongAbbreviation(ParserTestCase): - """Do not allow abbreviations of long options at all""" - - parser_signature = Sig(allow_abbrev=False) - argument_signatures = [ - Sig('--foo'), - Sig('--foodle', action='store_true'), - Sig('--foonly'), - ] - failures = ['-foon 3', '--foon 3', '--food', '--food --foo 2'] - successes = [ - ('', NS(foo=None, foodle=False, foonly=None)), - ('--foo 3', NS(foo='3', foodle=False, foonly=None)), - ('--foonly 7 --foodle --foo 2', NS(foo='2', foodle=True, foonly='7')), - ] - - - class TestOptionalsDisallowLongAbbreviationPrefixChars(ParserTestCase): - """Disallowing abbreviations works with alternative prefix characters""" - - parser_signature = Sig(prefix_chars='+', allow_abbrev=False) - argument_signatures = [ - Sig('++foo'), - Sig('++foodle', action='store_true'), - Sig('++foonly'), - ] - failures = ['+foon 3', '++foon 3', '++food', '++food ++foo 2'] - successes = [ - ('', NS(foo=None, foodle=False, foonly=None)), - ('++foo 3', NS(foo='3', foodle=False, foonly=None)), - ('++foonly 7 ++foodle ++foo 2', NS(foo='2', foodle=True, foonly='7')), - ] - - - class TestDisallowLongAbbreviationAllowsShortGrouping(ParserTestCase): - """Do not allow abbreviations of long options at all""" - - parser_signature = Sig(allow_abbrev=False) - argument_signatures = [ - Sig('-r'), - Sig('-c', action='count'), - ] - failures = ['-r', '-c -r'] - successes = [ - ('', NS(r=None, c=None)), - ('-ra', NS(r='a', c=None)), - ('-rcc', NS(r='cc', c=None)), - ('-cc', NS(r=None, c=2)), - ('-cc -ra', NS(r='a', c=2)), - ('-ccrcc', NS(r='cc', c=2)), - ] - - - class TestDisallowLongAbbreviationAllowsShortGroupingPrefix(ParserTestCase): - """Short option grouping works with custom prefix and allow_abbrev=False""" - - parser_signature = Sig(prefix_chars='+', allow_abbrev=False) - argument_signatures = [ - Sig('+r'), - Sig('+c', action='count'), - ] - failures = ['+r', '+c +r'] - successes = [ - ('', NS(r=None, c=None)), - ('+ra', NS(r='a', c=None)), - ('+rcc', NS(r='cc', c=None)), - ('+cc', NS(r=None, c=2)), - ('+cc +ra', NS(r='a', c=2)), - ('+ccrcc', NS(r='cc', c=2)), - ] - - - # ================ - # Positional tests - # ================ - - class TestPositionalsNargsNone(ParserTestCase): - """Test a Positional that doesn't specify nargs""" - - argument_signatures = [Sig('foo')] - failures = ['', '-x', 'a b'] - successes = [ - ('a', NS(foo='a')), - ] - - - class TestPositionalsNargs1(ParserTestCase): - """Test a Positional that specifies an nargs of 1""" - - argument_signatures = [Sig('foo', nargs=1)] - failures = ['', '-x', 'a b'] - successes = [ - ('a', NS(foo=['a'])), - ] - - - class TestPositionalsNargs2(ParserTestCase): - """Test a Positional that specifies an nargs of 2""" - - argument_signatures = [Sig('foo', nargs=2)] - failures = ['', 'a', '-x', 'a b c'] - successes = [ - ('a b', NS(foo=['a', 'b'])), - ] - - - class TestPositionalsNargsZeroOrMore(ParserTestCase): - """Test a Positional that specifies unlimited nargs""" - - argument_signatures = [Sig('foo', nargs='*')] - failures = ['-x'] - successes = [ - ('', NS(foo=[])), - ('a', NS(foo=['a'])), - ('a b', NS(foo=['a', 'b'])), - ] - - - class TestPositionalsNargsZeroOrMoreDefault(ParserTestCase): - """Test a Positional that specifies unlimited nargs and a default""" - - argument_signatures = [Sig('foo', nargs='*', default='bar')] - failures = ['-x'] - successes = [ - ('', NS(foo='bar')), - ('a', NS(foo=['a'])), - ('a b', NS(foo=['a', 'b'])), - ] - - - class TestPositionalsNargsOneOrMore(ParserTestCase): - """Test a Positional that specifies one or more nargs""" - - argument_signatures = [Sig('foo', nargs='+')] - failures = ['', '-x'] - successes = [ - ('a', NS(foo=['a'])), - ('a b', NS(foo=['a', 'b'])), - ] - - - class TestPositionalsNargsOptional(ParserTestCase): - """Tests an Optional Positional""" - - argument_signatures = [Sig('foo', nargs='?')] - failures = ['-x', 'a b'] - successes = [ - ('', NS(foo=None)), - ('a', NS(foo='a')), - ] - - - class TestPositionalsNargsOptionalDefault(ParserTestCase): - """Tests an Optional Positional with a default value""" - - argument_signatures = [Sig('foo', nargs='?', default=42)] - failures = ['-x', 'a b'] - successes = [ - ('', NS(foo=42)), - ('a', NS(foo='a')), - ] - - - class TestPositionalsNargsOptionalConvertedDefault(ParserTestCase): - """Tests an Optional Positional with a default value - that needs to be converted to the appropriate type. - """ - - argument_signatures = [ - Sig('foo', nargs='?', type=int, default='42'), - ] - failures = ['-x', 'a b', '1 2'] - successes = [ - ('', NS(foo=42)), - ('1', NS(foo=1)), - ] - - - class TestPositionalsNargsNoneNone(ParserTestCase): - """Test two Positionals that don't specify nargs""" - - argument_signatures = [Sig('foo'), Sig('bar')] - failures = ['', '-x', 'a', 'a b c'] - successes = [ - ('a b', NS(foo='a', bar='b')), - ] - - - class TestPositionalsNargsNone1(ParserTestCase): - """Test a Positional with no nargs followed by one with 1""" - - argument_signatures = [Sig('foo'), Sig('bar', nargs=1)] - failures = ['', '--foo', 'a', 'a b c'] - successes = [ - ('a b', NS(foo='a', bar=['b'])), - ] - - - class TestPositionalsNargs2None(ParserTestCase): - """Test a Positional with 2 nargs followed by one with none""" - - argument_signatures = [Sig('foo', nargs=2), Sig('bar')] - failures = ['', '--foo', 'a', 'a b', 'a b c d'] - successes = [ - ('a b c', NS(foo=['a', 'b'], bar='c')), - ] - - - class TestPositionalsNargsNoneZeroOrMore(ParserTestCase): - """Test a Positional with no nargs followed by one with unlimited""" - - argument_signatures = [Sig('foo'), Sig('bar', nargs='*')] - failures = ['', '--foo'] - successes = [ - ('a', NS(foo='a', bar=[])), - ('a b', NS(foo='a', bar=['b'])), - ('a b c', NS(foo='a', bar=['b', 'c'])), - ] - - - class TestPositionalsNargsNoneOneOrMore(ParserTestCase): - """Test a Positional with no nargs followed by one with one or more""" - - argument_signatures = [Sig('foo'), Sig('bar', nargs='+')] - failures = ['', '--foo', 'a'] - successes = [ - ('a b', NS(foo='a', bar=['b'])), - ('a b c', NS(foo='a', bar=['b', 'c'])), - ] - - - class TestPositionalsNargsNoneOptional(ParserTestCase): - """Test a Positional with no nargs followed by one with an Optional""" - - argument_signatures = [Sig('foo'), Sig('bar', nargs='?')] - failures = ['', '--foo', 'a b c'] - successes = [ - ('a', NS(foo='a', bar=None)), - ('a b', NS(foo='a', bar='b')), - ] - - - class TestPositionalsNargsZeroOrMoreNone(ParserTestCase): - """Test a Positional with unlimited nargs followed by one with none""" - - argument_signatures = [Sig('foo', nargs='*'), Sig('bar')] - failures = ['', '--foo'] - successes = [ - ('a', NS(foo=[], bar='a')), - ('a b', NS(foo=['a'], bar='b')), - ('a b c', NS(foo=['a', 'b'], bar='c')), - ] - - - class TestPositionalsNargsOneOrMoreNone(ParserTestCase): - """Test a Positional with one or more nargs followed by one with none""" - - argument_signatures = [Sig('foo', nargs='+'), Sig('bar')] - failures = ['', '--foo', 'a'] - successes = [ - ('a b', NS(foo=['a'], bar='b')), - ('a b c', NS(foo=['a', 'b'], bar='c')), - ] - - - class TestPositionalsNargsOptionalNone(ParserTestCase): - """Test a Positional with an Optional nargs followed by one with none""" - - argument_signatures = [Sig('foo', nargs='?', default=42), Sig('bar')] - failures = ['', '--foo', 'a b c'] - successes = [ - ('a', NS(foo=42, bar='a')), - ('a b', NS(foo='a', bar='b')), - ] - - - class TestPositionalsNargs2ZeroOrMore(ParserTestCase): - """Test a Positional with 2 nargs followed by one with unlimited""" - - argument_signatures = [Sig('foo', nargs=2), Sig('bar', nargs='*')] - failures = ['', '--foo', 'a'] - successes = [ - ('a b', NS(foo=['a', 'b'], bar=[])), - ('a b c', NS(foo=['a', 'b'], bar=['c'])), - ] - - - class TestPositionalsNargs2OneOrMore(ParserTestCase): - """Test a Positional with 2 nargs followed by one with one or more""" - - argument_signatures = [Sig('foo', nargs=2), Sig('bar', nargs='+')] - failures = ['', '--foo', 'a', 'a b'] - successes = [ - ('a b c', NS(foo=['a', 'b'], bar=['c'])), - ] - - - class TestPositionalsNargs2Optional(ParserTestCase): - """Test a Positional with 2 nargs followed by one optional""" - - argument_signatures = [Sig('foo', nargs=2), Sig('bar', nargs='?')] - failures = ['', '--foo', 'a', 'a b c d'] - successes = [ - ('a b', NS(foo=['a', 'b'], bar=None)), - ('a b c', NS(foo=['a', 'b'], bar='c')), - ] - - - class TestPositionalsNargsZeroOrMore1(ParserTestCase): - """Test a Positional with unlimited nargs followed by one with 1""" - - argument_signatures = [Sig('foo', nargs='*'), Sig('bar', nargs=1)] - failures = ['', '--foo', ] - successes = [ - ('a', NS(foo=[], bar=['a'])), - ('a b', NS(foo=['a'], bar=['b'])), - ('a b c', NS(foo=['a', 'b'], bar=['c'])), - ] - - - class TestPositionalsNargsOneOrMore1(ParserTestCase): - """Test a Positional with one or more nargs followed by one with 1""" - - argument_signatures = [Sig('foo', nargs='+'), Sig('bar', nargs=1)] - failures = ['', '--foo', 'a'] - successes = [ - ('a b', NS(foo=['a'], bar=['b'])), - ('a b c', NS(foo=['a', 'b'], bar=['c'])), - ] - - - class TestPositionalsNargsOptional1(ParserTestCase): - """Test a Positional with an Optional nargs followed by one with 1""" - - argument_signatures = [Sig('foo', nargs='?'), Sig('bar', nargs=1)] - failures = ['', '--foo', 'a b c'] - successes = [ - ('a', NS(foo=None, bar=['a'])), - ('a b', NS(foo='a', bar=['b'])), - ] - - - class TestPositionalsNargsNoneZeroOrMore1(ParserTestCase): - """Test three Positionals: no nargs, unlimited nargs and 1 nargs""" - - argument_signatures = [ - Sig('foo'), - Sig('bar', nargs='*'), - Sig('baz', nargs=1), - ] - failures = ['', '--foo', 'a'] - successes = [ - ('a b', NS(foo='a', bar=[], baz=['b'])), - ('a b c', NS(foo='a', bar=['b'], baz=['c'])), - ] - - - class TestPositionalsNargsNoneOneOrMore1(ParserTestCase): - """Test three Positionals: no nargs, one or more nargs and 1 nargs""" - - argument_signatures = [ - Sig('foo'), - Sig('bar', nargs='+'), - Sig('baz', nargs=1), - ] - failures = ['', '--foo', 'a', 'b'] - successes = [ - ('a b c', NS(foo='a', bar=['b'], baz=['c'])), - ('a b c d', NS(foo='a', bar=['b', 'c'], baz=['d'])), - ] - - - class TestPositionalsNargsNoneOptional1(ParserTestCase): - """Test three Positionals: no nargs, optional narg and 1 nargs""" - - argument_signatures = [ - Sig('foo'), - Sig('bar', nargs='?', default=0.625), - Sig('baz', nargs=1), - ] - failures = ['', '--foo', 'a'] - successes = [ - ('a b', NS(foo='a', bar=0.625, baz=['b'])), - ('a b c', NS(foo='a', bar='b', baz=['c'])), - ] - - - class TestPositionalsNargsOptionalOptional(ParserTestCase): - """Test two optional nargs""" - - argument_signatures = [ - Sig('foo', nargs='?'), - Sig('bar', nargs='?', default=42), - ] - failures = ['--foo', 'a b c'] - successes = [ - ('', NS(foo=None, bar=42)), - ('a', NS(foo='a', bar=42)), - ('a b', NS(foo='a', bar='b')), - ] - - - class TestPositionalsNargsOptionalZeroOrMore(ParserTestCase): - """Test an Optional narg followed by unlimited nargs""" - - argument_signatures = [Sig('foo', nargs='?'), Sig('bar', nargs='*')] - failures = ['--foo'] - successes = [ - ('', NS(foo=None, bar=[])), - ('a', NS(foo='a', bar=[])), - ('a b', NS(foo='a', bar=['b'])), - ('a b c', NS(foo='a', bar=['b', 'c'])), - ] - - - class TestPositionalsNargsOptionalOneOrMore(ParserTestCase): - """Test an Optional narg followed by one or more nargs""" - - argument_signatures = [Sig('foo', nargs='?'), Sig('bar', nargs='+')] - failures = ['', '--foo'] - successes = [ - ('a', NS(foo=None, bar=['a'])), - ('a b', NS(foo='a', bar=['b'])), - ('a b c', NS(foo='a', bar=['b', 'c'])), - ] - - - class TestPositionalsChoicesString(ParserTestCase): - """Test a set of single-character choices""" - - argument_signatures = [Sig('spam', choices=set('abcdefg'))] - failures = ['', '--foo', 'h', '42', 'ef'] - successes = [ - ('a', NS(spam='a')), - ('g', NS(spam='g')), - ] - - - class TestPositionalsChoicesInt(ParserTestCase): - """Test a set of integer choices""" - - argument_signatures = [Sig('spam', type=int, choices=range(20))] - failures = ['', '--foo', 'h', '42', 'ef'] - successes = [ - ('4', NS(spam=4)), - ('15', NS(spam=15)), - ] - - - class TestPositionalsActionAppend(ParserTestCase): - """Test the 'append' action""" - - argument_signatures = [ - Sig('spam', action='append'), - Sig('spam', action='append', nargs=2), - ] - failures = ['', '--foo', 'a', 'a b', 'a b c d'] - successes = [ - ('a b c', NS(spam=['a', ['b', 'c']])), - ] - - # ======================================== - # Combined optionals and positionals tests - # ======================================== - - class TestOptionalsNumericAndPositionals(ParserTestCase): - """Tests negative number args when numeric options are present""" - - argument_signatures = [ - Sig('x', nargs='?'), - Sig('-4', dest='y', action='store_true'), - ] - failures = ['-2', '-315'] - successes = [ - ('', NS(x=None, y=False)), - ('a', NS(x='a', y=False)), - ('-4', NS(x=None, y=True)), - ('-4 a', NS(x='a', y=True)), - ] - - - class TestOptionalsAlmostNumericAndPositionals(ParserTestCase): - """Tests negative number args when almost numeric options are present""" - - argument_signatures = [ - Sig('x', nargs='?'), - Sig('-k4', dest='y', action='store_true'), - ] - failures = ['-k3'] - successes = [ - ('', NS(x=None, y=False)), - ('-2', NS(x='-2', y=False)), - ('a', NS(x='a', y=False)), - ('-k4', NS(x=None, y=True)), - ('-k4 a', NS(x='a', y=True)), - ] - - - class TestEmptyAndSpaceContainingArguments(ParserTestCase): - - argument_signatures = [ - Sig('x', nargs='?'), - Sig('-y', '--yyy', dest='y'), - ] - failures = ['-y'] - successes = [ - ([''], NS(x='', y=None)), - (['a badger'], NS(x='a badger', y=None)), - (['-a badger'], NS(x='-a badger', y=None)), - (['-y', ''], NS(x=None, y='')), - (['-y', 'a badger'], NS(x=None, y='a badger')), - (['-y', '-a badger'], NS(x=None, y='-a badger')), - (['--yyy=a badger'], NS(x=None, y='a badger')), - (['--yyy=-a badger'], NS(x=None, y='-a badger')), - ] - - - class TestPrefixCharacterOnlyArguments(ParserTestCase): - - parser_signature = Sig(prefix_chars='-+') - argument_signatures = [ - Sig('-', dest='x', nargs='?', const='badger'), - Sig('+', dest='y', type=int, default=42), - Sig('-+-', dest='z', action='store_true'), - ] - failures = ['-y', '+ -'] - successes = [ - ('', NS(x=None, y=42, z=False)), - ('-', NS(x='badger', y=42, z=False)), - ('- X', NS(x='X', y=42, z=False)), - ('+ -3', NS(x=None, y=-3, z=False)), - ('-+-', NS(x=None, y=42, z=True)), - ('- ===', NS(x='===', y=42, z=False)), - ] - - - class TestNargsZeroOrMore(ParserTestCase): - """Tests specifying args for an Optional that accepts zero or more""" - - argument_signatures = [Sig('-x', nargs='*'), Sig('y', nargs='*')] - failures = [] - successes = [ - ('', NS(x=None, y=[])), - ('-x', NS(x=[], y=[])), - ('-x a', NS(x=['a'], y=[])), - ('-x a -- b', NS(x=['a'], y=['b'])), - ('a', NS(x=None, y=['a'])), - ('a -x', NS(x=[], y=['a'])), - ('a -x b', NS(x=['b'], y=['a'])), - ] - - - class TestNargsRemainder(ParserTestCase): - """Tests specifying a positional with nargs=REMAINDER""" - - argument_signatures = [Sig('x'), Sig('y', nargs='...'), Sig('-z')] - failures = ['', '-z', '-z Z'] - successes = [ - ('X', NS(x='X', y=[], z=None)), - ('-z Z X', NS(x='X', y=[], z='Z')), - ('X A B -z Z', NS(x='X', y=['A', 'B', '-z', 'Z'], z=None)), - ('X Y --foo', NS(x='X', y=['Y', '--foo'], z=None)), - ] - - - class TestOptionLike(ParserTestCase): - """Tests options that may or may not be arguments""" - - argument_signatures = [ - Sig('-x', type=float), - Sig('-3', type=float, dest='y'), - Sig('z', nargs='*'), - ] - failures = ['-x', '-y2.5', '-xa', '-x -a', - '-x -3', '-x -3.5', '-3 -3.5', - '-x -2.5', '-x -2.5 a', '-3 -.5', - 'a x -1', '-x -1 a', '-3 -1 a'] - successes = [ - ('', NS(x=None, y=None, z=[])), - ('-x 2.5', NS(x=2.5, y=None, z=[])), - ('-x 2.5 a', NS(x=2.5, y=None, z=['a'])), - ('-3.5', NS(x=None, y=0.5, z=[])), - ('-3-.5', NS(x=None, y=-0.5, z=[])), - ('-3 .5', NS(x=None, y=0.5, z=[])), - ('a -3.5', NS(x=None, y=0.5, z=['a'])), - ('a', NS(x=None, y=None, z=['a'])), - ('a -x 1', NS(x=1.0, y=None, z=['a'])), - ('-x 1 a', NS(x=1.0, y=None, z=['a'])), - ('-3 1 a', NS(x=None, y=1.0, z=['a'])), - ] - - - class TestDefaultSuppress(ParserTestCase): - """Test actions with suppressed defaults""" - - argument_signatures = [ - Sig('foo', nargs='?', default=argparse.SUPPRESS), - Sig('bar', nargs='*', default=argparse.SUPPRESS), - Sig('--baz', action='store_true', default=argparse.SUPPRESS), - ] - failures = ['-x'] - successes = [ - ('', NS()), - ('a', NS(foo='a')), - ('a b', NS(foo='a', bar=['b'])), - ('--baz', NS(baz=True)), - ('a --baz', NS(foo='a', baz=True)), - ('--baz a b', NS(foo='a', bar=['b'], baz=True)), - ] - - - class TestParserDefaultSuppress(ParserTestCase): - """Test actions with a parser-level default of SUPPRESS""" - - parser_signature = Sig(argument_default=argparse.SUPPRESS) - argument_signatures = [ - Sig('foo', nargs='?'), - Sig('bar', nargs='*'), - Sig('--baz', action='store_true'), - ] - failures = ['-x'] - successes = [ - ('', NS()), - ('a', NS(foo='a')), - ('a b', NS(foo='a', bar=['b'])), - ('--baz', NS(baz=True)), - ('a --baz', NS(foo='a', baz=True)), - ('--baz a b', NS(foo='a', bar=['b'], baz=True)), - ] - - - class TestParserDefault42(ParserTestCase): - """Test actions with a parser-level default of 42""" - - parser_signature = Sig(argument_default=42) - argument_signatures = [ - Sig('--version', action='version', version='1.0'), - Sig('foo', nargs='?'), - Sig('bar', nargs='*'), - Sig('--baz', action='store_true'), - ] - failures = ['-x'] - successes = [ - ('', NS(foo=42, bar=42, baz=42, version=42)), - ('a', NS(foo='a', bar=42, baz=42, version=42)), - ('a b', NS(foo='a', bar=['b'], baz=42, version=42)), - ('--baz', NS(foo=42, bar=42, baz=True, version=42)), - ('a --baz', NS(foo='a', bar=42, baz=True, version=42)), - ('--baz a b', NS(foo='a', bar=['b'], baz=True, version=42)), - ] - - - class TestArgumentsFromFile(TempDirMixin, ParserTestCase): - """Test reading arguments from a file""" - - def setUp(self): - super(TestArgumentsFromFile, self).setUp() - file_texts = [ - ('hello', 'hello world!\n'), - ('recursive', '-a\n' - 'A\n' - '@hello'), - ('invalid', '@no-such-path\n'), - ] - for path, text in file_texts: - with open(path, 'w') as file: - file.write(text) - - parser_signature = Sig(fromfile_prefix_chars='@') - argument_signatures = [ - Sig('-a'), - Sig('x'), - Sig('y', nargs='+'), - ] - failures = ['', '-b', 'X', '@invalid', '@missing'] - successes = [ - ('X Y', NS(a=None, x='X', y=['Y'])), - ('X -a A Y Z', NS(a='A', x='X', y=['Y', 'Z'])), - ('@hello X', NS(a=None, x='hello world!', y=['X'])), - ('X @hello', NS(a=None, x='X', y=['hello world!'])), - ('-a B @recursive Y Z', NS(a='A', x='hello world!', y=['Y', 'Z'])), - ('X @recursive Z -a B', NS(a='B', x='X', y=['hello world!', 'Z'])), - (["-a", "", "X", "Y"], NS(a='', x='X', y=['Y'])), - ] - - - class TestArgumentsFromFileConverter(TempDirMixin, ParserTestCase): - """Test reading arguments from a file""" - - def setUp(self): - super(TestArgumentsFromFileConverter, self).setUp() - file_texts = [ - ('hello', 'hello world!\n'), - ] - for path, text in file_texts: - with open(path, 'w') as file: - file.write(text) - - class FromFileConverterArgumentParser(ErrorRaisingArgumentParser): - - def convert_arg_line_to_args(self, arg_line): - for arg in arg_line.split(): - if not arg.strip(): - continue - yield arg - parser_class = FromFileConverterArgumentParser - parser_signature = Sig(fromfile_prefix_chars='@') - argument_signatures = [ - Sig('y', nargs='+'), - ] - failures = [] - successes = [ - ('@hello X', NS(y=['hello', 'world!', 'X'])), - ] - - - # ===================== - # Type conversion tests - # ===================== - - class TestFileTypeRepr(TestCase): - - def test_r(self): - type = argparse.FileType('r') - self.assertEqual("FileType('r')", repr(type)) - - def test_wb_1(self): - type = argparse.FileType('wb', 1) - self.assertEqual("FileType('wb', 1)", repr(type)) - - def test_r_latin(self): - type = argparse.FileType('r', encoding='latin_1') - self.assertEqual("FileType('r', encoding='latin_1')", repr(type)) - - def test_w_big5_ignore(self): - type = argparse.FileType('w', encoding='big5', errors='ignore') - self.assertEqual("FileType('w', encoding='big5', errors='ignore')", - repr(type)) - - def test_r_1_replace(self): - type = argparse.FileType('r', 1, errors='replace') - self.assertEqual("FileType('r', 1, errors='replace')", repr(type)) - - class StdStreamComparer: - def __init__(self, attr): - self.attr = attr - - def __eq__(self, other): - return other == getattr(sys, self.attr) - - eq_stdin = StdStreamComparer('stdin') - eq_stdout = StdStreamComparer('stdout') - eq_stderr = StdStreamComparer('stderr') - - class RFile(object): - seen = {} - - def __init__(self, name): - self.name = name - - def __eq__(self, other): - if other in self.seen: - text = self.seen[other] - else: - text = self.seen[other] = other.read() - other.close() - if not isinstance(text, str): - text = text.decode('ascii') - return self.name == other.name == text - - - class TestFileTypeR(TempDirMixin, ParserTestCase): - """Test the FileType option/argument type for reading files""" - - def setUp(self): - super(TestFileTypeR, self).setUp() - for file_name in ['foo', 'bar']: - with open(os.path.join(self.temp_dir, file_name), 'w') as file: - file.write(file_name) - self.create_readonly_file('readonly') - - argument_signatures = [ - Sig('-x', type=argparse.FileType()), - Sig('spam', type=argparse.FileType('r')), - ] - failures = ['-x', '', 'non-existent-file.txt'] - successes = [ - ('foo', NS(x=None, spam=RFile('foo'))), - ('-x foo bar', NS(x=RFile('foo'), spam=RFile('bar'))), - ('bar -x foo', NS(x=RFile('foo'), spam=RFile('bar'))), - ('-x - -', NS(x=eq_stdin, spam=eq_stdin)), - ('readonly', NS(x=None, spam=RFile('readonly'))), - ] - - class TestFileTypeDefaults(TempDirMixin, ParserTestCase): - """Test that a file is not created unless the default is needed""" - def setUp(self): - super(TestFileTypeDefaults, self).setUp() - file = open(os.path.join(self.temp_dir, 'good'), 'w') - file.write('good') - file.close() - - argument_signatures = [ - Sig('-c', type=argparse.FileType('r'), default='no-file.txt'), - ] - # should provoke no such file error - failures = [''] - # should not provoke error because default file is created - successes = [('-c good', NS(c=RFile('good')))] - - - class TestFileTypeRB(TempDirMixin, ParserTestCase): - """Test the FileType option/argument type for reading files""" - - def setUp(self): - super(TestFileTypeRB, self).setUp() - for file_name in ['foo', 'bar']: - with open(os.path.join(self.temp_dir, file_name), 'w') as file: - file.write(file_name) - - argument_signatures = [ - Sig('-x', type=argparse.FileType('rb')), - Sig('spam', type=argparse.FileType('rb')), - ] - failures = ['-x', ''] - successes = [ - ('foo', NS(x=None, spam=RFile('foo'))), - ('-x foo bar', NS(x=RFile('foo'), spam=RFile('bar'))), - ('bar -x foo', NS(x=RFile('foo'), spam=RFile('bar'))), - ('-x - -', NS(x=eq_stdin, spam=eq_stdin)), - ] - - - class WFile(object): - seen = set() - - def __init__(self, name): - self.name = name - - def __eq__(self, other): - if other not in self.seen: - text = 'Check that file is writable.' - if 'b' in other.mode: - text = text.encode('ascii') - other.write(text) - other.close() - self.seen.add(other) - return self.name == other.name - - - @unittest.skipIf(hasattr(os, 'geteuid') and os.geteuid() == 0, - "non-root user required") - class TestFileTypeW(TempDirMixin, ParserTestCase): - """Test the FileType option/argument type for writing files""" - - def setUp(self): - super(TestFileTypeW, self).setUp() - self.create_readonly_file('readonly') - - argument_signatures = [ - Sig('-x', type=argparse.FileType('w')), - Sig('spam', type=argparse.FileType('w')), - ] - failures = ['-x', '', 'readonly'] - successes = [ - ('foo', NS(x=None, spam=WFile('foo'))), - ('-x foo bar', NS(x=WFile('foo'), spam=WFile('bar'))), - ('bar -x foo', NS(x=WFile('foo'), spam=WFile('bar'))), - ('-x - -', NS(x=eq_stdout, spam=eq_stdout)), - ] - - - class TestFileTypeWB(TempDirMixin, ParserTestCase): - - argument_signatures = [ - Sig('-x', type=argparse.FileType('wb')), - Sig('spam', type=argparse.FileType('wb')), - ] - failures = ['-x', ''] - successes = [ - ('foo', NS(x=None, spam=WFile('foo'))), - ('-x foo bar', NS(x=WFile('foo'), spam=WFile('bar'))), - ('bar -x foo', NS(x=WFile('foo'), spam=WFile('bar'))), - ('-x - -', NS(x=eq_stdout, spam=eq_stdout)), - ] - - - class TestFileTypeOpenArgs(TestCase): - """Test that open (the builtin) is correctly called""" - - def test_open_args(self): - FT = argparse.FileType - cases = [ - (FT('rb'), ('rb', -1, None, None)), - (FT('w', 1), ('w', 1, None, None)), - (FT('w', errors='replace'), ('w', -1, None, 'replace')), - (FT('wb', encoding='big5'), ('wb', -1, 'big5', None)), - (FT('w', 0, 'l1', 'strict'), ('w', 0, 'l1', 'strict')), - ] - with mock.patch('builtins.open') as m: - for type, args in cases: - type('foo') - m.assert_called_with('foo', *args) - - - class TestFileTypeMissingInitialization(TestCase): - """ - Test that add_argument throws an error if FileType class - object was passed instead of instance of FileType - """ - - def test(self): - parser = argparse.ArgumentParser() - with self.assertRaises(ValueError) as cm: - parser.add_argument('-x', type=argparse.FileType) - - self.assertEqual( - '%r is a FileType class object, instance of it must be passed' - % (argparse.FileType,), - str(cm.exception) - ) - - - class TestTypeCallable(ParserTestCase): - """Test some callables as option/argument types""" - - argument_signatures = [ - Sig('--eggs', type=complex), - Sig('spam', type=float), - ] - failures = ['a', '42j', '--eggs a', '--eggs 2i'] - successes = [ - ('--eggs=42 42', NS(eggs=42, spam=42.0)), - ('--eggs 2j -- -1.5', NS(eggs=2j, spam=-1.5)), - ('1024.675', NS(eggs=None, spam=1024.675)), - ] - - - class TestTypeUserDefined(ParserTestCase): - """Test a user-defined option/argument type""" - - class MyType(TestCase): - - def __init__(self, value): - self.value = value - - def __eq__(self, other): - return (type(self), self.value) == (type(other), other.value) - - argument_signatures = [ - Sig('-x', type=MyType), - Sig('spam', type=MyType), - ] - failures = [] - successes = [ - ('a -x b', NS(x=MyType('b'), spam=MyType('a'))), - ('-xf g', NS(x=MyType('f'), spam=MyType('g'))), - ] - - - class TestTypeClassicClass(ParserTestCase): - """Test a classic class type""" - - class C: - - def __init__(self, value): - self.value = value - - def __eq__(self, other): - return (type(self), self.value) == (type(other), other.value) - - argument_signatures = [ - Sig('-x', type=C), - Sig('spam', type=C), - ] - failures = [] - successes = [ - ('a -x b', NS(x=C('b'), spam=C('a'))), - ('-xf g', NS(x=C('f'), spam=C('g'))), - ] - - - class TestTypeRegistration(TestCase): - """Test a user-defined type by registering it""" - - def test(self): - - def get_my_type(string): - return 'my_type{%s}' % string - - parser = argparse.ArgumentParser() - parser.register('type', 'my_type', get_my_type) - parser.add_argument('-x', type='my_type') - parser.add_argument('y', type='my_type') - - self.assertEqual(parser.parse_args('1'.split()), - NS(x=None, y='my_type{1}')) - self.assertEqual(parser.parse_args('-x 1 42'.split()), - NS(x='my_type{1}', y='my_type{42}')) - - - # ============ - # Action tests - # ============ - - class TestActionUserDefined(ParserTestCase): - """Test a user-defined option/argument action""" - - class OptionalAction(argparse.Action): - - def __call__(self, parser, namespace, value, option_string=None): - try: - # check destination and option string - assert self.dest == 'spam', 'dest: %s' % self.dest - assert option_string == '-s', 'flag: %s' % option_string - # when option is before argument, badger=2, and when - # option is after argument, badger= - expected_ns = NS(spam=0.25) - if value in [0.125, 0.625]: - expected_ns.badger = 2 - elif value in [2.0]: - expected_ns.badger = 84 - else: - raise AssertionError('value: %s' % value) - assert expected_ns == namespace, ('expected %s, got %s' % - (expected_ns, namespace)) - except AssertionError: - e = sys.exc_info()[1] - raise ArgumentParserError('opt_action failed: %s' % e) - setattr(namespace, 'spam', value) - - class PositionalAction(argparse.Action): - - def __call__(self, parser, namespace, value, option_string=None): - try: - assert option_string is None, ('option_string: %s' % - option_string) - # check destination - assert self.dest == 'badger', 'dest: %s' % self.dest - # when argument is before option, spam=0.25, and when - # option is after argument, spam= - expected_ns = NS(badger=2) - if value in [42, 84]: - expected_ns.spam = 0.25 - elif value in [1]: - expected_ns.spam = 0.625 - elif value in [2]: - expected_ns.spam = 0.125 - else: - raise AssertionError('value: %s' % value) - assert expected_ns == namespace, ('expected %s, got %s' % - (expected_ns, namespace)) - except AssertionError: - e = sys.exc_info()[1] - raise ArgumentParserError('arg_action failed: %s' % e) - setattr(namespace, 'badger', value) - - argument_signatures = [ - Sig('-s', dest='spam', action=OptionalAction, - type=float, default=0.25), - Sig('badger', action=PositionalAction, - type=int, nargs='?', default=2), - ] - failures = [] - successes = [ - ('-s0.125', NS(spam=0.125, badger=2)), - ('42', NS(spam=0.25, badger=42)), - ('-s 0.625 1', NS(spam=0.625, badger=1)), - ('84 -s2', NS(spam=2.0, badger=84)), - ] - - - class TestActionRegistration(TestCase): - """Test a user-defined action supplied by registering it""" - - class MyAction(argparse.Action): - - def __call__(self, parser, namespace, values, option_string=None): - setattr(namespace, self.dest, 'foo[%s]' % values) - - def test(self): - - parser = argparse.ArgumentParser() - parser.register('action', 'my_action', self.MyAction) - parser.add_argument('badger', action='my_action') - - self.assertEqual(parser.parse_args(['1']), NS(badger='foo[1]')) - self.assertEqual(parser.parse_args(['42']), NS(badger='foo[42]')) - - - class TestActionExtend(ParserTestCase): - argument_signatures = [ - Sig('--foo', action="extend", nargs="+", type=str), - ] - failures = () - successes = [ - ('--foo f1 --foo f2 f3 f4', NS(foo=['f1', 'f2', 'f3', 'f4'])), - ] - - # ================ - # Subparsers tests - # ================ - - class TestAddSubparsers(TestCase): - """Test the add_subparsers method""" - - def assertArgumentParserError(self, *args, **kwargs): - self.assertRaises(ArgumentParserError, *args, **kwargs) - - def _get_parser(self, subparser_help=False, prefix_chars=None, - aliases=False): - # create a parser with a subparsers argument - if prefix_chars: - parser = ErrorRaisingArgumentParser( - prog='PROG', description='main description', prefix_chars=prefix_chars) - parser.add_argument( - prefix_chars[0] * 2 + 'foo', action='store_true', help='foo help') - else: - parser = ErrorRaisingArgumentParser( - prog='PROG', description='main description') - parser.add_argument( - '--foo', action='store_true', help='foo help') - parser.add_argument( - 'bar', type=float, help='bar help') - - # check that only one subparsers argument can be added - subparsers_kwargs = {'required': False} - if aliases: - subparsers_kwargs['metavar'] = 'COMMAND' - subparsers_kwargs['title'] = 'commands' - else: - subparsers_kwargs['help'] = 'command help' - subparsers = parser.add_subparsers(**subparsers_kwargs) - self.assertArgumentParserError(parser.add_subparsers) - - # add first sub-parser - parser1_kwargs = dict(description='1 description') - if subparser_help: - parser1_kwargs['help'] = '1 help' - if aliases: - parser1_kwargs['aliases'] = ['1alias1', '1alias2'] - parser1 = subparsers.add_parser('1', **parser1_kwargs) - parser1.add_argument('-w', type=int, help='w help') - parser1.add_argument('x', choices='abc', help='x help') - - # add second sub-parser - parser2_kwargs = dict(description='2 description') - if subparser_help: - parser2_kwargs['help'] = '2 help' - parser2 = subparsers.add_parser('2', **parser2_kwargs) - parser2.add_argument('-y', choices='123', help='y help') - parser2.add_argument('z', type=complex, nargs='*', help='z help') - - # add third sub-parser - parser3_kwargs = dict(description='3 description') - if subparser_help: - parser3_kwargs['help'] = '3 help' - parser3 = subparsers.add_parser('3', **parser3_kwargs) - parser3.add_argument('t', type=int, help='t help') - parser3.add_argument('u', nargs='...', help='u help') - - # return the main parser - return parser - - def setUp(self): - super().setUp() - self.parser = self._get_parser() - self.command_help_parser = self._get_parser(subparser_help=True) - - def test_parse_args_failures(self): - # check some failure cases: - for args_str in ['', 'a', 'a a', '0.5 a', '0.5 1', - '0.5 1 -y', '0.5 2 -w']: - args = args_str.split() - self.assertArgumentParserError(self.parser.parse_args, args) - - def test_parse_args(self): - # check some non-failure cases: - self.assertEqual( - self.parser.parse_args('0.5 1 b -w 7'.split()), - NS(foo=False, bar=0.5, w=7, x='b'), - ) - self.assertEqual( - self.parser.parse_args('0.25 --foo 2 -y 2 3j -- -1j'.split()), - NS(foo=True, bar=0.25, y='2', z=[3j, -1j]), - ) - self.assertEqual( - self.parser.parse_args('--foo 0.125 1 c'.split()), - NS(foo=True, bar=0.125, w=None, x='c'), - ) - self.assertEqual( - self.parser.parse_args('-1.5 3 11 -- a --foo 7 -- b'.split()), - NS(foo=False, bar=-1.5, t=11, u=['a', '--foo', '7', '--', 'b']), - ) - - def test_parse_known_args(self): - self.assertEqual( - self.parser.parse_known_args('0.5 1 b -w 7'.split()), - (NS(foo=False, bar=0.5, w=7, x='b'), []), - ) - self.assertEqual( - self.parser.parse_known_args('0.5 -p 1 b -w 7'.split()), - (NS(foo=False, bar=0.5, w=7, x='b'), ['-p']), - ) - self.assertEqual( - self.parser.parse_known_args('0.5 1 b -w 7 -p'.split()), - (NS(foo=False, bar=0.5, w=7, x='b'), ['-p']), - ) - self.assertEqual( - self.parser.parse_known_args('0.5 1 b -q -rs -w 7'.split()), - (NS(foo=False, bar=0.5, w=7, x='b'), ['-q', '-rs']), - ) - self.assertEqual( - self.parser.parse_known_args('0.5 -W 1 b -X Y -w 7 Z'.split()), - (NS(foo=False, bar=0.5, w=7, x='b'), ['-W', '-X', 'Y', 'Z']), - ) - - def test_dest(self): - parser = ErrorRaisingArgumentParser() - parser.add_argument('--foo', action='store_true') - subparsers = parser.add_subparsers(dest='bar') - parser1 = subparsers.add_parser('1') - parser1.add_argument('baz') - self.assertEqual(NS(foo=False, bar='1', baz='2'), - parser.parse_args('1 2'.split())) - - def _test_required_subparsers(self, parser): - # Should parse the sub command - ret = parser.parse_args(['run']) - self.assertEqual(ret.command, 'run') - - # Error when the command is missing - self.assertArgumentParserError(parser.parse_args, ()) - - def test_required_subparsers_via_attribute(self): - parser = ErrorRaisingArgumentParser() - subparsers = parser.add_subparsers(dest='command') - subparsers.required = True - subparsers.add_parser('run') - self._test_required_subparsers(parser) - - def test_required_subparsers_via_kwarg(self): - parser = ErrorRaisingArgumentParser() - subparsers = parser.add_subparsers(dest='command', required=True) - subparsers.add_parser('run') - self._test_required_subparsers(parser) - - def test_required_subparsers_default(self): - parser = ErrorRaisingArgumentParser() - subparsers = parser.add_subparsers(dest='command') - subparsers.add_parser('run') - # No error here - ret = parser.parse_args(()) - self.assertIsNone(ret.command) - - def test_optional_subparsers(self): - parser = ErrorRaisingArgumentParser() - subparsers = parser.add_subparsers(dest='command', required=False) - subparsers.add_parser('run') - # No error here - ret = parser.parse_args(()) - self.assertIsNone(ret.command) - - def test_help(self): - self.assertEqual(self.parser.format_usage(), - 'usage: PROG [-h] [--foo] bar {1,2,3} ...\n') - self.assertEqual(self.parser.format_help(), textwrap.dedent('''\ - usage: PROG [-h] [--foo] bar {1,2,3} ... - - main description - - positional arguments: - bar bar help - {1,2,3} command help - - optional arguments: - -h, --help show this help message and exit - --foo foo help - ''')) - - def test_help_extra_prefix_chars(self): - # Make sure - is still used for help if it is a non-first prefix char - parser = self._get_parser(prefix_chars='+:-') - self.assertEqual(parser.format_usage(), - 'usage: PROG [-h] [++foo] bar {1,2,3} ...\n') - self.assertEqual(parser.format_help(), textwrap.dedent('''\ - usage: PROG [-h] [++foo] bar {1,2,3} ... - - main description - - positional arguments: - bar bar help - {1,2,3} command help - - optional arguments: - -h, --help show this help message and exit - ++foo foo help - ''')) - - def test_help_non_breaking_spaces(self): - parser = ErrorRaisingArgumentParser( - prog='PROG', description='main description') - parser.add_argument( - "--non-breaking", action='store_false', - help='help message containing non-breaking spaces shall not ' - 'wrap\N{NO-BREAK SPACE}at non-breaking spaces') - self.assertEqual(parser.format_help(), textwrap.dedent('''\ - usage: PROG [-h] [--non-breaking] - - main description - - optional arguments: - -h, --help show this help message and exit - --non-breaking help message containing non-breaking spaces shall not - wrap\N{NO-BREAK SPACE}at non-breaking spaces - ''')) - - def test_help_alternate_prefix_chars(self): - parser = self._get_parser(prefix_chars='+:/') - self.assertEqual(parser.format_usage(), - 'usage: PROG [+h] [++foo] bar {1,2,3} ...\n') - self.assertEqual(parser.format_help(), textwrap.dedent('''\ - usage: PROG [+h] [++foo] bar {1,2,3} ... - - main description - - positional arguments: - bar bar help - {1,2,3} command help - - optional arguments: - +h, ++help show this help message and exit - ++foo foo help - ''')) - - def test_parser_command_help(self): - self.assertEqual(self.command_help_parser.format_usage(), - 'usage: PROG [-h] [--foo] bar {1,2,3} ...\n') - self.assertEqual(self.command_help_parser.format_help(), - textwrap.dedent('''\ - usage: PROG [-h] [--foo] bar {1,2,3} ... - - main description - - positional arguments: - bar bar help - {1,2,3} command help - 1 1 help - 2 2 help - 3 3 help - - optional arguments: - -h, --help show this help message and exit - --foo foo help - ''')) - - def test_subparser_title_help(self): - parser = ErrorRaisingArgumentParser(prog='PROG', - description='main description') - parser.add_argument('--foo', action='store_true', help='foo help') - parser.add_argument('bar', help='bar help') - subparsers = parser.add_subparsers(title='subcommands', - description='command help', - help='additional text') - parser1 = subparsers.add_parser('1') - parser2 = subparsers.add_parser('2') - self.assertEqual(parser.format_usage(), - 'usage: PROG [-h] [--foo] bar {1,2} ...\n') - self.assertEqual(parser.format_help(), textwrap.dedent('''\ - usage: PROG [-h] [--foo] bar {1,2} ... - - main description - - positional arguments: - bar bar help - - optional arguments: - -h, --help show this help message and exit - --foo foo help - - subcommands: - command help - - {1,2} additional text - ''')) - - def _test_subparser_help(self, args_str, expected_help): - with self.assertRaises(ArgumentParserError) as cm: - self.parser.parse_args(args_str.split()) - self.assertEqual(expected_help, cm.exception.stdout) - - def test_subparser1_help(self): - self._test_subparser_help('5.0 1 -h', textwrap.dedent('''\ - usage: PROG bar 1 [-h] [-w W] {a,b,c} - - 1 description - - positional arguments: - {a,b,c} x help - - optional arguments: - -h, --help show this help message and exit - -w W w help - ''')) - - def test_subparser2_help(self): - self._test_subparser_help('5.0 2 -h', textwrap.dedent('''\ - usage: PROG bar 2 [-h] [-y {1,2,3}] [z [z ...]] - - 2 description - - positional arguments: - z z help - - optional arguments: - -h, --help show this help message and exit - -y {1,2,3} y help - ''')) - - def test_alias_invocation(self): - parser = self._get_parser(aliases=True) - self.assertEqual( - parser.parse_known_args('0.5 1alias1 b'.split()), - (NS(foo=False, bar=0.5, w=None, x='b'), []), - ) - self.assertEqual( - parser.parse_known_args('0.5 1alias2 b'.split()), - (NS(foo=False, bar=0.5, w=None, x='b'), []), - ) - - def test_error_alias_invocation(self): - parser = self._get_parser(aliases=True) - self.assertArgumentParserError(parser.parse_args, - '0.5 1alias3 b'.split()) - - def test_alias_help(self): - parser = self._get_parser(aliases=True, subparser_help=True) - self.maxDiff = None - self.assertEqual(parser.format_help(), textwrap.dedent("""\ - usage: PROG [-h] [--foo] bar COMMAND ... - - main description - - positional arguments: - bar bar help - - optional arguments: - -h, --help show this help message and exit - --foo foo help - - commands: - COMMAND - 1 (1alias1, 1alias2) - 1 help - 2 2 help - 3 3 help - """)) - - # ============ - # Groups tests - # ============ - - class TestPositionalsGroups(TestCase): - """Tests that order of group positionals matches construction order""" - - def test_nongroup_first(self): - parser = ErrorRaisingArgumentParser() - parser.add_argument('foo') - group = parser.add_argument_group('g') - group.add_argument('bar') - parser.add_argument('baz') - expected = NS(foo='1', bar='2', baz='3') - result = parser.parse_args('1 2 3'.split()) - self.assertEqual(expected, result) - - def test_group_first(self): - parser = ErrorRaisingArgumentParser() - group = parser.add_argument_group('xxx') - group.add_argument('foo') - parser.add_argument('bar') - parser.add_argument('baz') - expected = NS(foo='1', bar='2', baz='3') - result = parser.parse_args('1 2 3'.split()) - self.assertEqual(expected, result) - - def test_interleaved_groups(self): - parser = ErrorRaisingArgumentParser() - group = parser.add_argument_group('xxx') - parser.add_argument('foo') - group.add_argument('bar') - parser.add_argument('baz') - group = parser.add_argument_group('yyy') - group.add_argument('frell') - expected = NS(foo='1', bar='2', baz='3', frell='4') - result = parser.parse_args('1 2 3 4'.split()) - self.assertEqual(expected, result) - - # =================== - # Parent parser tests - # =================== - - class TestParentParsers(TestCase): - """Tests that parsers can be created with parent parsers""" - - def assertArgumentParserError(self, *args, **kwargs): - self.assertRaises(ArgumentParserError, *args, **kwargs) - - def setUp(self): - super().setUp() - self.wxyz_parent = ErrorRaisingArgumentParser(add_help=False) - self.wxyz_parent.add_argument('--w') - x_group = self.wxyz_parent.add_argument_group('x') - x_group.add_argument('-y') - self.wxyz_parent.add_argument('z') - - self.abcd_parent = ErrorRaisingArgumentParser(add_help=False) - self.abcd_parent.add_argument('a') - self.abcd_parent.add_argument('-b') - c_group = self.abcd_parent.add_argument_group('c') - c_group.add_argument('--d') - - self.w_parent = ErrorRaisingArgumentParser(add_help=False) - self.w_parent.add_argument('--w') - - self.z_parent = ErrorRaisingArgumentParser(add_help=False) - self.z_parent.add_argument('z') - - # parents with mutually exclusive groups - self.ab_mutex_parent = ErrorRaisingArgumentParser(add_help=False) - group = self.ab_mutex_parent.add_mutually_exclusive_group() - group.add_argument('-a', action='store_true') - group.add_argument('-b', action='store_true') - - self.main_program = os.path.basename(sys.argv[0]) - - def test_single_parent(self): - parser = ErrorRaisingArgumentParser(parents=[self.wxyz_parent]) - self.assertEqual(parser.parse_args('-y 1 2 --w 3'.split()), - NS(w='3', y='1', z='2')) - - def test_single_parent_mutex(self): - self._test_mutex_ab(self.ab_mutex_parent.parse_args) - parser = ErrorRaisingArgumentParser(parents=[self.ab_mutex_parent]) - self._test_mutex_ab(parser.parse_args) - - def test_single_granparent_mutex(self): - parents = [self.ab_mutex_parent] - parser = ErrorRaisingArgumentParser(add_help=False, parents=parents) - parser = ErrorRaisingArgumentParser(parents=[parser]) - self._test_mutex_ab(parser.parse_args) - - def _test_mutex_ab(self, parse_args): - self.assertEqual(parse_args([]), NS(a=False, b=False)) - self.assertEqual(parse_args(['-a']), NS(a=True, b=False)) - self.assertEqual(parse_args(['-b']), NS(a=False, b=True)) - self.assertArgumentParserError(parse_args, ['-a', '-b']) - self.assertArgumentParserError(parse_args, ['-b', '-a']) - self.assertArgumentParserError(parse_args, ['-c']) - self.assertArgumentParserError(parse_args, ['-a', '-c']) - self.assertArgumentParserError(parse_args, ['-b', '-c']) - - def test_multiple_parents(self): - parents = [self.abcd_parent, self.wxyz_parent] - parser = ErrorRaisingArgumentParser(parents=parents) - self.assertEqual(parser.parse_args('--d 1 --w 2 3 4'.split()), - NS(a='3', b=None, d='1', w='2', y=None, z='4')) - - def test_multiple_parents_mutex(self): - parents = [self.ab_mutex_parent, self.wxyz_parent] - parser = ErrorRaisingArgumentParser(parents=parents) - self.assertEqual(parser.parse_args('-a --w 2 3'.split()), - NS(a=True, b=False, w='2', y=None, z='3')) - self.assertArgumentParserError( - parser.parse_args, '-a --w 2 3 -b'.split()) - self.assertArgumentParserError( - parser.parse_args, '-a -b --w 2 3'.split()) - - def test_conflicting_parents(self): - self.assertRaises( - argparse.ArgumentError, - argparse.ArgumentParser, - parents=[self.w_parent, self.wxyz_parent]) - - def test_conflicting_parents_mutex(self): - self.assertRaises( - argparse.ArgumentError, - argparse.ArgumentParser, - parents=[self.abcd_parent, self.ab_mutex_parent]) - - def test_same_argument_name_parents(self): - parents = [self.wxyz_parent, self.z_parent] - parser = ErrorRaisingArgumentParser(parents=parents) - self.assertEqual(parser.parse_args('1 2'.split()), - NS(w=None, y=None, z='2')) - - def test_subparser_parents(self): - parser = ErrorRaisingArgumentParser() - subparsers = parser.add_subparsers() - abcde_parser = subparsers.add_parser('bar', parents=[self.abcd_parent]) - abcde_parser.add_argument('e') - self.assertEqual(parser.parse_args('bar -b 1 --d 2 3 4'.split()), - NS(a='3', b='1', d='2', e='4')) - - def test_subparser_parents_mutex(self): - parser = ErrorRaisingArgumentParser() - subparsers = parser.add_subparsers() - parents = [self.ab_mutex_parent] - abc_parser = subparsers.add_parser('foo', parents=parents) - c_group = abc_parser.add_argument_group('c_group') - c_group.add_argument('c') - parents = [self.wxyz_parent, self.ab_mutex_parent] - wxyzabe_parser = subparsers.add_parser('bar', parents=parents) - wxyzabe_parser.add_argument('e') - self.assertEqual(parser.parse_args('foo -a 4'.split()), - NS(a=True, b=False, c='4')) - self.assertEqual(parser.parse_args('bar -b --w 2 3 4'.split()), - NS(a=False, b=True, w='2', y=None, z='3', e='4')) - self.assertArgumentParserError( - parser.parse_args, 'foo -a -b 4'.split()) - self.assertArgumentParserError( - parser.parse_args, 'bar -b -a 4'.split()) - - def test_parent_help(self): - parents = [self.abcd_parent, self.wxyz_parent] - parser = ErrorRaisingArgumentParser(parents=parents) - parser_help = parser.format_help() - progname = self.main_program - self.assertEqual(parser_help, textwrap.dedent('''\ - usage: {}{}[-h] [-b B] [--d D] [--w W] [-y Y] a z - - positional arguments: - a - z - - optional arguments: - -h, --help show this help message and exit - -b B - --w W - - c: - --d D - - x: - -y Y - '''.format(progname, ' ' if progname else '' ))) - - def test_groups_parents(self): - parent = ErrorRaisingArgumentParser(add_help=False) - g = parent.add_argument_group(title='g', description='gd') - g.add_argument('-w') - g.add_argument('-x') - m = parent.add_mutually_exclusive_group() - m.add_argument('-y') - m.add_argument('-z') - parser = ErrorRaisingArgumentParser(parents=[parent]) - - self.assertRaises(ArgumentParserError, parser.parse_args, - ['-y', 'Y', '-z', 'Z']) - - parser_help = parser.format_help() - progname = self.main_program - self.assertEqual(parser_help, textwrap.dedent('''\ - usage: {}{}[-h] [-w W] [-x X] [-y Y | -z Z] - - optional arguments: - -h, --help show this help message and exit - -y Y - -z Z - - g: - gd - - -w W - -x X - '''.format(progname, ' ' if progname else '' ))) - - # ============================== - # Mutually exclusive group tests - # ============================== - - class TestMutuallyExclusiveGroupErrors(TestCase): - - def test_invalid_add_argument_group(self): - parser = ErrorRaisingArgumentParser() - raises = self.assertRaises - raises(TypeError, parser.add_mutually_exclusive_group, title='foo') - - def test_invalid_add_argument(self): - parser = ErrorRaisingArgumentParser() - group = parser.add_mutually_exclusive_group() - add_argument = group.add_argument - raises = self.assertRaises - raises(ValueError, add_argument, '--foo', required=True) - raises(ValueError, add_argument, 'bar') - raises(ValueError, add_argument, 'bar', nargs='+') - raises(ValueError, add_argument, 'bar', nargs=1) - raises(ValueError, add_argument, 'bar', nargs=argparse.PARSER) - - def test_help(self): - parser = ErrorRaisingArgumentParser(prog='PROG') - group1 = parser.add_mutually_exclusive_group() - group1.add_argument('--foo', action='store_true') - group1.add_argument('--bar', action='store_false') - group2 = parser.add_mutually_exclusive_group() - group2.add_argument('--soup', action='store_true') - group2.add_argument('--nuts', action='store_false') - expected = '''\ - usage: PROG [-h] [--foo | --bar] [--soup | --nuts] - - optional arguments: - -h, --help show this help message and exit - --foo - --bar - --soup - --nuts - ''' - self.assertEqual(parser.format_help(), textwrap.dedent(expected)) - - class MEMixin(object): - - def test_failures_when_not_required(self): - parse_args = self.get_parser(required=False).parse_args - error = ArgumentParserError - for args_string in self.failures: - self.assertRaises(error, parse_args, args_string.split()) - - def test_failures_when_required(self): - parse_args = self.get_parser(required=True).parse_args - error = ArgumentParserError - for args_string in self.failures + ['']: - self.assertRaises(error, parse_args, args_string.split()) - - def test_successes_when_not_required(self): - parse_args = self.get_parser(required=False).parse_args - successes = self.successes + self.successes_when_not_required - for args_string, expected_ns in successes: - actual_ns = parse_args(args_string.split()) - self.assertEqual(actual_ns, expected_ns) - - def test_successes_when_required(self): - parse_args = self.get_parser(required=True).parse_args - for args_string, expected_ns in self.successes: - actual_ns = parse_args(args_string.split()) - self.assertEqual(actual_ns, expected_ns) - - def test_usage_when_not_required(self): - format_usage = self.get_parser(required=False).format_usage - expected_usage = self.usage_when_not_required - self.assertEqual(format_usage(), textwrap.dedent(expected_usage)) - - def test_usage_when_required(self): - format_usage = self.get_parser(required=True).format_usage - expected_usage = self.usage_when_required - self.assertEqual(format_usage(), textwrap.dedent(expected_usage)) - - def test_help_when_not_required(self): - format_help = self.get_parser(required=False).format_help - help = self.usage_when_not_required + self.help - self.assertEqual(format_help(), textwrap.dedent(help)) - - def test_help_when_required(self): - format_help = self.get_parser(required=True).format_help - help = self.usage_when_required + self.help - self.assertEqual(format_help(), textwrap.dedent(help)) - - - class TestMutuallyExclusiveSimple(MEMixin, TestCase): - - def get_parser(self, required=None): - parser = ErrorRaisingArgumentParser(prog='PROG') - group = parser.add_mutually_exclusive_group(required=required) - group.add_argument('--bar', help='bar help') - group.add_argument('--baz', nargs='?', const='Z', help='baz help') - return parser - - failures = ['--bar X --baz Y', '--bar X --baz'] - successes = [ - ('--bar X', NS(bar='X', baz=None)), - ('--bar X --bar Z', NS(bar='Z', baz=None)), - ('--baz Y', NS(bar=None, baz='Y')), - ('--baz', NS(bar=None, baz='Z')), - ] - successes_when_not_required = [ - ('', NS(bar=None, baz=None)), - ] - - usage_when_not_required = '''\ - usage: PROG [-h] [--bar BAR | --baz [BAZ]] - ''' - usage_when_required = '''\ - usage: PROG [-h] (--bar BAR | --baz [BAZ]) - ''' - help = '''\ - - optional arguments: - -h, --help show this help message and exit - --bar BAR bar help - --baz [BAZ] baz help - ''' - - - class TestMutuallyExclusiveLong(MEMixin, TestCase): - - def get_parser(self, required=None): - parser = ErrorRaisingArgumentParser(prog='PROG') - parser.add_argument('--abcde', help='abcde help') - parser.add_argument('--fghij', help='fghij help') - group = parser.add_mutually_exclusive_group(required=required) - group.add_argument('--klmno', help='klmno help') - group.add_argument('--pqrst', help='pqrst help') - return parser - - failures = ['--klmno X --pqrst Y'] - successes = [ - ('--klmno X', NS(abcde=None, fghij=None, klmno='X', pqrst=None)), - ('--abcde Y --klmno X', - NS(abcde='Y', fghij=None, klmno='X', pqrst=None)), - ('--pqrst X', NS(abcde=None, fghij=None, klmno=None, pqrst='X')), - ('--pqrst X --fghij Y', - NS(abcde=None, fghij='Y', klmno=None, pqrst='X')), - ] - successes_when_not_required = [ - ('', NS(abcde=None, fghij=None, klmno=None, pqrst=None)), - ] - - usage_when_not_required = '''\ - usage: PROG [-h] [--abcde ABCDE] [--fghij FGHIJ] - [--klmno KLMNO | --pqrst PQRST] - ''' - usage_when_required = '''\ - usage: PROG [-h] [--abcde ABCDE] [--fghij FGHIJ] - (--klmno KLMNO | --pqrst PQRST) - ''' - help = '''\ - - optional arguments: - -h, --help show this help message and exit - --abcde ABCDE abcde help - --fghij FGHIJ fghij help - --klmno KLMNO klmno help - --pqrst PQRST pqrst help - ''' - - - class TestMutuallyExclusiveFirstSuppressed(MEMixin, TestCase): - - def get_parser(self, required): - parser = ErrorRaisingArgumentParser(prog='PROG') - group = parser.add_mutually_exclusive_group(required=required) - group.add_argument('-x', help=argparse.SUPPRESS) - group.add_argument('-y', action='store_false', help='y help') - return parser - - failures = ['-x X -y'] - successes = [ - ('-x X', NS(x='X', y=True)), - ('-x X -x Y', NS(x='Y', y=True)), - ('-y', NS(x=None, y=False)), - ] - successes_when_not_required = [ - ('', NS(x=None, y=True)), - ] - - usage_when_not_required = '''\ - usage: PROG [-h] [-y] - ''' - usage_when_required = '''\ - usage: PROG [-h] -y - ''' - help = '''\ - - optional arguments: - -h, --help show this help message and exit - -y y help - ''' - - - class TestMutuallyExclusiveManySuppressed(MEMixin, TestCase): - - def get_parser(self, required): - parser = ErrorRaisingArgumentParser(prog='PROG') - group = parser.add_mutually_exclusive_group(required=required) - add = group.add_argument - add('--spam', action='store_true', help=argparse.SUPPRESS) - add('--badger', action='store_false', help=argparse.SUPPRESS) - add('--bladder', help=argparse.SUPPRESS) - return parser - - failures = [ - '--spam --badger', - '--badger --bladder B', - '--bladder B --spam', - ] - successes = [ - ('--spam', NS(spam=True, badger=True, bladder=None)), - ('--badger', NS(spam=False, badger=False, bladder=None)), - ('--bladder B', NS(spam=False, badger=True, bladder='B')), - ('--spam --spam', NS(spam=True, badger=True, bladder=None)), - ] - successes_when_not_required = [ - ('', NS(spam=False, badger=True, bladder=None)), - ] - - usage_when_required = usage_when_not_required = '''\ - usage: PROG [-h] - ''' - help = '''\ - - optional arguments: - -h, --help show this help message and exit - ''' - - - class TestMutuallyExclusiveOptionalAndPositional(MEMixin, TestCase): - - def get_parser(self, required): - parser = ErrorRaisingArgumentParser(prog='PROG') - group = parser.add_mutually_exclusive_group(required=required) - group.add_argument('--foo', action='store_true', help='FOO') - group.add_argument('--spam', help='SPAM') - group.add_argument('badger', nargs='*', default='X', help='BADGER') - return parser - - failures = [ - '--foo --spam S', - '--spam S X', - 'X --foo', - 'X Y Z --spam S', - '--foo X Y', - ] - successes = [ - ('--foo', NS(foo=True, spam=None, badger='X')), - ('--spam S', NS(foo=False, spam='S', badger='X')), - ('X', NS(foo=False, spam=None, badger=['X'])), - ('X Y Z', NS(foo=False, spam=None, badger=['X', 'Y', 'Z'])), - ] - successes_when_not_required = [ - ('', NS(foo=False, spam=None, badger='X')), - ] - - usage_when_not_required = '''\ - usage: PROG [-h] [--foo | --spam SPAM | badger [badger ...]] - ''' - usage_when_required = '''\ - usage: PROG [-h] (--foo | --spam SPAM | badger [badger ...]) - ''' - help = '''\ - - positional arguments: - badger BADGER - - optional arguments: - -h, --help show this help message and exit - --foo FOO - --spam SPAM SPAM - ''' - - - class TestMutuallyExclusiveOptionalsMixed(MEMixin, TestCase): - - def get_parser(self, required): - parser = ErrorRaisingArgumentParser(prog='PROG') - parser.add_argument('-x', action='store_true', help='x help') - group = parser.add_mutually_exclusive_group(required=required) - group.add_argument('-a', action='store_true', help='a help') - group.add_argument('-b', action='store_true', help='b help') - parser.add_argument('-y', action='store_true', help='y help') - group.add_argument('-c', action='store_true', help='c help') - return parser - - failures = ['-a -b', '-b -c', '-a -c', '-a -b -c'] - successes = [ - ('-a', NS(a=True, b=False, c=False, x=False, y=False)), - ('-b', NS(a=False, b=True, c=False, x=False, y=False)), - ('-c', NS(a=False, b=False, c=True, x=False, y=False)), - ('-a -x', NS(a=True, b=False, c=False, x=True, y=False)), - ('-y -b', NS(a=False, b=True, c=False, x=False, y=True)), - ('-x -y -c', NS(a=False, b=False, c=True, x=True, y=True)), - ] - successes_when_not_required = [ - ('', NS(a=False, b=False, c=False, x=False, y=False)), - ('-x', NS(a=False, b=False, c=False, x=True, y=False)), - ('-y', NS(a=False, b=False, c=False, x=False, y=True)), - ] - - usage_when_required = usage_when_not_required = '''\ - usage: PROG [-h] [-x] [-a] [-b] [-y] [-c] - ''' - help = '''\ - - optional arguments: - -h, --help show this help message and exit - -x x help - -a a help - -b b help - -y y help - -c c help - ''' - - - class TestMutuallyExclusiveInGroup(MEMixin, TestCase): - - def get_parser(self, required=None): - parser = ErrorRaisingArgumentParser(prog='PROG') - titled_group = parser.add_argument_group( - title='Titled group', description='Group description') - mutex_group = \ - titled_group.add_mutually_exclusive_group(required=required) - mutex_group.add_argument('--bar', help='bar help') - mutex_group.add_argument('--baz', help='baz help') - return parser - - failures = ['--bar X --baz Y', '--baz X --bar Y'] - successes = [ - ('--bar X', NS(bar='X', baz=None)), - ('--baz Y', NS(bar=None, baz='Y')), - ] - successes_when_not_required = [ - ('', NS(bar=None, baz=None)), - ] - - usage_when_not_required = '''\ - usage: PROG [-h] [--bar BAR | --baz BAZ] - ''' - usage_when_required = '''\ - usage: PROG [-h] (--bar BAR | --baz BAZ) - ''' - help = '''\ - - optional arguments: - -h, --help show this help message and exit - - Titled group: - Group description - - --bar BAR bar help - --baz BAZ baz help - ''' - - - class TestMutuallyExclusiveOptionalsAndPositionalsMixed(MEMixin, TestCase): - - def get_parser(self, required): - parser = ErrorRaisingArgumentParser(prog='PROG') - parser.add_argument('x', help='x help') - parser.add_argument('-y', action='store_true', help='y help') - group = parser.add_mutually_exclusive_group(required=required) - group.add_argument('a', nargs='?', help='a help') - group.add_argument('-b', action='store_true', help='b help') - group.add_argument('-c', action='store_true', help='c help') - return parser - - failures = ['X A -b', '-b -c', '-c X A'] - successes = [ - ('X A', NS(a='A', b=False, c=False, x='X', y=False)), - ('X -b', NS(a=None, b=True, c=False, x='X', y=False)), - ('X -c', NS(a=None, b=False, c=True, x='X', y=False)), - ('X A -y', NS(a='A', b=False, c=False, x='X', y=True)), - ('X -y -b', NS(a=None, b=True, c=False, x='X', y=True)), - ] - successes_when_not_required = [ - ('X', NS(a=None, b=False, c=False, x='X', y=False)), - ('X -y', NS(a=None, b=False, c=False, x='X', y=True)), - ] - - usage_when_required = usage_when_not_required = '''\ - usage: PROG [-h] [-y] [-b] [-c] x [a] - ''' - help = '''\ - - positional arguments: - x x help - a a help - - optional arguments: - -h, --help show this help message and exit - -y y help - -b b help - -c c help - ''' - - class TestMutuallyExclusiveNested(MEMixin, TestCase): - - def get_parser(self, required): - parser = ErrorRaisingArgumentParser(prog='PROG') - group = parser.add_mutually_exclusive_group(required=required) - group.add_argument('-a') - group.add_argument('-b') - group2 = group.add_mutually_exclusive_group(required=required) - group2.add_argument('-c') - group2.add_argument('-d') - group3 = group2.add_mutually_exclusive_group(required=required) - group3.add_argument('-e') - group3.add_argument('-f') - return parser - - usage_when_not_required = '''\ - usage: PROG [-h] [-a A | -b B | [-c C | -d D | [-e E | -f F]]] - ''' - usage_when_required = '''\ - usage: PROG [-h] (-a A | -b B | (-c C | -d D | (-e E | -f F))) - ''' - - help = '''\ - - optional arguments: - -h, --help show this help message and exit - -a A - -b B - -c C - -d D - -e E - -f F - ''' - - # We are only interested in testing the behavior of format_usage(). - test_failures_when_not_required = None - test_failures_when_required = None - test_successes_when_not_required = None - test_successes_when_required = None - - # ================================================= - # Mutually exclusive group in parent parser tests - # ================================================= - - class MEPBase(object): - - def get_parser(self, required=None): - parent = super(MEPBase, self).get_parser(required=required) - parser = ErrorRaisingArgumentParser( - prog=parent.prog, add_help=False, parents=[parent]) - return parser - - - class TestMutuallyExclusiveGroupErrorsParent( - MEPBase, TestMutuallyExclusiveGroupErrors): - pass - - - class TestMutuallyExclusiveSimpleParent( - MEPBase, TestMutuallyExclusiveSimple): - pass - - - class TestMutuallyExclusiveLongParent( - MEPBase, TestMutuallyExclusiveLong): - pass - - - class TestMutuallyExclusiveFirstSuppressedParent( - MEPBase, TestMutuallyExclusiveFirstSuppressed): - pass - - - class TestMutuallyExclusiveManySuppressedParent( - MEPBase, TestMutuallyExclusiveManySuppressed): - pass - - - class TestMutuallyExclusiveOptionalAndPositionalParent( - MEPBase, TestMutuallyExclusiveOptionalAndPositional): - pass - - - class TestMutuallyExclusiveOptionalsMixedParent( - MEPBase, TestMutuallyExclusiveOptionalsMixed): - pass - - - class TestMutuallyExclusiveOptionalsAndPositionalsMixedParent( - MEPBase, TestMutuallyExclusiveOptionalsAndPositionalsMixed): - pass - - # ================= - # Set default tests - # ================= - - class TestSetDefaults(TestCase): - - def test_set_defaults_no_args(self): - parser = ErrorRaisingArgumentParser() - parser.set_defaults(x='foo') - parser.set_defaults(y='bar', z=1) - self.assertEqual(NS(x='foo', y='bar', z=1), - parser.parse_args([])) - self.assertEqual(NS(x='foo', y='bar', z=1), - parser.parse_args([], NS())) - self.assertEqual(NS(x='baz', y='bar', z=1), - parser.parse_args([], NS(x='baz'))) - self.assertEqual(NS(x='baz', y='bar', z=2), - parser.parse_args([], NS(x='baz', z=2))) - - def test_set_defaults_with_args(self): - parser = ErrorRaisingArgumentParser() - parser.set_defaults(x='foo', y='bar') - parser.add_argument('-x', default='xfoox') - self.assertEqual(NS(x='xfoox', y='bar'), - parser.parse_args([])) - self.assertEqual(NS(x='xfoox', y='bar'), - parser.parse_args([], NS())) - self.assertEqual(NS(x='baz', y='bar'), - parser.parse_args([], NS(x='baz'))) - self.assertEqual(NS(x='1', y='bar'), - parser.parse_args('-x 1'.split())) - self.assertEqual(NS(x='1', y='bar'), - parser.parse_args('-x 1'.split(), NS())) - self.assertEqual(NS(x='1', y='bar'), - parser.parse_args('-x 1'.split(), NS(x='baz'))) - - def test_set_defaults_subparsers(self): - parser = ErrorRaisingArgumentParser() - parser.set_defaults(x='foo') - subparsers = parser.add_subparsers() - parser_a = subparsers.add_parser('a') - parser_a.set_defaults(y='bar') - self.assertEqual(NS(x='foo', y='bar'), - parser.parse_args('a'.split())) - - def test_set_defaults_parents(self): - parent = ErrorRaisingArgumentParser(add_help=False) - parent.set_defaults(x='foo') - parser = ErrorRaisingArgumentParser(parents=[parent]) - self.assertEqual(NS(x='foo'), parser.parse_args([])) - - def test_set_defaults_on_parent_and_subparser(self): - parser = argparse.ArgumentParser() - xparser = parser.add_subparsers().add_parser('X') - parser.set_defaults(foo=1) - xparser.set_defaults(foo=2) - self.assertEqual(NS(foo=2), parser.parse_args(['X'])) - - def test_set_defaults_same_as_add_argument(self): - parser = ErrorRaisingArgumentParser() - parser.set_defaults(w='W', x='X', y='Y', z='Z') - parser.add_argument('-w') - parser.add_argument('-x', default='XX') - parser.add_argument('y', nargs='?') - parser.add_argument('z', nargs='?', default='ZZ') - - # defaults set previously - self.assertEqual(NS(w='W', x='XX', y='Y', z='ZZ'), - parser.parse_args([])) - - # reset defaults - parser.set_defaults(w='WW', x='X', y='YY', z='Z') - self.assertEqual(NS(w='WW', x='X', y='YY', z='Z'), - parser.parse_args([])) - - def test_set_defaults_same_as_add_argument_group(self): - parser = ErrorRaisingArgumentParser() - parser.set_defaults(w='W', x='X', y='Y', z='Z') - group = parser.add_argument_group('foo') - group.add_argument('-w') - group.add_argument('-x', default='XX') - group.add_argument('y', nargs='?') - group.add_argument('z', nargs='?', default='ZZ') - - - # defaults set previously - self.assertEqual(NS(w='W', x='XX', y='Y', z='ZZ'), - parser.parse_args([])) - - # reset defaults - parser.set_defaults(w='WW', x='X', y='YY', z='Z') - self.assertEqual(NS(w='WW', x='X', y='YY', z='Z'), - parser.parse_args([])) - - # ================= - # Get default tests - # ================= - - class TestGetDefault(TestCase): - - def test_get_default(self): - parser = ErrorRaisingArgumentParser() - self.assertIsNone(parser.get_default("foo")) - self.assertIsNone(parser.get_default("bar")) - - parser.add_argument("--foo") - self.assertIsNone(parser.get_default("foo")) - self.assertIsNone(parser.get_default("bar")) - - parser.add_argument("--bar", type=int, default=42) - self.assertIsNone(parser.get_default("foo")) - self.assertEqual(42, parser.get_default("bar")) - - parser.set_defaults(foo="badger") - self.assertEqual("badger", parser.get_default("foo")) - self.assertEqual(42, parser.get_default("bar")) - - # ========================== - # Namespace 'contains' tests - # ========================== - - class TestNamespaceContainsSimple(TestCase): - - def test_empty(self): - ns = argparse.Namespace() - self.assertNotIn('', ns) - self.assertNotIn('x', ns) - - def test_non_empty(self): - ns = argparse.Namespace(x=1, y=2) - self.assertNotIn('', ns) - self.assertIn('x', ns) - self.assertIn('y', ns) - self.assertNotIn('xx', ns) - self.assertNotIn('z', ns) - - # ===================== - # Help formatting tests - # ===================== - - class TestHelpFormattingMetaclass(type): - - def __init__(cls, name, bases, bodydict): - if name == 'HelpTestCase': - return - - class AddTests(object): - - def __init__(self, test_class, func_suffix, std_name): - self.func_suffix = func_suffix - self.std_name = std_name - - for test_func in [self.test_format, - self.test_print, - self.test_print_file]: - test_name = '%s_%s' % (test_func.__name__, func_suffix) - - def test_wrapper(self, test_func=test_func): - test_func(self) - try: - test_wrapper.__name__ = test_name - except TypeError: - pass - setattr(test_class, test_name, test_wrapper) - - def _get_parser(self, tester): - parser = argparse.ArgumentParser( - *tester.parser_signature.args, - **tester.parser_signature.kwargs) - for argument_sig in getattr(tester, 'argument_signatures', []): - parser.add_argument(*argument_sig.args, - **argument_sig.kwargs) - group_sigs = getattr(tester, 'argument_group_signatures', []) - for group_sig, argument_sigs in group_sigs: - group = parser.add_argument_group(*group_sig.args, - **group_sig.kwargs) - for argument_sig in argument_sigs: - group.add_argument(*argument_sig.args, - **argument_sig.kwargs) - subparsers_sigs = getattr(tester, 'subparsers_signatures', []) - if subparsers_sigs: - subparsers = parser.add_subparsers() - for subparser_sig in subparsers_sigs: - subparsers.add_parser(*subparser_sig.args, - **subparser_sig.kwargs) - return parser - - def _test(self, tester, parser_text): - expected_text = getattr(tester, self.func_suffix) - expected_text = textwrap.dedent(expected_text) - tester.assertEqual(expected_text, parser_text) - - def test_format(self, tester): - parser = self._get_parser(tester) - format = getattr(parser, 'format_%s' % self.func_suffix) - self._test(tester, format()) - - def test_print(self, tester): - parser = self._get_parser(tester) - print_ = getattr(parser, 'print_%s' % self.func_suffix) - old_stream = getattr(sys, self.std_name) - setattr(sys, self.std_name, StdIOBuffer()) - try: - print_() - parser_text = getattr(sys, self.std_name).getvalue() - finally: - setattr(sys, self.std_name, old_stream) - self._test(tester, parser_text) - - def test_print_file(self, tester): - parser = self._get_parser(tester) - print_ = getattr(parser, 'print_%s' % self.func_suffix) - sfile = StdIOBuffer() - print_(sfile) - parser_text = sfile.getvalue() - self._test(tester, parser_text) - - # add tests for {format,print}_{usage,help} - for func_suffix, std_name in [('usage', 'stdout'), - ('help', 'stdout')]: - AddTests(cls, func_suffix, std_name) - - bases = TestCase, - HelpTestCase = TestHelpFormattingMetaclass('HelpTestCase', bases, {}) - - - class TestHelpBiggerOptionals(HelpTestCase): - """Make sure that argument help aligns when options are longer""" - - parser_signature = Sig(prog='PROG', description='DESCRIPTION', - epilog='EPILOG') - argument_signatures = [ - Sig('-v', '--version', action='version', version='0.1'), - Sig('-x', action='store_true', help='X HELP'), - Sig('--y', help='Y HELP'), - Sig('foo', help='FOO HELP'), - Sig('bar', help='BAR HELP'), - ] - argument_group_signatures = [] - usage = '''\ - usage: PROG [-h] [-v] [-x] [--y Y] foo bar - ''' - help = usage + '''\ - - DESCRIPTION - - positional arguments: - foo FOO HELP - bar BAR HELP - - optional arguments: - -h, --help show this help message and exit - -v, --version show program's version number and exit - -x X HELP - --y Y Y HELP - - EPILOG - ''' - version = '''\ - 0.1 - ''' - - class TestShortColumns(HelpTestCase): - '''Test extremely small number of columns. - - TestCase prevents "COLUMNS" from being too small in the tests themselves, - but we don't want any exceptions thrown in such cases. Only ugly representation. - ''' - def setUp(self): - env = support.EnvironmentVarGuard() - env.set("COLUMNS", '15') - self.addCleanup(env.__exit__) - - parser_signature = TestHelpBiggerOptionals.parser_signature - argument_signatures = TestHelpBiggerOptionals.argument_signatures - argument_group_signatures = TestHelpBiggerOptionals.argument_group_signatures - usage = '''\ - usage: PROG - [-h] - [-v] - [-x] - [--y Y] - foo - bar - ''' - help = usage + '''\ - - DESCRIPTION - - positional arguments: - foo - FOO HELP - bar - BAR HELP - - optional arguments: - -h, --help - show this - help - message and - exit - -v, --version - show - program's - version - number and - exit - -x - X HELP - --y Y - Y HELP - - EPILOG - ''' - version = TestHelpBiggerOptionals.version - - - class TestHelpBiggerOptionalGroups(HelpTestCase): - """Make sure that argument help aligns when options are longer""" - - parser_signature = Sig(prog='PROG', description='DESCRIPTION', - epilog='EPILOG') - argument_signatures = [ - Sig('-v', '--version', action='version', version='0.1'), - Sig('-x', action='store_true', help='X HELP'), - Sig('--y', help='Y HELP'), - Sig('foo', help='FOO HELP'), - Sig('bar', help='BAR HELP'), - ] - argument_group_signatures = [ - (Sig('GROUP TITLE', description='GROUP DESCRIPTION'), [ - Sig('baz', help='BAZ HELP'), - Sig('-z', nargs='+', help='Z HELP')]), - ] - usage = '''\ - usage: PROG [-h] [-v] [-x] [--y Y] [-z Z [Z ...]] foo bar baz - ''' - help = usage + '''\ - - DESCRIPTION - - positional arguments: - foo FOO HELP - bar BAR HELP - - optional arguments: - -h, --help show this help message and exit - -v, --version show program's version number and exit - -x X HELP - --y Y Y HELP - - GROUP TITLE: - GROUP DESCRIPTION - - baz BAZ HELP - -z Z [Z ...] Z HELP - - EPILOG - ''' - version = '''\ - 0.1 - ''' - - - class TestHelpBiggerPositionals(HelpTestCase): - """Make sure that help aligns when arguments are longer""" - - parser_signature = Sig(usage='USAGE', description='DESCRIPTION') - argument_signatures = [ - Sig('-x', action='store_true', help='X HELP'), - Sig('--y', help='Y HELP'), - Sig('ekiekiekifekang', help='EKI HELP'), - Sig('bar', help='BAR HELP'), - ] - argument_group_signatures = [] - usage = '''\ - usage: USAGE - ''' - help = usage + '''\ - - DESCRIPTION - - positional arguments: - ekiekiekifekang EKI HELP - bar BAR HELP - - optional arguments: - -h, --help show this help message and exit - -x X HELP - --y Y Y HELP - ''' - - version = '' - - - class TestHelpReformatting(HelpTestCase): - """Make sure that text after short names starts on the first line""" - - parser_signature = Sig( - prog='PROG', - description=' oddly formatted\n' - 'description\n' - '\n' - 'that is so long that it should go onto multiple ' - 'lines when wrapped') - argument_signatures = [ - Sig('-x', metavar='XX', help='oddly\n' - ' formatted -x help'), - Sig('y', metavar='yyy', help='normal y help'), - ] - argument_group_signatures = [ - (Sig('title', description='\n' - ' oddly formatted group\n' - '\n' - 'description'), - [Sig('-a', action='store_true', - help=' oddly \n' - 'formatted -a help \n' - ' again, so long that it should be wrapped over ' - 'multiple lines')]), - ] - usage = '''\ - usage: PROG [-h] [-x XX] [-a] yyy - ''' - help = usage + '''\ - - oddly formatted description that is so long that it should go onto \ - multiple - lines when wrapped - - positional arguments: - yyy normal y help - - optional arguments: - -h, --help show this help message and exit - -x XX oddly formatted -x help - - title: - oddly formatted group description - - -a oddly formatted -a help again, so long that it should \ - be wrapped - over multiple lines - ''' - version = '' - - - class TestHelpWrappingShortNames(HelpTestCase): - """Make sure that text after short names starts on the first line""" - - parser_signature = Sig(prog='PROG', description= 'D\nD' * 30) - argument_signatures = [ - Sig('-x', metavar='XX', help='XHH HX' * 20), - Sig('y', metavar='yyy', help='YH YH' * 20), - ] - argument_group_signatures = [ - (Sig('ALPHAS'), [ - Sig('-a', action='store_true', help='AHHH HHA' * 10)]), - ] - usage = '''\ - usage: PROG [-h] [-x XX] [-a] yyy - ''' - help = usage + '''\ - - D DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD \ - DD DD DD - DD DD DD DD D - - positional arguments: - yyy YH YHYH YHYH YHYH YHYH YHYH YHYH YHYH YHYH YHYH YHYH \ - YHYH YHYH - YHYH YHYH YHYH YHYH YHYH YHYH YHYH YH - - optional arguments: - -h, --help show this help message and exit - -x XX XHH HXXHH HXXHH HXXHH HXXHH HXXHH HXXHH HXXHH HXXHH \ - HXXHH HXXHH - HXXHH HXXHH HXXHH HXXHH HXXHH HXXHH HXXHH HXXHH HXXHH HX - - ALPHAS: - -a AHHH HHAAHHH HHAAHHH HHAAHHH HHAAHHH HHAAHHH HHAAHHH \ - HHAAHHH - HHAAHHH HHAAHHH HHA - ''' - version = '' - - - class TestHelpWrappingLongNames(HelpTestCase): - """Make sure that text after long names starts on the next line""" - - parser_signature = Sig(usage='USAGE', description= 'D D' * 30) - argument_signatures = [ - Sig('-v', '--version', action='version', version='V V' * 30), - Sig('-x', metavar='X' * 25, help='XH XH' * 20), - Sig('y', metavar='y' * 25, help='YH YH' * 20), - ] - argument_group_signatures = [ - (Sig('ALPHAS'), [ - Sig('-a', metavar='A' * 25, help='AH AH' * 20), - Sig('z', metavar='z' * 25, help='ZH ZH' * 20)]), - ] - usage = '''\ - usage: USAGE - ''' - help = usage + '''\ - - D DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD \ - DD DD DD - DD DD DD DD D - - positional arguments: - yyyyyyyyyyyyyyyyyyyyyyyyy - YH YHYH YHYH YHYH YHYH YHYH YHYH YHYH YHYH \ - YHYH YHYH - YHYH YHYH YHYH YHYH YHYH YHYH YHYH YHYH YHYH YH - - optional arguments: - -h, --help show this help message and exit - -v, --version show program's version number and exit - -x XXXXXXXXXXXXXXXXXXXXXXXXX - XH XHXH XHXH XHXH XHXH XHXH XHXH XHXH XHXH \ - XHXH XHXH - XHXH XHXH XHXH XHXH XHXH XHXH XHXH XHXH XHXH XH - - ALPHAS: - -a AAAAAAAAAAAAAAAAAAAAAAAAA - AH AHAH AHAH AHAH AHAH AHAH AHAH AHAH AHAH \ - AHAH AHAH - AHAH AHAH AHAH AHAH AHAH AHAH AHAH AHAH AHAH AH - zzzzzzzzzzzzzzzzzzzzzzzzz - ZH ZHZH ZHZH ZHZH ZHZH ZHZH ZHZH ZHZH ZHZH \ - ZHZH ZHZH - ZHZH ZHZH ZHZH ZHZH ZHZH ZHZH ZHZH ZHZH ZHZH ZH - ''' - version = '''\ - V VV VV VV VV VV VV VV VV VV VV VV VV VV VV VV VV VV VV VV VV VV VV \ - VV VV VV - VV VV VV VV V - ''' - - - class TestHelpUsage(HelpTestCase): - """Test basic usage messages""" - - parser_signature = Sig(prog='PROG') - argument_signatures = [ - Sig('-w', nargs='+', help='w'), - Sig('-x', nargs='*', help='x'), - Sig('a', help='a'), - Sig('b', help='b', nargs=2), - Sig('c', help='c', nargs='?'), - ] - argument_group_signatures = [ - (Sig('group'), [ - Sig('-y', nargs='?', help='y'), - Sig('-z', nargs=3, help='z'), - Sig('d', help='d', nargs='*'), - Sig('e', help='e', nargs='+'), - ]) - ] - usage = '''\ - usage: PROG [-h] [-w W [W ...]] [-x [X [X ...]]] [-y [Y]] [-z Z Z Z] - a b b [c] [d [d ...]] e [e ...] - ''' - help = usage + '''\ - - positional arguments: - a a - b b - c c - - optional arguments: - -h, --help show this help message and exit - -w W [W ...] w - -x [X [X ...]] x - - group: - -y [Y] y - -z Z Z Z z - d d - e e - ''' - version = '' - - - class TestHelpOnlyUserGroups(HelpTestCase): - """Test basic usage messages""" - - parser_signature = Sig(prog='PROG', add_help=False) - argument_signatures = [] - argument_group_signatures = [ - (Sig('xxxx'), [ - Sig('-x', help='x'), - Sig('a', help='a'), - ]), - (Sig('yyyy'), [ - Sig('b', help='b'), - Sig('-y', help='y'), - ]), - ] - usage = '''\ - usage: PROG [-x X] [-y Y] a b - ''' - help = usage + '''\ - - xxxx: - -x X x - a a - - yyyy: - b b - -y Y y - ''' - version = '' - - - class TestHelpUsageLongProg(HelpTestCase): - """Test usage messages where the prog is long""" - - parser_signature = Sig(prog='P' * 60) - argument_signatures = [ - Sig('-w', metavar='W'), - Sig('-x', metavar='X'), - Sig('a'), - Sig('b'), - ] - argument_group_signatures = [] - usage = '''\ - usage: PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP - [-h] [-w W] [-x X] a b - ''' - help = usage + '''\ - - positional arguments: - a - b - - optional arguments: - -h, --help show this help message and exit - -w W - -x X - ''' - version = '' - - - class TestHelpUsageLongProgOptionsWrap(HelpTestCase): - """Test usage messages where the prog is long and the optionals wrap""" - - parser_signature = Sig(prog='P' * 60) - argument_signatures = [ - Sig('-w', metavar='W' * 25), - Sig('-x', metavar='X' * 25), - Sig('-y', metavar='Y' * 25), - Sig('-z', metavar='Z' * 25), - Sig('a'), - Sig('b'), - ] - argument_group_signatures = [] - usage = '''\ - usage: PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP - [-h] [-w WWWWWWWWWWWWWWWWWWWWWWWWW] \ - [-x XXXXXXXXXXXXXXXXXXXXXXXXX] - [-y YYYYYYYYYYYYYYYYYYYYYYYYY] [-z ZZZZZZZZZZZZZZZZZZZZZZZZZ] - a b - ''' - help = usage + '''\ - - positional arguments: - a - b - - optional arguments: - -h, --help show this help message and exit - -w WWWWWWWWWWWWWWWWWWWWWWWWW - -x XXXXXXXXXXXXXXXXXXXXXXXXX - -y YYYYYYYYYYYYYYYYYYYYYYYYY - -z ZZZZZZZZZZZZZZZZZZZZZZZZZ - ''' - version = '' - - - class TestHelpUsageLongProgPositionalsWrap(HelpTestCase): - """Test usage messages where the prog is long and the positionals wrap""" - - parser_signature = Sig(prog='P' * 60, add_help=False) - argument_signatures = [ - Sig('a' * 25), - Sig('b' * 25), - Sig('c' * 25), - ] - argument_group_signatures = [] - usage = '''\ - usage: PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP - aaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbb - ccccccccccccccccccccccccc - ''' - help = usage + '''\ - - positional arguments: - aaaaaaaaaaaaaaaaaaaaaaaaa - bbbbbbbbbbbbbbbbbbbbbbbbb - ccccccccccccccccccccccccc - ''' - version = '' - - - class TestHelpUsageOptionalsWrap(HelpTestCase): - """Test usage messages where the optionals wrap""" - - parser_signature = Sig(prog='PROG') - argument_signatures = [ - Sig('-w', metavar='W' * 25), - Sig('-x', metavar='X' * 25), - Sig('-y', metavar='Y' * 25), - Sig('-z', metavar='Z' * 25), - Sig('a'), - Sig('b'), - Sig('c'), - ] - argument_group_signatures = [] - usage = '''\ - usage: PROG [-h] [-w WWWWWWWWWWWWWWWWWWWWWWWWW] \ - [-x XXXXXXXXXXXXXXXXXXXXXXXXX] - [-y YYYYYYYYYYYYYYYYYYYYYYYYY] \ - [-z ZZZZZZZZZZZZZZZZZZZZZZZZZ] - a b c - ''' - help = usage + '''\ - - positional arguments: - a - b - c - - optional arguments: - -h, --help show this help message and exit - -w WWWWWWWWWWWWWWWWWWWWWWWWW - -x XXXXXXXXXXXXXXXXXXXXXXXXX - -y YYYYYYYYYYYYYYYYYYYYYYYYY - -z ZZZZZZZZZZZZZZZZZZZZZZZZZ - ''' - version = '' - - - class TestHelpUsagePositionalsWrap(HelpTestCase): - """Test usage messages where the positionals wrap""" - - parser_signature = Sig(prog='PROG') - argument_signatures = [ - Sig('-x'), - Sig('-y'), - Sig('-z'), - Sig('a' * 25), - Sig('b' * 25), - Sig('c' * 25), - ] - argument_group_signatures = [] - usage = '''\ - usage: PROG [-h] [-x X] [-y Y] [-z Z] - aaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbb - ccccccccccccccccccccccccc - ''' - help = usage + '''\ - - positional arguments: - aaaaaaaaaaaaaaaaaaaaaaaaa - bbbbbbbbbbbbbbbbbbbbbbbbb - ccccccccccccccccccccccccc - - optional arguments: - -h, --help show this help message and exit - -x X - -y Y - -z Z - ''' - version = '' - - - class TestHelpUsageOptionalsPositionalsWrap(HelpTestCase): - """Test usage messages where the optionals and positionals wrap""" - - parser_signature = Sig(prog='PROG') - argument_signatures = [ - Sig('-x', metavar='X' * 25), - Sig('-y', metavar='Y' * 25), - Sig('-z', metavar='Z' * 25), - Sig('a' * 25), - Sig('b' * 25), - Sig('c' * 25), - ] - argument_group_signatures = [] - usage = '''\ - usage: PROG [-h] [-x XXXXXXXXXXXXXXXXXXXXXXXXX] \ - [-y YYYYYYYYYYYYYYYYYYYYYYYYY] - [-z ZZZZZZZZZZZZZZZZZZZZZZZZZ] - aaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbb - ccccccccccccccccccccccccc - ''' - help = usage + '''\ - - positional arguments: - aaaaaaaaaaaaaaaaaaaaaaaaa - bbbbbbbbbbbbbbbbbbbbbbbbb - ccccccccccccccccccccccccc - - optional arguments: - -h, --help show this help message and exit - -x XXXXXXXXXXXXXXXXXXXXXXXXX - -y YYYYYYYYYYYYYYYYYYYYYYYYY - -z ZZZZZZZZZZZZZZZZZZZZZZZZZ - ''' - version = '' - - - class TestHelpUsageOptionalsOnlyWrap(HelpTestCase): - """Test usage messages where there are only optionals and they wrap""" - - parser_signature = Sig(prog='PROG') - argument_signatures = [ - Sig('-x', metavar='X' * 25), - Sig('-y', metavar='Y' * 25), - Sig('-z', metavar='Z' * 25), - ] - argument_group_signatures = [] - usage = '''\ - usage: PROG [-h] [-x XXXXXXXXXXXXXXXXXXXXXXXXX] \ - [-y YYYYYYYYYYYYYYYYYYYYYYYYY] - [-z ZZZZZZZZZZZZZZZZZZZZZZZZZ] - ''' - help = usage + '''\ - - optional arguments: - -h, --help show this help message and exit - -x XXXXXXXXXXXXXXXXXXXXXXXXX - -y YYYYYYYYYYYYYYYYYYYYYYYYY - -z ZZZZZZZZZZZZZZZZZZZZZZZZZ - ''' - version = '' - - - class TestHelpUsagePositionalsOnlyWrap(HelpTestCase): - """Test usage messages where there are only positionals and they wrap""" - - parser_signature = Sig(prog='PROG', add_help=False) - argument_signatures = [ - Sig('a' * 25), - Sig('b' * 25), - Sig('c' * 25), - ] - argument_group_signatures = [] - usage = '''\ - usage: PROG aaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbb - ccccccccccccccccccccccccc - ''' - help = usage + '''\ - - positional arguments: - aaaaaaaaaaaaaaaaaaaaaaaaa - bbbbbbbbbbbbbbbbbbbbbbbbb - ccccccccccccccccccccccccc - ''' - version = '' - - - class TestHelpVariableExpansion(HelpTestCase): - """Test that variables are expanded properly in help messages""" - - parser_signature = Sig(prog='PROG') - argument_signatures = [ - Sig('-x', type=int, - help='x %(prog)s %(default)s %(type)s %%'), - Sig('-y', action='store_const', default=42, const='XXX', - help='y %(prog)s %(default)s %(const)s'), - Sig('--foo', choices='abc', - help='foo %(prog)s %(default)s %(choices)s'), - Sig('--bar', default='baz', choices=[1, 2], metavar='BBB', - help='bar %(prog)s %(default)s %(dest)s'), - Sig('spam', help='spam %(prog)s %(default)s'), - Sig('badger', default=0.5, help='badger %(prog)s %(default)s'), - ] - argument_group_signatures = [ - (Sig('group'), [ - Sig('-a', help='a %(prog)s %(default)s'), - Sig('-b', default=-1, help='b %(prog)s %(default)s'), - ]) - ] - usage = ('''\ - usage: PROG [-h] [-x X] [-y] [--foo {a,b,c}] [--bar BBB] [-a A] [-b B] - spam badger - ''') - help = usage + '''\ - - positional arguments: - spam spam PROG None - badger badger PROG 0.5 - - optional arguments: - -h, --help show this help message and exit - -x X x PROG None int % - -y y PROG 42 XXX - --foo {a,b,c} foo PROG None a, b, c - --bar BBB bar PROG baz bar - - group: - -a A a PROG None - -b B b PROG -1 - ''' - version = '' - - - class TestHelpVariableExpansionUsageSupplied(HelpTestCase): - """Test that variables are expanded properly when usage= is present""" - - parser_signature = Sig(prog='PROG', usage='%(prog)s FOO') - argument_signatures = [] - argument_group_signatures = [] - usage = ('''\ - usage: PROG FOO - ''') - help = usage + '''\ - - optional arguments: - -h, --help show this help message and exit - ''' - version = '' - - - class TestHelpVariableExpansionNoArguments(HelpTestCase): - """Test that variables are expanded properly with no arguments""" - - parser_signature = Sig(prog='PROG', add_help=False) - argument_signatures = [] - argument_group_signatures = [] - usage = ('''\ - usage: PROG - ''') - help = usage - version = '' - - - class TestHelpSuppressUsage(HelpTestCase): - """Test that items can be suppressed in usage messages""" - - parser_signature = Sig(prog='PROG', usage=argparse.SUPPRESS) - argument_signatures = [ - Sig('--foo', help='foo help'), - Sig('spam', help='spam help'), - ] - argument_group_signatures = [] - help = '''\ - positional arguments: - spam spam help - - optional arguments: - -h, --help show this help message and exit - --foo FOO foo help - ''' - usage = '' - version = '' - - - class TestHelpSuppressOptional(HelpTestCase): - """Test that optional arguments can be suppressed in help messages""" - - parser_signature = Sig(prog='PROG', add_help=False) - argument_signatures = [ - Sig('--foo', help=argparse.SUPPRESS), - Sig('spam', help='spam help'), - ] - argument_group_signatures = [] - usage = '''\ - usage: PROG spam - ''' - help = usage + '''\ - - positional arguments: - spam spam help - ''' - version = '' - - - class TestHelpSuppressOptionalGroup(HelpTestCase): - """Test that optional groups can be suppressed in help messages""" - - parser_signature = Sig(prog='PROG') - argument_signatures = [ - Sig('--foo', help='foo help'), - Sig('spam', help='spam help'), - ] - argument_group_signatures = [ - (Sig('group'), [Sig('--bar', help=argparse.SUPPRESS)]), - ] - usage = '''\ - usage: PROG [-h] [--foo FOO] spam - ''' - help = usage + '''\ - - positional arguments: - spam spam help - - optional arguments: - -h, --help show this help message and exit - --foo FOO foo help - ''' - version = '' - - - class TestHelpSuppressPositional(HelpTestCase): - """Test that positional arguments can be suppressed in help messages""" - - parser_signature = Sig(prog='PROG') - argument_signatures = [ - Sig('--foo', help='foo help'), - Sig('spam', help=argparse.SUPPRESS), - ] - argument_group_signatures = [] - usage = '''\ - usage: PROG [-h] [--foo FOO] - ''' - help = usage + '''\ - - optional arguments: - -h, --help show this help message and exit - --foo FOO foo help - ''' - version = '' - - - class TestHelpRequiredOptional(HelpTestCase): - """Test that required options don't look optional""" - - parser_signature = Sig(prog='PROG') - argument_signatures = [ - Sig('--foo', required=True, help='foo help'), - ] - argument_group_signatures = [] - usage = '''\ - usage: PROG [-h] --foo FOO - ''' - help = usage + '''\ - - optional arguments: - -h, --help show this help message and exit - --foo FOO foo help - ''' - version = '' - - - class TestHelpAlternatePrefixChars(HelpTestCase): - """Test that options display with different prefix characters""" - - parser_signature = Sig(prog='PROG', prefix_chars='^;', add_help=False) - argument_signatures = [ - Sig('^^foo', action='store_true', help='foo help'), - Sig(';b', ';;bar', help='bar help'), - ] - argument_group_signatures = [] - usage = '''\ - usage: PROG [^^foo] [;b BAR] - ''' - help = usage + '''\ - - optional arguments: - ^^foo foo help - ;b BAR, ;;bar BAR bar help - ''' - version = '' - - - class TestHelpNoHelpOptional(HelpTestCase): - """Test that the --help argument can be suppressed help messages""" - - parser_signature = Sig(prog='PROG', add_help=False) - argument_signatures = [ - Sig('--foo', help='foo help'), - Sig('spam', help='spam help'), - ] - argument_group_signatures = [] - usage = '''\ - usage: PROG [--foo FOO] spam - ''' - help = usage + '''\ - - positional arguments: - spam spam help - - optional arguments: - --foo FOO foo help - ''' - version = '' - - - class TestHelpNone(HelpTestCase): - """Test that no errors occur if no help is specified""" - - parser_signature = Sig(prog='PROG') - argument_signatures = [ - Sig('--foo'), - Sig('spam'), - ] - argument_group_signatures = [] - usage = '''\ - usage: PROG [-h] [--foo FOO] spam - ''' - help = usage + '''\ - - positional arguments: - spam - - optional arguments: - -h, --help show this help message and exit - --foo FOO - ''' - version = '' - - - class TestHelpTupleMetavar(HelpTestCase): - """Test specifying metavar as a tuple""" - - parser_signature = Sig(prog='PROG') - argument_signatures = [ - Sig('-w', help='w', nargs='+', metavar=('W1', 'W2')), - Sig('-x', help='x', nargs='*', metavar=('X1', 'X2')), - Sig('-y', help='y', nargs=3, metavar=('Y1', 'Y2', 'Y3')), - Sig('-z', help='z', nargs='?', metavar=('Z1', )), - ] - argument_group_signatures = [] - usage = '''\ - usage: PROG [-h] [-w W1 [W2 ...]] [-x [X1 [X2 ...]]] [-y Y1 Y2 Y3] \ - [-z [Z1]] - ''' - help = usage + '''\ - - optional arguments: - -h, --help show this help message and exit - -w W1 [W2 ...] w - -x [X1 [X2 ...]] x - -y Y1 Y2 Y3 y - -z [Z1] z - ''' - version = '' - - - class TestHelpRawText(HelpTestCase): - """Test the RawTextHelpFormatter""" - - parser_signature = Sig( - prog='PROG', formatter_class=argparse.RawTextHelpFormatter, - description='Keep the formatting\n' - ' exactly as it is written\n' - '\n' - 'here\n') - - argument_signatures = [ - Sig('--foo', help=' foo help should also\n' - 'appear as given here'), - Sig('spam', help='spam help'), - ] - argument_group_signatures = [ - (Sig('title', description=' This text\n' - ' should be indented\n' - ' exactly like it is here\n'), - [Sig('--bar', help='bar help')]), - ] - usage = '''\ - usage: PROG [-h] [--foo FOO] [--bar BAR] spam - ''' - help = usage + '''\ - - Keep the formatting - exactly as it is written - - here - - positional arguments: - spam spam help - - optional arguments: - -h, --help show this help message and exit - --foo FOO foo help should also - appear as given here - - title: - This text - should be indented - exactly like it is here - - --bar BAR bar help - ''' - version = '' - - - class TestHelpRawDescription(HelpTestCase): - """Test the RawTextHelpFormatter""" - - parser_signature = Sig( - prog='PROG', formatter_class=argparse.RawDescriptionHelpFormatter, - description='Keep the formatting\n' - ' exactly as it is written\n' - '\n' - 'here\n') - - argument_signatures = [ - Sig('--foo', help=' foo help should not\n' - ' retain this odd formatting'), - Sig('spam', help='spam help'), - ] - argument_group_signatures = [ - (Sig('title', description=' This text\n' - ' should be indented\n' - ' exactly like it is here\n'), - [Sig('--bar', help='bar help')]), - ] - usage = '''\ - usage: PROG [-h] [--foo FOO] [--bar BAR] spam - ''' - help = usage + '''\ - - Keep the formatting - exactly as it is written - - here - - positional arguments: - spam spam help - - optional arguments: - -h, --help show this help message and exit - --foo FOO foo help should not retain this odd formatting - - title: - This text - should be indented - exactly like it is here - - --bar BAR bar help - ''' - version = '' - - - class TestHelpArgumentDefaults(HelpTestCase): - """Test the ArgumentDefaultsHelpFormatter""" - - parser_signature = Sig( - prog='PROG', formatter_class=argparse.ArgumentDefaultsHelpFormatter, - description='description') - - argument_signatures = [ - Sig('--foo', help='foo help - oh and by the way, %(default)s'), - Sig('--bar', action='store_true', help='bar help'), - Sig('spam', help='spam help'), - Sig('badger', nargs='?', default='wooden', help='badger help'), - ] - argument_group_signatures = [ - (Sig('title', description='description'), - [Sig('--baz', type=int, default=42, help='baz help')]), - ] - usage = '''\ - usage: PROG [-h] [--foo FOO] [--bar] [--baz BAZ] spam [badger] - ''' - help = usage + '''\ - - description - - positional arguments: - spam spam help - badger badger help (default: wooden) - - optional arguments: - -h, --help show this help message and exit - --foo FOO foo help - oh and by the way, None - --bar bar help (default: False) - - title: - description - - --baz BAZ baz help (default: 42) - ''' - version = '' - - class TestHelpVersionAction(HelpTestCase): - """Test the default help for the version action""" - - parser_signature = Sig(prog='PROG', description='description') - argument_signatures = [Sig('-V', '--version', action='version', version='3.6')] - argument_group_signatures = [] - usage = '''\ - usage: PROG [-h] [-V] - ''' - help = usage + '''\ - - description - - optional arguments: - -h, --help show this help message and exit - -V, --version show program's version number and exit - ''' - version = '' - - - class TestHelpVersionActionSuppress(HelpTestCase): - """Test that the --version argument can be suppressed in help messages""" - - parser_signature = Sig(prog='PROG') - argument_signatures = [ - Sig('-v', '--version', action='version', version='1.0', - help=argparse.SUPPRESS), - Sig('--foo', help='foo help'), - Sig('spam', help='spam help'), - ] - argument_group_signatures = [] - usage = '''\ - usage: PROG [-h] [--foo FOO] spam - ''' - help = usage + '''\ - - positional arguments: - spam spam help - - optional arguments: - -h, --help show this help message and exit - --foo FOO foo help - ''' - - - class TestHelpSubparsersOrdering(HelpTestCase): - """Test ordering of subcommands in help matches the code""" - parser_signature = Sig(prog='PROG', - description='display some subcommands') - argument_signatures = [Sig('-v', '--version', action='version', version='0.1')] - - subparsers_signatures = [Sig(name=name) - for name in ('a', 'b', 'c', 'd', 'e')] - - usage = '''\ - usage: PROG [-h] [-v] {a,b,c,d,e} ... - ''' - - help = usage + '''\ - - display some subcommands - - positional arguments: - {a,b,c,d,e} - - optional arguments: - -h, --help show this help message and exit - -v, --version show program's version number and exit - ''' - - version = '''\ - 0.1 - ''' - - class TestHelpSubparsersWithHelpOrdering(HelpTestCase): - """Test ordering of subcommands in help matches the code""" - parser_signature = Sig(prog='PROG', - description='display some subcommands') - argument_signatures = [Sig('-v', '--version', action='version', version='0.1')] - - subcommand_data = (('a', 'a subcommand help'), - ('b', 'b subcommand help'), - ('c', 'c subcommand help'), - ('d', 'd subcommand help'), - ('e', 'e subcommand help'), - ) - - subparsers_signatures = [Sig(name=name, help=help) - for name, help in subcommand_data] - - usage = '''\ - usage: PROG [-h] [-v] {a,b,c,d,e} ... - ''' - - help = usage + '''\ - - display some subcommands - - positional arguments: - {a,b,c,d,e} - a a subcommand help - b b subcommand help - c c subcommand help - d d subcommand help - e e subcommand help - - optional arguments: - -h, --help show this help message and exit - -v, --version show program's version number and exit - ''' - - version = '''\ - 0.1 - ''' - - - - class TestHelpMetavarTypeFormatter(HelpTestCase): - - def custom_type(string): - return string - - parser_signature = Sig(prog='PROG', description='description', - formatter_class=argparse.MetavarTypeHelpFormatter) - argument_signatures = [Sig('a', type=int), - Sig('-b', type=custom_type), - Sig('-c', type=float, metavar='SOME FLOAT')] - argument_group_signatures = [] - usage = '''\ - usage: PROG [-h] [-b custom_type] [-c SOME FLOAT] int - ''' - help = usage + '''\ - - description - - positional arguments: - int - - optional arguments: - -h, --help show this help message and exit - -b custom_type - -c SOME FLOAT - ''' - version = '' - - - # ===================================== - # Optional/Positional constructor tests - # ===================================== - - class TestInvalidArgumentConstructors(TestCase): - """Test a bunch of invalid Argument constructors""" - - def assertTypeError(self, *args, **kwargs): - parser = argparse.ArgumentParser() - self.assertRaises(TypeError, parser.add_argument, - *args, **kwargs) - - def assertValueError(self, *args, **kwargs): - parser = argparse.ArgumentParser() - self.assertRaises(ValueError, parser.add_argument, - *args, **kwargs) - - def test_invalid_keyword_arguments(self): - self.assertTypeError('-x', bar=None) - self.assertTypeError('-y', callback='foo') - self.assertTypeError('-y', callback_args=()) - self.assertTypeError('-y', callback_kwargs={}) - - def test_missing_destination(self): - self.assertTypeError() - for action in ['append', 'store']: - self.assertTypeError(action=action) - - def test_invalid_option_strings(self): - self.assertValueError('--') - self.assertValueError('---') - - def test_invalid_type(self): - self.assertValueError('--foo', type='int') - self.assertValueError('--foo', type=(int, float)) - - def test_invalid_action(self): - self.assertValueError('-x', action='foo') - self.assertValueError('foo', action='baz') - self.assertValueError('--foo', action=('store', 'append')) - parser = argparse.ArgumentParser() - with self.assertRaises(ValueError) as cm: - parser.add_argument("--foo", action="store-true") - self.assertIn('unknown action', str(cm.exception)) - - def test_multiple_dest(self): - parser = argparse.ArgumentParser() - parser.add_argument(dest='foo') - with self.assertRaises(ValueError) as cm: - parser.add_argument('bar', dest='baz') - self.assertIn('dest supplied twice for positional argument', - str(cm.exception)) - - def test_no_argument_actions(self): - for action in ['store_const', 'store_true', 'store_false', - 'append_const', 'count']: - for attrs in [dict(type=int), dict(nargs='+'), - dict(choices='ab')]: - self.assertTypeError('-x', action=action, **attrs) - - def test_no_argument_no_const_actions(self): - # options with zero arguments - for action in ['store_true', 'store_false', 'count']: - - # const is always disallowed - self.assertTypeError('-x', const='foo', action=action) - - # nargs is always disallowed - self.assertTypeError('-x', nargs='*', action=action) - - def test_more_than_one_argument_actions(self): - for action in ['store', 'append']: - - # nargs=0 is disallowed - self.assertValueError('-x', nargs=0, action=action) - self.assertValueError('spam', nargs=0, action=action) - - # const is disallowed with non-optional arguments - for nargs in [1, '*', '+']: - self.assertValueError('-x', const='foo', - nargs=nargs, action=action) - self.assertValueError('spam', const='foo', - nargs=nargs, action=action) - - def test_required_const_actions(self): - for action in ['store_const', 'append_const']: - - # nargs is always disallowed - self.assertTypeError('-x', nargs='+', action=action) - - def test_parsers_action_missing_params(self): - self.assertTypeError('command', action='parsers') - self.assertTypeError('command', action='parsers', prog='PROG') - self.assertTypeError('command', action='parsers', - parser_class=argparse.ArgumentParser) - - def test_required_positional(self): - self.assertTypeError('foo', required=True) - - def test_user_defined_action(self): - - class Success(Exception): - pass - - class Action(object): - - def __init__(self, - option_strings, - dest, - const, - default, - required=False): - if dest == 'spam': - if const is Success: - if default is Success: - raise Success() - - def __call__(self, *args, **kwargs): - pass - - parser = argparse.ArgumentParser() - self.assertRaises(Success, parser.add_argument, '--spam', - action=Action, default=Success, const=Success) - self.assertRaises(Success, parser.add_argument, 'spam', - action=Action, default=Success, const=Success) - - # ================================ - # Actions returned by add_argument - # ================================ - - class TestActionsReturned(TestCase): - - def test_dest(self): - parser = argparse.ArgumentParser() - action = parser.add_argument('--foo') - self.assertEqual(action.dest, 'foo') - action = parser.add_argument('-b', '--bar') - self.assertEqual(action.dest, 'bar') - action = parser.add_argument('-x', '-y') - self.assertEqual(action.dest, 'x') - - def test_misc(self): - parser = argparse.ArgumentParser() - action = parser.add_argument('--foo', nargs='?', const=42, - default=84, type=int, choices=[1, 2], - help='FOO', metavar='BAR', dest='baz') - self.assertEqual(action.nargs, '?') - self.assertEqual(action.const, 42) - self.assertEqual(action.default, 84) - self.assertEqual(action.type, int) - self.assertEqual(action.choices, [1, 2]) - self.assertEqual(action.help, 'FOO') - self.assertEqual(action.metavar, 'BAR') - self.assertEqual(action.dest, 'baz') - - - # ================================ - # Argument conflict handling tests - # ================================ - - class TestConflictHandling(TestCase): - - def test_bad_type(self): - self.assertRaises(ValueError, argparse.ArgumentParser, - conflict_handler='foo') - - def test_conflict_error(self): - parser = argparse.ArgumentParser() - parser.add_argument('-x') - self.assertRaises(argparse.ArgumentError, - parser.add_argument, '-x') - parser.add_argument('--spam') - self.assertRaises(argparse.ArgumentError, - parser.add_argument, '--spam') - - def test_resolve_error(self): - get_parser = argparse.ArgumentParser - parser = get_parser(prog='PROG', conflict_handler='resolve') - - parser.add_argument('-x', help='OLD X') - parser.add_argument('-x', help='NEW X') - self.assertEqual(parser.format_help(), textwrap.dedent('''\ - usage: PROG [-h] [-x X] - - optional arguments: - -h, --help show this help message and exit - -x X NEW X - ''')) - - parser.add_argument('--spam', metavar='OLD_SPAM') - parser.add_argument('--spam', metavar='NEW_SPAM') - self.assertEqual(parser.format_help(), textwrap.dedent('''\ - usage: PROG [-h] [-x X] [--spam NEW_SPAM] - - optional arguments: - -h, --help show this help message and exit - -x X NEW X - --spam NEW_SPAM - ''')) - - - # ============================= - # Help and Version option tests - # ============================= - - class TestOptionalsHelpVersionActions(TestCase): - """Test the help and version actions""" - - def assertPrintHelpExit(self, parser, args_str): - with self.assertRaises(ArgumentParserError) as cm: - parser.parse_args(args_str.split()) - self.assertEqual(parser.format_help(), cm.exception.stdout) - - def assertArgumentParserError(self, parser, *args): - self.assertRaises(ArgumentParserError, parser.parse_args, args) - - def test_version(self): - parser = ErrorRaisingArgumentParser() - parser.add_argument('-v', '--version', action='version', version='1.0') - self.assertPrintHelpExit(parser, '-h') - self.assertPrintHelpExit(parser, '--help') - self.assertRaises(AttributeError, getattr, parser, 'format_version') - - def test_version_format(self): - parser = ErrorRaisingArgumentParser(prog='PPP') - parser.add_argument('-v', '--version', action='version', version='%(prog)s 3.5') - with self.assertRaises(ArgumentParserError) as cm: - parser.parse_args(['-v']) - self.assertEqual('PPP 3.5\n', cm.exception.stdout) - - def test_version_no_help(self): - parser = ErrorRaisingArgumentParser(add_help=False) - parser.add_argument('-v', '--version', action='version', version='1.0') - self.assertArgumentParserError(parser, '-h') - self.assertArgumentParserError(parser, '--help') - self.assertRaises(AttributeError, getattr, parser, 'format_version') - - def test_version_action(self): - parser = ErrorRaisingArgumentParser(prog='XXX') - parser.add_argument('-V', action='version', version='%(prog)s 3.7') - with self.assertRaises(ArgumentParserError) as cm: - parser.parse_args(['-V']) - self.assertEqual('XXX 3.7\n', cm.exception.stdout) - - def test_no_help(self): - parser = ErrorRaisingArgumentParser(add_help=False) - self.assertArgumentParserError(parser, '-h') - self.assertArgumentParserError(parser, '--help') - self.assertArgumentParserError(parser, '-v') - self.assertArgumentParserError(parser, '--version') - - def test_alternate_help_version(self): - parser = ErrorRaisingArgumentParser() - parser.add_argument('-x', action='help') - parser.add_argument('-y', action='version') - self.assertPrintHelpExit(parser, '-x') - self.assertArgumentParserError(parser, '-v') - self.assertArgumentParserError(parser, '--version') - self.assertRaises(AttributeError, getattr, parser, 'format_version') - - def test_help_version_extra_arguments(self): - parser = ErrorRaisingArgumentParser() - parser.add_argument('--version', action='version', version='1.0') - parser.add_argument('-x', action='store_true') - parser.add_argument('y') - - # try all combinations of valid prefixes and suffixes - valid_prefixes = ['', '-x', 'foo', '-x bar', 'baz -x'] - valid_suffixes = valid_prefixes + ['--bad-option', 'foo bar baz'] - for prefix in valid_prefixes: - for suffix in valid_suffixes: - format = '%s %%s %s' % (prefix, suffix) - self.assertPrintHelpExit(parser, format % '-h') - self.assertPrintHelpExit(parser, format % '--help') - self.assertRaises(AttributeError, getattr, parser, 'format_version') - - - # ====================== - # str() and repr() tests - # ====================== - - class TestStrings(TestCase): - """Test str() and repr() on Optionals and Positionals""" - - def assertStringEqual(self, obj, result_string): - for func in [str, repr]: - self.assertEqual(func(obj), result_string) - - def test_optional(self): - option = argparse.Action( - option_strings=['--foo', '-a', '-b'], - dest='b', - type='int', - nargs='+', - default=42, - choices=[1, 2, 3], - help='HELP', - metavar='METAVAR') - string = ( - "Action(option_strings=['--foo', '-a', '-b'], dest='b', " - "nargs='+', const=None, default=42, type='int', " - "choices=[1, 2, 3], help='HELP', metavar='METAVAR')") - self.assertStringEqual(option, string) - - def test_argument(self): - argument = argparse.Action( - option_strings=[], - dest='x', - type=float, - nargs='?', - default=2.5, - choices=[0.5, 1.5, 2.5], - help='H HH H', - metavar='MV MV MV') - string = ( - "Action(option_strings=[], dest='x', nargs='?', " - "const=None, default=2.5, type=%r, choices=[0.5, 1.5, 2.5], " - "help='H HH H', metavar='MV MV MV')" % float) - self.assertStringEqual(argument, string) - - def test_namespace(self): - ns = argparse.Namespace(foo=42, bar='spam') - string = "Namespace(bar='spam', foo=42)" - self.assertStringEqual(ns, string) - - def test_namespace_starkwargs_notidentifier(self): - ns = argparse.Namespace(**{'"': 'quote'}) - string = """Namespace(**{'"': 'quote'})""" - self.assertStringEqual(ns, string) - - def test_namespace_kwargs_and_starkwargs_notidentifier(self): - ns = argparse.Namespace(a=1, **{'"': 'quote'}) - string = """Namespace(a=1, **{'"': 'quote'})""" - self.assertStringEqual(ns, string) - - def test_namespace_starkwargs_identifier(self): - ns = argparse.Namespace(**{'valid': True}) - string = "Namespace(valid=True)" - self.assertStringEqual(ns, string) - - def test_parser(self): - parser = argparse.ArgumentParser(prog='PROG') - string = ( - "ArgumentParser(prog='PROG', usage=None, description=None, " - "formatter_class=%r, conflict_handler='error', " - "add_help=True)" % argparse.HelpFormatter) - self.assertStringEqual(parser, string) - - # =============== - # Namespace tests - # =============== - - class TestNamespace(TestCase): - - def test_constructor(self): - ns = argparse.Namespace() - self.assertRaises(AttributeError, getattr, ns, 'x') - - ns = argparse.Namespace(a=42, b='spam') - self.assertEqual(ns.a, 42) - self.assertEqual(ns.b, 'spam') - - def test_equality(self): - ns1 = argparse.Namespace(a=1, b=2) - ns2 = argparse.Namespace(b=2, a=1) - ns3 = argparse.Namespace(a=1) - ns4 = argparse.Namespace(b=2) - - self.assertEqual(ns1, ns2) - self.assertNotEqual(ns1, ns3) - self.assertNotEqual(ns1, ns4) - self.assertNotEqual(ns2, ns3) - self.assertNotEqual(ns2, ns4) - self.assertTrue(ns1 != ns3) - self.assertTrue(ns1 != ns4) - self.assertTrue(ns2 != ns3) - self.assertTrue(ns2 != ns4) - - def test_equality_returns_notimplemented(self): - # See issue 21481 - ns = argparse.Namespace(a=1, b=2) - self.assertIs(ns.__eq__(None), NotImplemented) - self.assertIs(ns.__ne__(None), NotImplemented) - - - # =================== - # File encoding tests - # =================== - - class TestEncoding(TestCase): - - def _test_module_encoding(self, path): - path, _ = os.path.splitext(path) - path += ".py" - with open(path, 'r', encoding='utf-8') as f: - f.read() - - def test_argparse_module_encoding(self): - self._test_module_encoding(argparse.__file__) - - def test_test_argparse_module_encoding(self): - self._test_module_encoding(__file__) - - # =================== - # ArgumentError tests - # =================== - - class TestArgumentError(TestCase): - - def test_argument_error(self): - msg = "my error here" - error = argparse.ArgumentError(None, msg) - self.assertEqual(str(error), msg) - - # ======================= - # ArgumentTypeError tests - # ======================= - - class TestArgumentTypeError(TestCase): - - def test_argument_type_error(self): - - def spam(string): - raise argparse.ArgumentTypeError('spam!') - - parser = ErrorRaisingArgumentParser(prog='PROG', add_help=False) - parser.add_argument('x', type=spam) - with self.assertRaises(ArgumentParserError) as cm: - parser.parse_args(['XXX']) - self.assertEqual('usage: PROG x\nPROG: error: argument x: spam!\n', - cm.exception.stderr) - - # ========================= - # MessageContentError tests - # ========================= - - class TestMessageContentError(TestCase): - - def test_missing_argument_name_in_message(self): - parser = ErrorRaisingArgumentParser(prog='PROG', usage='') - parser.add_argument('req_pos', type=str) - parser.add_argument('-req_opt', type=int, required=True) - parser.add_argument('need_one', type=str, nargs='+') - - with self.assertRaises(ArgumentParserError) as cm: - parser.parse_args([]) - msg = str(cm.exception) - self.assertRegex(msg, 'req_pos') - self.assertRegex(msg, 'req_opt') - self.assertRegex(msg, 'need_one') - with self.assertRaises(ArgumentParserError) as cm: - parser.parse_args(['myXargument']) - msg = str(cm.exception) - self.assertNotIn(msg, 'req_pos') - self.assertRegex(msg, 'req_opt') - self.assertRegex(msg, 'need_one') - with self.assertRaises(ArgumentParserError) as cm: - parser.parse_args(['myXargument', '-req_opt=1']) - msg = str(cm.exception) - self.assertNotIn(msg, 'req_pos') - self.assertNotIn(msg, 'req_opt') - self.assertRegex(msg, 'need_one') - - def test_optional_optional_not_in_message(self): - parser = ErrorRaisingArgumentParser(prog='PROG', usage='') - parser.add_argument('req_pos', type=str) - parser.add_argument('--req_opt', type=int, required=True) - parser.add_argument('--opt_opt', type=bool, nargs='?', - default=True) - with self.assertRaises(ArgumentParserError) as cm: - parser.parse_args([]) - msg = str(cm.exception) - self.assertRegex(msg, 'req_pos') - self.assertRegex(msg, 'req_opt') - self.assertNotIn(msg, 'opt_opt') - with self.assertRaises(ArgumentParserError) as cm: - parser.parse_args(['--req_opt=1']) - msg = str(cm.exception) - self.assertRegex(msg, 'req_pos') - self.assertNotIn(msg, 'req_opt') - self.assertNotIn(msg, 'opt_opt') - - def test_optional_positional_not_in_message(self): - parser = ErrorRaisingArgumentParser(prog='PROG', usage='') - parser.add_argument('req_pos') - parser.add_argument('optional_positional', nargs='?', default='eggs') - with self.assertRaises(ArgumentParserError) as cm: - parser.parse_args([]) - msg = str(cm.exception) - self.assertRegex(msg, 'req_pos') - self.assertNotIn(msg, 'optional_positional') - - - # ================================================ - # Check that the type function is called only once - # ================================================ - - class TestTypeFunctionCallOnlyOnce(TestCase): - - def test_type_function_call_only_once(self): - def spam(string_to_convert): - self.assertEqual(string_to_convert, 'spam!') - return 'foo_converted' - - parser = argparse.ArgumentParser() - parser.add_argument('--foo', type=spam, default='bar') - args = parser.parse_args('--foo spam!'.split()) - self.assertEqual(NS(foo='foo_converted'), args) - - # ================================================================== - # Check semantics regarding the default argument and type conversion - # ================================================================== - - class TestTypeFunctionCalledOnDefault(TestCase): - - def test_type_function_call_with_non_string_default(self): - def spam(int_to_convert): - self.assertEqual(int_to_convert, 0) - return 'foo_converted' - - parser = argparse.ArgumentParser() - parser.add_argument('--foo', type=spam, default=0) - args = parser.parse_args([]) - # foo should *not* be converted because its default is not a string. - self.assertEqual(NS(foo=0), args) - - def test_type_function_call_with_string_default(self): - def spam(int_to_convert): - return 'foo_converted' - - parser = argparse.ArgumentParser() - parser.add_argument('--foo', type=spam, default='0') - args = parser.parse_args([]) - # foo is converted because its default is a string. - self.assertEqual(NS(foo='foo_converted'), args) - - def test_no_double_type_conversion_of_default(self): - def extend(str_to_convert): - return str_to_convert + '*' - - parser = argparse.ArgumentParser() - parser.add_argument('--test', type=extend, default='*') - args = parser.parse_args([]) - # The test argument will be two stars, one coming from the default - # value and one coming from the type conversion being called exactly - # once. - self.assertEqual(NS(test='**'), args) - - def test_issue_15906(self): - # Issue #15906: When action='append', type=str, default=[] are - # providing, the dest value was the string representation "[]" when it - # should have been an empty list. - parser = argparse.ArgumentParser() - parser.add_argument('--test', dest='test', type=str, - default=[], action='append') - args = parser.parse_args([]) - self.assertEqual(args.test, []) - - # ====================== - # parse_known_args tests - # ====================== - - class TestParseKnownArgs(TestCase): - - def test_arguments_tuple(self): - parser = argparse.ArgumentParser() - parser.parse_args(()) - - def test_arguments_list(self): - parser = argparse.ArgumentParser() - parser.parse_args([]) - - def test_arguments_tuple_positional(self): - parser = argparse.ArgumentParser() - parser.add_argument('x') - parser.parse_args(('x',)) - - def test_arguments_list_positional(self): - parser = argparse.ArgumentParser() - parser.add_argument('x') - parser.parse_args(['x']) - - def test_optionals(self): - parser = argparse.ArgumentParser() - parser.add_argument('--foo') - args, extras = parser.parse_known_args('--foo F --bar --baz'.split()) - self.assertEqual(NS(foo='F'), args) - self.assertEqual(['--bar', '--baz'], extras) - - def test_mixed(self): - parser = argparse.ArgumentParser() - parser.add_argument('-v', nargs='?', const=1, type=int) - parser.add_argument('--spam', action='store_false') - parser.add_argument('badger') - - argv = ["B", "C", "--foo", "-v", "3", "4"] - args, extras = parser.parse_known_args(argv) - self.assertEqual(NS(v=3, spam=True, badger="B"), args) - self.assertEqual(["C", "--foo", "4"], extras) - - # =========================== - # parse_intermixed_args tests - # =========================== - - class TestIntermixedArgs(TestCase): - def test_basic(self): - # test parsing intermixed optionals and positionals - parser = argparse.ArgumentParser(prog='PROG') - parser.add_argument('--foo', dest='foo') - bar = parser.add_argument('--bar', dest='bar', required=True) - parser.add_argument('cmd') - parser.add_argument('rest', nargs='*', type=int) - argv = 'cmd --foo x 1 --bar y 2 3'.split() - args = parser.parse_intermixed_args(argv) - # rest gets [1,2,3] despite the foo and bar strings - self.assertEqual(NS(bar='y', cmd='cmd', foo='x', rest=[1, 2, 3]), args) - - args, extras = parser.parse_known_args(argv) - # cannot parse the '1,2,3' - self.assertEqual(NS(bar='y', cmd='cmd', foo='x', rest=[]), args) - self.assertEqual(["1", "2", "3"], extras) - - argv = 'cmd --foo x 1 --error 2 --bar y 3'.split() - args, extras = parser.parse_known_intermixed_args(argv) - # unknown optionals go into extras - self.assertEqual(NS(bar='y', cmd='cmd', foo='x', rest=[1]), args) - self.assertEqual(['--error', '2', '3'], extras) - - # restores attributes that were temporarily changed - self.assertIsNone(parser.usage) - self.assertEqual(bar.required, True) - - def test_remainder(self): - # Intermixed and remainder are incompatible - parser = ErrorRaisingArgumentParser(prog='PROG') - parser.add_argument('-z') - parser.add_argument('x') - parser.add_argument('y', nargs='...') - argv = 'X A B -z Z'.split() - # intermixed fails with '...' (also 'A...') - # self.assertRaises(TypeError, parser.parse_intermixed_args, argv) - with self.assertRaises(TypeError) as cm: - parser.parse_intermixed_args(argv) - self.assertRegex(str(cm.exception), r'\.\.\.') - - def test_exclusive(self): - # mutually exclusive group; intermixed works fine - parser = ErrorRaisingArgumentParser(prog='PROG') - group = parser.add_mutually_exclusive_group(required=True) - group.add_argument('--foo', action='store_true', help='FOO') - group.add_argument('--spam', help='SPAM') - parser.add_argument('badger', nargs='*', default='X', help='BADGER') - args = parser.parse_intermixed_args('1 --foo 2'.split()) - self.assertEqual(NS(badger=['1', '2'], foo=True, spam=None), args) - self.assertRaises(ArgumentParserError, parser.parse_intermixed_args, '1 2'.split()) - self.assertEqual(group.required, True) - - def test_exclusive_incompatible(self): - # mutually exclusive group including positional - fail - parser = ErrorRaisingArgumentParser(prog='PROG') - group = parser.add_mutually_exclusive_group(required=True) - group.add_argument('--foo', action='store_true', help='FOO') - group.add_argument('--spam', help='SPAM') - group.add_argument('badger', nargs='*', default='X', help='BADGER') - self.assertRaises(TypeError, parser.parse_intermixed_args, []) - self.assertEqual(group.required, True) - - class TestIntermixedMessageContentError(TestCase): - # case where Intermixed gives different error message - # error is raised by 1st parsing step - def test_missing_argument_name_in_message(self): - parser = ErrorRaisingArgumentParser(prog='PROG', usage='') - parser.add_argument('req_pos', type=str) - parser.add_argument('-req_opt', type=int, required=True) - - with self.assertRaises(ArgumentParserError) as cm: - parser.parse_args([]) - msg = str(cm.exception) - self.assertRegex(msg, 'req_pos') - self.assertRegex(msg, 'req_opt') - - with self.assertRaises(ArgumentParserError) as cm: - parser.parse_intermixed_args([]) - msg = str(cm.exception) - self.assertNotRegex(msg, 'req_pos') - self.assertRegex(msg, 'req_opt') - - # ========================== - # add_argument metavar tests - # ========================== - - class TestAddArgumentMetavar(TestCase): - - EXPECTED_MESSAGE = "length of metavar tuple does not match nargs" - - def do_test_no_exception(self, nargs, metavar): - parser = argparse.ArgumentParser() - parser.add_argument("--foo", nargs=nargs, metavar=metavar) - - def do_test_exception(self, nargs, metavar): - parser = argparse.ArgumentParser() - with self.assertRaises(ValueError) as cm: - parser.add_argument("--foo", nargs=nargs, metavar=metavar) - self.assertEqual(cm.exception.args[0], self.EXPECTED_MESSAGE) - - # Unit tests for different values of metavar when nargs=None - - def test_nargs_None_metavar_string(self): - self.do_test_no_exception(nargs=None, metavar="1") - - def test_nargs_None_metavar_length0(self): - self.do_test_exception(nargs=None, metavar=tuple()) - - def test_nargs_None_metavar_length1(self): - self.do_test_no_exception(nargs=None, metavar=("1",)) - - def test_nargs_None_metavar_length2(self): - self.do_test_exception(nargs=None, metavar=("1", "2")) - - def test_nargs_None_metavar_length3(self): - self.do_test_exception(nargs=None, metavar=("1", "2", "3")) - - # Unit tests for different values of metavar when nargs=? - - def test_nargs_optional_metavar_string(self): - self.do_test_no_exception(nargs="?", metavar="1") - - def test_nargs_optional_metavar_length0(self): - self.do_test_exception(nargs="?", metavar=tuple()) - - def test_nargs_optional_metavar_length1(self): - self.do_test_no_exception(nargs="?", metavar=("1",)) - - def test_nargs_optional_metavar_length2(self): - self.do_test_exception(nargs="?", metavar=("1", "2")) - - def test_nargs_optional_metavar_length3(self): - self.do_test_exception(nargs="?", metavar=("1", "2", "3")) - - # Unit tests for different values of metavar when nargs=* - - def test_nargs_zeroormore_metavar_string(self): - self.do_test_no_exception(nargs="*", metavar="1") - - def test_nargs_zeroormore_metavar_length0(self): - self.do_test_exception(nargs="*", metavar=tuple()) - - def test_nargs_zeroormore_metavar_length1(self): - self.do_test_exception(nargs="*", metavar=("1",)) - - def test_nargs_zeroormore_metavar_length2(self): - self.do_test_no_exception(nargs="*", metavar=("1", "2")) - - def test_nargs_zeroormore_metavar_length3(self): - self.do_test_exception(nargs="*", metavar=("1", "2", "3")) - - # Unit tests for different values of metavar when nargs=+ - - def test_nargs_oneormore_metavar_string(self): - self.do_test_no_exception(nargs="+", metavar="1") - - def test_nargs_oneormore_metavar_length0(self): - self.do_test_exception(nargs="+", metavar=tuple()) - - def test_nargs_oneormore_metavar_length1(self): - self.do_test_exception(nargs="+", metavar=("1",)) - - def test_nargs_oneormore_metavar_length2(self): - self.do_test_no_exception(nargs="+", metavar=("1", "2")) - - def test_nargs_oneormore_metavar_length3(self): - self.do_test_exception(nargs="+", metavar=("1", "2", "3")) - - # Unit tests for different values of metavar when nargs=... - - def test_nargs_remainder_metavar_string(self): - self.do_test_no_exception(nargs="...", metavar="1") - - def test_nargs_remainder_metavar_length0(self): - self.do_test_no_exception(nargs="...", metavar=tuple()) - - def test_nargs_remainder_metavar_length1(self): - self.do_test_no_exception(nargs="...", metavar=("1",)) - - def test_nargs_remainder_metavar_length2(self): - self.do_test_no_exception(nargs="...", metavar=("1", "2")) - - def test_nargs_remainder_metavar_length3(self): - self.do_test_no_exception(nargs="...", metavar=("1", "2", "3")) - - # Unit tests for different values of metavar when nargs=A... - - def test_nargs_parser_metavar_string(self): - self.do_test_no_exception(nargs="A...", metavar="1") - - def test_nargs_parser_metavar_length0(self): - self.do_test_exception(nargs="A...", metavar=tuple()) - - def test_nargs_parser_metavar_length1(self): - self.do_test_no_exception(nargs="A...", metavar=("1",)) - - def test_nargs_parser_metavar_length2(self): - self.do_test_exception(nargs="A...", metavar=("1", "2")) - - def test_nargs_parser_metavar_length3(self): - self.do_test_exception(nargs="A...", metavar=("1", "2", "3")) - - # Unit tests for different values of metavar when nargs=1 - - def test_nargs_1_metavar_string(self): - self.do_test_no_exception(nargs=1, metavar="1") - - def test_nargs_1_metavar_length0(self): - self.do_test_exception(nargs=1, metavar=tuple()) - - def test_nargs_1_metavar_length1(self): - self.do_test_no_exception(nargs=1, metavar=("1",)) - - def test_nargs_1_metavar_length2(self): - self.do_test_exception(nargs=1, metavar=("1", "2")) - - def test_nargs_1_metavar_length3(self): - self.do_test_exception(nargs=1, metavar=("1", "2", "3")) - - # Unit tests for different values of metavar when nargs=2 - - def test_nargs_2_metavar_string(self): - self.do_test_no_exception(nargs=2, metavar="1") - - def test_nargs_2_metavar_length0(self): - self.do_test_exception(nargs=2, metavar=tuple()) - - def test_nargs_2_metavar_length1(self): - self.do_test_exception(nargs=2, metavar=("1",)) - - def test_nargs_2_metavar_length2(self): - self.do_test_no_exception(nargs=2, metavar=("1", "2")) - - def test_nargs_2_metavar_length3(self): - self.do_test_exception(nargs=2, metavar=("1", "2", "3")) - - # Unit tests for different values of metavar when nargs=3 - - def test_nargs_3_metavar_string(self): - self.do_test_no_exception(nargs=3, metavar="1") - - def test_nargs_3_metavar_length0(self): - self.do_test_exception(nargs=3, metavar=tuple()) - - def test_nargs_3_metavar_length1(self): - self.do_test_exception(nargs=3, metavar=("1",)) - - def test_nargs_3_metavar_length2(self): - self.do_test_exception(nargs=3, metavar=("1", "2")) - - def test_nargs_3_metavar_length3(self): - self.do_test_no_exception(nargs=3, metavar=("1", "2", "3")) - - - class TestInvalidNargs(TestCase): - - EXPECTED_INVALID_MESSAGE = "invalid nargs value" - EXPECTED_RANGE_MESSAGE = ("nargs for store actions must be != 0; if you " - "have nothing to store, actions such as store " - "true or store const may be more appropriate") - - def do_test_range_exception(self, nargs): - parser = argparse.ArgumentParser() - with self.assertRaises(ValueError) as cm: - parser.add_argument("--foo", nargs=nargs) - self.assertEqual(cm.exception.args[0], self.EXPECTED_RANGE_MESSAGE) - - def do_test_invalid_exception(self, nargs): - parser = argparse.ArgumentParser() - with self.assertRaises(ValueError) as cm: - parser.add_argument("--foo", nargs=nargs) - self.assertEqual(cm.exception.args[0], self.EXPECTED_INVALID_MESSAGE) - - # Unit tests for different values of nargs - - def test_nargs_alphabetic(self): - self.do_test_invalid_exception(nargs='a') - self.do_test_invalid_exception(nargs="abcd") - - def test_nargs_zero(self): - self.do_test_range_exception(nargs=0) - - # ============================ - # from argparse import * tests - # ============================ - - class TestImportStar(TestCase): - - def test(self): - for name in argparse.__all__: - self.assertTrue(hasattr(argparse, name)) - - def test_all_exports_everything_but_modules(self): - items = [ - name - for name, value in vars(argparse).items() - if not (name.startswith("_") or name == 'ngettext') - if not inspect.ismodule(value) - ] - self.assertEqual(sorted(items), sorted(argparse.__all__)) - - - class TestWrappingMetavar(TestCase): - - def setUp(self): - super().setUp() - self.parser = ErrorRaisingArgumentParser( - 'this_is_spammy_prog_with_a_long_name_sorry_about_the_name' - ) - # this metavar was triggering library assertion errors due to usage - # message formatting incorrectly splitting on the ] chars within - metavar = '' - self.parser.add_argument('--proxy', metavar=metavar) - - def test_help_with_metavar(self): - help_text = self.parser.format_help() - self.assertEqual(help_text, textwrap.dedent('''\ - usage: this_is_spammy_prog_with_a_long_name_sorry_about_the_name - [-h] [--proxy ] - - optional arguments: - -h, --help show this help message and exit - --proxy - ''')) - - - def test_main(): - support.run_unittest(__name__) - # Remove global references to avoid looking like we have refleaks. - RFile.seen = {} - WFile.seen = set() - - - - if __name__ == '__main__': - test_main() diff --git a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_array.yaml b/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_array.yaml deleted file mode 100644 index 2cb4f17cc..000000000 --- a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_array.yaml +++ /dev/null @@ -1,1542 +0,0 @@ -python: | - """Test the arraymodule. - Roger E. Masse - """ - - import unittest - from test import support - from test.support import _2G - import weakref - import pickle - import operator - import struct - import sys - import warnings - - import array - from array import _array_reconstructor as array_reconstructor - - sizeof_wchar = array.array('u').itemsize - - - class ArraySubclass(array.array): - pass - - class ArraySubclassWithKwargs(array.array): - def __init__(self, typecode, newarg=None): - array.array.__init__(self) - - typecodes = 'ubBhHiIlLfdqQ' - - class MiscTest(unittest.TestCase): - - def test_bad_constructor(self): - self.assertRaises(TypeError, array.array) - self.assertRaises(TypeError, array.array, spam=42) - self.assertRaises(TypeError, array.array, 'xx') - self.assertRaises(ValueError, array.array, 'x') - - def test_empty(self): - # Exercise code for handling zero-length arrays - a = array.array('B') - a[:] = a - self.assertEqual(len(a), 0) - self.assertEqual(len(a + a), 0) - self.assertEqual(len(a * 3), 0) - a += a - self.assertEqual(len(a), 0) - - - # Machine format codes. - # - # Search for "enum machine_format_code" in Modules/arraymodule.c to get the - # authoritative values. - UNKNOWN_FORMAT = -1 - UNSIGNED_INT8 = 0 - SIGNED_INT8 = 1 - UNSIGNED_INT16_LE = 2 - UNSIGNED_INT16_BE = 3 - SIGNED_INT16_LE = 4 - SIGNED_INT16_BE = 5 - UNSIGNED_INT32_LE = 6 - UNSIGNED_INT32_BE = 7 - SIGNED_INT32_LE = 8 - SIGNED_INT32_BE = 9 - UNSIGNED_INT64_LE = 10 - UNSIGNED_INT64_BE = 11 - SIGNED_INT64_LE = 12 - SIGNED_INT64_BE = 13 - IEEE_754_FLOAT_LE = 14 - IEEE_754_FLOAT_BE = 15 - IEEE_754_DOUBLE_LE = 16 - IEEE_754_DOUBLE_BE = 17 - UTF16_LE = 18 - UTF16_BE = 19 - UTF32_LE = 20 - UTF32_BE = 21 - - class ArrayReconstructorTest(unittest.TestCase): - - def test_error(self): - self.assertRaises(TypeError, array_reconstructor, - "", "b", 0, b"") - self.assertRaises(TypeError, array_reconstructor, - str, "b", 0, b"") - self.assertRaises(TypeError, array_reconstructor, - array.array, "b", '', b"") - self.assertRaises(TypeError, array_reconstructor, - array.array, "b", 0, "") - self.assertRaises(ValueError, array_reconstructor, - array.array, "?", 0, b"") - self.assertRaises(ValueError, array_reconstructor, - array.array, "b", UNKNOWN_FORMAT, b"") - self.assertRaises(ValueError, array_reconstructor, - array.array, "b", 22, b"") - self.assertRaises(ValueError, array_reconstructor, - array.array, "d", 16, b"a") - - def test_numbers(self): - testcases = ( - (['B', 'H', 'I', 'L'], UNSIGNED_INT8, '=BBBB', - [0x80, 0x7f, 0, 0xff]), - (['b', 'h', 'i', 'l'], SIGNED_INT8, '=bbb', - [-0x80, 0x7f, 0]), - (['H', 'I', 'L'], UNSIGNED_INT16_LE, 'HHHH', - [0x8000, 0x7fff, 0, 0xffff]), - (['h', 'i', 'l'], SIGNED_INT16_LE, 'hhh', - [-0x8000, 0x7fff, 0]), - (['I', 'L'], UNSIGNED_INT32_LE, 'IIII', - [1<<31, (1<<31)-1, 0, (1<<32)-1]), - (['i', 'l'], SIGNED_INT32_LE, 'iii', - [-1<<31, (1<<31)-1, 0]), - (['L'], UNSIGNED_INT64_LE, 'QQQQ', - [1<<31, (1<<31)-1, 0, (1<<32)-1]), - (['l'], SIGNED_INT64_LE, 'qqq', - [-1<<31, (1<<31)-1, 0]), - # The following tests for INT64 will raise an OverflowError - # when run on a 32-bit machine. The tests are simply skipped - # in that case. - (['L'], UNSIGNED_INT64_LE, 'QQQQ', - [1<<63, (1<<63)-1, 0, (1<<64)-1]), - (['l'], SIGNED_INT64_LE, 'qqq', - [-1<<63, (1<<63)-1, 0]), - (['f'], IEEE_754_FLOAT_LE, 'ffff', - [16711938.0, float('inf'), float('-inf'), -0.0]), - (['d'], IEEE_754_DOUBLE_LE, 'dddd', - [9006104071832581.0, float('inf'), float('-inf'), -0.0]) - ) - for testcase in testcases: - valid_typecodes, mformat_code, struct_fmt, values = testcase - arraystr = struct.pack(struct_fmt, *values) - for typecode in valid_typecodes: - try: - a = array.array(typecode, values) - except OverflowError: - continue # Skip this test case. - b = array_reconstructor( - array.array, typecode, mformat_code, arraystr) - self.assertEqual(a, b, - msg="{0!r} != {1!r}; testcase={2!r}".format(a, b, testcase)) - - def test_unicode(self): - teststr = "Bonne Journ\xe9e \U0002030a\U00020347" - testcases = ( - (UTF16_LE, "UTF-16-LE"), - (UTF16_BE, "UTF-16-BE"), - (UTF32_LE, "UTF-32-LE"), - (UTF32_BE, "UTF-32-BE") - ) - for testcase in testcases: - mformat_code, encoding = testcase - a = array.array('u', teststr) - b = array_reconstructor( - array.array, 'u', mformat_code, teststr.encode(encoding)) - self.assertEqual(a, b, - msg="{0!r} != {1!r}; testcase={2!r}".format(a, b, testcase)) - - - class BaseTest: - # Required class attributes (provided by subclasses - # typecode: the typecode to test - # example: an initializer usable in the constructor for this type - # smallerexample: the same length as example, but smaller - # biggerexample: the same length as example, but bigger - # outside: An entry that is not in example - # minitemsize: the minimum guaranteed itemsize - - def assertEntryEqual(self, entry1, entry2): - self.assertEqual(entry1, entry2) - - def badtypecode(self): - # Return a typecode that is different from our own - return typecodes[(typecodes.index(self.typecode)+1) % len(typecodes)] - - def test_constructor(self): - a = array.array(self.typecode) - self.assertEqual(a.typecode, self.typecode) - self.assertGreaterEqual(a.itemsize, self.minitemsize) - self.assertRaises(TypeError, array.array, self.typecode, None) - - def test_len(self): - a = array.array(self.typecode) - a.append(self.example[0]) - self.assertEqual(len(a), 1) - - a = array.array(self.typecode, self.example) - self.assertEqual(len(a), len(self.example)) - - def test_buffer_info(self): - a = array.array(self.typecode, self.example) - self.assertRaises(TypeError, a.buffer_info, 42) - bi = a.buffer_info() - self.assertIsInstance(bi, tuple) - self.assertEqual(len(bi), 2) - self.assertIsInstance(bi[0], int) - self.assertIsInstance(bi[1], int) - self.assertEqual(bi[1], len(a)) - - def test_byteswap(self): - if self.typecode == 'u': - example = '\U00100100' - else: - example = self.example - a = array.array(self.typecode, example) - self.assertRaises(TypeError, a.byteswap, 42) - if a.itemsize in (1, 2, 4, 8): - b = array.array(self.typecode, example) - b.byteswap() - if a.itemsize==1: - self.assertEqual(a, b) - else: - self.assertNotEqual(a, b) - b.byteswap() - self.assertEqual(a, b) - - def test_copy(self): - import copy - a = array.array(self.typecode, self.example) - b = copy.copy(a) - self.assertNotEqual(id(a), id(b)) - self.assertEqual(a, b) - - def test_deepcopy(self): - import copy - a = array.array(self.typecode, self.example) - b = copy.deepcopy(a) - self.assertNotEqual(id(a), id(b)) - self.assertEqual(a, b) - - def test_reduce_ex(self): - a = array.array(self.typecode, self.example) - for protocol in range(3): - self.assertIs(a.__reduce_ex__(protocol)[0], array.array) - for protocol in range(3, pickle.HIGHEST_PROTOCOL + 1): - self.assertIs(a.__reduce_ex__(protocol)[0], array_reconstructor) - - def test_pickle(self): - for protocol in range(pickle.HIGHEST_PROTOCOL + 1): - a = array.array(self.typecode, self.example) - b = pickle.loads(pickle.dumps(a, protocol)) - self.assertNotEqual(id(a), id(b)) - self.assertEqual(a, b) - - a = ArraySubclass(self.typecode, self.example) - a.x = 10 - b = pickle.loads(pickle.dumps(a, protocol)) - self.assertNotEqual(id(a), id(b)) - self.assertEqual(a, b) - self.assertEqual(a.x, b.x) - self.assertEqual(type(a), type(b)) - - def test_pickle_for_empty_array(self): - for protocol in range(pickle.HIGHEST_PROTOCOL + 1): - a = array.array(self.typecode) - b = pickle.loads(pickle.dumps(a, protocol)) - self.assertNotEqual(id(a), id(b)) - self.assertEqual(a, b) - - a = ArraySubclass(self.typecode) - a.x = 10 - b = pickle.loads(pickle.dumps(a, protocol)) - self.assertNotEqual(id(a), id(b)) - self.assertEqual(a, b) - self.assertEqual(a.x, b.x) - self.assertEqual(type(a), type(b)) - - def test_iterator_pickle(self): - orig = array.array(self.typecode, self.example) - data = list(orig) - data2 = data[::-1] - for proto in range(pickle.HIGHEST_PROTOCOL + 1): - # initial iterator - itorig = iter(orig) - d = pickle.dumps((itorig, orig), proto) - it, a = pickle.loads(d) - a.fromlist(data2) - self.assertEqual(type(it), type(itorig)) - self.assertEqual(list(it), data + data2) - - # running iterator - next(itorig) - d = pickle.dumps((itorig, orig), proto) - it, a = pickle.loads(d) - a.fromlist(data2) - self.assertEqual(type(it), type(itorig)) - self.assertEqual(list(it), data[1:] + data2) - - # empty iterator - for i in range(1, len(data)): - next(itorig) - d = pickle.dumps((itorig, orig), proto) - it, a = pickle.loads(d) - a.fromlist(data2) - self.assertEqual(type(it), type(itorig)) - self.assertEqual(list(it), data2) - - # exhausted iterator - self.assertRaises(StopIteration, next, itorig) - d = pickle.dumps((itorig, orig), proto) - it, a = pickle.loads(d) - a.fromlist(data2) - self.assertEqual(list(it), []) - - def test_exhausted_iterator(self): - a = array.array(self.typecode, self.example) - self.assertEqual(list(a), list(self.example)) - exhit = iter(a) - empit = iter(a) - for x in exhit: # exhaust the iterator - next(empit) # not exhausted - a.append(self.outside) - self.assertEqual(list(exhit), []) - self.assertEqual(list(empit), [self.outside]) - self.assertEqual(list(a), list(self.example) + [self.outside]) - - def test_insert(self): - a = array.array(self.typecode, self.example) - a.insert(0, self.example[0]) - self.assertEqual(len(a), 1+len(self.example)) - self.assertEqual(a[0], a[1]) - self.assertRaises(TypeError, a.insert) - self.assertRaises(TypeError, a.insert, None) - self.assertRaises(TypeError, a.insert, 0, None) - - a = array.array(self.typecode, self.example) - a.insert(-1, self.example[0]) - self.assertEqual( - a, - array.array( - self.typecode, - self.example[:-1] + self.example[:1] + self.example[-1:] - ) - ) - - a = array.array(self.typecode, self.example) - a.insert(-1000, self.example[0]) - self.assertEqual( - a, - array.array(self.typecode, self.example[:1] + self.example) - ) - - a = array.array(self.typecode, self.example) - a.insert(1000, self.example[0]) - self.assertEqual( - a, - array.array(self.typecode, self.example + self.example[:1]) - ) - - def test_tofromfile(self): - a = array.array(self.typecode, 2*self.example) - self.assertRaises(TypeError, a.tofile) - support.unlink(support.TESTFN) - f = open(support.TESTFN, 'wb') - try: - a.tofile(f) - f.close() - b = array.array(self.typecode) - f = open(support.TESTFN, 'rb') - self.assertRaises(TypeError, b.fromfile) - b.fromfile(f, len(self.example)) - self.assertEqual(b, array.array(self.typecode, self.example)) - self.assertNotEqual(a, b) - self.assertRaises(EOFError, b.fromfile, f, len(self.example)+1) - self.assertEqual(a, b) - f.close() - finally: - if not f.closed: - f.close() - support.unlink(support.TESTFN) - - def test_fromfile_ioerror(self): - # Issue #5395: Check if fromfile raises a proper OSError - # instead of EOFError. - a = array.array(self.typecode) - f = open(support.TESTFN, 'wb') - try: - self.assertRaises(OSError, a.fromfile, f, len(self.example)) - finally: - f.close() - support.unlink(support.TESTFN) - - def test_filewrite(self): - a = array.array(self.typecode, 2*self.example) - f = open(support.TESTFN, 'wb') - try: - f.write(a) - f.close() - b = array.array(self.typecode) - f = open(support.TESTFN, 'rb') - b.fromfile(f, len(self.example)) - self.assertEqual(b, array.array(self.typecode, self.example)) - self.assertNotEqual(a, b) - b.fromfile(f, len(self.example)) - self.assertEqual(a, b) - f.close() - finally: - if not f.closed: - f.close() - support.unlink(support.TESTFN) - - def test_tofromlist(self): - a = array.array(self.typecode, 2*self.example) - b = array.array(self.typecode) - self.assertRaises(TypeError, a.tolist, 42) - self.assertRaises(TypeError, b.fromlist) - self.assertRaises(TypeError, b.fromlist, 42) - self.assertRaises(TypeError, b.fromlist, [None]) - b.fromlist(a.tolist()) - self.assertEqual(a, b) - - def test_tofromstring(self): - # Warnings not raised when arguments are incorrect as Argument Clinic - # handles that before the warning can be raised. - nb_warnings = 2 - with warnings.catch_warnings(record=True) as r: - warnings.filterwarnings("always", - message=r"(to|from)string\(\) is deprecated", - category=DeprecationWarning) - a = array.array(self.typecode, 2*self.example) - b = array.array(self.typecode) - self.assertRaises(TypeError, a.tostring, 42) - self.assertRaises(TypeError, b.fromstring) - self.assertRaises(TypeError, b.fromstring, 42) - b.fromstring(a.tostring()) - self.assertEqual(a, b) - if a.itemsize>1: - self.assertRaises(ValueError, b.fromstring, "x") - nb_warnings += 1 - self.assertEqual(len(r), nb_warnings) - - def test_tofrombytes(self): - a = array.array(self.typecode, 2*self.example) - b = array.array(self.typecode) - self.assertRaises(TypeError, a.tobytes, 42) - self.assertRaises(TypeError, b.frombytes) - self.assertRaises(TypeError, b.frombytes, 42) - b.frombytes(a.tobytes()) - c = array.array(self.typecode, bytearray(a.tobytes())) - self.assertEqual(a, b) - self.assertEqual(a, c) - if a.itemsize>1: - self.assertRaises(ValueError, b.frombytes, b"x") - - def test_fromarray(self): - a = array.array(self.typecode, self.example) - b = array.array(self.typecode, a) - self.assertEqual(a, b) - - def test_repr(self): - a = array.array(self.typecode, 2*self.example) - self.assertEqual(a, eval(repr(a), {"array": array.array})) - - a = array.array(self.typecode) - self.assertEqual(repr(a), "array('%s')" % self.typecode) - - def test_str(self): - a = array.array(self.typecode, 2*self.example) - str(a) - - def test_cmp(self): - a = array.array(self.typecode, self.example) - self.assertIs(a == 42, False) - self.assertIs(a != 42, True) - - self.assertIs(a == a, True) - self.assertIs(a != a, False) - self.assertIs(a < a, False) - self.assertIs(a <= a, True) - self.assertIs(a > a, False) - self.assertIs(a >= a, True) - - al = array.array(self.typecode, self.smallerexample) - ab = array.array(self.typecode, self.biggerexample) - - self.assertIs(a == 2*a, False) - self.assertIs(a != 2*a, True) - self.assertIs(a < 2*a, True) - self.assertIs(a <= 2*a, True) - self.assertIs(a > 2*a, False) - self.assertIs(a >= 2*a, False) - - self.assertIs(a == al, False) - self.assertIs(a != al, True) - self.assertIs(a < al, False) - self.assertIs(a <= al, False) - self.assertIs(a > al, True) - self.assertIs(a >= al, True) - - self.assertIs(a == ab, False) - self.assertIs(a != ab, True) - self.assertIs(a < ab, True) - self.assertIs(a <= ab, True) - self.assertIs(a > ab, False) - self.assertIs(a >= ab, False) - - def test_add(self): - a = array.array(self.typecode, self.example) \ - + array.array(self.typecode, self.example[::-1]) - self.assertEqual( - a, - array.array(self.typecode, self.example + self.example[::-1]) - ) - - b = array.array(self.badtypecode()) - self.assertRaises(TypeError, a.__add__, b) - - self.assertRaises(TypeError, a.__add__, "bad") - - def test_iadd(self): - a = array.array(self.typecode, self.example[::-1]) - b = a - a += array.array(self.typecode, 2*self.example) - self.assertIs(a, b) - self.assertEqual( - a, - array.array(self.typecode, self.example[::-1]+2*self.example) - ) - a = array.array(self.typecode, self.example) - a += a - self.assertEqual( - a, - array.array(self.typecode, self.example + self.example) - ) - - b = array.array(self.badtypecode()) - self.assertRaises(TypeError, a.__add__, b) - - self.assertRaises(TypeError, a.__iadd__, "bad") - - def test_mul(self): - a = 5*array.array(self.typecode, self.example) - self.assertEqual( - a, - array.array(self.typecode, 5*self.example) - ) - - a = array.array(self.typecode, self.example)*5 - self.assertEqual( - a, - array.array(self.typecode, self.example*5) - ) - - a = 0*array.array(self.typecode, self.example) - self.assertEqual( - a, - array.array(self.typecode) - ) - - a = (-1)*array.array(self.typecode, self.example) - self.assertEqual( - a, - array.array(self.typecode) - ) - - a = 5 * array.array(self.typecode, self.example[:1]) - self.assertEqual( - a, - array.array(self.typecode, [a[0]] * 5) - ) - - self.assertRaises(TypeError, a.__mul__, "bad") - - def test_imul(self): - a = array.array(self.typecode, self.example) - b = a - - a *= 5 - self.assertIs(a, b) - self.assertEqual( - a, - array.array(self.typecode, 5*self.example) - ) - - a *= 0 - self.assertIs(a, b) - self.assertEqual(a, array.array(self.typecode)) - - a *= 1000 - self.assertIs(a, b) - self.assertEqual(a, array.array(self.typecode)) - - a *= -1 - self.assertIs(a, b) - self.assertEqual(a, array.array(self.typecode)) - - a = array.array(self.typecode, self.example) - a *= -1 - self.assertEqual(a, array.array(self.typecode)) - - self.assertRaises(TypeError, a.__imul__, "bad") - - def test_getitem(self): - a = array.array(self.typecode, self.example) - self.assertEntryEqual(a[0], self.example[0]) - self.assertEntryEqual(a[0], self.example[0]) - self.assertEntryEqual(a[-1], self.example[-1]) - self.assertEntryEqual(a[-1], self.example[-1]) - self.assertEntryEqual(a[len(self.example)-1], self.example[-1]) - self.assertEntryEqual(a[-len(self.example)], self.example[0]) - self.assertRaises(TypeError, a.__getitem__) - self.assertRaises(IndexError, a.__getitem__, len(self.example)) - self.assertRaises(IndexError, a.__getitem__, -len(self.example)-1) - - def test_setitem(self): - a = array.array(self.typecode, self.example) - a[0] = a[-1] - self.assertEntryEqual(a[0], a[-1]) - - a = array.array(self.typecode, self.example) - a[0] = a[-1] - self.assertEntryEqual(a[0], a[-1]) - - a = array.array(self.typecode, self.example) - a[-1] = a[0] - self.assertEntryEqual(a[0], a[-1]) - - a = array.array(self.typecode, self.example) - a[-1] = a[0] - self.assertEntryEqual(a[0], a[-1]) - - a = array.array(self.typecode, self.example) - a[len(self.example)-1] = a[0] - self.assertEntryEqual(a[0], a[-1]) - - a = array.array(self.typecode, self.example) - a[-len(self.example)] = a[-1] - self.assertEntryEqual(a[0], a[-1]) - - self.assertRaises(TypeError, a.__setitem__) - self.assertRaises(TypeError, a.__setitem__, None) - self.assertRaises(TypeError, a.__setitem__, 0, None) - self.assertRaises( - IndexError, - a.__setitem__, - len(self.example), self.example[0] - ) - self.assertRaises( - IndexError, - a.__setitem__, - -len(self.example)-1, self.example[0] - ) - - def test_delitem(self): - a = array.array(self.typecode, self.example) - del a[0] - self.assertEqual( - a, - array.array(self.typecode, self.example[1:]) - ) - - a = array.array(self.typecode, self.example) - del a[-1] - self.assertEqual( - a, - array.array(self.typecode, self.example[:-1]) - ) - - a = array.array(self.typecode, self.example) - del a[len(self.example)-1] - self.assertEqual( - a, - array.array(self.typecode, self.example[:-1]) - ) - - a = array.array(self.typecode, self.example) - del a[-len(self.example)] - self.assertEqual( - a, - array.array(self.typecode, self.example[1:]) - ) - - self.assertRaises(TypeError, a.__delitem__) - self.assertRaises(TypeError, a.__delitem__, None) - self.assertRaises(IndexError, a.__delitem__, len(self.example)) - self.assertRaises(IndexError, a.__delitem__, -len(self.example)-1) - - def test_getslice(self): - a = array.array(self.typecode, self.example) - self.assertEqual(a[:], a) - - self.assertEqual( - a[1:], - array.array(self.typecode, self.example[1:]) - ) - - self.assertEqual( - a[:1], - array.array(self.typecode, self.example[:1]) - ) - - self.assertEqual( - a[:-1], - array.array(self.typecode, self.example[:-1]) - ) - - self.assertEqual( - a[-1:], - array.array(self.typecode, self.example[-1:]) - ) - - self.assertEqual( - a[-1:-1], - array.array(self.typecode) - ) - - self.assertEqual( - a[2:1], - array.array(self.typecode) - ) - - self.assertEqual( - a[1000:], - array.array(self.typecode) - ) - self.assertEqual(a[-1000:], a) - self.assertEqual(a[:1000], a) - self.assertEqual( - a[:-1000], - array.array(self.typecode) - ) - self.assertEqual(a[-1000:1000], a) - self.assertEqual( - a[2000:1000], - array.array(self.typecode) - ) - - def test_extended_getslice(self): - # Test extended slicing by comparing with list slicing - # (Assumes list conversion works correctly, too) - a = array.array(self.typecode, self.example) - indices = (0, None, 1, 3, 19, 100, sys.maxsize, -1, -2, -31, -100) - for start in indices: - for stop in indices: - # Everything except the initial 0 (invalid step) - for step in indices[1:]: - self.assertEqual(list(a[start:stop:step]), - list(a)[start:stop:step]) - - def test_setslice(self): - a = array.array(self.typecode, self.example) - a[:1] = a - self.assertEqual( - a, - array.array(self.typecode, self.example + self.example[1:]) - ) - - a = array.array(self.typecode, self.example) - a[:-1] = a - self.assertEqual( - a, - array.array(self.typecode, self.example + self.example[-1:]) - ) - - a = array.array(self.typecode, self.example) - a[-1:] = a - self.assertEqual( - a, - array.array(self.typecode, self.example[:-1] + self.example) - ) - - a = array.array(self.typecode, self.example) - a[1:] = a - self.assertEqual( - a, - array.array(self.typecode, self.example[:1] + self.example) - ) - - a = array.array(self.typecode, self.example) - a[1:-1] = a - self.assertEqual( - a, - array.array( - self.typecode, - self.example[:1] + self.example + self.example[-1:] - ) - ) - - a = array.array(self.typecode, self.example) - a[1000:] = a - self.assertEqual( - a, - array.array(self.typecode, 2*self.example) - ) - - a = array.array(self.typecode, self.example) - a[-1000:] = a - self.assertEqual( - a, - array.array(self.typecode, self.example) - ) - - a = array.array(self.typecode, self.example) - a[:1000] = a - self.assertEqual( - a, - array.array(self.typecode, self.example) - ) - - a = array.array(self.typecode, self.example) - a[:-1000] = a - self.assertEqual( - a, - array.array(self.typecode, 2*self.example) - ) - - a = array.array(self.typecode, self.example) - a[1:0] = a - self.assertEqual( - a, - array.array(self.typecode, self.example[:1] + self.example + self.example[1:]) - ) - - a = array.array(self.typecode, self.example) - a[2000:1000] = a - self.assertEqual( - a, - array.array(self.typecode, 2*self.example) - ) - - a = array.array(self.typecode, self.example) - self.assertRaises(TypeError, a.__setitem__, slice(0, 0), None) - self.assertRaises(TypeError, a.__setitem__, slice(0, 1), None) - - b = array.array(self.badtypecode()) - self.assertRaises(TypeError, a.__setitem__, slice(0, 0), b) - self.assertRaises(TypeError, a.__setitem__, slice(0, 1), b) - - def test_extended_set_del_slice(self): - indices = (0, None, 1, 3, 19, 100, sys.maxsize, -1, -2, -31, -100) - for start in indices: - for stop in indices: - # Everything except the initial 0 (invalid step) - for step in indices[1:]: - a = array.array(self.typecode, self.example) - L = list(a) - # Make sure we have a slice of exactly the right length, - # but with (hopefully) different data. - data = L[start:stop:step] - data.reverse() - L[start:stop:step] = data - a[start:stop:step] = array.array(self.typecode, data) - self.assertEqual(a, array.array(self.typecode, L)) - - del L[start:stop:step] - del a[start:stop:step] - self.assertEqual(a, array.array(self.typecode, L)) - - def test_index(self): - example = 2*self.example - a = array.array(self.typecode, example) - self.assertRaises(TypeError, a.index) - for x in example: - self.assertEqual(a.index(x), example.index(x)) - self.assertRaises(ValueError, a.index, None) - self.assertRaises(ValueError, a.index, self.outside) - - def test_count(self): - example = 2*self.example - a = array.array(self.typecode, example) - self.assertRaises(TypeError, a.count) - for x in example: - self.assertEqual(a.count(x), example.count(x)) - self.assertEqual(a.count(self.outside), 0) - self.assertEqual(a.count(None), 0) - - def test_remove(self): - for x in self.example: - example = 2*self.example - a = array.array(self.typecode, example) - pos = example.index(x) - example2 = example[:pos] + example[pos+1:] - a.remove(x) - self.assertEqual(a, array.array(self.typecode, example2)) - - a = array.array(self.typecode, self.example) - self.assertRaises(ValueError, a.remove, self.outside) - - self.assertRaises(ValueError, a.remove, None) - - def test_pop(self): - a = array.array(self.typecode) - self.assertRaises(IndexError, a.pop) - - a = array.array(self.typecode, 2*self.example) - self.assertRaises(TypeError, a.pop, 42, 42) - self.assertRaises(TypeError, a.pop, None) - self.assertRaises(IndexError, a.pop, len(a)) - self.assertRaises(IndexError, a.pop, -len(a)-1) - - self.assertEntryEqual(a.pop(0), self.example[0]) - self.assertEqual( - a, - array.array(self.typecode, self.example[1:]+self.example) - ) - self.assertEntryEqual(a.pop(1), self.example[2]) - self.assertEqual( - a, - array.array(self.typecode, self.example[1:2]+self.example[3:]+self.example) - ) - self.assertEntryEqual(a.pop(0), self.example[1]) - self.assertEntryEqual(a.pop(), self.example[-1]) - self.assertEqual( - a, - array.array(self.typecode, self.example[3:]+self.example[:-1]) - ) - - def test_reverse(self): - a = array.array(self.typecode, self.example) - self.assertRaises(TypeError, a.reverse, 42) - a.reverse() - self.assertEqual( - a, - array.array(self.typecode, self.example[::-1]) - ) - - def test_extend(self): - a = array.array(self.typecode, self.example) - self.assertRaises(TypeError, a.extend) - a.extend(array.array(self.typecode, self.example[::-1])) - self.assertEqual( - a, - array.array(self.typecode, self.example+self.example[::-1]) - ) - - a = array.array(self.typecode, self.example) - a.extend(a) - self.assertEqual( - a, - array.array(self.typecode, self.example+self.example) - ) - - b = array.array(self.badtypecode()) - self.assertRaises(TypeError, a.extend, b) - - a = array.array(self.typecode, self.example) - a.extend(self.example[::-1]) - self.assertEqual( - a, - array.array(self.typecode, self.example+self.example[::-1]) - ) - - def test_constructor_with_iterable_argument(self): - a = array.array(self.typecode, iter(self.example)) - b = array.array(self.typecode, self.example) - self.assertEqual(a, b) - - # non-iterable argument - self.assertRaises(TypeError, array.array, self.typecode, 10) - - # pass through errors raised in __iter__ - class A: - def __iter__(self): - raise UnicodeError - self.assertRaises(UnicodeError, array.array, self.typecode, A()) - - # pass through errors raised in next() - def B(): - raise UnicodeError - yield None - self.assertRaises(UnicodeError, array.array, self.typecode, B()) - - def test_coveritertraverse(self): - try: - import gc - except ImportError: - self.skipTest('gc module not available') - a = array.array(self.typecode) - l = [iter(a)] - l.append(l) - gc.collect() - - def test_buffer(self): - a = array.array(self.typecode, self.example) - m = memoryview(a) - expected = m.tobytes() - self.assertEqual(a.tobytes(), expected) - self.assertEqual(a.tobytes()[0], expected[0]) - # Resizing is forbidden when there are buffer exports. - # For issue 4509, we also check after each error that - # the array was not modified. - self.assertRaises(BufferError, a.append, a[0]) - self.assertEqual(m.tobytes(), expected) - self.assertRaises(BufferError, a.extend, a[0:1]) - self.assertEqual(m.tobytes(), expected) - self.assertRaises(BufferError, a.remove, a[0]) - self.assertEqual(m.tobytes(), expected) - self.assertRaises(BufferError, a.pop, 0) - self.assertEqual(m.tobytes(), expected) - self.assertRaises(BufferError, a.fromlist, a.tolist()) - self.assertEqual(m.tobytes(), expected) - self.assertRaises(BufferError, a.frombytes, a.tobytes()) - self.assertEqual(m.tobytes(), expected) - if self.typecode == 'u': - self.assertRaises(BufferError, a.fromunicode, a.tounicode()) - self.assertEqual(m.tobytes(), expected) - self.assertRaises(BufferError, operator.imul, a, 2) - self.assertEqual(m.tobytes(), expected) - self.assertRaises(BufferError, operator.imul, a, 0) - self.assertEqual(m.tobytes(), expected) - self.assertRaises(BufferError, operator.setitem, a, slice(0, 0), a) - self.assertEqual(m.tobytes(), expected) - self.assertRaises(BufferError, operator.delitem, a, 0) - self.assertEqual(m.tobytes(), expected) - self.assertRaises(BufferError, operator.delitem, a, slice(0, 1)) - self.assertEqual(m.tobytes(), expected) - - def test_weakref(self): - s = array.array(self.typecode, self.example) - p = weakref.proxy(s) - self.assertEqual(p.tobytes(), s.tobytes()) - s = None - self.assertRaises(ReferenceError, len, p) - - @unittest.skipUnless(hasattr(sys, 'getrefcount'), - 'test needs sys.getrefcount()') - def test_bug_782369(self): - for i in range(10): - b = array.array('B', range(64)) - rc = sys.getrefcount(10) - for i in range(10): - b = array.array('B', range(64)) - self.assertEqual(rc, sys.getrefcount(10)) - - def test_subclass_with_kwargs(self): - # SF bug #1486663 -- this used to erroneously raise a TypeError - ArraySubclassWithKwargs('b', newarg=1) - - def test_create_from_bytes(self): - # XXX This test probably needs to be moved in a subclass or - # generalized to use self.typecode. - a = array.array('H', b"1234") - self.assertEqual(len(a) * a.itemsize, 4) - - @support.cpython_only - def test_sizeof_with_buffer(self): - a = array.array(self.typecode, self.example) - basesize = support.calcvobjsize('Pn2Pi') - buffer_size = a.buffer_info()[1] * a.itemsize - support.check_sizeof(self, a, basesize + buffer_size) - - @support.cpython_only - def test_sizeof_without_buffer(self): - a = array.array(self.typecode) - basesize = support.calcvobjsize('Pn2Pi') - support.check_sizeof(self, a, basesize) - - def test_initialize_with_unicode(self): - if self.typecode != 'u': - with self.assertRaises(TypeError) as cm: - a = array.array(self.typecode, 'foo') - self.assertIn("cannot use a str", str(cm.exception)) - with self.assertRaises(TypeError) as cm: - a = array.array(self.typecode, array.array('u', 'foo')) - self.assertIn("cannot use a unicode array", str(cm.exception)) - else: - a = array.array(self.typecode, "foo") - a = array.array(self.typecode, array.array('u', 'foo')) - - @support.cpython_only - def test_obsolete_write_lock(self): - from _testcapi import getbuffer_with_null_view - a = array.array('B', b"") - self.assertRaises(BufferError, getbuffer_with_null_view, a) - - def test_free_after_iterating(self): - support.check_free_after_iterating(self, iter, array.array, - (self.typecode,)) - support.check_free_after_iterating(self, reversed, array.array, - (self.typecode,)) - - class StringTest(BaseTest): - - def test_setitem(self): - super().test_setitem() - a = array.array(self.typecode, self.example) - self.assertRaises(TypeError, a.__setitem__, 0, self.example[:2]) - - class UnicodeTest(StringTest, unittest.TestCase): - typecode = 'u' - example = '\x01\u263a\x00\ufeff' - smallerexample = '\x01\u263a\x00\ufefe' - biggerexample = '\x01\u263a\x01\ufeff' - outside = str('\x33') - minitemsize = 2 - - def test_unicode(self): - self.assertRaises(TypeError, array.array, 'b', 'foo') - - a = array.array('u', '\xa0\xc2\u1234') - a.fromunicode(' ') - a.fromunicode('') - a.fromunicode('') - a.fromunicode('\x11abc\xff\u1234') - s = a.tounicode() - self.assertEqual(s, '\xa0\xc2\u1234 \x11abc\xff\u1234') - self.assertEqual(a.itemsize, sizeof_wchar) - - s = '\x00="\'a\\b\x80\xff\u0000\u0001\u1234' - a = array.array('u', s) - self.assertEqual( - repr(a), - "array('u', '\\x00=\"\\'a\\\\b\\x80\xff\\x00\\x01\u1234')") - - self.assertRaises(TypeError, a.fromunicode) - - def test_issue17223(self): - # this used to crash - if sizeof_wchar == 4: - # U+FFFFFFFF is an invalid code point in Unicode 6.0 - invalid_str = b'\xff\xff\xff\xff' - else: - # PyUnicode_FromUnicode() cannot fail with 16-bit wchar_t - self.skipTest("specific to 32-bit wchar_t") - a = array.array('u', invalid_str) - self.assertRaises(ValueError, a.tounicode) - self.assertRaises(ValueError, str, a) - - class NumberTest(BaseTest): - - def test_extslice(self): - a = array.array(self.typecode, range(5)) - self.assertEqual(a[::], a) - self.assertEqual(a[::2], array.array(self.typecode, [0,2,4])) - self.assertEqual(a[1::2], array.array(self.typecode, [1,3])) - self.assertEqual(a[::-1], array.array(self.typecode, [4,3,2,1,0])) - self.assertEqual(a[::-2], array.array(self.typecode, [4,2,0])) - self.assertEqual(a[3::-2], array.array(self.typecode, [3,1])) - self.assertEqual(a[-100:100:], a) - self.assertEqual(a[100:-100:-1], a[::-1]) - self.assertEqual(a[-100:100:2], array.array(self.typecode, [0,2,4])) - self.assertEqual(a[1000:2000:2], array.array(self.typecode, [])) - self.assertEqual(a[-1000:-2000:-2], array.array(self.typecode, [])) - - def test_delslice(self): - a = array.array(self.typecode, range(5)) - del a[::2] - self.assertEqual(a, array.array(self.typecode, [1,3])) - a = array.array(self.typecode, range(5)) - del a[1::2] - self.assertEqual(a, array.array(self.typecode, [0,2,4])) - a = array.array(self.typecode, range(5)) - del a[1::-2] - self.assertEqual(a, array.array(self.typecode, [0,2,3,4])) - a = array.array(self.typecode, range(10)) - del a[::1000] - self.assertEqual(a, array.array(self.typecode, [1,2,3,4,5,6,7,8,9])) - # test issue7788 - a = array.array(self.typecode, range(10)) - del a[9::1<<333] - - def test_assignment(self): - a = array.array(self.typecode, range(10)) - a[::2] = array.array(self.typecode, [42]*5) - self.assertEqual(a, array.array(self.typecode, [42, 1, 42, 3, 42, 5, 42, 7, 42, 9])) - a = array.array(self.typecode, range(10)) - a[::-4] = array.array(self.typecode, [10]*3) - self.assertEqual(a, array.array(self.typecode, [0, 10, 2, 3, 4, 10, 6, 7, 8 ,10])) - a = array.array(self.typecode, range(4)) - a[::-1] = a - self.assertEqual(a, array.array(self.typecode, [3, 2, 1, 0])) - a = array.array(self.typecode, range(10)) - b = a[:] - c = a[:] - ins = array.array(self.typecode, range(2)) - a[2:3] = ins - b[slice(2,3)] = ins - c[2:3:] = ins - - def test_iterationcontains(self): - a = array.array(self.typecode, range(10)) - self.assertEqual(list(a), list(range(10))) - b = array.array(self.typecode, [20]) - self.assertEqual(a[-1] in a, True) - self.assertEqual(b[0] not in a, True) - - def check_overflow(self, lower, upper): - # method to be used by subclasses - - # should not overflow assigning lower limit - a = array.array(self.typecode, [lower]) - a[0] = lower - # should overflow assigning less than lower limit - self.assertRaises(OverflowError, array.array, self.typecode, [lower-1]) - self.assertRaises(OverflowError, a.__setitem__, 0, lower-1) - # should not overflow assigning upper limit - a = array.array(self.typecode, [upper]) - a[0] = upper - # should overflow assigning more than upper limit - self.assertRaises(OverflowError, array.array, self.typecode, [upper+1]) - self.assertRaises(OverflowError, a.__setitem__, 0, upper+1) - - def test_subclassing(self): - typecode = self.typecode - class ExaggeratingArray(array.array): - __slots__ = ['offset'] - - def __new__(cls, typecode, data, offset): - return array.array.__new__(cls, typecode, data) - - def __init__(self, typecode, data, offset): - self.offset = offset - - def __getitem__(self, i): - return array.array.__getitem__(self, i) + self.offset - - a = ExaggeratingArray(self.typecode, [3, 6, 7, 11], 4) - self.assertEntryEqual(a[0], 7) - - self.assertRaises(AttributeError, setattr, a, "color", "blue") - - def test_frombytearray(self): - a = array.array('b', range(10)) - b = array.array(self.typecode, a) - self.assertEqual(a, b) - - class IntegerNumberTest(NumberTest): - def test_type_error(self): - a = array.array(self.typecode) - a.append(42) - with self.assertRaises(TypeError): - a.append(42.0) - with self.assertRaises(TypeError): - a[0] = 42.0 - - class Intable: - def __init__(self, num): - self._num = num - def __index__(self): - return self._num - def __int__(self): - return self._num - def __sub__(self, other): - return Intable(int(self) - int(other)) - def __add__(self, other): - return Intable(int(self) + int(other)) - - class SignedNumberTest(IntegerNumberTest): - example = [-1, 0, 1, 42, 0x7f] - smallerexample = [-1, 0, 1, 42, 0x7e] - biggerexample = [-1, 0, 1, 43, 0x7f] - outside = 23 - - def test_overflow(self): - a = array.array(self.typecode) - lower = -1 * int(pow(2, a.itemsize * 8 - 1)) - upper = int(pow(2, a.itemsize * 8 - 1)) - 1 - self.check_overflow(lower, upper) - self.check_overflow(Intable(lower), Intable(upper)) - - class UnsignedNumberTest(IntegerNumberTest): - example = [0, 1, 17, 23, 42, 0xff] - smallerexample = [0, 1, 17, 23, 42, 0xfe] - biggerexample = [0, 1, 17, 23, 43, 0xff] - outside = 0xaa - - def test_overflow(self): - a = array.array(self.typecode) - lower = 0 - upper = int(pow(2, a.itemsize * 8)) - 1 - self.check_overflow(lower, upper) - self.check_overflow(Intable(lower), Intable(upper)) - - def test_bytes_extend(self): - s = bytes(self.example) - - a = array.array(self.typecode, self.example) - a.extend(s) - self.assertEqual( - a, - array.array(self.typecode, self.example+self.example) - ) - - a = array.array(self.typecode, self.example) - a.extend(bytearray(reversed(s))) - self.assertEqual( - a, - array.array(self.typecode, self.example+self.example[::-1]) - ) - - - class ByteTest(SignedNumberTest, unittest.TestCase): - typecode = 'b' - minitemsize = 1 - - class UnsignedByteTest(UnsignedNumberTest, unittest.TestCase): - typecode = 'B' - minitemsize = 1 - - class ShortTest(SignedNumberTest, unittest.TestCase): - typecode = 'h' - minitemsize = 2 - - class UnsignedShortTest(UnsignedNumberTest, unittest.TestCase): - typecode = 'H' - minitemsize = 2 - - class IntTest(SignedNumberTest, unittest.TestCase): - typecode = 'i' - minitemsize = 2 - - class UnsignedIntTest(UnsignedNumberTest, unittest.TestCase): - typecode = 'I' - minitemsize = 2 - - class LongTest(SignedNumberTest, unittest.TestCase): - typecode = 'l' - minitemsize = 4 - - class UnsignedLongTest(UnsignedNumberTest, unittest.TestCase): - typecode = 'L' - minitemsize = 4 - - class LongLongTest(SignedNumberTest, unittest.TestCase): - typecode = 'q' - minitemsize = 8 - - class UnsignedLongLongTest(UnsignedNumberTest, unittest.TestCase): - typecode = 'Q' - minitemsize = 8 - - class FPTest(NumberTest): - example = [-42.0, 0, 42, 1e5, -1e10] - smallerexample = [-42.0, 0, 42, 1e5, -2e10] - biggerexample = [-42.0, 0, 42, 1e5, 1e10] - outside = 23 - - def assertEntryEqual(self, entry1, entry2): - self.assertAlmostEqual(entry1, entry2) - - def test_nan(self): - a = array.array(self.typecode, [float('nan')]) - b = array.array(self.typecode, [float('nan')]) - self.assertIs(a != b, True) - self.assertIs(a == b, False) - self.assertIs(a > b, False) - self.assertIs(a >= b, False) - self.assertIs(a < b, False) - self.assertIs(a <= b, False) - - def test_byteswap(self): - a = array.array(self.typecode, self.example) - self.assertRaises(TypeError, a.byteswap, 42) - if a.itemsize in (1, 2, 4, 8): - b = array.array(self.typecode, self.example) - b.byteswap() - if a.itemsize==1: - self.assertEqual(a, b) - else: - # On alphas treating the byte swapped bit patters as - # floats/doubles results in floating point exceptions - # => compare the 8bit string values instead - self.assertNotEqual(a.tobytes(), b.tobytes()) - b.byteswap() - self.assertEqual(a, b) - - class FloatTest(FPTest, unittest.TestCase): - typecode = 'f' - minitemsize = 4 - - class DoubleTest(FPTest, unittest.TestCase): - typecode = 'd' - minitemsize = 8 - - def test_alloc_overflow(self): - from sys import maxsize - a = array.array('d', [-1]*65536) - try: - a *= maxsize//65536 + 1 - except MemoryError: - pass - else: - self.fail("Array of size > maxsize created - MemoryError expected") - b = array.array('d', [ 2.71828183, 3.14159265, -1]) - try: - b * (maxsize//3 + 1) - except MemoryError: - pass - else: - self.fail("Array of size > maxsize created - MemoryError expected") - - - class LargeArrayTest(unittest.TestCase): - typecode = 'b' - - def example(self, size): - # We assess a base memuse of <=2.125 for constructing this array - base = array.array(self.typecode, [0, 1, 2, 3, 4, 5, 6, 7]) * (size // 8) - base += array.array(self.typecode, [99]*(size % 8) + [8, 9, 10, 11]) - return base - - @support.bigmemtest(_2G, memuse=2.125) - def test_example_data(self, size): - example = self.example(size) - self.assertEqual(len(example), size+4) - - @support.bigmemtest(_2G, memuse=2.125) - def test_access(self, size): - example = self.example(size) - self.assertEqual(example[0], 0) - self.assertEqual(example[-(size+4)], 0) - self.assertEqual(example[size], 8) - self.assertEqual(example[-4], 8) - self.assertEqual(example[size+3], 11) - self.assertEqual(example[-1], 11) - - @support.bigmemtest(_2G, memuse=2.125+1) - def test_slice(self, size): - example = self.example(size) - self.assertEqual(list(example[:4]), [0, 1, 2, 3]) - self.assertEqual(list(example[-4:]), [8, 9, 10, 11]) - part = example[1:-1] - self.assertEqual(len(part), size+2) - self.assertEqual(part[0], 1) - self.assertEqual(part[-1], 10) - del part - part = example[::2] - self.assertEqual(len(part), (size+5)//2) - self.assertEqual(list(part[:4]), [0, 2, 4, 6]) - if size % 2: - self.assertEqual(list(part[-2:]), [9, 11]) - else: - self.assertEqual(list(part[-2:]), [8, 10]) - - @support.bigmemtest(_2G, memuse=2.125) - def test_count(self, size): - example = self.example(size) - self.assertEqual(example.count(0), size//8) - self.assertEqual(example.count(11), 1) - - @support.bigmemtest(_2G, memuse=2.125) - def test_append(self, size): - example = self.example(size) - example.append(12) - self.assertEqual(example[-1], 12) - - @support.bigmemtest(_2G, memuse=2.125) - def test_extend(self, size): - example = self.example(size) - example.extend(iter([12, 13, 14, 15])) - self.assertEqual(len(example), size+8) - self.assertEqual(list(example[-8:]), [8, 9, 10, 11, 12, 13, 14, 15]) - - @support.bigmemtest(_2G, memuse=2.125) - def test_frombytes(self, size): - example = self.example(size) - example.frombytes(b'abcd') - self.assertEqual(len(example), size+8) - self.assertEqual(list(example[-8:]), [8, 9, 10, 11] + list(b'abcd')) - - @support.bigmemtest(_2G, memuse=2.125) - def test_fromlist(self, size): - example = self.example(size) - example.fromlist([12, 13, 14, 15]) - self.assertEqual(len(example), size+8) - self.assertEqual(list(example[-8:]), [8, 9, 10, 11, 12, 13, 14, 15]) - - @support.bigmemtest(_2G, memuse=2.125) - def test_index(self, size): - example = self.example(size) - self.assertEqual(example.index(0), 0) - self.assertEqual(example.index(1), 1) - self.assertEqual(example.index(7), 7) - self.assertEqual(example.index(11), size+3) - - @support.bigmemtest(_2G, memuse=2.125) - def test_insert(self, size): - example = self.example(size) - example.insert(0, 12) - example.insert(10, 13) - example.insert(size+1, 14) - self.assertEqual(len(example), size+7) - self.assertEqual(example[0], 12) - self.assertEqual(example[10], 13) - self.assertEqual(example[size+1], 14) - - @support.bigmemtest(_2G, memuse=2.125) - def test_pop(self, size): - example = self.example(size) - self.assertEqual(example.pop(0), 0) - self.assertEqual(example[0], 1) - self.assertEqual(example.pop(size+1), 10) - self.assertEqual(example[size+1], 11) - self.assertEqual(example.pop(1), 2) - self.assertEqual(example[1], 3) - self.assertEqual(len(example), size+1) - self.assertEqual(example.pop(), 11) - self.assertEqual(len(example), size) - - @support.bigmemtest(_2G, memuse=2.125) - def test_remove(self, size): - example = self.example(size) - example.remove(0) - self.assertEqual(len(example), size+3) - self.assertEqual(example[0], 1) - example.remove(10) - self.assertEqual(len(example), size+2) - self.assertEqual(example[size], 9) - self.assertEqual(example[size+1], 11) - - @support.bigmemtest(_2G, memuse=2.125) - def test_reverse(self, size): - example = self.example(size) - example.reverse() - self.assertEqual(len(example), size+4) - self.assertEqual(example[0], 11) - self.assertEqual(example[3], 8) - self.assertEqual(example[-1], 0) - example.reverse() - self.assertEqual(len(example), size+4) - self.assertEqual(list(example[:4]), [0, 1, 2, 3]) - self.assertEqual(list(example[-4:]), [8, 9, 10, 11]) - - # list takes about 9 bytes per element - @support.bigmemtest(_2G, memuse=2.125+9) - def test_tolist(self, size): - example = self.example(size) - ls = example.tolist() - self.assertEqual(len(ls), len(example)) - self.assertEqual(ls[:8], list(example[:8])) - self.assertEqual(ls[-8:], list(example[-8:])) - - if __name__ == "__main__": - unittest.main() diff --git a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_ast.yaml b/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_ast.yaml deleted file mode 100644 index 7e50f4eb0..000000000 --- a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_ast.yaml +++ /dev/null @@ -1,1972 +0,0 @@ -python: | - import ast - import dis - import os - import sys - import unittest - import warnings - import weakref - from textwrap import dedent - - from test import support - - def to_tuple(t): - if t is None or isinstance(t, (str, int, complex)): - return t - elif isinstance(t, list): - return [to_tuple(e) for e in t] - result = [t.__class__.__name__] - if hasattr(t, 'lineno') and hasattr(t, 'col_offset'): - result.append((t.lineno, t.col_offset)) - if t._fields is None: - return tuple(result) - for f in t._fields: - result.append(to_tuple(getattr(t, f))) - return tuple(result) - - - # These tests are compiled through "exec" - # There should be at least one test per statement - exec_tests = [ - # None - "None", - # Module docstring - "'module docstring'", - # FunctionDef - "def f(): pass", - # FunctionDef with docstring - "def f(): 'function docstring'", - # FunctionDef with arg - "def f(a): pass", - # FunctionDef with arg and default value - "def f(a=0): pass", - # FunctionDef with varargs - "def f(*args): pass", - # FunctionDef with kwargs - "def f(**kwargs): pass", - # FunctionDef with all kind of args and docstring - "def f(a, b=1, c=None, d=[], e={}, *args, f=42, **kwargs): 'doc for f()'", - # ClassDef - "class C:pass", - # ClassDef with docstring - "class C: 'docstring for class C'", - # ClassDef, new style class - "class C(object): pass", - # Return - "def f():return 1", - # Delete - "del v", - # Assign - "v = 1", - "a,b = c", - "(a,b) = c", - "[a,b] = c", - # AugAssign - "v += 1", - # For - "for v in v:pass", - # While - "while v:pass", - # If - "if v:pass", - # If-Elif - "if a:\n pass\nelif b:\n pass", - # If-Elif-Else - "if a:\n pass\nelif b:\n pass\nelse:\n pass", - # With - "with x as y: pass", - "with x as y, z as q: pass", - # Raise - "raise Exception('string')", - # TryExcept - "try:\n pass\nexcept Exception:\n pass", - # TryFinally - "try:\n pass\nfinally:\n pass", - # Assert - "assert v", - # Import - "import sys", - # ImportFrom - "from sys import v", - # Global - "global v", - # Expr - "1", - # Pass, - "pass", - # Break - "for v in v:break", - # Continue - "for v in v:continue", - # for statements with naked tuples (see http://bugs.python.org/issue6704) - "for a,b in c: pass", - "for (a,b) in c: pass", - "for [a,b] in c: pass", - # Multiline generator expression (test for .lineno & .col_offset) - """( - ( - Aa - , - Bb - ) - for - Aa - , - Bb in Cc - )""", - # dictcomp - "{a : b for w in x for m in p if g}", - # dictcomp with naked tuple - "{a : b for v,w in x}", - # setcomp - "{r for l in x if g}", - # setcomp with naked tuple - "{r for l,m in x}", - # AsyncFunctionDef - "async def f():\n 'async function'\n await something()", - # AsyncFor - "async def f():\n async for e in i: 1\n else: 2", - # AsyncWith - "async def f():\n async with a as b: 1", - # PEP 448: Additional Unpacking Generalizations - "{**{1:2}, 2:3}", - "{*{1, 2}, 3}", - # Asynchronous comprehensions - "async def f():\n [i async for b in c]", - # Decorated FunctionDef - "@deco1\n@deco2()\n@deco3(1)\ndef f(): pass", - # Decorated AsyncFunctionDef - "@deco1\n@deco2()\n@deco3(1)\nasync def f(): pass", - # Decorated ClassDef - "@deco1\n@deco2()\n@deco3(1)\nclass C: pass", - # Decorator with generator argument - "@deco(a for a in b)\ndef f(): pass", - # Decorator with attribute - "@a.b.c\ndef f(): pass", - # Simple assignment expression - "(a := 1)", - # Positional-only arguments - "def f(a, /,): pass", - "def f(a, /, c, d, e): pass", - "def f(a, /, c, *, d, e): pass", - "def f(a, /, c, *, d, e, **kwargs): pass", - # Positional-only arguments with defaults - "def f(a=1, /,): pass", - "def f(a=1, /, b=2, c=4): pass", - "def f(a=1, /, b=2, *, c=4): pass", - "def f(a=1, /, b=2, *, c): pass", - "def f(a=1, /, b=2, *, c=4, **kwargs): pass", - "def f(a=1, /, b=2, *, c, **kwargs): pass", - - ] - - # These are compiled through "single" - # because of overlap with "eval", it just tests what - # can't be tested with "eval" - single_tests = [ - "1+2" - ] - - # These are compiled through "eval" - # It should test all expressions - eval_tests = [ - # None - "None", - # BoolOp - "a and b", - # BinOp - "a + b", - # UnaryOp - "not v", - # Lambda - "lambda:None", - # Dict - "{ 1:2 }", - # Empty dict - "{}", - # Set - "{None,}", - # Multiline dict (test for .lineno & .col_offset) - """{ - 1 - : - 2 - }""", - # ListComp - "[a for b in c if d]", - # GeneratorExp - "(a for b in c if d)", - # Comprehensions with multiple for targets - "[(a,b) for a,b in c]", - "[(a,b) for (a,b) in c]", - "[(a,b) for [a,b] in c]", - "{(a,b) for a,b in c}", - "{(a,b) for (a,b) in c}", - "{(a,b) for [a,b] in c}", - "((a,b) for a,b in c)", - "((a,b) for (a,b) in c)", - "((a,b) for [a,b] in c)", - # Yield - yield expressions can't work outside a function - # - # Compare - "1 < 2 < 3", - # Call - "f(1,2,c=3,*d,**e)", - # Call with multi-character starred - "f(*[0, 1])", - # Call with a generator argument - "f(a for a in b)", - # Num - "10", - # Str - "'string'", - # Attribute - "a.b", - # Subscript - "a[b:c]", - # Name - "v", - # List - "[1,2,3]", - # Empty list - "[]", - # Tuple - "1,2,3", - # Tuple - "(1,2,3)", - # Empty tuple - "()", - # Combination - "a.b.c.d(a.b[1:2])", - - ] - - # TODO: expr_context, slice, boolop, operator, unaryop, cmpop, comprehension - # excepthandler, arguments, keywords, alias - - class AST_Tests(unittest.TestCase): - - def _assertTrueorder(self, ast_node, parent_pos): - if not isinstance(ast_node, ast.AST) or ast_node._fields is None: - return - if isinstance(ast_node, (ast.expr, ast.stmt, ast.excepthandler)): - node_pos = (ast_node.lineno, ast_node.col_offset) - self.assertGreaterEqual(node_pos, parent_pos) - parent_pos = (ast_node.lineno, ast_node.col_offset) - for name in ast_node._fields: - value = getattr(ast_node, name) - if isinstance(value, list): - first_pos = parent_pos - if value and name == 'decorator_list': - first_pos = (value[0].lineno, value[0].col_offset) - for child in value: - self._assertTrueorder(child, first_pos) - elif value is not None: - self._assertTrueorder(value, parent_pos) - - def test_AST_objects(self): - x = ast.AST() - self.assertEqual(x._fields, ()) - x.foobar = 42 - self.assertEqual(x.foobar, 42) - self.assertEqual(x.__dict__["foobar"], 42) - - with self.assertRaises(AttributeError): - x.vararg - - with self.assertRaises(TypeError): - # "_ast.AST constructor takes 0 positional arguments" - ast.AST(2) - - def test_AST_garbage_collection(self): - class X: - pass - a = ast.AST() - a.x = X() - a.x.a = a - ref = weakref.ref(a.x) - del a - support.gc_collect() - self.assertIsNone(ref()) - - def test_snippets(self): - for input, output, kind in ((exec_tests, exec_results, "exec"), - (single_tests, single_results, "single"), - (eval_tests, eval_results, "eval")): - for i, o in zip(input, output): - with self.subTest(action="parsing", input=i): - ast_tree = compile(i, "?", kind, ast.PyCF_ONLY_AST) - self.assertEqual(to_tuple(ast_tree), o) - self._assertTrueorder(ast_tree, (0, 0)) - with self.subTest(action="compiling", input=i, kind=kind): - compile(ast_tree, "?", kind) - - def test_ast_validation(self): - # compile() is the only function that calls PyAST_Validate - snippets_to_validate = exec_tests + single_tests + eval_tests - for snippet in snippets_to_validate: - tree = ast.parse(snippet) - compile(tree, '', 'exec') - - def test_slice(self): - slc = ast.parse("x[::]").body[0].value.slice - self.assertIsNone(slc.upper) - self.assertIsNone(slc.lower) - self.assertIsNone(slc.step) - - def test_from_import(self): - im = ast.parse("from . import y").body[0] - self.assertIsNone(im.module) - - def test_non_interned_future_from_ast(self): - mod = ast.parse("from __future__ import division") - self.assertIsInstance(mod.body[0], ast.ImportFrom) - mod.body[0].module = " __future__ ".strip() - compile(mod, "", "exec") - - def test_base_classes(self): - self.assertTrue(issubclass(ast.For, ast.stmt)) - self.assertTrue(issubclass(ast.Name, ast.expr)) - self.assertTrue(issubclass(ast.stmt, ast.AST)) - self.assertTrue(issubclass(ast.expr, ast.AST)) - self.assertTrue(issubclass(ast.comprehension, ast.AST)) - self.assertTrue(issubclass(ast.Gt, ast.AST)) - - def test_field_attr_existence(self): - for name, item in ast.__dict__.items(): - if isinstance(item, type) and name != 'AST' and name[0].isupper(): - x = item() - if isinstance(x, ast.AST): - self.assertEqual(type(x._fields), tuple) - - def test_arguments(self): - x = ast.arguments() - self.assertEqual(x._fields, ('posonlyargs', 'args', 'vararg', 'kwonlyargs', - 'kw_defaults', 'kwarg', 'defaults')) - - with self.assertRaises(AttributeError): - x.vararg - - x = ast.arguments(*range(1, 8)) - self.assertEqual(x.vararg, 3) - - def test_field_attr_writable(self): - x = ast.Num() - # We can assign to _fields - x._fields = 666 - self.assertEqual(x._fields, 666) - - def test_classattrs(self): - x = ast.Num() - self.assertEqual(x._fields, ('value', 'kind')) - - with self.assertRaises(AttributeError): - x.value - - with self.assertRaises(AttributeError): - x.n - - x = ast.Num(42) - self.assertEqual(x.value, 42) - self.assertEqual(x.n, 42) - - with self.assertRaises(AttributeError): - x.lineno - - with self.assertRaises(AttributeError): - x.foobar - - x = ast.Num(lineno=2) - self.assertEqual(x.lineno, 2) - - x = ast.Num(42, lineno=0) - self.assertEqual(x.lineno, 0) - self.assertEqual(x._fields, ('value', 'kind')) - self.assertEqual(x.value, 42) - self.assertEqual(x.n, 42) - - self.assertRaises(TypeError, ast.Num, 1, None, 2) - self.assertRaises(TypeError, ast.Num, 1, None, 2, lineno=0) - - # Arbitrary keyword arguments are supported - self.assertEqual(ast.Constant(1, foo='bar').foo, 'bar') - self.assertEqual(ast.Num(1, foo='bar').foo, 'bar') - - with self.assertRaisesRegex(TypeError, "Num got multiple values for argument 'n'"): - ast.Num(1, n=2) - with self.assertRaisesRegex(TypeError, "Constant got multiple values for argument 'value'"): - ast.Constant(1, value=2) - - self.assertEqual(ast.Num(42).n, 42) - self.assertEqual(ast.Num(4.25).n, 4.25) - self.assertEqual(ast.Num(4.25j).n, 4.25j) - self.assertEqual(ast.Str('42').s, '42') - self.assertEqual(ast.Bytes(b'42').s, b'42') - self.assertIs(ast.NameConstant(True).value, True) - self.assertIs(ast.NameConstant(False).value, False) - self.assertIs(ast.NameConstant(None).value, None) - - self.assertEqual(ast.Constant(42).value, 42) - self.assertEqual(ast.Constant(4.25).value, 4.25) - self.assertEqual(ast.Constant(4.25j).value, 4.25j) - self.assertEqual(ast.Constant('42').value, '42') - self.assertEqual(ast.Constant(b'42').value, b'42') - self.assertIs(ast.Constant(True).value, True) - self.assertIs(ast.Constant(False).value, False) - self.assertIs(ast.Constant(None).value, None) - self.assertIs(ast.Constant(...).value, ...) - - def test_realtype(self): - self.assertEqual(type(ast.Num(42)), ast.Constant) - self.assertEqual(type(ast.Num(4.25)), ast.Constant) - self.assertEqual(type(ast.Num(4.25j)), ast.Constant) - self.assertEqual(type(ast.Str('42')), ast.Constant) - self.assertEqual(type(ast.Bytes(b'42')), ast.Constant) - self.assertEqual(type(ast.NameConstant(True)), ast.Constant) - self.assertEqual(type(ast.NameConstant(False)), ast.Constant) - self.assertEqual(type(ast.NameConstant(None)), ast.Constant) - self.assertEqual(type(ast.Ellipsis()), ast.Constant) - - def test_isinstance(self): - self.assertTrue(isinstance(ast.Num(42), ast.Num)) - self.assertTrue(isinstance(ast.Num(4.2), ast.Num)) - self.assertTrue(isinstance(ast.Num(4.2j), ast.Num)) - self.assertTrue(isinstance(ast.Str('42'), ast.Str)) - self.assertTrue(isinstance(ast.Bytes(b'42'), ast.Bytes)) - self.assertTrue(isinstance(ast.NameConstant(True), ast.NameConstant)) - self.assertTrue(isinstance(ast.NameConstant(False), ast.NameConstant)) - self.assertTrue(isinstance(ast.NameConstant(None), ast.NameConstant)) - self.assertTrue(isinstance(ast.Ellipsis(), ast.Ellipsis)) - - self.assertTrue(isinstance(ast.Constant(42), ast.Num)) - self.assertTrue(isinstance(ast.Constant(4.2), ast.Num)) - self.assertTrue(isinstance(ast.Constant(4.2j), ast.Num)) - self.assertTrue(isinstance(ast.Constant('42'), ast.Str)) - self.assertTrue(isinstance(ast.Constant(b'42'), ast.Bytes)) - self.assertTrue(isinstance(ast.Constant(True), ast.NameConstant)) - self.assertTrue(isinstance(ast.Constant(False), ast.NameConstant)) - self.assertTrue(isinstance(ast.Constant(None), ast.NameConstant)) - self.assertTrue(isinstance(ast.Constant(...), ast.Ellipsis)) - - self.assertFalse(isinstance(ast.Str('42'), ast.Num)) - self.assertFalse(isinstance(ast.Num(42), ast.Str)) - self.assertFalse(isinstance(ast.Str('42'), ast.Bytes)) - self.assertFalse(isinstance(ast.Num(42), ast.NameConstant)) - self.assertFalse(isinstance(ast.Num(42), ast.Ellipsis)) - self.assertFalse(isinstance(ast.NameConstant(True), ast.Num)) - self.assertFalse(isinstance(ast.NameConstant(False), ast.Num)) - - self.assertFalse(isinstance(ast.Constant('42'), ast.Num)) - self.assertFalse(isinstance(ast.Constant(42), ast.Str)) - self.assertFalse(isinstance(ast.Constant('42'), ast.Bytes)) - self.assertFalse(isinstance(ast.Constant(42), ast.NameConstant)) - self.assertFalse(isinstance(ast.Constant(42), ast.Ellipsis)) - self.assertFalse(isinstance(ast.Constant(True), ast.Num)) - self.assertFalse(isinstance(ast.Constant(False), ast.Num)) - - self.assertFalse(isinstance(ast.Constant(), ast.Num)) - self.assertFalse(isinstance(ast.Constant(), ast.Str)) - self.assertFalse(isinstance(ast.Constant(), ast.Bytes)) - self.assertFalse(isinstance(ast.Constant(), ast.NameConstant)) - self.assertFalse(isinstance(ast.Constant(), ast.Ellipsis)) - - class S(str): pass - self.assertTrue(isinstance(ast.Constant(S('42')), ast.Str)) - self.assertFalse(isinstance(ast.Constant(S('42')), ast.Num)) - - def test_subclasses(self): - class N(ast.Num): - def __init__(self, *args, **kwargs): - super().__init__(*args, **kwargs) - self.z = 'spam' - class N2(ast.Num): - pass - - n = N(42) - self.assertEqual(n.n, 42) - self.assertEqual(n.z, 'spam') - self.assertEqual(type(n), N) - self.assertTrue(isinstance(n, N)) - self.assertTrue(isinstance(n, ast.Num)) - self.assertFalse(isinstance(n, N2)) - self.assertFalse(isinstance(ast.Num(42), N)) - n = N(n=42) - self.assertEqual(n.n, 42) - self.assertEqual(type(n), N) - - def test_module(self): - body = [ast.Num(42)] - x = ast.Module(body, []) - self.assertEqual(x.body, body) - - def test_nodeclasses(self): - # Zero arguments constructor explicitly allowed - x = ast.BinOp() - self.assertEqual(x._fields, ('left', 'op', 'right')) - - # Random attribute allowed too - x.foobarbaz = 5 - self.assertEqual(x.foobarbaz, 5) - - n1 = ast.Num(1) - n3 = ast.Num(3) - addop = ast.Add() - x = ast.BinOp(n1, addop, n3) - self.assertEqual(x.left, n1) - self.assertEqual(x.op, addop) - self.assertEqual(x.right, n3) - - x = ast.BinOp(1, 2, 3) - self.assertEqual(x.left, 1) - self.assertEqual(x.op, 2) - self.assertEqual(x.right, 3) - - x = ast.BinOp(1, 2, 3, lineno=0) - self.assertEqual(x.left, 1) - self.assertEqual(x.op, 2) - self.assertEqual(x.right, 3) - self.assertEqual(x.lineno, 0) - - # node raises exception when given too many arguments - self.assertRaises(TypeError, ast.BinOp, 1, 2, 3, 4) - # node raises exception when given too many arguments - self.assertRaises(TypeError, ast.BinOp, 1, 2, 3, 4, lineno=0) - - # can set attributes through kwargs too - x = ast.BinOp(left=1, op=2, right=3, lineno=0) - self.assertEqual(x.left, 1) - self.assertEqual(x.op, 2) - self.assertEqual(x.right, 3) - self.assertEqual(x.lineno, 0) - - # Random kwargs also allowed - x = ast.BinOp(1, 2, 3, foobarbaz=42) - self.assertEqual(x.foobarbaz, 42) - - def test_no_fields(self): - # this used to fail because Sub._fields was None - x = ast.Sub() - self.assertEqual(x._fields, ()) - - def test_pickling(self): - import pickle - mods = [pickle] - try: - import cPickle - mods.append(cPickle) - except ImportError: - pass - protocols = [0, 1, 2] - for mod in mods: - for protocol in protocols: - for ast in (compile(i, "?", "exec", 0x400) for i in exec_tests): - ast2 = mod.loads(mod.dumps(ast, protocol)) - self.assertEqual(to_tuple(ast2), to_tuple(ast)) - - def test_invalid_sum(self): - pos = dict(lineno=2, col_offset=3) - m = ast.Module([ast.Expr(ast.expr(**pos), **pos)], []) - with self.assertRaises(TypeError) as cm: - compile(m, "", "exec") - self.assertIn("but got <_ast.expr", str(cm.exception)) - - def test_invalid_identitifer(self): - m = ast.Module([ast.Expr(ast.Name(42, ast.Load()))], []) - ast.fix_missing_locations(m) - with self.assertRaises(TypeError) as cm: - compile(m, "", "exec") - self.assertIn("identifier must be of type str", str(cm.exception)) - - def test_empty_yield_from(self): - # Issue 16546: yield from value is not optional. - empty_yield_from = ast.parse("def f():\n yield from g()") - empty_yield_from.body[0].body[0].value.value = None - with self.assertRaises(ValueError) as cm: - compile(empty_yield_from, "", "exec") - self.assertIn("field value is required", str(cm.exception)) - - @support.cpython_only - def test_issue31592(self): - # There shouldn't be an assertion failure in case of a bad - # unicodedata.normalize(). - import unicodedata - def bad_normalize(*args): - return None - with support.swap_attr(unicodedata, 'normalize', bad_normalize): - self.assertRaises(TypeError, ast.parse, '\u03D5') - - def test_issue18374_binop_col_offset(self): - tree = ast.parse('4+5+6+7') - parent_binop = tree.body[0].value - child_binop = parent_binop.left - grandchild_binop = child_binop.left - self.assertEqual(parent_binop.col_offset, 0) - self.assertEqual(parent_binop.end_col_offset, 7) - self.assertEqual(child_binop.col_offset, 0) - self.assertEqual(child_binop.end_col_offset, 5) - self.assertEqual(grandchild_binop.col_offset, 0) - self.assertEqual(grandchild_binop.end_col_offset, 3) - - tree = ast.parse('4+5-\\\n 6-7') - parent_binop = tree.body[0].value - child_binop = parent_binop.left - grandchild_binop = child_binop.left - self.assertEqual(parent_binop.col_offset, 0) - self.assertEqual(parent_binop.lineno, 1) - self.assertEqual(parent_binop.end_col_offset, 4) - self.assertEqual(parent_binop.end_lineno, 2) - - self.assertEqual(child_binop.col_offset, 0) - self.assertEqual(child_binop.lineno, 1) - self.assertEqual(child_binop.end_col_offset, 2) - self.assertEqual(child_binop.end_lineno, 2) - - self.assertEqual(grandchild_binop.col_offset, 0) - self.assertEqual(grandchild_binop.lineno, 1) - self.assertEqual(grandchild_binop.end_col_offset, 3) - self.assertEqual(grandchild_binop.end_lineno, 1) - - def test_issue39579_dotted_name_end_col_offset(self): - tree = ast.parse('@a.b.c\ndef f(): pass') - attr_b = tree.body[0].decorator_list[0].value - self.assertEqual(attr_b.end_col_offset, 4) - - def test_issue40614_feature_version(self): - ast.parse('f"{x=}"', feature_version=(3, 8)) - with self.assertRaises(SyntaxError): - ast.parse('f"{x=}"', feature_version=(3, 7)) - - def test_constant_as_name(self): - for constant in "True", "False", "None": - expr = ast.Expression(ast.Name(constant, ast.Load())) - ast.fix_missing_locations(expr) - with self.assertRaisesRegex(ValueError, f"Name node can't be used with '{constant}' constant"): - compile(expr, "", "eval") - - - class ASTHelpers_Test(unittest.TestCase): - maxDiff = None - - def test_parse(self): - a = ast.parse('foo(1 + 1)') - b = compile('foo(1 + 1)', '', 'exec', ast.PyCF_ONLY_AST) - self.assertEqual(ast.dump(a), ast.dump(b)) - - def test_parse_in_error(self): - try: - 1/0 - except Exception: - with self.assertRaises(SyntaxError) as e: - ast.literal_eval(r"'\U'") - self.assertIsNotNone(e.exception.__context__) - - def test_dump(self): - node = ast.parse('spam(eggs, "and cheese")') - self.assertEqual(ast.dump(node), - "Module(body=[Expr(value=Call(func=Name(id='spam', ctx=Load()), " - "args=[Name(id='eggs', ctx=Load()), Constant(value='and cheese', kind=None)], " - "keywords=[]))], type_ignores=[])" - ) - self.assertEqual(ast.dump(node, annotate_fields=False), - "Module([Expr(Call(Name('spam', Load()), [Name('eggs', Load()), " - "Constant('and cheese', None)], []))], [])" - ) - self.assertEqual(ast.dump(node, include_attributes=True), - "Module(body=[Expr(value=Call(func=Name(id='spam', ctx=Load(), " - "lineno=1, col_offset=0, end_lineno=1, end_col_offset=4), " - "args=[Name(id='eggs', ctx=Load(), lineno=1, col_offset=5, " - "end_lineno=1, end_col_offset=9), Constant(value='and cheese', kind=None, " - "lineno=1, col_offset=11, end_lineno=1, end_col_offset=23)], keywords=[], " - "lineno=1, col_offset=0, end_lineno=1, end_col_offset=24), " - "lineno=1, col_offset=0, end_lineno=1, end_col_offset=24)], type_ignores=[])" - ) - - def test_dump_incomplete(self): - node = ast.Raise(lineno=3, col_offset=4) - self.assertEqual(ast.dump(node), - "Raise()" - ) - self.assertEqual(ast.dump(node, include_attributes=True), - "Raise(lineno=3, col_offset=4)" - ) - node = ast.Raise(exc=ast.Name(id='e', ctx=ast.Load()), lineno=3, col_offset=4) - self.assertEqual(ast.dump(node), - "Raise(exc=Name(id='e', ctx=Load()))" - ) - self.assertEqual(ast.dump(node, annotate_fields=False), - "Raise(Name('e', Load()))" - ) - self.assertEqual(ast.dump(node, include_attributes=True), - "Raise(exc=Name(id='e', ctx=Load()), lineno=3, col_offset=4)" - ) - self.assertEqual(ast.dump(node, annotate_fields=False, include_attributes=True), - "Raise(Name('e', Load()), lineno=3, col_offset=4)" - ) - node = ast.Raise(cause=ast.Name(id='e', ctx=ast.Load())) - self.assertEqual(ast.dump(node), - "Raise(cause=Name(id='e', ctx=Load()))" - ) - self.assertEqual(ast.dump(node, annotate_fields=False), - "Raise(cause=Name('e', Load()))" - ) - - def test_copy_location(self): - src = ast.parse('1 + 1', mode='eval') - src.body.right = ast.copy_location(ast.Num(2), src.body.right) - self.assertEqual(ast.dump(src, include_attributes=True), - 'Expression(body=BinOp(left=Constant(value=1, kind=None, lineno=1, col_offset=0, ' - 'end_lineno=1, end_col_offset=1), op=Add(), right=Constant(value=2, ' - 'lineno=1, col_offset=4, end_lineno=1, end_col_offset=5), lineno=1, ' - 'col_offset=0, end_lineno=1, end_col_offset=5))' - ) - src = ast.Call(col_offset=1, lineno=1, end_lineno=1, end_col_offset=1) - new = ast.copy_location(src, ast.Call( - col_offset=None, lineno=None, - end_lineno=None, end_col_offset=None - )) - self.assertIsNone(new.end_lineno) - self.assertIsNone(new.end_col_offset) - self.assertEqual(new.lineno, 1) - self.assertEqual(new.col_offset, 1) - - def test_fix_missing_locations(self): - src = ast.parse('write("spam")') - src.body.append(ast.Expr(ast.Call(ast.Name('spam', ast.Load()), - [ast.Str('eggs')], []))) - self.assertEqual(src, ast.fix_missing_locations(src)) - self.maxDiff = None - self.assertEqual(ast.dump(src, include_attributes=True), - "Module(body=[Expr(value=Call(func=Name(id='write', ctx=Load(), " - "lineno=1, col_offset=0, end_lineno=1, end_col_offset=5), " - "args=[Constant(value='spam', kind=None, lineno=1, col_offset=6, end_lineno=1, " - "end_col_offset=12)], keywords=[], lineno=1, col_offset=0, end_lineno=1, " - "end_col_offset=13), lineno=1, col_offset=0, end_lineno=1, " - "end_col_offset=13), Expr(value=Call(func=Name(id='spam', ctx=Load(), " - "lineno=1, col_offset=0, end_lineno=1, end_col_offset=0), " - "args=[Constant(value='eggs', lineno=1, col_offset=0, end_lineno=1, " - "end_col_offset=0)], keywords=[], lineno=1, col_offset=0, end_lineno=1, " - "end_col_offset=0), lineno=1, col_offset=0, end_lineno=1, end_col_offset=0)], " - "type_ignores=[])" - ) - - def test_increment_lineno(self): - src = ast.parse('1 + 1', mode='eval') - self.assertEqual(ast.increment_lineno(src, n=3), src) - self.assertEqual(ast.dump(src, include_attributes=True), - 'Expression(body=BinOp(left=Constant(value=1, kind=None, lineno=4, col_offset=0, ' - 'end_lineno=4, end_col_offset=1), op=Add(), right=Constant(value=1, kind=None, ' - 'lineno=4, col_offset=4, end_lineno=4, end_col_offset=5), lineno=4, ' - 'col_offset=0, end_lineno=4, end_col_offset=5))' - ) - # issue10869: do not increment lineno of root twice - src = ast.parse('1 + 1', mode='eval') - self.assertEqual(ast.increment_lineno(src.body, n=3), src.body) - self.assertEqual(ast.dump(src, include_attributes=True), - 'Expression(body=BinOp(left=Constant(value=1, kind=None, lineno=4, col_offset=0, ' - 'end_lineno=4, end_col_offset=1), op=Add(), right=Constant(value=1, kind=None, ' - 'lineno=4, col_offset=4, end_lineno=4, end_col_offset=5), lineno=4, ' - 'col_offset=0, end_lineno=4, end_col_offset=5))' - ) - src = ast.Call( - func=ast.Name("test", ast.Load()), args=[], keywords=[], - lineno=1, end_lineno=None - ) - self.assertEqual(ast.increment_lineno(src).lineno, 2) - self.assertIsNone(ast.increment_lineno(src).end_lineno) - - def test_iter_fields(self): - node = ast.parse('foo()', mode='eval') - d = dict(ast.iter_fields(node.body)) - self.assertEqual(d.pop('func').id, 'foo') - self.assertEqual(d, {'keywords': [], 'args': []}) - - def test_iter_child_nodes(self): - node = ast.parse("spam(23, 42, eggs='leek')", mode='eval') - self.assertEqual(len(list(ast.iter_child_nodes(node.body))), 4) - iterator = ast.iter_child_nodes(node.body) - self.assertEqual(next(iterator).id, 'spam') - self.assertEqual(next(iterator).value, 23) - self.assertEqual(next(iterator).value, 42) - self.assertEqual(ast.dump(next(iterator)), - "keyword(arg='eggs', value=Constant(value='leek', kind=None))" - ) - - def test_get_docstring(self): - node = ast.parse('"""line one\n line two"""') - self.assertEqual(ast.get_docstring(node), - 'line one\nline two') - - node = ast.parse('class foo:\n """line one\n line two"""') - self.assertEqual(ast.get_docstring(node.body[0]), - 'line one\nline two') - - node = ast.parse('def foo():\n """line one\n line two"""') - self.assertEqual(ast.get_docstring(node.body[0]), - 'line one\nline two') - - node = ast.parse('async def foo():\n """spam\n ham"""') - self.assertEqual(ast.get_docstring(node.body[0]), 'spam\nham') - - def test_get_docstring_none(self): - self.assertIsNone(ast.get_docstring(ast.parse(''))) - node = ast.parse('x = "not docstring"') - self.assertIsNone(ast.get_docstring(node)) - node = ast.parse('def foo():\n pass') - self.assertIsNone(ast.get_docstring(node)) - - node = ast.parse('class foo:\n pass') - self.assertIsNone(ast.get_docstring(node.body[0])) - node = ast.parse('class foo:\n x = "not docstring"') - self.assertIsNone(ast.get_docstring(node.body[0])) - node = ast.parse('class foo:\n def bar(self): pass') - self.assertIsNone(ast.get_docstring(node.body[0])) - - node = ast.parse('def foo():\n pass') - self.assertIsNone(ast.get_docstring(node.body[0])) - node = ast.parse('def foo():\n x = "not docstring"') - self.assertIsNone(ast.get_docstring(node.body[0])) - - node = ast.parse('async def foo():\n pass') - self.assertIsNone(ast.get_docstring(node.body[0])) - node = ast.parse('async def foo():\n x = "not docstring"') - self.assertIsNone(ast.get_docstring(node.body[0])) - - def test_multi_line_docstring_col_offset_and_lineno_issue16806(self): - node = ast.parse( - '"""line one\nline two"""\n\n' - 'def foo():\n """line one\n line two"""\n\n' - ' def bar():\n """line one\n line two"""\n' - ' """line one\n line two"""\n' - '"""line one\nline two"""\n\n' - ) - self.assertEqual(node.body[0].col_offset, 0) - self.assertEqual(node.body[0].lineno, 1) - self.assertEqual(node.body[1].body[0].col_offset, 2) - self.assertEqual(node.body[1].body[0].lineno, 5) - self.assertEqual(node.body[1].body[1].body[0].col_offset, 4) - self.assertEqual(node.body[1].body[1].body[0].lineno, 9) - self.assertEqual(node.body[1].body[2].col_offset, 2) - self.assertEqual(node.body[1].body[2].lineno, 11) - self.assertEqual(node.body[2].col_offset, 0) - self.assertEqual(node.body[2].lineno, 13) - - def test_elif_stmt_start_position(self): - node = ast.parse('if a:\n pass\nelif b:\n pass\n') - elif_stmt = node.body[0].orelse[0] - self.assertEqual(elif_stmt.lineno, 3) - self.assertEqual(elif_stmt.col_offset, 0) - - def test_elif_stmt_start_position_with_else(self): - node = ast.parse('if a:\n pass\nelif b:\n pass\nelse:\n pass\n') - elif_stmt = node.body[0].orelse[0] - self.assertEqual(elif_stmt.lineno, 3) - self.assertEqual(elif_stmt.col_offset, 0) - - def test_starred_expr_end_position_within_call(self): - node = ast.parse('f(*[0, 1])') - starred_expr = node.body[0].value.args[0] - self.assertEqual(starred_expr.end_lineno, 1) - self.assertEqual(starred_expr.end_col_offset, 9) - - def test_literal_eval(self): - self.assertEqual(ast.literal_eval('[1, 2, 3]'), [1, 2, 3]) - self.assertEqual(ast.literal_eval('{"foo": 42}'), {"foo": 42}) - self.assertEqual(ast.literal_eval('(True, False, None)'), (True, False, None)) - self.assertEqual(ast.literal_eval('{1, 2, 3}'), {1, 2, 3}) - self.assertEqual(ast.literal_eval('b"hi"'), b"hi") - self.assertRaises(ValueError, ast.literal_eval, 'foo()') - self.assertEqual(ast.literal_eval('6'), 6) - self.assertEqual(ast.literal_eval('+6'), 6) - self.assertEqual(ast.literal_eval('-6'), -6) - self.assertEqual(ast.literal_eval('3.25'), 3.25) - self.assertEqual(ast.literal_eval('+3.25'), 3.25) - self.assertEqual(ast.literal_eval('-3.25'), -3.25) - self.assertEqual(repr(ast.literal_eval('-0.0')), '-0.0') - self.assertRaises(ValueError, ast.literal_eval, '++6') - self.assertRaises(ValueError, ast.literal_eval, '+True') - self.assertRaises(ValueError, ast.literal_eval, '2+3') - - def test_literal_eval_complex(self): - # Issue #4907 - self.assertEqual(ast.literal_eval('6j'), 6j) - self.assertEqual(ast.literal_eval('-6j'), -6j) - self.assertEqual(ast.literal_eval('6.75j'), 6.75j) - self.assertEqual(ast.literal_eval('-6.75j'), -6.75j) - self.assertEqual(ast.literal_eval('3+6j'), 3+6j) - self.assertEqual(ast.literal_eval('-3+6j'), -3+6j) - self.assertEqual(ast.literal_eval('3-6j'), 3-6j) - self.assertEqual(ast.literal_eval('-3-6j'), -3-6j) - self.assertEqual(ast.literal_eval('3.25+6.75j'), 3.25+6.75j) - self.assertEqual(ast.literal_eval('-3.25+6.75j'), -3.25+6.75j) - self.assertEqual(ast.literal_eval('3.25-6.75j'), 3.25-6.75j) - self.assertEqual(ast.literal_eval('-3.25-6.75j'), -3.25-6.75j) - self.assertEqual(ast.literal_eval('(3+6j)'), 3+6j) - self.assertRaises(ValueError, ast.literal_eval, '-6j+3') - self.assertRaises(ValueError, ast.literal_eval, '-6j+3j') - self.assertRaises(ValueError, ast.literal_eval, '3+-6j') - self.assertRaises(ValueError, ast.literal_eval, '3+(0+6j)') - self.assertRaises(ValueError, ast.literal_eval, '-(3+6j)') - - def test_literal_eval_malformed_dict_nodes(self): - malformed = ast.Dict(keys=[ast.Constant(1), ast.Constant(2)], values=[ast.Constant(3)]) - self.assertRaises(ValueError, ast.literal_eval, malformed) - malformed = ast.Dict(keys=[ast.Constant(1)], values=[ast.Constant(2), ast.Constant(3)]) - self.assertRaises(ValueError, ast.literal_eval, malformed) - - def test_bad_integer(self): - # issue13436: Bad error message with invalid numeric values - body = [ast.ImportFrom(module='time', - names=[ast.alias(name='sleep')], - level=None, - lineno=None, col_offset=None)] - mod = ast.Module(body, []) - with self.assertRaises(ValueError) as cm: - compile(mod, 'test', 'exec') - self.assertIn("invalid integer value: None", str(cm.exception)) - - def test_level_as_none(self): - body = [ast.ImportFrom(module='time', - names=[ast.alias(name='sleep')], - level=None, - lineno=0, col_offset=0)] - mod = ast.Module(body, []) - code = compile(mod, 'test', 'exec') - ns = {} - exec(code, ns) - self.assertIn('sleep', ns) - - - class ASTValidatorTests(unittest.TestCase): - - def mod(self, mod, msg=None, mode="exec", *, exc=ValueError): - mod.lineno = mod.col_offset = 0 - ast.fix_missing_locations(mod) - if msg is None: - compile(mod, "", mode) - else: - with self.assertRaises(exc) as cm: - compile(mod, "", mode) - self.assertIn(msg, str(cm.exception)) - - def expr(self, node, msg=None, *, exc=ValueError): - mod = ast.Module([ast.Expr(node)], []) - self.mod(mod, msg, exc=exc) - - def stmt(self, stmt, msg=None): - mod = ast.Module([stmt], []) - self.mod(mod, msg) - - def test_module(self): - m = ast.Interactive([ast.Expr(ast.Name("x", ast.Store()))]) - self.mod(m, "must have Load context", "single") - m = ast.Expression(ast.Name("x", ast.Store())) - self.mod(m, "must have Load context", "eval") - - def _check_arguments(self, fac, check): - def arguments(args=None, posonlyargs=None, vararg=None, - kwonlyargs=None, kwarg=None, - defaults=None, kw_defaults=None): - if args is None: - args = [] - if posonlyargs is None: - posonlyargs = [] - if kwonlyargs is None: - kwonlyargs = [] - if defaults is None: - defaults = [] - if kw_defaults is None: - kw_defaults = [] - args = ast.arguments(args, posonlyargs, vararg, kwonlyargs, - kw_defaults, kwarg, defaults) - return fac(args) - args = [ast.arg("x", ast.Name("x", ast.Store()))] - check(arguments(args=args), "must have Load context") - check(arguments(posonlyargs=args), "must have Load context") - check(arguments(kwonlyargs=args), "must have Load context") - check(arguments(defaults=[ast.Num(3)]), - "more positional defaults than args") - check(arguments(kw_defaults=[ast.Num(4)]), - "length of kwonlyargs is not the same as kw_defaults") - args = [ast.arg("x", ast.Name("x", ast.Load()))] - check(arguments(args=args, defaults=[ast.Name("x", ast.Store())]), - "must have Load context") - args = [ast.arg("a", ast.Name("x", ast.Load())), - ast.arg("b", ast.Name("y", ast.Load()))] - check(arguments(kwonlyargs=args, - kw_defaults=[None, ast.Name("x", ast.Store())]), - "must have Load context") - - def test_funcdef(self): - a = ast.arguments([], [], None, [], [], None, []) - f = ast.FunctionDef("x", a, [], [], None) - self.stmt(f, "empty body on FunctionDef") - f = ast.FunctionDef("x", a, [ast.Pass()], [ast.Name("x", ast.Store())], - None) - self.stmt(f, "must have Load context") - f = ast.FunctionDef("x", a, [ast.Pass()], [], - ast.Name("x", ast.Store())) - self.stmt(f, "must have Load context") - def fac(args): - return ast.FunctionDef("x", args, [ast.Pass()], [], None) - self._check_arguments(fac, self.stmt) - - def test_classdef(self): - def cls(bases=None, keywords=None, body=None, decorator_list=None): - if bases is None: - bases = [] - if keywords is None: - keywords = [] - if body is None: - body = [ast.Pass()] - if decorator_list is None: - decorator_list = [] - return ast.ClassDef("myclass", bases, keywords, - body, decorator_list) - self.stmt(cls(bases=[ast.Name("x", ast.Store())]), - "must have Load context") - self.stmt(cls(keywords=[ast.keyword("x", ast.Name("x", ast.Store()))]), - "must have Load context") - self.stmt(cls(body=[]), "empty body on ClassDef") - self.stmt(cls(body=[None]), "None disallowed") - self.stmt(cls(decorator_list=[ast.Name("x", ast.Store())]), - "must have Load context") - - def test_delete(self): - self.stmt(ast.Delete([]), "empty targets on Delete") - self.stmt(ast.Delete([None]), "None disallowed") - self.stmt(ast.Delete([ast.Name("x", ast.Load())]), - "must have Del context") - - def test_assign(self): - self.stmt(ast.Assign([], ast.Num(3)), "empty targets on Assign") - self.stmt(ast.Assign([None], ast.Num(3)), "None disallowed") - self.stmt(ast.Assign([ast.Name("x", ast.Load())], ast.Num(3)), - "must have Store context") - self.stmt(ast.Assign([ast.Name("x", ast.Store())], - ast.Name("y", ast.Store())), - "must have Load context") - - def test_augassign(self): - aug = ast.AugAssign(ast.Name("x", ast.Load()), ast.Add(), - ast.Name("y", ast.Load())) - self.stmt(aug, "must have Store context") - aug = ast.AugAssign(ast.Name("x", ast.Store()), ast.Add(), - ast.Name("y", ast.Store())) - self.stmt(aug, "must have Load context") - - def test_for(self): - x = ast.Name("x", ast.Store()) - y = ast.Name("y", ast.Load()) - p = ast.Pass() - self.stmt(ast.For(x, y, [], []), "empty body on For") - self.stmt(ast.For(ast.Name("x", ast.Load()), y, [p], []), - "must have Store context") - self.stmt(ast.For(x, ast.Name("y", ast.Store()), [p], []), - "must have Load context") - e = ast.Expr(ast.Name("x", ast.Store())) - self.stmt(ast.For(x, y, [e], []), "must have Load context") - self.stmt(ast.For(x, y, [p], [e]), "must have Load context") - - def test_while(self): - self.stmt(ast.While(ast.Num(3), [], []), "empty body on While") - self.stmt(ast.While(ast.Name("x", ast.Store()), [ast.Pass()], []), - "must have Load context") - self.stmt(ast.While(ast.Num(3), [ast.Pass()], - [ast.Expr(ast.Name("x", ast.Store()))]), - "must have Load context") - - def test_if(self): - self.stmt(ast.If(ast.Num(3), [], []), "empty body on If") - i = ast.If(ast.Name("x", ast.Store()), [ast.Pass()], []) - self.stmt(i, "must have Load context") - i = ast.If(ast.Num(3), [ast.Expr(ast.Name("x", ast.Store()))], []) - self.stmt(i, "must have Load context") - i = ast.If(ast.Num(3), [ast.Pass()], - [ast.Expr(ast.Name("x", ast.Store()))]) - self.stmt(i, "must have Load context") - - def test_with(self): - p = ast.Pass() - self.stmt(ast.With([], [p]), "empty items on With") - i = ast.withitem(ast.Num(3), None) - self.stmt(ast.With([i], []), "empty body on With") - i = ast.withitem(ast.Name("x", ast.Store()), None) - self.stmt(ast.With([i], [p]), "must have Load context") - i = ast.withitem(ast.Num(3), ast.Name("x", ast.Load())) - self.stmt(ast.With([i], [p]), "must have Store context") - - def test_raise(self): - r = ast.Raise(None, ast.Num(3)) - self.stmt(r, "Raise with cause but no exception") - r = ast.Raise(ast.Name("x", ast.Store()), None) - self.stmt(r, "must have Load context") - r = ast.Raise(ast.Num(4), ast.Name("x", ast.Store())) - self.stmt(r, "must have Load context") - - def test_try(self): - p = ast.Pass() - t = ast.Try([], [], [], [p]) - self.stmt(t, "empty body on Try") - t = ast.Try([ast.Expr(ast.Name("x", ast.Store()))], [], [], [p]) - self.stmt(t, "must have Load context") - t = ast.Try([p], [], [], []) - self.stmt(t, "Try has neither except handlers nor finalbody") - t = ast.Try([p], [], [p], [p]) - self.stmt(t, "Try has orelse but no except handlers") - t = ast.Try([p], [ast.ExceptHandler(None, "x", [])], [], []) - self.stmt(t, "empty body on ExceptHandler") - e = [ast.ExceptHandler(ast.Name("x", ast.Store()), "y", [p])] - self.stmt(ast.Try([p], e, [], []), "must have Load context") - e = [ast.ExceptHandler(None, "x", [p])] - t = ast.Try([p], e, [ast.Expr(ast.Name("x", ast.Store()))], [p]) - self.stmt(t, "must have Load context") - t = ast.Try([p], e, [p], [ast.Expr(ast.Name("x", ast.Store()))]) - self.stmt(t, "must have Load context") - - def test_assert(self): - self.stmt(ast.Assert(ast.Name("x", ast.Store()), None), - "must have Load context") - assrt = ast.Assert(ast.Name("x", ast.Load()), - ast.Name("y", ast.Store())) - self.stmt(assrt, "must have Load context") - - def test_import(self): - self.stmt(ast.Import([]), "empty names on Import") - - def test_importfrom(self): - imp = ast.ImportFrom(None, [ast.alias("x", None)], -42) - self.stmt(imp, "Negative ImportFrom level") - self.stmt(ast.ImportFrom(None, [], 0), "empty names on ImportFrom") - - def test_global(self): - self.stmt(ast.Global([]), "empty names on Global") - - def test_nonlocal(self): - self.stmt(ast.Nonlocal([]), "empty names on Nonlocal") - - def test_expr(self): - e = ast.Expr(ast.Name("x", ast.Store())) - self.stmt(e, "must have Load context") - - def test_boolop(self): - b = ast.BoolOp(ast.And(), []) - self.expr(b, "less than 2 values") - b = ast.BoolOp(ast.And(), [ast.Num(3)]) - self.expr(b, "less than 2 values") - b = ast.BoolOp(ast.And(), [ast.Num(4), None]) - self.expr(b, "None disallowed") - b = ast.BoolOp(ast.And(), [ast.Num(4), ast.Name("x", ast.Store())]) - self.expr(b, "must have Load context") - - def test_unaryop(self): - u = ast.UnaryOp(ast.Not(), ast.Name("x", ast.Store())) - self.expr(u, "must have Load context") - - def test_lambda(self): - a = ast.arguments([], [], None, [], [], None, []) - self.expr(ast.Lambda(a, ast.Name("x", ast.Store())), - "must have Load context") - def fac(args): - return ast.Lambda(args, ast.Name("x", ast.Load())) - self._check_arguments(fac, self.expr) - - def test_ifexp(self): - l = ast.Name("x", ast.Load()) - s = ast.Name("y", ast.Store()) - for args in (s, l, l), (l, s, l), (l, l, s): - self.expr(ast.IfExp(*args), "must have Load context") - - def test_dict(self): - d = ast.Dict([], [ast.Name("x", ast.Load())]) - self.expr(d, "same number of keys as values") - d = ast.Dict([ast.Name("x", ast.Load())], [None]) - self.expr(d, "None disallowed") - - def test_set(self): - self.expr(ast.Set([None]), "None disallowed") - s = ast.Set([ast.Name("x", ast.Store())]) - self.expr(s, "must have Load context") - - def _check_comprehension(self, fac): - self.expr(fac([]), "comprehension with no generators") - g = ast.comprehension(ast.Name("x", ast.Load()), - ast.Name("x", ast.Load()), [], 0) - self.expr(fac([g]), "must have Store context") - g = ast.comprehension(ast.Name("x", ast.Store()), - ast.Name("x", ast.Store()), [], 0) - self.expr(fac([g]), "must have Load context") - x = ast.Name("x", ast.Store()) - y = ast.Name("y", ast.Load()) - g = ast.comprehension(x, y, [None], 0) - self.expr(fac([g]), "None disallowed") - g = ast.comprehension(x, y, [ast.Name("x", ast.Store())], 0) - self.expr(fac([g]), "must have Load context") - - def _simple_comp(self, fac): - g = ast.comprehension(ast.Name("x", ast.Store()), - ast.Name("x", ast.Load()), [], 0) - self.expr(fac(ast.Name("x", ast.Store()), [g]), - "must have Load context") - def wrap(gens): - return fac(ast.Name("x", ast.Store()), gens) - self._check_comprehension(wrap) - - def test_listcomp(self): - self._simple_comp(ast.ListComp) - - def test_setcomp(self): - self._simple_comp(ast.SetComp) - - def test_generatorexp(self): - self._simple_comp(ast.GeneratorExp) - - def test_dictcomp(self): - g = ast.comprehension(ast.Name("y", ast.Store()), - ast.Name("p", ast.Load()), [], 0) - c = ast.DictComp(ast.Name("x", ast.Store()), - ast.Name("y", ast.Load()), [g]) - self.expr(c, "must have Load context") - c = ast.DictComp(ast.Name("x", ast.Load()), - ast.Name("y", ast.Store()), [g]) - self.expr(c, "must have Load context") - def factory(comps): - k = ast.Name("x", ast.Load()) - v = ast.Name("y", ast.Load()) - return ast.DictComp(k, v, comps) - self._check_comprehension(factory) - - def test_yield(self): - self.expr(ast.Yield(ast.Name("x", ast.Store())), "must have Load") - self.expr(ast.YieldFrom(ast.Name("x", ast.Store())), "must have Load") - - def test_compare(self): - left = ast.Name("x", ast.Load()) - comp = ast.Compare(left, [ast.In()], []) - self.expr(comp, "no comparators") - comp = ast.Compare(left, [ast.In()], [ast.Num(4), ast.Num(5)]) - self.expr(comp, "different number of comparators and operands") - comp = ast.Compare(ast.Num("blah"), [ast.In()], [left]) - self.expr(comp) - comp = ast.Compare(left, [ast.In()], [ast.Num("blah")]) - self.expr(comp) - - def test_call(self): - func = ast.Name("x", ast.Load()) - args = [ast.Name("y", ast.Load())] - keywords = [ast.keyword("w", ast.Name("z", ast.Load()))] - call = ast.Call(ast.Name("x", ast.Store()), args, keywords) - self.expr(call, "must have Load context") - call = ast.Call(func, [None], keywords) - self.expr(call, "None disallowed") - bad_keywords = [ast.keyword("w", ast.Name("z", ast.Store()))] - call = ast.Call(func, args, bad_keywords) - self.expr(call, "must have Load context") - - def test_num(self): - class subint(int): - pass - class subfloat(float): - pass - class subcomplex(complex): - pass - for obj in "0", "hello": - self.expr(ast.Num(obj)) - for obj in subint(), subfloat(), subcomplex(): - self.expr(ast.Num(obj), "invalid type", exc=TypeError) - - def test_attribute(self): - attr = ast.Attribute(ast.Name("x", ast.Store()), "y", ast.Load()) - self.expr(attr, "must have Load context") - - def test_subscript(self): - sub = ast.Subscript(ast.Name("x", ast.Store()), ast.Index(ast.Num(3)), - ast.Load()) - self.expr(sub, "must have Load context") - x = ast.Name("x", ast.Load()) - sub = ast.Subscript(x, ast.Index(ast.Name("y", ast.Store())), - ast.Load()) - self.expr(sub, "must have Load context") - s = ast.Name("x", ast.Store()) - for args in (s, None, None), (None, s, None), (None, None, s): - sl = ast.Slice(*args) - self.expr(ast.Subscript(x, sl, ast.Load()), - "must have Load context") - sl = ast.ExtSlice([]) - self.expr(ast.Subscript(x, sl, ast.Load()), "empty dims on ExtSlice") - sl = ast.ExtSlice([ast.Index(s)]) - self.expr(ast.Subscript(x, sl, ast.Load()), "must have Load context") - - def test_starred(self): - left = ast.List([ast.Starred(ast.Name("x", ast.Load()), ast.Store())], - ast.Store()) - assign = ast.Assign([left], ast.Num(4)) - self.stmt(assign, "must have Store context") - - def _sequence(self, fac): - self.expr(fac([None], ast.Load()), "None disallowed") - self.expr(fac([ast.Name("x", ast.Store())], ast.Load()), - "must have Load context") - - def test_list(self): - self._sequence(ast.List) - - def test_tuple(self): - self._sequence(ast.Tuple) - - def test_nameconstant(self): - self.expr(ast.NameConstant(4)) - - def test_stdlib_validates(self): - stdlib = os.path.dirname(ast.__file__) - tests = [fn for fn in os.listdir(stdlib) if fn.endswith(".py")] - tests.extend(["test/test_grammar.py", "test/test_unpack_ex.py"]) - for module in tests: - with self.subTest(module): - fn = os.path.join(stdlib, module) - with open(fn, "r", encoding="utf-8") as fp: - source = fp.read() - mod = ast.parse(source, fn) - compile(mod, fn, "exec") - - - class ConstantTests(unittest.TestCase): - """Tests on the ast.Constant node type.""" - - def compile_constant(self, value): - tree = ast.parse("x = 123") - - node = tree.body[0].value - new_node = ast.Constant(value=value) - ast.copy_location(new_node, node) - tree.body[0].value = new_node - - code = compile(tree, "", "exec") - - ns = {} - exec(code, ns) - return ns['x'] - - def test_validation(self): - with self.assertRaises(TypeError) as cm: - self.compile_constant([1, 2, 3]) - self.assertEqual(str(cm.exception), - "got an invalid type in Constant: list") - - def test_singletons(self): - for const in (None, False, True, Ellipsis, b'', frozenset()): - with self.subTest(const=const): - value = self.compile_constant(const) - self.assertIs(value, const) - - def test_values(self): - nested_tuple = (1,) - nested_frozenset = frozenset({1}) - for level in range(3): - nested_tuple = (nested_tuple, 2) - nested_frozenset = frozenset({nested_frozenset, 2}) - values = (123, 123.0, 123j, - "unicode", b'bytes', - tuple("tuple"), frozenset("frozenset"), - nested_tuple, nested_frozenset) - for value in values: - with self.subTest(value=value): - result = self.compile_constant(value) - self.assertEqual(result, value) - - def test_assign_to_constant(self): - tree = ast.parse("x = 1") - - target = tree.body[0].targets[0] - new_target = ast.Constant(value=1) - ast.copy_location(new_target, target) - tree.body[0].targets[0] = new_target - - with self.assertRaises(ValueError) as cm: - compile(tree, "string", "exec") - self.assertEqual(str(cm.exception), - "expression which can't be assigned " - "to in Store context") - - def test_get_docstring(self): - tree = ast.parse("'docstring'\nx = 1") - self.assertEqual(ast.get_docstring(tree), 'docstring') - - def get_load_const(self, tree): - # Compile to bytecode, disassemble and get parameter of LOAD_CONST - # instructions - co = compile(tree, '', 'exec') - consts = [] - for instr in dis.get_instructions(co): - if instr.opname == 'LOAD_CONST': - consts.append(instr.argval) - return consts - - @support.cpython_only - def test_load_const(self): - consts = [None, - True, False, - 124, - 2.0, - 3j, - "unicode", - b'bytes', - (1, 2, 3)] - - code = '\n'.join(['x={!r}'.format(const) for const in consts]) - code += '\nx = ...' - consts.extend((Ellipsis, None)) - - tree = ast.parse(code) - self.assertEqual(self.get_load_const(tree), - consts) - - # Replace expression nodes with constants - for assign, const in zip(tree.body, consts): - assert isinstance(assign, ast.Assign), ast.dump(assign) - new_node = ast.Constant(value=const) - ast.copy_location(new_node, assign.value) - assign.value = new_node - - self.assertEqual(self.get_load_const(tree), - consts) - - def test_literal_eval(self): - tree = ast.parse("1 + 2") - binop = tree.body[0].value - - new_left = ast.Constant(value=10) - ast.copy_location(new_left, binop.left) - binop.left = new_left - - new_right = ast.Constant(value=20j) - ast.copy_location(new_right, binop.right) - binop.right = new_right - - self.assertEqual(ast.literal_eval(binop), 10+20j) - - def test_string_kind(self): - c = ast.parse('"x"', mode='eval').body - self.assertEqual(c.value, "x") - self.assertEqual(c.kind, None) - - c = ast.parse('u"x"', mode='eval').body - self.assertEqual(c.value, "x") - self.assertEqual(c.kind, "u") - - c = ast.parse('r"x"', mode='eval').body - self.assertEqual(c.value, "x") - self.assertEqual(c.kind, None) - - c = ast.parse('b"x"', mode='eval').body - self.assertEqual(c.value, b"x") - self.assertEqual(c.kind, None) - - - class EndPositionTests(unittest.TestCase): - """Tests for end position of AST nodes. - - Testing end positions of nodes requires a bit of extra care - because of how LL parsers work. - """ - def _check_end_pos(self, ast_node, end_lineno, end_col_offset): - self.assertEqual(ast_node.end_lineno, end_lineno) - self.assertEqual(ast_node.end_col_offset, end_col_offset) - - def _check_content(self, source, ast_node, content): - self.assertEqual(ast.get_source_segment(source, ast_node), content) - - def _parse_value(self, s): - # Use duck-typing to support both single expression - # and a right hand side of an assignment statement. - return ast.parse(s).body[0].value - - def test_lambda(self): - s = 'lambda x, *y: None' - lam = self._parse_value(s) - self._check_content(s, lam.body, 'None') - self._check_content(s, lam.args.args[0], 'x') - self._check_content(s, lam.args.vararg, 'y') - - def test_func_def(self): - s = dedent(''' - def func(x: int, - *args: str, - z: float = 0, - **kwargs: Any) -> bool: - return True - ''').strip() - fdef = ast.parse(s).body[0] - self._check_end_pos(fdef, 5, 15) - self._check_content(s, fdef.body[0], 'return True') - self._check_content(s, fdef.args.args[0], 'x: int') - self._check_content(s, fdef.args.args[0].annotation, 'int') - self._check_content(s, fdef.args.kwarg, 'kwargs: Any') - self._check_content(s, fdef.args.kwarg.annotation, 'Any') - - def test_call(self): - s = 'func(x, y=2, **kw)' - call = self._parse_value(s) - self._check_content(s, call.func, 'func') - self._check_content(s, call.keywords[0].value, '2') - self._check_content(s, call.keywords[1].value, 'kw') - - def test_call_noargs(self): - s = 'x[0]()' - call = self._parse_value(s) - self._check_content(s, call.func, 'x[0]') - self._check_end_pos(call, 1, 6) - - def test_class_def(self): - s = dedent(''' - class C(A, B): - x: int = 0 - ''').strip() - cdef = ast.parse(s).body[0] - self._check_end_pos(cdef, 2, 14) - self._check_content(s, cdef.bases[1], 'B') - self._check_content(s, cdef.body[0], 'x: int = 0') - - def test_class_kw(self): - s = 'class S(metaclass=abc.ABCMeta): pass' - cdef = ast.parse(s).body[0] - self._check_content(s, cdef.keywords[0].value, 'abc.ABCMeta') - - def test_multi_line_str(self): - s = dedent(''' - x = """Some multi-line text. - - It goes on starting from same indent.""" - ''').strip() - assign = ast.parse(s).body[0] - self._check_end_pos(assign, 3, 40) - self._check_end_pos(assign.value, 3, 40) - - def test_continued_str(self): - s = dedent(''' - x = "first part" \\ - "second part" - ''').strip() - assign = ast.parse(s).body[0] - self._check_end_pos(assign, 2, 13) - self._check_end_pos(assign.value, 2, 13) - - def test_suites(self): - # We intentionally put these into the same string to check - # that empty lines are not part of the suite. - s = dedent(''' - while True: - pass - - if one(): - x = None - elif other(): - y = None - else: - z = None - - for x, y in stuff: - assert True - - try: - raise RuntimeError - except TypeError as e: - pass - - pass - ''').strip() - mod = ast.parse(s) - while_loop = mod.body[0] - if_stmt = mod.body[1] - for_loop = mod.body[2] - try_stmt = mod.body[3] - pass_stmt = mod.body[4] - - self._check_end_pos(while_loop, 2, 8) - self._check_end_pos(if_stmt, 9, 12) - self._check_end_pos(for_loop, 12, 15) - self._check_end_pos(try_stmt, 17, 8) - self._check_end_pos(pass_stmt, 19, 4) - - self._check_content(s, while_loop.test, 'True') - self._check_content(s, if_stmt.body[0], 'x = None') - self._check_content(s, if_stmt.orelse[0].test, 'other()') - self._check_content(s, for_loop.target, 'x, y') - self._check_content(s, try_stmt.body[0], 'raise RuntimeError') - self._check_content(s, try_stmt.handlers[0].type, 'TypeError') - - def test_fstring(self): - s = 'x = f"abc {x + y} abc"' - fstr = self._parse_value(s) - binop = fstr.values[1].value - self._check_content(s, binop, 'x + y') - - def test_fstring_multi_line(self): - s = dedent(''' - f"""Some multi-line text. - { - arg_one - + - arg_two - } - It goes on...""" - ''').strip() - fstr = self._parse_value(s) - binop = fstr.values[1].value - self._check_end_pos(binop, 5, 7) - self._check_content(s, binop.left, 'arg_one') - self._check_content(s, binop.right, 'arg_two') - - def test_import_from_multi_line(self): - s = dedent(''' - from x.y.z import ( - a, b, c as c - ) - ''').strip() - imp = ast.parse(s).body[0] - self._check_end_pos(imp, 3, 1) - - def test_slices(self): - s1 = 'f()[1, 2] [0]' - s2 = 'x[ a.b: c.d]' - sm = dedent(''' - x[ a.b: f () , - g () : c.d - ] - ''').strip() - i1, i2, im = map(self._parse_value, (s1, s2, sm)) - self._check_content(s1, i1.value, 'f()[1, 2]') - self._check_content(s1, i1.value.slice.value, '1, 2') - self._check_content(s2, i2.slice.lower, 'a.b') - self._check_content(s2, i2.slice.upper, 'c.d') - self._check_content(sm, im.slice.dims[0].upper, 'f ()') - self._check_content(sm, im.slice.dims[1].lower, 'g ()') - self._check_end_pos(im, 3, 3) - - def test_binop(self): - s = dedent(''' - (1 * 2 + (3 ) + - 4 - ) - ''').strip() - binop = self._parse_value(s) - self._check_end_pos(binop, 2, 6) - self._check_content(s, binop.right, '4') - self._check_content(s, binop.left, '1 * 2 + (3 )') - self._check_content(s, binop.left.right, '3') - - def test_boolop(self): - s = dedent(''' - if (one_condition and - (other_condition or yet_another_one)): - pass - ''').strip() - bop = ast.parse(s).body[0].test - self._check_end_pos(bop, 2, 44) - self._check_content(s, bop.values[1], - 'other_condition or yet_another_one') - - def test_tuples(self): - s1 = 'x = () ;' - s2 = 'x = 1 , ;' - s3 = 'x = (1 , 2 ) ;' - sm = dedent(''' - x = ( - a, b, - ) - ''').strip() - t1, t2, t3, tm = map(self._parse_value, (s1, s2, s3, sm)) - self._check_content(s1, t1, '()') - self._check_content(s2, t2, '1 ,') - self._check_content(s3, t3, '(1 , 2 )') - self._check_end_pos(tm, 3, 1) - - def test_attribute_spaces(self): - s = 'func(x. y .z)' - call = self._parse_value(s) - self._check_content(s, call, s) - self._check_content(s, call.args[0], 'x. y .z') - - def test_redundant_parenthesis(self): - s = '( ( ( a + b ) ) )' - v = ast.parse(s).body[0].value - self.assertEqual(type(v).__name__, 'BinOp') - self._check_content(s, v, 'a + b') - s2 = 'await ' + s - v = ast.parse(s2).body[0].value.value - self.assertEqual(type(v).__name__, 'BinOp') - self._check_content(s2, v, 'a + b') - - def test_trailers_with_redundant_parenthesis(self): - tests = ( - ('( ( ( a ) ) ) ( )', 'Call'), - ('( ( ( a ) ) ) ( b )', 'Call'), - ('( ( ( a ) ) ) [ b ]', 'Subscript'), - ('( ( ( a ) ) ) . b', 'Attribute'), - ) - for s, t in tests: - with self.subTest(s): - v = ast.parse(s).body[0].value - self.assertEqual(type(v).__name__, t) - self._check_content(s, v, s) - s2 = 'await ' + s - v = ast.parse(s2).body[0].value.value - self.assertEqual(type(v).__name__, t) - self._check_content(s2, v, s) - - def test_displays(self): - s1 = '[{}, {1, }, {1, 2,} ]' - s2 = '{a: b, f (): g () ,}' - c1 = self._parse_value(s1) - c2 = self._parse_value(s2) - self._check_content(s1, c1.elts[0], '{}') - self._check_content(s1, c1.elts[1], '{1, }') - self._check_content(s1, c1.elts[2], '{1, 2,}') - self._check_content(s2, c2.keys[1], 'f ()') - self._check_content(s2, c2.values[1], 'g ()') - - def test_comprehensions(self): - s = dedent(''' - x = [{x for x, y in stuff - if cond.x} for stuff in things] - ''').strip() - cmp = self._parse_value(s) - self._check_end_pos(cmp, 2, 37) - self._check_content(s, cmp.generators[0].iter, 'things') - self._check_content(s, cmp.elt.generators[0].iter, 'stuff') - self._check_content(s, cmp.elt.generators[0].ifs[0], 'cond.x') - self._check_content(s, cmp.elt.generators[0].target, 'x, y') - - def test_yield_await(self): - s = dedent(''' - async def f(): - yield x - await y - ''').strip() - fdef = ast.parse(s).body[0] - self._check_content(s, fdef.body[0].value, 'yield x') - self._check_content(s, fdef.body[1].value, 'await y') - - def test_source_segment_multi(self): - s_orig = dedent(''' - x = ( - a, b, - ) + () - ''').strip() - s_tuple = dedent(''' - ( - a, b, - ) - ''').strip() - binop = self._parse_value(s_orig) - self.assertEqual(ast.get_source_segment(s_orig, binop.left), s_tuple) - - def test_source_segment_padded(self): - s_orig = dedent(''' - class C: - def fun(self) -> None: - "ЖЖЖЖЖ" - ''').strip() - s_method = ' def fun(self) -> None:\n' \ - ' "ЖЖЖЖЖ"' - cdef = ast.parse(s_orig).body[0] - self.assertEqual(ast.get_source_segment(s_orig, cdef.body[0], padded=True), - s_method) - - def test_source_segment_endings(self): - s = 'v = 1\r\nw = 1\nx = 1\n\ry = 1\rz = 1\r\n' - v, w, x, y, z = ast.parse(s).body - self._check_content(s, v, 'v = 1') - self._check_content(s, w, 'w = 1') - self._check_content(s, x, 'x = 1') - self._check_content(s, y, 'y = 1') - self._check_content(s, z, 'z = 1') - - def test_source_segment_tabs(self): - s = dedent(''' - class C: - \t\f def fun(self) -> None: - \t\f pass - ''').strip() - s_method = ' \t\f def fun(self) -> None:\n' \ - ' \t\f pass' - - cdef = ast.parse(s).body[0] - self.assertEqual(ast.get_source_segment(s, cdef.body[0], padded=True), s_method) - - - class NodeVisitorTests(unittest.TestCase): - def test_old_constant_nodes(self): - class Visitor(ast.NodeVisitor): - def visit_Num(self, node): - log.append((node.lineno, 'Num', node.n)) - def visit_Str(self, node): - log.append((node.lineno, 'Str', node.s)) - def visit_Bytes(self, node): - log.append((node.lineno, 'Bytes', node.s)) - def visit_NameConstant(self, node): - log.append((node.lineno, 'NameConstant', node.value)) - def visit_Ellipsis(self, node): - log.append((node.lineno, 'Ellipsis', ...)) - mod = ast.parse(dedent('''\ - i = 42 - f = 4.25 - c = 4.25j - s = 'string' - b = b'bytes' - t = True - n = None - e = ... - ''')) - visitor = Visitor() - log = [] - with warnings.catch_warnings(record=True) as wlog: - warnings.filterwarnings('always', '', PendingDeprecationWarning) - visitor.visit(mod) - self.assertEqual(log, [ - (1, 'Num', 42), - (2, 'Num', 4.25), - (3, 'Num', 4.25j), - (4, 'Str', 'string'), - (5, 'Bytes', b'bytes'), - (6, 'NameConstant', True), - (7, 'NameConstant', None), - (8, 'Ellipsis', ...), - ]) - self.assertEqual([str(w.message) for w in wlog], [ - 'visit_Num is deprecated; add visit_Constant', - 'visit_Num is deprecated; add visit_Constant', - 'visit_Num is deprecated; add visit_Constant', - 'visit_Str is deprecated; add visit_Constant', - 'visit_Bytes is deprecated; add visit_Constant', - 'visit_NameConstant is deprecated; add visit_Constant', - 'visit_NameConstant is deprecated; add visit_Constant', - 'visit_Ellipsis is deprecated; add visit_Constant', - ]) - - - def main(): - if __name__ != '__main__': - return - if sys.argv[1:] == ['-g']: - for statements, kind in ((exec_tests, "exec"), (single_tests, "single"), - (eval_tests, "eval")): - print(kind+"_results = [") - for statement in statements: - tree = ast.parse(statement, "?", kind) - print("%r," % (to_tuple(tree),)) - print("]") - print("main()") - raise SystemExit - unittest.main() - - #### EVERYTHING BELOW IS GENERATED BY python Lib/test/test_ast.py -g ##### - exec_results = [ - ('Module', [('Expr', (1, 0), ('Constant', (1, 0), None, None))], []), - ('Module', [('Expr', (1, 0), ('Constant', (1, 0), 'module docstring', None))], []), - ('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [], [], None, [], [], None, []), [('Pass', (1, 9))], [], None, None)], []), - ('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [], [], None, [], [], None, []), [('Expr', (1, 9), ('Constant', (1, 9), 'function docstring', None))], [], None, None)], []), - ('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [], [('arg', (1, 6), 'a', None, None)], None, [], [], None, []), [('Pass', (1, 10))], [], None, None)], []), - ('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [], [('arg', (1, 6), 'a', None, None)], None, [], [], None, [('Constant', (1, 8), 0, None)]), [('Pass', (1, 12))], [], None, None)], []), - ('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [], [], ('arg', (1, 7), 'args', None, None), [], [], None, []), [('Pass', (1, 14))], [], None, None)], []), - ('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [], [], None, [], [], ('arg', (1, 8), 'kwargs', None, None), []), [('Pass', (1, 17))], [], None, None)], []), - ('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [], [('arg', (1, 6), 'a', None, None), ('arg', (1, 9), 'b', None, None), ('arg', (1, 14), 'c', None, None), ('arg', (1, 22), 'd', None, None), ('arg', (1, 28), 'e', None, None)], ('arg', (1, 35), 'args', None, None), [('arg', (1, 41), 'f', None, None)], [('Constant', (1, 43), 42, None)], ('arg', (1, 49), 'kwargs', None, None), [('Constant', (1, 11), 1, None), ('Constant', (1, 16), None, None), ('List', (1, 24), [], ('Load',)), ('Dict', (1, 30), [], [])]), [('Expr', (1, 58), ('Constant', (1, 58), 'doc for f()', None))], [], None, None)], []), - ('Module', [('ClassDef', (1, 0), 'C', [], [], [('Pass', (1, 8))], [])], []), - ('Module', [('ClassDef', (1, 0), 'C', [], [], [('Expr', (1, 9), ('Constant', (1, 9), 'docstring for class C', None))], [])], []), - ('Module', [('ClassDef', (1, 0), 'C', [('Name', (1, 8), 'object', ('Load',))], [], [('Pass', (1, 17))], [])], []), - ('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [], [], None, [], [], None, []), [('Return', (1, 8), ('Constant', (1, 15), 1, None))], [], None, None)], []), - ('Module', [('Delete', (1, 0), [('Name', (1, 4), 'v', ('Del',))])], []), - ('Module', [('Assign', (1, 0), [('Name', (1, 0), 'v', ('Store',))], ('Constant', (1, 4), 1, None), None)], []), - ('Module', [('Assign', (1, 0), [('Tuple', (1, 0), [('Name', (1, 0), 'a', ('Store',)), ('Name', (1, 2), 'b', ('Store',))], ('Store',))], ('Name', (1, 6), 'c', ('Load',)), None)], []), - ('Module', [('Assign', (1, 0), [('Tuple', (1, 0), [('Name', (1, 1), 'a', ('Store',)), ('Name', (1, 3), 'b', ('Store',))], ('Store',))], ('Name', (1, 8), 'c', ('Load',)), None)], []), - ('Module', [('Assign', (1, 0), [('List', (1, 0), [('Name', (1, 1), 'a', ('Store',)), ('Name', (1, 3), 'b', ('Store',))], ('Store',))], ('Name', (1, 8), 'c', ('Load',)), None)], []), - ('Module', [('AugAssign', (1, 0), ('Name', (1, 0), 'v', ('Store',)), ('Add',), ('Constant', (1, 5), 1, None))], []), - ('Module', [('For', (1, 0), ('Name', (1, 4), 'v', ('Store',)), ('Name', (1, 9), 'v', ('Load',)), [('Pass', (1, 11))], [], None)], []), - ('Module', [('While', (1, 0), ('Name', (1, 6), 'v', ('Load',)), [('Pass', (1, 8))], [])], []), - ('Module', [('If', (1, 0), ('Name', (1, 3), 'v', ('Load',)), [('Pass', (1, 5))], [])], []), - ('Module', [('If', (1, 0), ('Name', (1, 3), 'a', ('Load',)), [('Pass', (2, 2))], [('If', (3, 0), ('Name', (3, 5), 'b', ('Load',)), [('Pass', (4, 2))], [])])], []), - ('Module', [('If', (1, 0), ('Name', (1, 3), 'a', ('Load',)), [('Pass', (2, 2))], [('If', (3, 0), ('Name', (3, 5), 'b', ('Load',)), [('Pass', (4, 2))], [('Pass', (6, 2))])])], []), - ('Module', [('With', (1, 0), [('withitem', ('Name', (1, 5), 'x', ('Load',)), ('Name', (1, 10), 'y', ('Store',)))], [('Pass', (1, 13))], None)], []), - ('Module', [('With', (1, 0), [('withitem', ('Name', (1, 5), 'x', ('Load',)), ('Name', (1, 10), 'y', ('Store',))), ('withitem', ('Name', (1, 13), 'z', ('Load',)), ('Name', (1, 18), 'q', ('Store',)))], [('Pass', (1, 21))], None)], []), - ('Module', [('Raise', (1, 0), ('Call', (1, 6), ('Name', (1, 6), 'Exception', ('Load',)), [('Constant', (1, 16), 'string', None)], []), None)], []), - ('Module', [('Try', (1, 0), [('Pass', (2, 2))], [('ExceptHandler', (3, 0), ('Name', (3, 7), 'Exception', ('Load',)), None, [('Pass', (4, 2))])], [], [])], []), - ('Module', [('Try', (1, 0), [('Pass', (2, 2))], [], [], [('Pass', (4, 2))])], []), - ('Module', [('Assert', (1, 0), ('Name', (1, 7), 'v', ('Load',)), None)], []), - ('Module', [('Import', (1, 0), [('alias', 'sys', None)])], []), - ('Module', [('ImportFrom', (1, 0), 'sys', [('alias', 'v', None)], 0)], []), - ('Module', [('Global', (1, 0), ['v'])], []), - ('Module', [('Expr', (1, 0), ('Constant', (1, 0), 1, None))], []), - ('Module', [('Pass', (1, 0))], []), - ('Module', [('For', (1, 0), ('Name', (1, 4), 'v', ('Store',)), ('Name', (1, 9), 'v', ('Load',)), [('Break', (1, 11))], [], None)], []), - ('Module', [('For', (1, 0), ('Name', (1, 4), 'v', ('Store',)), ('Name', (1, 9), 'v', ('Load',)), [('Continue', (1, 11))], [], None)], []), - ('Module', [('For', (1, 0), ('Tuple', (1, 4), [('Name', (1, 4), 'a', ('Store',)), ('Name', (1, 6), 'b', ('Store',))], ('Store',)), ('Name', (1, 11), 'c', ('Load',)), [('Pass', (1, 14))], [], None)], []), - ('Module', [('For', (1, 0), ('Tuple', (1, 4), [('Name', (1, 5), 'a', ('Store',)), ('Name', (1, 7), 'b', ('Store',))], ('Store',)), ('Name', (1, 13), 'c', ('Load',)), [('Pass', (1, 16))], [], None)], []), - ('Module', [('For', (1, 0), ('List', (1, 4), [('Name', (1, 5), 'a', ('Store',)), ('Name', (1, 7), 'b', ('Store',))], ('Store',)), ('Name', (1, 13), 'c', ('Load',)), [('Pass', (1, 16))], [], None)], []), - ('Module', [('Expr', (1, 0), ('GeneratorExp', (1, 0), ('Tuple', (2, 4), [('Name', (3, 4), 'Aa', ('Load',)), ('Name', (5, 7), 'Bb', ('Load',))], ('Load',)), [('comprehension', ('Tuple', (8, 4), [('Name', (8, 4), 'Aa', ('Store',)), ('Name', (10, 4), 'Bb', ('Store',))], ('Store',)), ('Name', (10, 10), 'Cc', ('Load',)), [], 0)]))], []), - ('Module', [('Expr', (1, 0), ('DictComp', (1, 0), ('Name', (1, 1), 'a', ('Load',)), ('Name', (1, 5), 'b', ('Load',)), [('comprehension', ('Name', (1, 11), 'w', ('Store',)), ('Name', (1, 16), 'x', ('Load',)), [], 0), ('comprehension', ('Name', (1, 22), 'm', ('Store',)), ('Name', (1, 27), 'p', ('Load',)), [('Name', (1, 32), 'g', ('Load',))], 0)]))], []), - ('Module', [('Expr', (1, 0), ('DictComp', (1, 0), ('Name', (1, 1), 'a', ('Load',)), ('Name', (1, 5), 'b', ('Load',)), [('comprehension', ('Tuple', (1, 11), [('Name', (1, 11), 'v', ('Store',)), ('Name', (1, 13), 'w', ('Store',))], ('Store',)), ('Name', (1, 18), 'x', ('Load',)), [], 0)]))], []), - ('Module', [('Expr', (1, 0), ('SetComp', (1, 0), ('Name', (1, 1), 'r', ('Load',)), [('comprehension', ('Name', (1, 7), 'l', ('Store',)), ('Name', (1, 12), 'x', ('Load',)), [('Name', (1, 17), 'g', ('Load',))], 0)]))], []), - ('Module', [('Expr', (1, 0), ('SetComp', (1, 0), ('Name', (1, 1), 'r', ('Load',)), [('comprehension', ('Tuple', (1, 7), [('Name', (1, 7), 'l', ('Store',)), ('Name', (1, 9), 'm', ('Store',))], ('Store',)), ('Name', (1, 14), 'x', ('Load',)), [], 0)]))], []), - ('Module', [('AsyncFunctionDef', (1, 0), 'f', ('arguments', [], [], None, [], [], None, []), [('Expr', (2, 1), ('Constant', (2, 1), 'async function', None)), ('Expr', (3, 1), ('Await', (3, 1), ('Call', (3, 7), ('Name', (3, 7), 'something', ('Load',)), [], [])))], [], None, None)], []), - ('Module', [('AsyncFunctionDef', (1, 0), 'f', ('arguments', [], [], None, [], [], None, []), [('AsyncFor', (2, 1), ('Name', (2, 11), 'e', ('Store',)), ('Name', (2, 16), 'i', ('Load',)), [('Expr', (2, 19), ('Constant', (2, 19), 1, None))], [('Expr', (3, 7), ('Constant', (3, 7), 2, None))], None)], [], None, None)], []), - ('Module', [('AsyncFunctionDef', (1, 0), 'f', ('arguments', [], [], None, [], [], None, []), [('AsyncWith', (2, 1), [('withitem', ('Name', (2, 12), 'a', ('Load',)), ('Name', (2, 17), 'b', ('Store',)))], [('Expr', (2, 20), ('Constant', (2, 20), 1, None))], None)], [], None, None)], []), - ('Module', [('Expr', (1, 0), ('Dict', (1, 0), [None, ('Constant', (1, 10), 2, None)], [('Dict', (1, 3), [('Constant', (1, 4), 1, None)], [('Constant', (1, 6), 2, None)]), ('Constant', (1, 12), 3, None)]))], []), - ('Module', [('Expr', (1, 0), ('Set', (1, 0), [('Starred', (1, 1), ('Set', (1, 2), [('Constant', (1, 3), 1, None), ('Constant', (1, 6), 2, None)]), ('Load',)), ('Constant', (1, 10), 3, None)]))], []), - ('Module', [('AsyncFunctionDef', (1, 0), 'f', ('arguments', [], [], None, [], [], None, []), [('Expr', (2, 1), ('ListComp', (2, 1), ('Name', (2, 2), 'i', ('Load',)), [('comprehension', ('Name', (2, 14), 'b', ('Store',)), ('Name', (2, 19), 'c', ('Load',)), [], 1)]))], [], None, None)], []), - ('Module', [('FunctionDef', (4, 0), 'f', ('arguments', [], [], None, [], [], None, []), [('Pass', (4, 9))], [('Name', (1, 1), 'deco1', ('Load',)), ('Call', (2, 1), ('Name', (2, 1), 'deco2', ('Load',)), [], []), ('Call', (3, 1), ('Name', (3, 1), 'deco3', ('Load',)), [('Constant', (3, 7), 1, None)], [])], None, None)], []), - ('Module', [('AsyncFunctionDef', (4, 0), 'f', ('arguments', [], [], None, [], [], None, []), [('Pass', (4, 15))], [('Name', (1, 1), 'deco1', ('Load',)), ('Call', (2, 1), ('Name', (2, 1), 'deco2', ('Load',)), [], []), ('Call', (3, 1), ('Name', (3, 1), 'deco3', ('Load',)), [('Constant', (3, 7), 1, None)], [])], None, None)], []), - ('Module', [('ClassDef', (4, 0), 'C', [], [], [('Pass', (4, 9))], [('Name', (1, 1), 'deco1', ('Load',)), ('Call', (2, 1), ('Name', (2, 1), 'deco2', ('Load',)), [], []), ('Call', (3, 1), ('Name', (3, 1), 'deco3', ('Load',)), [('Constant', (3, 7), 1, None)], [])])], []), - ('Module', [('FunctionDef', (2, 0), 'f', ('arguments', [], [], None, [], [], None, []), [('Pass', (2, 9))], [('Call', (1, 1), ('Name', (1, 1), 'deco', ('Load',)), [('GeneratorExp', (1, 5), ('Name', (1, 6), 'a', ('Load',)), [('comprehension', ('Name', (1, 12), 'a', ('Store',)), ('Name', (1, 17), 'b', ('Load',)), [], 0)])], [])], None, None)], []), - ('Module', [('FunctionDef', (2, 0), 'f', ('arguments', [], [], None, [], [], None, []), [('Pass', (2, 9))], [('Attribute', (1, 1), ('Attribute', (1, 1), ('Name', (1, 1), 'a', ('Load',)), 'b', ('Load',)), 'c', ('Load',))], None, None)], []), - ('Module', [('Expr', (1, 0), ('NamedExpr', (1, 1), ('Name', (1, 1), 'a', ('Store',)), ('Constant', (1, 6), 1, None)))], []), - ('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [('arg', (1, 6), 'a', None, None)], [], None, [], [], None, []), [('Pass', (1, 14))], [], None, None)], []), - ('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [('arg', (1, 6), 'a', None, None)], [('arg', (1, 12), 'c', None, None), ('arg', (1, 15), 'd', None, None), ('arg', (1, 18), 'e', None, None)], None, [], [], None, []), [('Pass', (1, 22))], [], None, None)], []), - ('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [('arg', (1, 6), 'a', None, None)], [('arg', (1, 12), 'c', None, None)], None, [('arg', (1, 18), 'd', None, None), ('arg', (1, 21), 'e', None, None)], [None, None], None, []), [('Pass', (1, 25))], [], None, None)], []), - ('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [('arg', (1, 6), 'a', None, None)], [('arg', (1, 12), 'c', None, None)], None, [('arg', (1, 18), 'd', None, None), ('arg', (1, 21), 'e', None, None)], [None, None], ('arg', (1, 26), 'kwargs', None, None), []), [('Pass', (1, 35))], [], None, None)], []), - ('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [('arg', (1, 6), 'a', None, None)], [], None, [], [], None, [('Constant', (1, 8), 1, None)]), [('Pass', (1, 16))], [], None, None)], []), - ('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [('arg', (1, 6), 'a', None, None)], [('arg', (1, 14), 'b', None, None), ('arg', (1, 19), 'c', None, None)], None, [], [], None, [('Constant', (1, 8), 1, None), ('Constant', (1, 16), 2, None), ('Constant', (1, 21), 4, None)]), [('Pass', (1, 25))], [], None, None)], []), - ('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [('arg', (1, 6), 'a', None, None)], [('arg', (1, 14), 'b', None, None)], None, [('arg', (1, 22), 'c', None, None)], [('Constant', (1, 24), 4, None)], None, [('Constant', (1, 8), 1, None), ('Constant', (1, 16), 2, None)]), [('Pass', (1, 28))], [], None, None)], []), - ('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [('arg', (1, 6), 'a', None, None)], [('arg', (1, 14), 'b', None, None)], None, [('arg', (1, 22), 'c', None, None)], [None], None, [('Constant', (1, 8), 1, None), ('Constant', (1, 16), 2, None)]), [('Pass', (1, 26))], [], None, None)], []), - ('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [('arg', (1, 6), 'a', None, None)], [('arg', (1, 14), 'b', None, None)], None, [('arg', (1, 22), 'c', None, None)], [('Constant', (1, 24), 4, None)], ('arg', (1, 29), 'kwargs', None, None), [('Constant', (1, 8), 1, None), ('Constant', (1, 16), 2, None)]), [('Pass', (1, 38))], [], None, None)], []), - ('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [('arg', (1, 6), 'a', None, None)], [('arg', (1, 14), 'b', None, None)], None, [('arg', (1, 22), 'c', None, None)], [None], ('arg', (1, 27), 'kwargs', None, None), [('Constant', (1, 8), 1, None), ('Constant', (1, 16), 2, None)]), [('Pass', (1, 36))], [], None, None)], []), - ] - single_results = [ - ('Interactive', [('Expr', (1, 0), ('BinOp', (1, 0), ('Constant', (1, 0), 1, None), ('Add',), ('Constant', (1, 2), 2, None)))]), - ] - eval_results = [ - ('Expression', ('Constant', (1, 0), None, None)), - ('Expression', ('BoolOp', (1, 0), ('And',), [('Name', (1, 0), 'a', ('Load',)), ('Name', (1, 6), 'b', ('Load',))])), - ('Expression', ('BinOp', (1, 0), ('Name', (1, 0), 'a', ('Load',)), ('Add',), ('Name', (1, 4), 'b', ('Load',)))), - ('Expression', ('UnaryOp', (1, 0), ('Not',), ('Name', (1, 4), 'v', ('Load',)))), - ('Expression', ('Lambda', (1, 0), ('arguments', [], [], None, [], [], None, []), ('Constant', (1, 7), None, None))), - ('Expression', ('Dict', (1, 0), [('Constant', (1, 2), 1, None)], [('Constant', (1, 4), 2, None)])), - ('Expression', ('Dict', (1, 0), [], [])), - ('Expression', ('Set', (1, 0), [('Constant', (1, 1), None, None)])), - ('Expression', ('Dict', (1, 0), [('Constant', (2, 6), 1, None)], [('Constant', (4, 10), 2, None)])), - ('Expression', ('ListComp', (1, 0), ('Name', (1, 1), 'a', ('Load',)), [('comprehension', ('Name', (1, 7), 'b', ('Store',)), ('Name', (1, 12), 'c', ('Load',)), [('Name', (1, 17), 'd', ('Load',))], 0)])), - ('Expression', ('GeneratorExp', (1, 0), ('Name', (1, 1), 'a', ('Load',)), [('comprehension', ('Name', (1, 7), 'b', ('Store',)), ('Name', (1, 12), 'c', ('Load',)), [('Name', (1, 17), 'd', ('Load',))], 0)])), - ('Expression', ('ListComp', (1, 0), ('Tuple', (1, 1), [('Name', (1, 2), 'a', ('Load',)), ('Name', (1, 4), 'b', ('Load',))], ('Load',)), [('comprehension', ('Tuple', (1, 11), [('Name', (1, 11), 'a', ('Store',)), ('Name', (1, 13), 'b', ('Store',))], ('Store',)), ('Name', (1, 18), 'c', ('Load',)), [], 0)])), - ('Expression', ('ListComp', (1, 0), ('Tuple', (1, 1), [('Name', (1, 2), 'a', ('Load',)), ('Name', (1, 4), 'b', ('Load',))], ('Load',)), [('comprehension', ('Tuple', (1, 11), [('Name', (1, 12), 'a', ('Store',)), ('Name', (1, 14), 'b', ('Store',))], ('Store',)), ('Name', (1, 20), 'c', ('Load',)), [], 0)])), - ('Expression', ('ListComp', (1, 0), ('Tuple', (1, 1), [('Name', (1, 2), 'a', ('Load',)), ('Name', (1, 4), 'b', ('Load',))], ('Load',)), [('comprehension', ('List', (1, 11), [('Name', (1, 12), 'a', ('Store',)), ('Name', (1, 14), 'b', ('Store',))], ('Store',)), ('Name', (1, 20), 'c', ('Load',)), [], 0)])), - ('Expression', ('SetComp', (1, 0), ('Tuple', (1, 1), [('Name', (1, 2), 'a', ('Load',)), ('Name', (1, 4), 'b', ('Load',))], ('Load',)), [('comprehension', ('Tuple', (1, 11), [('Name', (1, 11), 'a', ('Store',)), ('Name', (1, 13), 'b', ('Store',))], ('Store',)), ('Name', (1, 18), 'c', ('Load',)), [], 0)])), - ('Expression', ('SetComp', (1, 0), ('Tuple', (1, 1), [('Name', (1, 2), 'a', ('Load',)), ('Name', (1, 4), 'b', ('Load',))], ('Load',)), [('comprehension', ('Tuple', (1, 11), [('Name', (1, 12), 'a', ('Store',)), ('Name', (1, 14), 'b', ('Store',))], ('Store',)), ('Name', (1, 20), 'c', ('Load',)), [], 0)])), - ('Expression', ('SetComp', (1, 0), ('Tuple', (1, 1), [('Name', (1, 2), 'a', ('Load',)), ('Name', (1, 4), 'b', ('Load',))], ('Load',)), [('comprehension', ('List', (1, 11), [('Name', (1, 12), 'a', ('Store',)), ('Name', (1, 14), 'b', ('Store',))], ('Store',)), ('Name', (1, 20), 'c', ('Load',)), [], 0)])), - ('Expression', ('GeneratorExp', (1, 0), ('Tuple', (1, 1), [('Name', (1, 2), 'a', ('Load',)), ('Name', (1, 4), 'b', ('Load',))], ('Load',)), [('comprehension', ('Tuple', (1, 11), [('Name', (1, 11), 'a', ('Store',)), ('Name', (1, 13), 'b', ('Store',))], ('Store',)), ('Name', (1, 18), 'c', ('Load',)), [], 0)])), - ('Expression', ('GeneratorExp', (1, 0), ('Tuple', (1, 1), [('Name', (1, 2), 'a', ('Load',)), ('Name', (1, 4), 'b', ('Load',))], ('Load',)), [('comprehension', ('Tuple', (1, 11), [('Name', (1, 12), 'a', ('Store',)), ('Name', (1, 14), 'b', ('Store',))], ('Store',)), ('Name', (1, 20), 'c', ('Load',)), [], 0)])), - ('Expression', ('GeneratorExp', (1, 0), ('Tuple', (1, 1), [('Name', (1, 2), 'a', ('Load',)), ('Name', (1, 4), 'b', ('Load',))], ('Load',)), [('comprehension', ('List', (1, 11), [('Name', (1, 12), 'a', ('Store',)), ('Name', (1, 14), 'b', ('Store',))], ('Store',)), ('Name', (1, 20), 'c', ('Load',)), [], 0)])), - ('Expression', ('Compare', (1, 0), ('Constant', (1, 0), 1, None), [('Lt',), ('Lt',)], [('Constant', (1, 4), 2, None), ('Constant', (1, 8), 3, None)])), - ('Expression', ('Call', (1, 0), ('Name', (1, 0), 'f', ('Load',)), [('Constant', (1, 2), 1, None), ('Constant', (1, 4), 2, None), ('Starred', (1, 10), ('Name', (1, 11), 'd', ('Load',)), ('Load',))], [('keyword', 'c', ('Constant', (1, 8), 3, None)), ('keyword', None, ('Name', (1, 15), 'e', ('Load',)))])), - ('Expression', ('Call', (1, 0), ('Name', (1, 0), 'f', ('Load',)), [('Starred', (1, 2), ('List', (1, 3), [('Constant', (1, 4), 0, None), ('Constant', (1, 7), 1, None)], ('Load',)), ('Load',))], [])), - ('Expression', ('Call', (1, 0), ('Name', (1, 0), 'f', ('Load',)), [('GeneratorExp', (1, 1), ('Name', (1, 2), 'a', ('Load',)), [('comprehension', ('Name', (1, 8), 'a', ('Store',)), ('Name', (1, 13), 'b', ('Load',)), [], 0)])], [])), - ('Expression', ('Constant', (1, 0), 10, None)), - ('Expression', ('Constant', (1, 0), 'string', None)), - ('Expression', ('Attribute', (1, 0), ('Name', (1, 0), 'a', ('Load',)), 'b', ('Load',))), - ('Expression', ('Subscript', (1, 0), ('Name', (1, 0), 'a', ('Load',)), ('Slice', ('Name', (1, 2), 'b', ('Load',)), ('Name', (1, 4), 'c', ('Load',)), None), ('Load',))), - ('Expression', ('Name', (1, 0), 'v', ('Load',))), - ('Expression', ('List', (1, 0), [('Constant', (1, 1), 1, None), ('Constant', (1, 3), 2, None), ('Constant', (1, 5), 3, None)], ('Load',))), - ('Expression', ('List', (1, 0), [], ('Load',))), - ('Expression', ('Tuple', (1, 0), [('Constant', (1, 0), 1, None), ('Constant', (1, 2), 2, None), ('Constant', (1, 4), 3, None)], ('Load',))), - ('Expression', ('Tuple', (1, 0), [('Constant', (1, 1), 1, None), ('Constant', (1, 3), 2, None), ('Constant', (1, 5), 3, None)], ('Load',))), - ('Expression', ('Tuple', (1, 0), [], ('Load',))), - ('Expression', ('Call', (1, 0), ('Attribute', (1, 0), ('Attribute', (1, 0), ('Attribute', (1, 0), ('Name', (1, 0), 'a', ('Load',)), 'b', ('Load',)), 'c', ('Load',)), 'd', ('Load',)), [('Subscript', (1, 8), ('Attribute', (1, 8), ('Name', (1, 8), 'a', ('Load',)), 'b', ('Load',)), ('Slice', ('Constant', (1, 12), 1, None), ('Constant', (1, 14), 2, None), None), ('Load',))], [])), - ] - main() diff --git a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_asyncgen.yaml b/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_asyncgen.yaml deleted file mode 100644 index 28aea8f9d..000000000 --- a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_asyncgen.yaml +++ /dev/null @@ -1,1211 +0,0 @@ -python: | - import inspect - import types - import unittest - - from test.support import import_module - asyncio = import_module("asyncio") - - - class AwaitException(Exception): - pass - - - @types.coroutine - def awaitable(*, throw=False): - if throw: - yield ('throw',) - else: - yield ('result',) - - - def run_until_complete(coro): - exc = False - while True: - try: - if exc: - exc = False - fut = coro.throw(AwaitException) - else: - fut = coro.send(None) - except StopIteration as ex: - return ex.args[0] - - if fut == ('throw',): - exc = True - - - def to_list(gen): - async def iterate(): - res = [] - async for i in gen: - res.append(i) - return res - - return run_until_complete(iterate()) - - - class AsyncGenSyntaxTest(unittest.TestCase): - - def test_async_gen_syntax_01(self): - code = '''async def foo(): - await abc - yield from 123 - ''' - - with self.assertRaisesRegex(SyntaxError, 'yield from.*inside async'): - exec(code, {}, {}) - - def test_async_gen_syntax_02(self): - code = '''async def foo(): - yield from 123 - ''' - - with self.assertRaisesRegex(SyntaxError, 'yield from.*inside async'): - exec(code, {}, {}) - - def test_async_gen_syntax_03(self): - code = '''async def foo(): - await abc - yield - return 123 - ''' - - with self.assertRaisesRegex(SyntaxError, 'return.*value.*async gen'): - exec(code, {}, {}) - - def test_async_gen_syntax_04(self): - code = '''async def foo(): - yield - return 123 - ''' - - with self.assertRaisesRegex(SyntaxError, 'return.*value.*async gen'): - exec(code, {}, {}) - - def test_async_gen_syntax_05(self): - code = '''async def foo(): - if 0: - yield - return 12 - ''' - - with self.assertRaisesRegex(SyntaxError, 'return.*value.*async gen'): - exec(code, {}, {}) - - - class AsyncGenTest(unittest.TestCase): - - def compare_generators(self, sync_gen, async_gen): - def sync_iterate(g): - res = [] - while True: - try: - res.append(g.__next__()) - except StopIteration: - res.append('STOP') - break - except Exception as ex: - res.append(str(type(ex))) - return res - - def async_iterate(g): - res = [] - while True: - an = g.__anext__() - try: - while True: - try: - an.__next__() - except StopIteration as ex: - if ex.args: - res.append(ex.args[0]) - break - else: - res.append('EMPTY StopIteration') - break - except StopAsyncIteration: - raise - except Exception as ex: - res.append(str(type(ex))) - break - except StopAsyncIteration: - res.append('STOP') - break - return res - - sync_gen_result = sync_iterate(sync_gen) - async_gen_result = async_iterate(async_gen) - self.assertEqual(sync_gen_result, async_gen_result) - return async_gen_result - - def test_async_gen_iteration_01(self): - async def gen(): - await awaitable() - a = yield 123 - self.assertIs(a, None) - await awaitable() - yield 456 - await awaitable() - yield 789 - - self.assertEqual(to_list(gen()), [123, 456, 789]) - - def test_async_gen_iteration_02(self): - async def gen(): - await awaitable() - yield 123 - await awaitable() - - g = gen() - ai = g.__aiter__() - - an = ai.__anext__() - self.assertEqual(an.__next__(), ('result',)) - - try: - an.__next__() - except StopIteration as ex: - self.assertEqual(ex.args[0], 123) - else: - self.fail('StopIteration was not raised') - - an = ai.__anext__() - self.assertEqual(an.__next__(), ('result',)) - - try: - an.__next__() - except StopAsyncIteration as ex: - self.assertFalse(ex.args) - else: - self.fail('StopAsyncIteration was not raised') - - def test_async_gen_exception_03(self): - async def gen(): - await awaitable() - yield 123 - await awaitable(throw=True) - yield 456 - - with self.assertRaises(AwaitException): - to_list(gen()) - - def test_async_gen_exception_04(self): - async def gen(): - await awaitable() - yield 123 - 1 / 0 - - g = gen() - ai = g.__aiter__() - an = ai.__anext__() - self.assertEqual(an.__next__(), ('result',)) - - try: - an.__next__() - except StopIteration as ex: - self.assertEqual(ex.args[0], 123) - else: - self.fail('StopIteration was not raised') - - with self.assertRaises(ZeroDivisionError): - ai.__anext__().__next__() - - def test_async_gen_exception_05(self): - async def gen(): - yield 123 - raise StopAsyncIteration - - with self.assertRaisesRegex(RuntimeError, - 'async generator.*StopAsyncIteration'): - to_list(gen()) - - def test_async_gen_exception_06(self): - async def gen(): - yield 123 - raise StopIteration - - with self.assertRaisesRegex(RuntimeError, - 'async generator.*StopIteration'): - to_list(gen()) - - def test_async_gen_exception_07(self): - def sync_gen(): - try: - yield 1 - 1 / 0 - finally: - yield 2 - yield 3 - - yield 100 - - async def async_gen(): - try: - yield 1 - 1 / 0 - finally: - yield 2 - yield 3 - - yield 100 - - self.compare_generators(sync_gen(), async_gen()) - - def test_async_gen_exception_08(self): - def sync_gen(): - try: - yield 1 - finally: - yield 2 - 1 / 0 - yield 3 - - yield 100 - - async def async_gen(): - try: - yield 1 - await awaitable() - finally: - await awaitable() - yield 2 - 1 / 0 - yield 3 - - yield 100 - - self.compare_generators(sync_gen(), async_gen()) - - def test_async_gen_exception_09(self): - def sync_gen(): - try: - yield 1 - 1 / 0 - finally: - yield 2 - yield 3 - - yield 100 - - async def async_gen(): - try: - await awaitable() - yield 1 - 1 / 0 - finally: - yield 2 - await awaitable() - yield 3 - - yield 100 - - self.compare_generators(sync_gen(), async_gen()) - - def test_async_gen_exception_10(self): - async def gen(): - yield 123 - with self.assertRaisesRegex(TypeError, - "non-None value .* async generator"): - gen().__anext__().send(100) - - def test_async_gen_exception_11(self): - def sync_gen(): - yield 10 - yield 20 - - def sync_gen_wrapper(): - yield 1 - sg = sync_gen() - sg.send(None) - try: - sg.throw(GeneratorExit()) - except GeneratorExit: - yield 2 - yield 3 - - async def async_gen(): - yield 10 - yield 20 - - async def async_gen_wrapper(): - yield 1 - asg = async_gen() - await asg.asend(None) - try: - await asg.athrow(GeneratorExit()) - except GeneratorExit: - yield 2 - yield 3 - - self.compare_generators(sync_gen_wrapper(), async_gen_wrapper()) - - def test_async_gen_api_01(self): - async def gen(): - yield 123 - - g = gen() - - self.assertEqual(g.__name__, 'gen') - g.__name__ = '123' - self.assertEqual(g.__name__, '123') - - self.assertIn('.gen', g.__qualname__) - g.__qualname__ = '123' - self.assertEqual(g.__qualname__, '123') - - self.assertIsNone(g.ag_await) - self.assertIsInstance(g.ag_frame, types.FrameType) - self.assertFalse(g.ag_running) - self.assertIsInstance(g.ag_code, types.CodeType) - - self.assertTrue(inspect.isawaitable(g.aclose())) - - - class AsyncGenAsyncioTest(unittest.TestCase): - - def setUp(self): - self.loop = asyncio.new_event_loop() - asyncio.set_event_loop(None) - - def tearDown(self): - self.loop.close() - self.loop = None - asyncio.set_event_loop_policy(None) - - async def to_list(self, gen): - res = [] - async for i in gen: - res.append(i) - return res - - def test_async_gen_asyncio_01(self): - async def gen(): - yield 1 - await asyncio.sleep(0.01) - yield 2 - await asyncio.sleep(0.01) - return - yield 3 - - res = self.loop.run_until_complete(self.to_list(gen())) - self.assertEqual(res, [1, 2]) - - def test_async_gen_asyncio_02(self): - async def gen(): - yield 1 - await asyncio.sleep(0.01) - yield 2 - 1 / 0 - yield 3 - - with self.assertRaises(ZeroDivisionError): - self.loop.run_until_complete(self.to_list(gen())) - - def test_async_gen_asyncio_03(self): - loop = self.loop - - class Gen: - async def __aiter__(self): - yield 1 - await asyncio.sleep(0.01) - yield 2 - - res = loop.run_until_complete(self.to_list(Gen())) - self.assertEqual(res, [1, 2]) - - def test_async_gen_asyncio_anext_04(self): - async def foo(): - yield 1 - await asyncio.sleep(0.01) - try: - yield 2 - yield 3 - except ZeroDivisionError: - yield 1000 - await asyncio.sleep(0.01) - yield 4 - - async def run1(): - it = foo().__aiter__() - - self.assertEqual(await it.__anext__(), 1) - self.assertEqual(await it.__anext__(), 2) - self.assertEqual(await it.__anext__(), 3) - self.assertEqual(await it.__anext__(), 4) - with self.assertRaises(StopAsyncIteration): - await it.__anext__() - with self.assertRaises(StopAsyncIteration): - await it.__anext__() - - async def run2(): - it = foo().__aiter__() - - self.assertEqual(await it.__anext__(), 1) - self.assertEqual(await it.__anext__(), 2) - try: - it.__anext__().throw(ZeroDivisionError) - except StopIteration as ex: - self.assertEqual(ex.args[0], 1000) - else: - self.fail('StopIteration was not raised') - self.assertEqual(await it.__anext__(), 4) - with self.assertRaises(StopAsyncIteration): - await it.__anext__() - - self.loop.run_until_complete(run1()) - self.loop.run_until_complete(run2()) - - def test_async_gen_asyncio_anext_05(self): - async def foo(): - v = yield 1 - v = yield v - yield v * 100 - - async def run(): - it = foo().__aiter__() - - try: - it.__anext__().send(None) - except StopIteration as ex: - self.assertEqual(ex.args[0], 1) - else: - self.fail('StopIteration was not raised') - - try: - it.__anext__().send(10) - except StopIteration as ex: - self.assertEqual(ex.args[0], 10) - else: - self.fail('StopIteration was not raised') - - try: - it.__anext__().send(12) - except StopIteration as ex: - self.assertEqual(ex.args[0], 1200) - else: - self.fail('StopIteration was not raised') - - with self.assertRaises(StopAsyncIteration): - await it.__anext__() - - self.loop.run_until_complete(run()) - - def test_async_gen_asyncio_anext_06(self): - DONE = 0 - - # test synchronous generators - def foo(): - try: - yield - except: - pass - g = foo() - g.send(None) - with self.assertRaises(StopIteration): - g.send(None) - - # now with asynchronous generators - - async def gen(): - nonlocal DONE - try: - yield - except: - pass - DONE = 1 - - async def run(): - nonlocal DONE - g = gen() - await g.asend(None) - with self.assertRaises(StopAsyncIteration): - await g.asend(None) - DONE += 10 - - self.loop.run_until_complete(run()) - self.assertEqual(DONE, 11) - - def test_async_gen_asyncio_anext_tuple(self): - async def foo(): - try: - yield (1,) - except ZeroDivisionError: - yield (2,) - - async def run(): - it = foo().__aiter__() - - self.assertEqual(await it.__anext__(), (1,)) - with self.assertRaises(StopIteration) as cm: - it.__anext__().throw(ZeroDivisionError) - self.assertEqual(cm.exception.args[0], (2,)) - with self.assertRaises(StopAsyncIteration): - await it.__anext__() - - self.loop.run_until_complete(run()) - - def test_async_gen_asyncio_anext_stopiteration(self): - async def foo(): - try: - yield StopIteration(1) - except ZeroDivisionError: - yield StopIteration(3) - - async def run(): - it = foo().__aiter__() - - v = await it.__anext__() - self.assertIsInstance(v, StopIteration) - self.assertEqual(v.value, 1) - with self.assertRaises(StopIteration) as cm: - it.__anext__().throw(ZeroDivisionError) - v = cm.exception.args[0] - self.assertIsInstance(v, StopIteration) - self.assertEqual(v.value, 3) - with self.assertRaises(StopAsyncIteration): - await it.__anext__() - - self.loop.run_until_complete(run()) - - def test_async_gen_asyncio_aclose_06(self): - async def foo(): - try: - yield 1 - 1 / 0 - finally: - await asyncio.sleep(0.01) - yield 12 - - async def run(): - gen = foo() - it = gen.__aiter__() - await it.__anext__() - await gen.aclose() - - with self.assertRaisesRegex( - RuntimeError, - "async generator ignored GeneratorExit"): - self.loop.run_until_complete(run()) - - def test_async_gen_asyncio_aclose_07(self): - DONE = 0 - - async def foo(): - nonlocal DONE - try: - yield 1 - 1 / 0 - finally: - await asyncio.sleep(0.01) - await asyncio.sleep(0.01) - DONE += 1 - DONE += 1000 - - async def run(): - gen = foo() - it = gen.__aiter__() - await it.__anext__() - await gen.aclose() - - self.loop.run_until_complete(run()) - self.assertEqual(DONE, 1) - - def test_async_gen_asyncio_aclose_08(self): - DONE = 0 - - fut = asyncio.Future(loop=self.loop) - - async def foo(): - nonlocal DONE - try: - yield 1 - await fut - DONE += 1000 - yield 2 - finally: - await asyncio.sleep(0.01) - await asyncio.sleep(0.01) - DONE += 1 - DONE += 1000 - - async def run(): - gen = foo() - it = gen.__aiter__() - self.assertEqual(await it.__anext__(), 1) - await gen.aclose() - - self.loop.run_until_complete(run()) - self.assertEqual(DONE, 1) - - # Silence ResourceWarnings - fut.cancel() - self.loop.run_until_complete(asyncio.sleep(0.01)) - - def test_async_gen_asyncio_gc_aclose_09(self): - DONE = 0 - - async def gen(): - nonlocal DONE - try: - while True: - yield 1 - finally: - await asyncio.sleep(0.01) - await asyncio.sleep(0.01) - DONE = 1 - - async def run(): - g = gen() - await g.__anext__() - await g.__anext__() - del g - - await asyncio.sleep(0.1) - - self.loop.run_until_complete(run()) - self.assertEqual(DONE, 1) - - def test_async_gen_asyncio_aclose_10(self): - DONE = 0 - - # test synchronous generators - def foo(): - try: - yield - except: - pass - g = foo() - g.send(None) - g.close() - - # now with asynchronous generators - - async def gen(): - nonlocal DONE - try: - yield - except: - pass - DONE = 1 - - async def run(): - nonlocal DONE - g = gen() - await g.asend(None) - await g.aclose() - DONE += 10 - - self.loop.run_until_complete(run()) - self.assertEqual(DONE, 11) - - def test_async_gen_asyncio_aclose_11(self): - DONE = 0 - - # test synchronous generators - def foo(): - try: - yield - except: - pass - yield - g = foo() - g.send(None) - with self.assertRaisesRegex(RuntimeError, 'ignored GeneratorExit'): - g.close() - - # now with asynchronous generators - - async def gen(): - nonlocal DONE - try: - yield - except: - pass - yield - DONE += 1 - - async def run(): - nonlocal DONE - g = gen() - await g.asend(None) - with self.assertRaisesRegex(RuntimeError, 'ignored GeneratorExit'): - await g.aclose() - DONE += 10 - - self.loop.run_until_complete(run()) - self.assertEqual(DONE, 10) - - def test_async_gen_asyncio_aclose_12(self): - DONE = 0 - - async def target(): - await asyncio.sleep(0.01) - 1 / 0 - - async def foo(): - nonlocal DONE - task = asyncio.create_task(target()) - try: - yield 1 - finally: - try: - await task - except ZeroDivisionError: - DONE = 1 - - async def run(): - gen = foo() - it = gen.__aiter__() - await it.__anext__() - await gen.aclose() - - self.loop.run_until_complete(run()) - self.assertEqual(DONE, 1) - - def test_async_gen_asyncio_asend_01(self): - DONE = 0 - - # Sanity check: - def sgen(): - v = yield 1 - yield v * 2 - sg = sgen() - v = sg.send(None) - self.assertEqual(v, 1) - v = sg.send(100) - self.assertEqual(v, 200) - - async def gen(): - nonlocal DONE - try: - await asyncio.sleep(0.01) - v = yield 1 - await asyncio.sleep(0.01) - yield v * 2 - await asyncio.sleep(0.01) - return - finally: - await asyncio.sleep(0.01) - await asyncio.sleep(0.01) - DONE = 1 - - async def run(): - g = gen() - - v = await g.asend(None) - self.assertEqual(v, 1) - - v = await g.asend(100) - self.assertEqual(v, 200) - - with self.assertRaises(StopAsyncIteration): - await g.asend(None) - - self.loop.run_until_complete(run()) - self.assertEqual(DONE, 1) - - def test_async_gen_asyncio_asend_02(self): - DONE = 0 - - async def sleep_n_crash(delay): - await asyncio.sleep(delay) - 1 / 0 - - async def gen(): - nonlocal DONE - try: - await asyncio.sleep(0.01) - v = yield 1 - await sleep_n_crash(0.01) - DONE += 1000 - yield v * 2 - finally: - await asyncio.sleep(0.01) - await asyncio.sleep(0.01) - DONE = 1 - - async def run(): - g = gen() - - v = await g.asend(None) - self.assertEqual(v, 1) - - await g.asend(100) - - with self.assertRaises(ZeroDivisionError): - self.loop.run_until_complete(run()) - self.assertEqual(DONE, 1) - - def test_async_gen_asyncio_asend_03(self): - DONE = 0 - - async def sleep_n_crash(delay): - fut = asyncio.ensure_future(asyncio.sleep(delay), - loop=self.loop) - self.loop.call_later(delay / 2, lambda: fut.cancel()) - return await fut - - async def gen(): - nonlocal DONE - try: - await asyncio.sleep(0.01) - v = yield 1 - await sleep_n_crash(0.01) - DONE += 1000 - yield v * 2 - finally: - await asyncio.sleep(0.01) - await asyncio.sleep(0.01) - DONE = 1 - - async def run(): - g = gen() - - v = await g.asend(None) - self.assertEqual(v, 1) - - await g.asend(100) - - with self.assertRaises(asyncio.CancelledError): - self.loop.run_until_complete(run()) - self.assertEqual(DONE, 1) - - def test_async_gen_asyncio_athrow_01(self): - DONE = 0 - - class FooEr(Exception): - pass - - # Sanity check: - def sgen(): - try: - v = yield 1 - except FooEr: - v = 1000 - yield v * 2 - sg = sgen() - v = sg.send(None) - self.assertEqual(v, 1) - v = sg.throw(FooEr) - self.assertEqual(v, 2000) - with self.assertRaises(StopIteration): - sg.send(None) - - async def gen(): - nonlocal DONE - try: - await asyncio.sleep(0.01) - try: - v = yield 1 - except FooEr: - v = 1000 - await asyncio.sleep(0.01) - yield v * 2 - await asyncio.sleep(0.01) - # return - finally: - await asyncio.sleep(0.01) - await asyncio.sleep(0.01) - DONE = 1 - - async def run(): - g = gen() - - v = await g.asend(None) - self.assertEqual(v, 1) - - v = await g.athrow(FooEr) - self.assertEqual(v, 2000) - - with self.assertRaises(StopAsyncIteration): - await g.asend(None) - - self.loop.run_until_complete(run()) - self.assertEqual(DONE, 1) - - def test_async_gen_asyncio_athrow_02(self): - DONE = 0 - - class FooEr(Exception): - pass - - async def sleep_n_crash(delay): - fut = asyncio.ensure_future(asyncio.sleep(delay), - loop=self.loop) - self.loop.call_later(delay / 2, lambda: fut.cancel()) - return await fut - - async def gen(): - nonlocal DONE - try: - await asyncio.sleep(0.01) - try: - v = yield 1 - except FooEr: - await sleep_n_crash(0.01) - yield v * 2 - await asyncio.sleep(0.01) - # return - finally: - await asyncio.sleep(0.01) - await asyncio.sleep(0.01) - DONE = 1 - - async def run(): - g = gen() - - v = await g.asend(None) - self.assertEqual(v, 1) - - try: - await g.athrow(FooEr) - except asyncio.CancelledError: - self.assertEqual(DONE, 1) - raise - else: - self.fail('CancelledError was not raised') - - with self.assertRaises(asyncio.CancelledError): - self.loop.run_until_complete(run()) - self.assertEqual(DONE, 1) - - def test_async_gen_asyncio_athrow_03(self): - DONE = 0 - - # test synchronous generators - def foo(): - try: - yield - except: - pass - g = foo() - g.send(None) - with self.assertRaises(StopIteration): - g.throw(ValueError) - - # now with asynchronous generators - - async def gen(): - nonlocal DONE - try: - yield - except: - pass - DONE = 1 - - async def run(): - nonlocal DONE - g = gen() - await g.asend(None) - with self.assertRaises(StopAsyncIteration): - await g.athrow(ValueError) - DONE += 10 - - self.loop.run_until_complete(run()) - self.assertEqual(DONE, 11) - - def test_async_gen_asyncio_athrow_tuple(self): - async def gen(): - try: - yield 1 - except ZeroDivisionError: - yield (2,) - - async def run(): - g = gen() - v = await g.asend(None) - self.assertEqual(v, 1) - v = await g.athrow(ZeroDivisionError) - self.assertEqual(v, (2,)) - with self.assertRaises(StopAsyncIteration): - await g.asend(None) - - self.loop.run_until_complete(run()) - - def test_async_gen_asyncio_athrow_stopiteration(self): - async def gen(): - try: - yield 1 - except ZeroDivisionError: - yield StopIteration(2) - - async def run(): - g = gen() - v = await g.asend(None) - self.assertEqual(v, 1) - v = await g.athrow(ZeroDivisionError) - self.assertIsInstance(v, StopIteration) - self.assertEqual(v.value, 2) - with self.assertRaises(StopAsyncIteration): - await g.asend(None) - - self.loop.run_until_complete(run()) - - def test_async_gen_asyncio_shutdown_01(self): - finalized = 0 - - async def waiter(timeout): - nonlocal finalized - try: - await asyncio.sleep(timeout) - yield 1 - finally: - await asyncio.sleep(0) - finalized += 1 - - async def wait(): - async for _ in waiter(1): - pass - - t1 = self.loop.create_task(wait()) - t2 = self.loop.create_task(wait()) - - self.loop.run_until_complete(asyncio.sleep(0.1)) - - # Silence warnings - t1.cancel() - t2.cancel() - - with self.assertRaises(asyncio.CancelledError): - self.loop.run_until_complete(t1) - with self.assertRaises(asyncio.CancelledError): - self.loop.run_until_complete(t2) - - self.loop.run_until_complete(self.loop.shutdown_asyncgens()) - - self.assertEqual(finalized, 2) - - def test_async_gen_expression_01(self): - async def arange(n): - for i in range(n): - await asyncio.sleep(0.01) - yield i - - def make_arange(n): - # This syntax is legal starting with Python 3.7 - return (i * 2 async for i in arange(n)) - - async def run(): - return [i async for i in make_arange(10)] - - res = self.loop.run_until_complete(run()) - self.assertEqual(res, [i * 2 for i in range(10)]) - - def test_async_gen_expression_02(self): - async def wrap(n): - await asyncio.sleep(0.01) - return n - - def make_arange(n): - # This syntax is legal starting with Python 3.7 - return (i * 2 for i in range(n) if await wrap(i)) - - async def run(): - return [i async for i in make_arange(10)] - - res = self.loop.run_until_complete(run()) - self.assertEqual(res, [i * 2 for i in range(1, 10)]) - - def test_asyncgen_nonstarted_hooks_are_cancellable(self): - # See https://bugs.python.org/issue38013 - messages = [] - - def exception_handler(loop, context): - messages.append(context) - - async def async_iterate(): - yield 1 - yield 2 - - async def main(): - loop = asyncio.get_running_loop() - loop.set_exception_handler(exception_handler) - - async for i in async_iterate(): - break - - asyncio.run(main()) - - self.assertEqual([], messages) - - def test_async_gen_await_same_anext_coro_twice(self): - async def async_iterate(): - yield 1 - yield 2 - - async def run(): - it = async_iterate() - nxt = it.__anext__() - await nxt - with self.assertRaisesRegex( - RuntimeError, - r"cannot reuse already awaited __anext__\(\)/asend\(\)" - ): - await nxt - - await it.aclose() # prevent unfinished iterator warning - - self.loop.run_until_complete(run()) - - def test_async_gen_await_same_aclose_coro_twice(self): - async def async_iterate(): - yield 1 - yield 2 - - async def run(): - it = async_iterate() - nxt = it.aclose() - await nxt - with self.assertRaisesRegex( - RuntimeError, - r"cannot reuse already awaited aclose\(\)/athrow\(\)" - ): - await nxt - - self.loop.run_until_complete(run()) - - def test_async_gen_aclose_twice_with_different_coros(self): - # Regression test for https://bugs.python.org/issue39606 - async def async_iterate(): - yield 1 - yield 2 - - async def run(): - it = async_iterate() - await it.aclose() - await it.aclose() - - self.loop.run_until_complete(run()) - - def test_async_gen_aclose_after_exhaustion(self): - # Regression test for https://bugs.python.org/issue39606 - async def async_iterate(): - yield 1 - yield 2 - - async def run(): - it = async_iterate() - async for _ in it: - pass - await it.aclose() - - self.loop.run_until_complete(run()) - - def test_async_gen_aclose_compatible_with_get_stack(self): - async def async_generator(): - yield object() - - async def run(): - ag = async_generator() - asyncio.create_task(ag.aclose()) - tasks = asyncio.all_tasks() - for task in tasks: - # No AttributeError raised - task.get_stack() - - self.loop.run_until_complete(run()) - - - if __name__ == "__main__": - unittest.main() diff --git a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_asynchat.yaml b/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_asynchat.yaml deleted file mode 100644 index 3aff283ba..000000000 --- a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_asynchat.yaml +++ /dev/null @@ -1,288 +0,0 @@ -python: | - # test asynchat - - from test import support - - import asynchat - import asyncore - import errno - import socket - import sys - import threading - import time - import unittest - import unittest.mock - - HOST = support.HOST - SERVER_QUIT = b'QUIT\n' - TIMEOUT = 3.0 - - - class echo_server(threading.Thread): - # parameter to determine the number of bytes passed back to the - # client each send - chunk_size = 1 - - def __init__(self, event): - threading.Thread.__init__(self) - self.event = event - self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - self.port = support.bind_port(self.sock) - # This will be set if the client wants us to wait before echoing - # data back. - self.start_resend_event = None - - def run(self): - self.sock.listen() - self.event.set() - conn, client = self.sock.accept() - self.buffer = b"" - # collect data until quit message is seen - while SERVER_QUIT not in self.buffer: - data = conn.recv(1) - if not data: - break - self.buffer = self.buffer + data - - # remove the SERVER_QUIT message - self.buffer = self.buffer.replace(SERVER_QUIT, b'') - - if self.start_resend_event: - self.start_resend_event.wait() - - # re-send entire set of collected data - try: - # this may fail on some tests, such as test_close_when_done, - # since the client closes the channel when it's done sending - while self.buffer: - n = conn.send(self.buffer[:self.chunk_size]) - time.sleep(0.001) - self.buffer = self.buffer[n:] - except: - pass - - conn.close() - self.sock.close() - - class echo_client(asynchat.async_chat): - - def __init__(self, terminator, server_port): - asynchat.async_chat.__init__(self) - self.contents = [] - self.create_socket(socket.AF_INET, socket.SOCK_STREAM) - self.connect((HOST, server_port)) - self.set_terminator(terminator) - self.buffer = b"" - - def handle_connect(self): - pass - - if sys.platform == 'darwin': - # select.poll returns a select.POLLHUP at the end of the tests - # on darwin, so just ignore it - def handle_expt(self): - pass - - def collect_incoming_data(self, data): - self.buffer += data - - def found_terminator(self): - self.contents.append(self.buffer) - self.buffer = b"" - - def start_echo_server(): - event = threading.Event() - s = echo_server(event) - s.start() - event.wait() - event.clear() - time.sleep(0.01) # Give server time to start accepting. - return s, event - - - class TestAsynchat(unittest.TestCase): - usepoll = False - - def setUp(self): - self._threads = support.threading_setup() - - def tearDown(self): - support.threading_cleanup(*self._threads) - - def line_terminator_check(self, term, server_chunk): - event = threading.Event() - s = echo_server(event) - s.chunk_size = server_chunk - s.start() - event.wait() - event.clear() - time.sleep(0.01) # Give server time to start accepting. - c = echo_client(term, s.port) - c.push(b"hello ") - c.push(b"world" + term) - c.push(b"I'm not dead yet!" + term) - c.push(SERVER_QUIT) - asyncore.loop(use_poll=self.usepoll, count=300, timeout=.01) - support.join_thread(s, timeout=TIMEOUT) - - self.assertEqual(c.contents, [b"hello world", b"I'm not dead yet!"]) - - # the line terminator tests below check receiving variously-sized - # chunks back from the server in order to exercise all branches of - # async_chat.handle_read - - def test_line_terminator1(self): - # test one-character terminator - for l in (1, 2, 3): - self.line_terminator_check(b'\n', l) - - def test_line_terminator2(self): - # test two-character terminator - for l in (1, 2, 3): - self.line_terminator_check(b'\r\n', l) - - def test_line_terminator3(self): - # test three-character terminator - for l in (1, 2, 3): - self.line_terminator_check(b'qqq', l) - - def numeric_terminator_check(self, termlen): - # Try reading a fixed number of bytes - s, event = start_echo_server() - c = echo_client(termlen, s.port) - data = b"hello world, I'm not dead yet!\n" - c.push(data) - c.push(SERVER_QUIT) - asyncore.loop(use_poll=self.usepoll, count=300, timeout=.01) - support.join_thread(s, timeout=TIMEOUT) - - self.assertEqual(c.contents, [data[:termlen]]) - - def test_numeric_terminator1(self): - # check that ints & longs both work (since type is - # explicitly checked in async_chat.handle_read) - self.numeric_terminator_check(1) - - def test_numeric_terminator2(self): - self.numeric_terminator_check(6) - - def test_none_terminator(self): - # Try reading a fixed number of bytes - s, event = start_echo_server() - c = echo_client(None, s.port) - data = b"hello world, I'm not dead yet!\n" - c.push(data) - c.push(SERVER_QUIT) - asyncore.loop(use_poll=self.usepoll, count=300, timeout=.01) - support.join_thread(s, timeout=TIMEOUT) - - self.assertEqual(c.contents, []) - self.assertEqual(c.buffer, data) - - def test_simple_producer(self): - s, event = start_echo_server() - c = echo_client(b'\n', s.port) - data = b"hello world\nI'm not dead yet!\n" - p = asynchat.simple_producer(data+SERVER_QUIT, buffer_size=8) - c.push_with_producer(p) - asyncore.loop(use_poll=self.usepoll, count=300, timeout=.01) - support.join_thread(s, timeout=TIMEOUT) - - self.assertEqual(c.contents, [b"hello world", b"I'm not dead yet!"]) - - def test_string_producer(self): - s, event = start_echo_server() - c = echo_client(b'\n', s.port) - data = b"hello world\nI'm not dead yet!\n" - c.push_with_producer(data+SERVER_QUIT) - asyncore.loop(use_poll=self.usepoll, count=300, timeout=.01) - support.join_thread(s, timeout=TIMEOUT) - - self.assertEqual(c.contents, [b"hello world", b"I'm not dead yet!"]) - - def test_empty_line(self): - # checks that empty lines are handled correctly - s, event = start_echo_server() - c = echo_client(b'\n', s.port) - c.push(b"hello world\n\nI'm not dead yet!\n") - c.push(SERVER_QUIT) - asyncore.loop(use_poll=self.usepoll, count=300, timeout=.01) - support.join_thread(s, timeout=TIMEOUT) - - self.assertEqual(c.contents, - [b"hello world", b"", b"I'm not dead yet!"]) - - def test_close_when_done(self): - s, event = start_echo_server() - s.start_resend_event = threading.Event() - c = echo_client(b'\n', s.port) - c.push(b"hello world\nI'm not dead yet!\n") - c.push(SERVER_QUIT) - c.close_when_done() - asyncore.loop(use_poll=self.usepoll, count=300, timeout=.01) - - # Only allow the server to start echoing data back to the client after - # the client has closed its connection. This prevents a race condition - # where the server echoes all of its data before we can check that it - # got any down below. - s.start_resend_event.set() - support.join_thread(s, timeout=TIMEOUT) - - self.assertEqual(c.contents, []) - # the server might have been able to send a byte or two back, but this - # at least checks that it received something and didn't just fail - # (which could still result in the client not having received anything) - self.assertGreater(len(s.buffer), 0) - - def test_push(self): - # Issue #12523: push() should raise a TypeError if it doesn't get - # a bytes string - s, event = start_echo_server() - c = echo_client(b'\n', s.port) - data = b'bytes\n' - c.push(data) - c.push(bytearray(data)) - c.push(memoryview(data)) - self.assertRaises(TypeError, c.push, 10) - self.assertRaises(TypeError, c.push, 'unicode') - c.push(SERVER_QUIT) - asyncore.loop(use_poll=self.usepoll, count=300, timeout=.01) - support.join_thread(s, timeout=TIMEOUT) - self.assertEqual(c.contents, [b'bytes', b'bytes', b'bytes']) - - - class TestAsynchat_WithPoll(TestAsynchat): - usepoll = True - - - class TestAsynchatMocked(unittest.TestCase): - def test_blockingioerror(self): - # Issue #16133: handle_read() must ignore BlockingIOError - sock = unittest.mock.Mock() - sock.recv.side_effect = BlockingIOError(errno.EAGAIN) - - dispatcher = asynchat.async_chat() - dispatcher.set_socket(sock) - self.addCleanup(dispatcher.del_channel) - - with unittest.mock.patch.object(dispatcher, 'handle_error') as error: - dispatcher.handle_read() - self.assertFalse(error.called) - - - class TestHelperFunctions(unittest.TestCase): - def test_find_prefix_at_end(self): - self.assertEqual(asynchat.find_prefix_at_end("qwerty\r", "\r\n"), 1) - self.assertEqual(asynchat.find_prefix_at_end("qwertydkjf", "\r\n"), 0) - - - class TestNotConnected(unittest.TestCase): - def test_disallow_negative_terminator(self): - # Issue #11259 - client = asynchat.async_chat() - self.assertRaises(ValueError, client.set_terminator, -1) - - - - if __name__ == "__main__": - unittest.main() diff --git a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_asyncore.yaml b/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_asyncore.yaml deleted file mode 100644 index cbed17ecf..000000000 --- a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_asyncore.yaml +++ /dev/null @@ -1,835 +0,0 @@ -python: | - import asyncore - import unittest - import select - import os - import socket - import sys - import time - import errno - import struct - import threading - - from test import support - from io import BytesIO - - if support.PGO: - raise unittest.SkipTest("test is not helpful for PGO") - - - TIMEOUT = 3 - HAS_UNIX_SOCKETS = hasattr(socket, 'AF_UNIX') - - class dummysocket: - def __init__(self): - self.closed = False - - def close(self): - self.closed = True - - def fileno(self): - return 42 - - class dummychannel: - def __init__(self): - self.socket = dummysocket() - - def close(self): - self.socket.close() - - class exitingdummy: - def __init__(self): - pass - - def handle_read_event(self): - raise asyncore.ExitNow() - - handle_write_event = handle_read_event - handle_close = handle_read_event - handle_expt_event = handle_read_event - - class crashingdummy: - def __init__(self): - self.error_handled = False - - def handle_read_event(self): - raise Exception() - - handle_write_event = handle_read_event - handle_close = handle_read_event - handle_expt_event = handle_read_event - - def handle_error(self): - self.error_handled = True - - # used when testing senders; just collects what it gets until newline is sent - def capture_server(evt, buf, serv): - try: - serv.listen() - conn, addr = serv.accept() - except socket.timeout: - pass - else: - n = 200 - start = time.monotonic() - while n > 0 and time.monotonic() - start < 3.0: - r, w, e = select.select([conn], [], [], 0.1) - if r: - n -= 1 - data = conn.recv(10) - # keep everything except for the newline terminator - buf.write(data.replace(b'\n', b'')) - if b'\n' in data: - break - time.sleep(0.01) - - conn.close() - finally: - serv.close() - evt.set() - - def bind_af_aware(sock, addr): - """Helper function to bind a socket according to its family.""" - if HAS_UNIX_SOCKETS and sock.family == socket.AF_UNIX: - # Make sure the path doesn't exist. - support.unlink(addr) - support.bind_unix_socket(sock, addr) - else: - sock.bind(addr) - - - class HelperFunctionTests(unittest.TestCase): - def test_readwriteexc(self): - # Check exception handling behavior of read, write and _exception - - # check that ExitNow exceptions in the object handler method - # bubbles all the way up through asyncore read/write/_exception calls - tr1 = exitingdummy() - self.assertRaises(asyncore.ExitNow, asyncore.read, tr1) - self.assertRaises(asyncore.ExitNow, asyncore.write, tr1) - self.assertRaises(asyncore.ExitNow, asyncore._exception, tr1) - - # check that an exception other than ExitNow in the object handler - # method causes the handle_error method to get called - tr2 = crashingdummy() - asyncore.read(tr2) - self.assertEqual(tr2.error_handled, True) - - tr2 = crashingdummy() - asyncore.write(tr2) - self.assertEqual(tr2.error_handled, True) - - tr2 = crashingdummy() - asyncore._exception(tr2) - self.assertEqual(tr2.error_handled, True) - - # asyncore.readwrite uses constants in the select module that - # are not present in Windows systems (see this thread: - # http://mail.python.org/pipermail/python-list/2001-October/109973.html) - # These constants should be present as long as poll is available - - @unittest.skipUnless(hasattr(select, 'poll'), 'select.poll required') - def test_readwrite(self): - # Check that correct methods are called by readwrite() - - attributes = ('read', 'expt', 'write', 'closed', 'error_handled') - - expected = ( - (select.POLLIN, 'read'), - (select.POLLPRI, 'expt'), - (select.POLLOUT, 'write'), - (select.POLLERR, 'closed'), - (select.POLLHUP, 'closed'), - (select.POLLNVAL, 'closed'), - ) - - class testobj: - def __init__(self): - self.read = False - self.write = False - self.closed = False - self.expt = False - self.error_handled = False - - def handle_read_event(self): - self.read = True - - def handle_write_event(self): - self.write = True - - def handle_close(self): - self.closed = True - - def handle_expt_event(self): - self.expt = True - - def handle_error(self): - self.error_handled = True - - for flag, expectedattr in expected: - tobj = testobj() - self.assertEqual(getattr(tobj, expectedattr), False) - asyncore.readwrite(tobj, flag) - - # Only the attribute modified by the routine we expect to be - # called should be True. - for attr in attributes: - self.assertEqual(getattr(tobj, attr), attr==expectedattr) - - # check that ExitNow exceptions in the object handler method - # bubbles all the way up through asyncore readwrite call - tr1 = exitingdummy() - self.assertRaises(asyncore.ExitNow, asyncore.readwrite, tr1, flag) - - # check that an exception other than ExitNow in the object handler - # method causes the handle_error method to get called - tr2 = crashingdummy() - self.assertEqual(tr2.error_handled, False) - asyncore.readwrite(tr2, flag) - self.assertEqual(tr2.error_handled, True) - - def test_closeall(self): - self.closeall_check(False) - - def test_closeall_default(self): - self.closeall_check(True) - - def closeall_check(self, usedefault): - # Check that close_all() closes everything in a given map - - l = [] - testmap = {} - for i in range(10): - c = dummychannel() - l.append(c) - self.assertEqual(c.socket.closed, False) - testmap[i] = c - - if usedefault: - socketmap = asyncore.socket_map - try: - asyncore.socket_map = testmap - asyncore.close_all() - finally: - testmap, asyncore.socket_map = asyncore.socket_map, socketmap - else: - asyncore.close_all(testmap) - - self.assertEqual(len(testmap), 0) - - for c in l: - self.assertEqual(c.socket.closed, True) - - def test_compact_traceback(self): - try: - raise Exception("I don't like spam!") - except: - real_t, real_v, real_tb = sys.exc_info() - r = asyncore.compact_traceback() - else: - self.fail("Expected exception") - - (f, function, line), t, v, info = r - self.assertEqual(os.path.split(f)[-1], 'test_asyncore.py') - self.assertEqual(function, 'test_compact_traceback') - self.assertEqual(t, real_t) - self.assertEqual(v, real_v) - self.assertEqual(info, '[%s|%s|%s]' % (f, function, line)) - - - class DispatcherTests(unittest.TestCase): - def setUp(self): - pass - - def tearDown(self): - asyncore.close_all() - - def test_basic(self): - d = asyncore.dispatcher() - self.assertEqual(d.readable(), True) - self.assertEqual(d.writable(), True) - - def test_repr(self): - d = asyncore.dispatcher() - self.assertEqual(repr(d), '' % id(d)) - - def test_log(self): - d = asyncore.dispatcher() - - # capture output of dispatcher.log() (to stderr) - l1 = "Lovely spam! Wonderful spam!" - l2 = "I don't like spam!" - with support.captured_stderr() as stderr: - d.log(l1) - d.log(l2) - - lines = stderr.getvalue().splitlines() - self.assertEqual(lines, ['log: %s' % l1, 'log: %s' % l2]) - - def test_log_info(self): - d = asyncore.dispatcher() - - # capture output of dispatcher.log_info() (to stdout via print) - l1 = "Have you got anything without spam?" - l2 = "Why can't she have egg bacon spam and sausage?" - l3 = "THAT'S got spam in it!" - with support.captured_stdout() as stdout: - d.log_info(l1, 'EGGS') - d.log_info(l2) - d.log_info(l3, 'SPAM') - - lines = stdout.getvalue().splitlines() - expected = ['EGGS: %s' % l1, 'info: %s' % l2, 'SPAM: %s' % l3] - self.assertEqual(lines, expected) - - def test_unhandled(self): - d = asyncore.dispatcher() - d.ignore_log_types = () - - # capture output of dispatcher.log_info() (to stdout via print) - with support.captured_stdout() as stdout: - d.handle_expt() - d.handle_read() - d.handle_write() - d.handle_connect() - - lines = stdout.getvalue().splitlines() - expected = ['warning: unhandled incoming priority event', - 'warning: unhandled read event', - 'warning: unhandled write event', - 'warning: unhandled connect event'] - self.assertEqual(lines, expected) - - def test_strerror(self): - # refers to bug #8573 - err = asyncore._strerror(errno.EPERM) - if hasattr(os, 'strerror'): - self.assertEqual(err, os.strerror(errno.EPERM)) - err = asyncore._strerror(-1) - self.assertTrue(err != "") - - - class dispatcherwithsend_noread(asyncore.dispatcher_with_send): - def readable(self): - return False - - def handle_connect(self): - pass - - - class DispatcherWithSendTests(unittest.TestCase): - def setUp(self): - pass - - def tearDown(self): - asyncore.close_all() - - @support.reap_threads - def test_send(self): - evt = threading.Event() - sock = socket.socket() - sock.settimeout(3) - port = support.bind_port(sock) - - cap = BytesIO() - args = (evt, cap, sock) - t = threading.Thread(target=capture_server, args=args) - t.start() - try: - # wait a little longer for the server to initialize (it sometimes - # refuses connections on slow machines without this wait) - time.sleep(0.2) - - data = b"Suppose there isn't a 16-ton weight?" - d = dispatcherwithsend_noread() - d.create_socket() - d.connect((support.HOST, port)) - - # give time for socket to connect - time.sleep(0.1) - - d.send(data) - d.send(data) - d.send(b'\n') - - n = 1000 - while d.out_buffer and n > 0: - asyncore.poll() - n -= 1 - - evt.wait() - - self.assertEqual(cap.getvalue(), data*2) - finally: - support.join_thread(t, timeout=TIMEOUT) - - - @unittest.skipUnless(hasattr(asyncore, 'file_wrapper'), - 'asyncore.file_wrapper required') - class FileWrapperTest(unittest.TestCase): - def setUp(self): - self.d = b"It's not dead, it's sleeping!" - with open(support.TESTFN, 'wb') as file: - file.write(self.d) - - def tearDown(self): - support.unlink(support.TESTFN) - - def test_recv(self): - fd = os.open(support.TESTFN, os.O_RDONLY) - w = asyncore.file_wrapper(fd) - os.close(fd) - - self.assertNotEqual(w.fd, fd) - self.assertNotEqual(w.fileno(), fd) - self.assertEqual(w.recv(13), b"It's not dead") - self.assertEqual(w.read(6), b", it's") - w.close() - self.assertRaises(OSError, w.read, 1) - - def test_send(self): - d1 = b"Come again?" - d2 = b"I want to buy some cheese." - fd = os.open(support.TESTFN, os.O_WRONLY | os.O_APPEND) - w = asyncore.file_wrapper(fd) - os.close(fd) - - w.write(d1) - w.send(d2) - w.close() - with open(support.TESTFN, 'rb') as file: - self.assertEqual(file.read(), self.d + d1 + d2) - - @unittest.skipUnless(hasattr(asyncore, 'file_dispatcher'), - 'asyncore.file_dispatcher required') - def test_dispatcher(self): - fd = os.open(support.TESTFN, os.O_RDONLY) - data = [] - class FileDispatcher(asyncore.file_dispatcher): - def handle_read(self): - data.append(self.recv(29)) - s = FileDispatcher(fd) - os.close(fd) - asyncore.loop(timeout=0.01, use_poll=True, count=2) - self.assertEqual(b"".join(data), self.d) - - def test_resource_warning(self): - # Issue #11453 - fd = os.open(support.TESTFN, os.O_RDONLY) - f = asyncore.file_wrapper(fd) - - os.close(fd) - with support.check_warnings(('', ResourceWarning)): - f = None - support.gc_collect() - - def test_close_twice(self): - fd = os.open(support.TESTFN, os.O_RDONLY) - f = asyncore.file_wrapper(fd) - os.close(fd) - - os.close(f.fd) # file_wrapper dupped fd - with self.assertRaises(OSError): - f.close() - - self.assertEqual(f.fd, -1) - # calling close twice should not fail - f.close() - - - class BaseTestHandler(asyncore.dispatcher): - - def __init__(self, sock=None): - asyncore.dispatcher.__init__(self, sock) - self.flag = False - - def handle_accept(self): - raise Exception("handle_accept not supposed to be called") - - def handle_accepted(self): - raise Exception("handle_accepted not supposed to be called") - - def handle_connect(self): - raise Exception("handle_connect not supposed to be called") - - def handle_expt(self): - raise Exception("handle_expt not supposed to be called") - - def handle_close(self): - raise Exception("handle_close not supposed to be called") - - def handle_error(self): - raise - - - class BaseServer(asyncore.dispatcher): - """A server which listens on an address and dispatches the - connection to a handler. - """ - - def __init__(self, family, addr, handler=BaseTestHandler): - asyncore.dispatcher.__init__(self) - self.create_socket(family) - self.set_reuse_addr() - bind_af_aware(self.socket, addr) - self.listen(5) - self.handler = handler - - @property - def address(self): - return self.socket.getsockname() - - def handle_accepted(self, sock, addr): - self.handler(sock) - - def handle_error(self): - raise - - - class BaseClient(BaseTestHandler): - - def __init__(self, family, address): - BaseTestHandler.__init__(self) - self.create_socket(family) - self.connect(address) - - def handle_connect(self): - pass - - - class BaseTestAPI: - - def tearDown(self): - asyncore.close_all(ignore_all=True) - - def loop_waiting_for_flag(self, instance, timeout=5): - timeout = float(timeout) / 100 - count = 100 - while asyncore.socket_map and count > 0: - asyncore.loop(timeout=0.01, count=1, use_poll=self.use_poll) - if instance.flag: - return - count -= 1 - time.sleep(timeout) - self.fail("flag not set") - - def test_handle_connect(self): - # make sure handle_connect is called on connect() - - class TestClient(BaseClient): - def handle_connect(self): - self.flag = True - - server = BaseServer(self.family, self.addr) - client = TestClient(self.family, server.address) - self.loop_waiting_for_flag(client) - - def test_handle_accept(self): - # make sure handle_accept() is called when a client connects - - class TestListener(BaseTestHandler): - - def __init__(self, family, addr): - BaseTestHandler.__init__(self) - self.create_socket(family) - bind_af_aware(self.socket, addr) - self.listen(5) - self.address = self.socket.getsockname() - - def handle_accept(self): - self.flag = True - - server = TestListener(self.family, self.addr) - client = BaseClient(self.family, server.address) - self.loop_waiting_for_flag(server) - - def test_handle_accepted(self): - # make sure handle_accepted() is called when a client connects - - class TestListener(BaseTestHandler): - - def __init__(self, family, addr): - BaseTestHandler.__init__(self) - self.create_socket(family) - bind_af_aware(self.socket, addr) - self.listen(5) - self.address = self.socket.getsockname() - - def handle_accept(self): - asyncore.dispatcher.handle_accept(self) - - def handle_accepted(self, sock, addr): - sock.close() - self.flag = True - - server = TestListener(self.family, self.addr) - client = BaseClient(self.family, server.address) - self.loop_waiting_for_flag(server) - - - def test_handle_read(self): - # make sure handle_read is called on data received - - class TestClient(BaseClient): - def handle_read(self): - self.flag = True - - class TestHandler(BaseTestHandler): - def __init__(self, conn): - BaseTestHandler.__init__(self, conn) - self.send(b'x' * 1024) - - server = BaseServer(self.family, self.addr, TestHandler) - client = TestClient(self.family, server.address) - self.loop_waiting_for_flag(client) - - def test_handle_write(self): - # make sure handle_write is called - - class TestClient(BaseClient): - def handle_write(self): - self.flag = True - - server = BaseServer(self.family, self.addr) - client = TestClient(self.family, server.address) - self.loop_waiting_for_flag(client) - - def test_handle_close(self): - # make sure handle_close is called when the other end closes - # the connection - - class TestClient(BaseClient): - - def handle_read(self): - # in order to make handle_close be called we are supposed - # to make at least one recv() call - self.recv(1024) - - def handle_close(self): - self.flag = True - self.close() - - class TestHandler(BaseTestHandler): - def __init__(self, conn): - BaseTestHandler.__init__(self, conn) - self.close() - - server = BaseServer(self.family, self.addr, TestHandler) - client = TestClient(self.family, server.address) - self.loop_waiting_for_flag(client) - - def test_handle_close_after_conn_broken(self): - # Check that ECONNRESET/EPIPE is correctly handled (issues #5661 and - # #11265). - - data = b'\0' * 128 - - class TestClient(BaseClient): - - def handle_write(self): - self.send(data) - - def handle_close(self): - self.flag = True - self.close() - - def handle_expt(self): - self.flag = True - self.close() - - class TestHandler(BaseTestHandler): - - def handle_read(self): - self.recv(len(data)) - self.close() - - def writable(self): - return False - - server = BaseServer(self.family, self.addr, TestHandler) - client = TestClient(self.family, server.address) - self.loop_waiting_for_flag(client) - - @unittest.skipIf(sys.platform.startswith("sunos"), - "OOB support is broken on Solaris") - def test_handle_expt(self): - # Make sure handle_expt is called on OOB data received. - # Note: this might fail on some platforms as OOB data is - # tenuously supported and rarely used. - if HAS_UNIX_SOCKETS and self.family == socket.AF_UNIX: - self.skipTest("Not applicable to AF_UNIX sockets.") - - if sys.platform == "darwin" and self.use_poll: - self.skipTest("poll may fail on macOS; see issue #28087") - - class TestClient(BaseClient): - def handle_expt(self): - self.socket.recv(1024, socket.MSG_OOB) - self.flag = True - - class TestHandler(BaseTestHandler): - def __init__(self, conn): - BaseTestHandler.__init__(self, conn) - self.socket.send(bytes(chr(244), 'latin-1'), socket.MSG_OOB) - - server = BaseServer(self.family, self.addr, TestHandler) - client = TestClient(self.family, server.address) - self.loop_waiting_for_flag(client) - - def test_handle_error(self): - - class TestClient(BaseClient): - def handle_write(self): - 1.0 / 0 - def handle_error(self): - self.flag = True - try: - raise - except ZeroDivisionError: - pass - else: - raise Exception("exception not raised") - - server = BaseServer(self.family, self.addr) - client = TestClient(self.family, server.address) - self.loop_waiting_for_flag(client) - - def test_connection_attributes(self): - server = BaseServer(self.family, self.addr) - client = BaseClient(self.family, server.address) - - # we start disconnected - self.assertFalse(server.connected) - self.assertTrue(server.accepting) - # this can't be taken for granted across all platforms - #self.assertFalse(client.connected) - self.assertFalse(client.accepting) - - # execute some loops so that client connects to server - asyncore.loop(timeout=0.01, use_poll=self.use_poll, count=100) - self.assertFalse(server.connected) - self.assertTrue(server.accepting) - self.assertTrue(client.connected) - self.assertFalse(client.accepting) - - # disconnect the client - client.close() - self.assertFalse(server.connected) - self.assertTrue(server.accepting) - self.assertFalse(client.connected) - self.assertFalse(client.accepting) - - # stop serving - server.close() - self.assertFalse(server.connected) - self.assertFalse(server.accepting) - - def test_create_socket(self): - s = asyncore.dispatcher() - s.create_socket(self.family) - self.assertEqual(s.socket.type, socket.SOCK_STREAM) - self.assertEqual(s.socket.family, self.family) - self.assertEqual(s.socket.gettimeout(), 0) - self.assertFalse(s.socket.get_inheritable()) - - def test_bind(self): - if HAS_UNIX_SOCKETS and self.family == socket.AF_UNIX: - self.skipTest("Not applicable to AF_UNIX sockets.") - s1 = asyncore.dispatcher() - s1.create_socket(self.family) - s1.bind(self.addr) - s1.listen(5) - port = s1.socket.getsockname()[1] - - s2 = asyncore.dispatcher() - s2.create_socket(self.family) - # EADDRINUSE indicates the socket was correctly bound - self.assertRaises(OSError, s2.bind, (self.addr[0], port)) - - def test_set_reuse_addr(self): - if HAS_UNIX_SOCKETS and self.family == socket.AF_UNIX: - self.skipTest("Not applicable to AF_UNIX sockets.") - - with socket.socket(self.family) as sock: - try: - sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) - except OSError: - unittest.skip("SO_REUSEADDR not supported on this platform") - else: - # if SO_REUSEADDR succeeded for sock we expect asyncore - # to do the same - s = asyncore.dispatcher(socket.socket(self.family)) - self.assertFalse(s.socket.getsockopt(socket.SOL_SOCKET, - socket.SO_REUSEADDR)) - s.socket.close() - s.create_socket(self.family) - s.set_reuse_addr() - self.assertTrue(s.socket.getsockopt(socket.SOL_SOCKET, - socket.SO_REUSEADDR)) - - @support.reap_threads - def test_quick_connect(self): - # see: http://bugs.python.org/issue10340 - if self.family not in (socket.AF_INET, getattr(socket, "AF_INET6", object())): - self.skipTest("test specific to AF_INET and AF_INET6") - - server = BaseServer(self.family, self.addr) - # run the thread 500 ms: the socket should be connected in 200 ms - t = threading.Thread(target=lambda: asyncore.loop(timeout=0.1, - count=5)) - t.start() - try: - with socket.socket(self.family, socket.SOCK_STREAM) as s: - s.settimeout(.2) - s.setsockopt(socket.SOL_SOCKET, socket.SO_LINGER, - struct.pack('ii', 1, 0)) - - try: - s.connect(server.address) - except OSError: - pass - finally: - support.join_thread(t, timeout=TIMEOUT) - - class TestAPI_UseIPv4Sockets(BaseTestAPI): - family = socket.AF_INET - addr = (support.HOST, 0) - - @unittest.skipUnless(support.IPV6_ENABLED, 'IPv6 support required') - class TestAPI_UseIPv6Sockets(BaseTestAPI): - family = socket.AF_INET6 - addr = (support.HOSTv6, 0) - - @unittest.skipUnless(HAS_UNIX_SOCKETS, 'Unix sockets required') - class TestAPI_UseUnixSockets(BaseTestAPI): - if HAS_UNIX_SOCKETS: - family = socket.AF_UNIX - addr = support.TESTFN - - def tearDown(self): - support.unlink(self.addr) - BaseTestAPI.tearDown(self) - - class TestAPI_UseIPv4Select(TestAPI_UseIPv4Sockets, unittest.TestCase): - use_poll = False - - @unittest.skipUnless(hasattr(select, 'poll'), 'select.poll required') - class TestAPI_UseIPv4Poll(TestAPI_UseIPv4Sockets, unittest.TestCase): - use_poll = True - - class TestAPI_UseIPv6Select(TestAPI_UseIPv6Sockets, unittest.TestCase): - use_poll = False - - @unittest.skipUnless(hasattr(select, 'poll'), 'select.poll required') - class TestAPI_UseIPv6Poll(TestAPI_UseIPv6Sockets, unittest.TestCase): - use_poll = True - - class TestAPI_UseUnixSocketsSelect(TestAPI_UseUnixSockets, unittest.TestCase): - use_poll = False - - @unittest.skipUnless(hasattr(select, 'poll'), 'select.poll required') - class TestAPI_UseUnixSocketsPoll(TestAPI_UseUnixSockets, unittest.TestCase): - use_poll = True - - if __name__ == "__main__": - unittest.main() diff --git a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_atexit.yaml b/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_atexit.yaml deleted file mode 100644 index d17aa0f06..000000000 --- a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_atexit.yaml +++ /dev/null @@ -1,209 +0,0 @@ -python: | - import sys - import unittest - import io - import atexit - import os - from test import support - from test.support import script_helper - - ### helpers - def h1(): - print("h1") - - def h2(): - print("h2") - - def h3(): - print("h3") - - def h4(*args, **kwargs): - print("h4", args, kwargs) - - def raise1(): - raise TypeError - - def raise2(): - raise SystemError - - def exit(): - raise SystemExit - - - class GeneralTest(unittest.TestCase): - - def setUp(self): - self.save_stdout = sys.stdout - self.save_stderr = sys.stderr - self.stream = io.StringIO() - sys.stdout = sys.stderr = self.stream - atexit._clear() - - def tearDown(self): - sys.stdout = self.save_stdout - sys.stderr = self.save_stderr - atexit._clear() - - def test_args(self): - # be sure args are handled properly - atexit.register(h1) - atexit.register(h4) - atexit.register(h4, 4, kw="abc") - atexit._run_exitfuncs() - - self.assertEqual(self.stream.getvalue(), - "h4 (4,) {'kw': 'abc'}\nh4 () {}\nh1\n") - - def test_badargs(self): - atexit.register(lambda: 1, 0, 0, (x for x in (1,2)), 0, 0) - self.assertRaises(TypeError, atexit._run_exitfuncs) - - def test_order(self): - # be sure handlers are executed in reverse order - atexit.register(h1) - atexit.register(h2) - atexit.register(h3) - atexit._run_exitfuncs() - - self.assertEqual(self.stream.getvalue(), "h3\nh2\nh1\n") - - def test_raise(self): - # be sure raises are handled properly - atexit.register(raise1) - atexit.register(raise2) - - self.assertRaises(TypeError, atexit._run_exitfuncs) - - def test_raise_unnormalized(self): - # Issue #10756: Make sure that an unnormalized exception is - # handled properly - atexit.register(lambda: 1 / 0) - - self.assertRaises(ZeroDivisionError, atexit._run_exitfuncs) - self.assertIn("ZeroDivisionError", self.stream.getvalue()) - - def test_exit(self): - # be sure a SystemExit is handled properly - atexit.register(exit) - - self.assertRaises(SystemExit, atexit._run_exitfuncs) - self.assertEqual(self.stream.getvalue(), '') - - def test_stress(self): - a = [0] - def inc(): - a[0] += 1 - - for i in range(128): - atexit.register(inc) - atexit._run_exitfuncs() - - self.assertEqual(a[0], 128) - - def test_clear(self): - a = [0] - def inc(): - a[0] += 1 - - atexit.register(inc) - atexit._clear() - atexit._run_exitfuncs() - - self.assertEqual(a[0], 0) - - def test_unregister(self): - a = [0] - def inc(): - a[0] += 1 - def dec(): - a[0] -= 1 - - for i in range(4): - atexit.register(inc) - atexit.register(dec) - atexit.unregister(inc) - atexit._run_exitfuncs() - - self.assertEqual(a[0], -1) - - def test_bound_methods(self): - l = [] - atexit.register(l.append, 5) - atexit._run_exitfuncs() - self.assertEqual(l, [5]) - - atexit.unregister(l.append) - atexit._run_exitfuncs() - self.assertEqual(l, [5]) - - def test_shutdown(self): - # Actually test the shutdown mechanism in a subprocess - code = """if 1: - import atexit - - def f(msg): - print(msg) - - atexit.register(f, "one") - atexit.register(f, "two") - """ - res = script_helper.assert_python_ok("-c", code) - self.assertEqual(res.out.decode().splitlines(), ["two", "one"]) - self.assertFalse(res.err) - - - @support.cpython_only - class SubinterpreterTest(unittest.TestCase): - - def test_callbacks_leak(self): - # This test shows a leak in refleak mode if atexit doesn't - # take care to free callbacks in its per-subinterpreter module - # state. - n = atexit._ncallbacks() - code = r"""if 1: - import atexit - def f(): - pass - atexit.register(f) - del atexit - """ - ret = support.run_in_subinterp(code) - self.assertEqual(ret, 0) - self.assertEqual(atexit._ncallbacks(), n) - - def test_callbacks_leak_refcycle(self): - # Similar to the above, but with a refcycle through the atexit - # module. - n = atexit._ncallbacks() - code = r"""if 1: - import atexit - def f(): - pass - atexit.register(f) - atexit.__atexit = atexit - """ - ret = support.run_in_subinterp(code) - self.assertEqual(ret, 0) - self.assertEqual(atexit._ncallbacks(), n) - - def test_callback_on_subinterpreter_teardown(self): - # This tests if a callback is called on - # subinterpreter teardown. - expected = b"The test has passed!" - r, w = os.pipe() - - code = r"""if 1: - import os - import atexit - def callback(): - os.write({:d}, b"The test has passed!") - atexit.register(callback) - """.format(w) - ret = support.run_in_subinterp(code) - os.close(w) - self.assertEqual(os.read(r, len(expected)), expected) - os.close(r) - - - if __name__ == "__main__": - unittest.main() diff --git a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_audioop.yaml b/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_audioop.yaml deleted file mode 100644 index 7835becea..000000000 --- a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_audioop.yaml +++ /dev/null @@ -1,566 +0,0 @@ -python: | - import audioop - import sys - import unittest - - def pack(width, data): - return b''.join(v.to_bytes(width, sys.byteorder, signed=True) for v in data) - - def unpack(width, data): - return [int.from_bytes(data[i: i + width], sys.byteorder, signed=True) - for i in range(0, len(data), width)] - - packs = {w: (lambda *data, width=w: pack(width, data)) for w in (1, 2, 3, 4)} - maxvalues = {w: (1 << (8 * w - 1)) - 1 for w in (1, 2, 3, 4)} - minvalues = {w: -1 << (8 * w - 1) for w in (1, 2, 3, 4)} - - datas = { - 1: b'\x00\x12\x45\xbb\x7f\x80\xff', - 2: packs[2](0, 0x1234, 0x4567, -0x4567, 0x7fff, -0x8000, -1), - 3: packs[3](0, 0x123456, 0x456789, -0x456789, 0x7fffff, -0x800000, -1), - 4: packs[4](0, 0x12345678, 0x456789ab, -0x456789ab, - 0x7fffffff, -0x80000000, -1), - } - - INVALID_DATA = [ - (b'abc', 0), - (b'abc', 2), - (b'ab', 3), - (b'abc', 4), - ] - - - class TestAudioop(unittest.TestCase): - - def test_max(self): - for w in 1, 2, 3, 4: - self.assertEqual(audioop.max(b'', w), 0) - self.assertEqual(audioop.max(bytearray(), w), 0) - self.assertEqual(audioop.max(memoryview(b''), w), 0) - p = packs[w] - self.assertEqual(audioop.max(p(5), w), 5) - self.assertEqual(audioop.max(p(5, -8, -1), w), 8) - self.assertEqual(audioop.max(p(maxvalues[w]), w), maxvalues[w]) - self.assertEqual(audioop.max(p(minvalues[w]), w), -minvalues[w]) - self.assertEqual(audioop.max(datas[w], w), -minvalues[w]) - - def test_minmax(self): - for w in 1, 2, 3, 4: - self.assertEqual(audioop.minmax(b'', w), - (0x7fffffff, -0x80000000)) - self.assertEqual(audioop.minmax(bytearray(), w), - (0x7fffffff, -0x80000000)) - self.assertEqual(audioop.minmax(memoryview(b''), w), - (0x7fffffff, -0x80000000)) - p = packs[w] - self.assertEqual(audioop.minmax(p(5), w), (5, 5)) - self.assertEqual(audioop.minmax(p(5, -8, -1), w), (-8, 5)) - self.assertEqual(audioop.minmax(p(maxvalues[w]), w), - (maxvalues[w], maxvalues[w])) - self.assertEqual(audioop.minmax(p(minvalues[w]), w), - (minvalues[w], minvalues[w])) - self.assertEqual(audioop.minmax(datas[w], w), - (minvalues[w], maxvalues[w])) - - def test_maxpp(self): - for w in 1, 2, 3, 4: - self.assertEqual(audioop.maxpp(b'', w), 0) - self.assertEqual(audioop.maxpp(bytearray(), w), 0) - self.assertEqual(audioop.maxpp(memoryview(b''), w), 0) - self.assertEqual(audioop.maxpp(packs[w](*range(100)), w), 0) - self.assertEqual(audioop.maxpp(packs[w](9, 10, 5, 5, 0, 1), w), 10) - self.assertEqual(audioop.maxpp(datas[w], w), - maxvalues[w] - minvalues[w]) - - def test_avg(self): - for w in 1, 2, 3, 4: - self.assertEqual(audioop.avg(b'', w), 0) - self.assertEqual(audioop.avg(bytearray(), w), 0) - self.assertEqual(audioop.avg(memoryview(b''), w), 0) - p = packs[w] - self.assertEqual(audioop.avg(p(5), w), 5) - self .assertEqual(audioop.avg(p(5, 8), w), 6) - self.assertEqual(audioop.avg(p(5, -8), w), -2) - self.assertEqual(audioop.avg(p(maxvalues[w], maxvalues[w]), w), - maxvalues[w]) - self.assertEqual(audioop.avg(p(minvalues[w], minvalues[w]), w), - minvalues[w]) - self.assertEqual(audioop.avg(packs[4](0x50000000, 0x70000000), 4), - 0x60000000) - self.assertEqual(audioop.avg(packs[4](-0x50000000, -0x70000000), 4), - -0x60000000) - - def test_avgpp(self): - for w in 1, 2, 3, 4: - self.assertEqual(audioop.avgpp(b'', w), 0) - self.assertEqual(audioop.avgpp(bytearray(), w), 0) - self.assertEqual(audioop.avgpp(memoryview(b''), w), 0) - self.assertEqual(audioop.avgpp(packs[w](*range(100)), w), 0) - self.assertEqual(audioop.avgpp(packs[w](9, 10, 5, 5, 0, 1), w), 10) - self.assertEqual(audioop.avgpp(datas[1], 1), 196) - self.assertEqual(audioop.avgpp(datas[2], 2), 50534) - self.assertEqual(audioop.avgpp(datas[3], 3), 12937096) - self.assertEqual(audioop.avgpp(datas[4], 4), 3311897002) - - def test_rms(self): - for w in 1, 2, 3, 4: - self.assertEqual(audioop.rms(b'', w), 0) - self.assertEqual(audioop.rms(bytearray(), w), 0) - self.assertEqual(audioop.rms(memoryview(b''), w), 0) - p = packs[w] - self.assertEqual(audioop.rms(p(*range(100)), w), 57) - self.assertAlmostEqual(audioop.rms(p(maxvalues[w]) * 5, w), - maxvalues[w], delta=1) - self.assertAlmostEqual(audioop.rms(p(minvalues[w]) * 5, w), - -minvalues[w], delta=1) - self.assertEqual(audioop.rms(datas[1], 1), 77) - self.assertEqual(audioop.rms(datas[2], 2), 20001) - self.assertEqual(audioop.rms(datas[3], 3), 5120523) - self.assertEqual(audioop.rms(datas[4], 4), 1310854152) - - def test_cross(self): - for w in 1, 2, 3, 4: - self.assertEqual(audioop.cross(b'', w), -1) - self.assertEqual(audioop.cross(bytearray(), w), -1) - self.assertEqual(audioop.cross(memoryview(b''), w), -1) - p = packs[w] - self.assertEqual(audioop.cross(p(0, 1, 2), w), 0) - self.assertEqual(audioop.cross(p(1, 2, -3, -4), w), 1) - self.assertEqual(audioop.cross(p(-1, -2, 3, 4), w), 1) - self.assertEqual(audioop.cross(p(0, minvalues[w]), w), 1) - self.assertEqual(audioop.cross(p(minvalues[w], maxvalues[w]), w), 1) - - def test_add(self): - for w in 1, 2, 3, 4: - self.assertEqual(audioop.add(b'', b'', w), b'') - self.assertEqual(audioop.add(bytearray(), bytearray(), w), b'') - self.assertEqual(audioop.add(memoryview(b''), memoryview(b''), w), b'') - self.assertEqual(audioop.add(datas[w], b'\0' * len(datas[w]), w), - datas[w]) - self.assertEqual(audioop.add(datas[1], datas[1], 1), - b'\x00\x24\x7f\x80\x7f\x80\xfe') - self.assertEqual(audioop.add(datas[2], datas[2], 2), - packs[2](0, 0x2468, 0x7fff, -0x8000, 0x7fff, -0x8000, -2)) - self.assertEqual(audioop.add(datas[3], datas[3], 3), - packs[3](0, 0x2468ac, 0x7fffff, -0x800000, - 0x7fffff, -0x800000, -2)) - self.assertEqual(audioop.add(datas[4], datas[4], 4), - packs[4](0, 0x2468acf0, 0x7fffffff, -0x80000000, - 0x7fffffff, -0x80000000, -2)) - - def test_bias(self): - for w in 1, 2, 3, 4: - for bias in 0, 1, -1, 127, -128, 0x7fffffff, -0x80000000: - self.assertEqual(audioop.bias(b'', w, bias), b'') - self.assertEqual(audioop.bias(bytearray(), w, bias), b'') - self.assertEqual(audioop.bias(memoryview(b''), w, bias), b'') - self.assertEqual(audioop.bias(datas[1], 1, 1), - b'\x01\x13\x46\xbc\x80\x81\x00') - self.assertEqual(audioop.bias(datas[1], 1, -1), - b'\xff\x11\x44\xba\x7e\x7f\xfe') - self.assertEqual(audioop.bias(datas[1], 1, 0x7fffffff), - b'\xff\x11\x44\xba\x7e\x7f\xfe') - self.assertEqual(audioop.bias(datas[1], 1, -0x80000000), - datas[1]) - self.assertEqual(audioop.bias(datas[2], 2, 1), - packs[2](1, 0x1235, 0x4568, -0x4566, -0x8000, -0x7fff, 0)) - self.assertEqual(audioop.bias(datas[2], 2, -1), - packs[2](-1, 0x1233, 0x4566, -0x4568, 0x7ffe, 0x7fff, -2)) - self.assertEqual(audioop.bias(datas[2], 2, 0x7fffffff), - packs[2](-1, 0x1233, 0x4566, -0x4568, 0x7ffe, 0x7fff, -2)) - self.assertEqual(audioop.bias(datas[2], 2, -0x80000000), - datas[2]) - self.assertEqual(audioop.bias(datas[3], 3, 1), - packs[3](1, 0x123457, 0x45678a, -0x456788, - -0x800000, -0x7fffff, 0)) - self.assertEqual(audioop.bias(datas[3], 3, -1), - packs[3](-1, 0x123455, 0x456788, -0x45678a, - 0x7ffffe, 0x7fffff, -2)) - self.assertEqual(audioop.bias(datas[3], 3, 0x7fffffff), - packs[3](-1, 0x123455, 0x456788, -0x45678a, - 0x7ffffe, 0x7fffff, -2)) - self.assertEqual(audioop.bias(datas[3], 3, -0x80000000), - datas[3]) - self.assertEqual(audioop.bias(datas[4], 4, 1), - packs[4](1, 0x12345679, 0x456789ac, -0x456789aa, - -0x80000000, -0x7fffffff, 0)) - self.assertEqual(audioop.bias(datas[4], 4, -1), - packs[4](-1, 0x12345677, 0x456789aa, -0x456789ac, - 0x7ffffffe, 0x7fffffff, -2)) - self.assertEqual(audioop.bias(datas[4], 4, 0x7fffffff), - packs[4](0x7fffffff, -0x6dcba989, -0x3a987656, 0x3a987654, - -2, -1, 0x7ffffffe)) - self.assertEqual(audioop.bias(datas[4], 4, -0x80000000), - packs[4](-0x80000000, -0x6dcba988, -0x3a987655, 0x3a987655, - -1, 0, 0x7fffffff)) - - def test_lin2lin(self): - for w in 1, 2, 3, 4: - self.assertEqual(audioop.lin2lin(datas[w], w, w), datas[w]) - self.assertEqual(audioop.lin2lin(bytearray(datas[w]), w, w), - datas[w]) - self.assertEqual(audioop.lin2lin(memoryview(datas[w]), w, w), - datas[w]) - - self.assertEqual(audioop.lin2lin(datas[1], 1, 2), - packs[2](0, 0x1200, 0x4500, -0x4500, 0x7f00, -0x8000, -0x100)) - self.assertEqual(audioop.lin2lin(datas[1], 1, 3), - packs[3](0, 0x120000, 0x450000, -0x450000, - 0x7f0000, -0x800000, -0x10000)) - self.assertEqual(audioop.lin2lin(datas[1], 1, 4), - packs[4](0, 0x12000000, 0x45000000, -0x45000000, - 0x7f000000, -0x80000000, -0x1000000)) - self.assertEqual(audioop.lin2lin(datas[2], 2, 1), - b'\x00\x12\x45\xba\x7f\x80\xff') - self.assertEqual(audioop.lin2lin(datas[2], 2, 3), - packs[3](0, 0x123400, 0x456700, -0x456700, - 0x7fff00, -0x800000, -0x100)) - self.assertEqual(audioop.lin2lin(datas[2], 2, 4), - packs[4](0, 0x12340000, 0x45670000, -0x45670000, - 0x7fff0000, -0x80000000, -0x10000)) - self.assertEqual(audioop.lin2lin(datas[3], 3, 1), - b'\x00\x12\x45\xba\x7f\x80\xff') - self.assertEqual(audioop.lin2lin(datas[3], 3, 2), - packs[2](0, 0x1234, 0x4567, -0x4568, 0x7fff, -0x8000, -1)) - self.assertEqual(audioop.lin2lin(datas[3], 3, 4), - packs[4](0, 0x12345600, 0x45678900, -0x45678900, - 0x7fffff00, -0x80000000, -0x100)) - self.assertEqual(audioop.lin2lin(datas[4], 4, 1), - b'\x00\x12\x45\xba\x7f\x80\xff') - self.assertEqual(audioop.lin2lin(datas[4], 4, 2), - packs[2](0, 0x1234, 0x4567, -0x4568, 0x7fff, -0x8000, -1)) - self.assertEqual(audioop.lin2lin(datas[4], 4, 3), - packs[3](0, 0x123456, 0x456789, -0x45678a, - 0x7fffff, -0x800000, -1)) - - def test_adpcm2lin(self): - self.assertEqual(audioop.adpcm2lin(b'\x07\x7f\x7f', 1, None), - (b'\x00\x00\x00\xff\x00\xff', (-179, 40))) - self.assertEqual(audioop.adpcm2lin(bytearray(b'\x07\x7f\x7f'), 1, None), - (b'\x00\x00\x00\xff\x00\xff', (-179, 40))) - self.assertEqual(audioop.adpcm2lin(memoryview(b'\x07\x7f\x7f'), 1, None), - (b'\x00\x00\x00\xff\x00\xff', (-179, 40))) - self.assertEqual(audioop.adpcm2lin(b'\x07\x7f\x7f', 2, None), - (packs[2](0, 0xb, 0x29, -0x16, 0x72, -0xb3), (-179, 40))) - self.assertEqual(audioop.adpcm2lin(b'\x07\x7f\x7f', 3, None), - (packs[3](0, 0xb00, 0x2900, -0x1600, 0x7200, - -0xb300), (-179, 40))) - self.assertEqual(audioop.adpcm2lin(b'\x07\x7f\x7f', 4, None), - (packs[4](0, 0xb0000, 0x290000, -0x160000, 0x720000, - -0xb30000), (-179, 40))) - - # Very cursory test - for w in 1, 2, 3, 4: - self.assertEqual(audioop.adpcm2lin(b'\0' * 5, w, None), - (b'\0' * w * 10, (0, 0))) - - def test_lin2adpcm(self): - self.assertEqual(audioop.lin2adpcm(datas[1], 1, None), - (b'\x07\x7f\x7f', (-221, 39))) - self.assertEqual(audioop.lin2adpcm(bytearray(datas[1]), 1, None), - (b'\x07\x7f\x7f', (-221, 39))) - self.assertEqual(audioop.lin2adpcm(memoryview(datas[1]), 1, None), - (b'\x07\x7f\x7f', (-221, 39))) - for w in 2, 3, 4: - self.assertEqual(audioop.lin2adpcm(datas[w], w, None), - (b'\x07\x7f\x7f', (31, 39))) - - # Very cursory test - for w in 1, 2, 3, 4: - self.assertEqual(audioop.lin2adpcm(b'\0' * w * 10, w, None), - (b'\0' * 5, (0, 0))) - - def test_invalid_adpcm_state(self): - # state must be a tuple or None, not an integer - self.assertRaises(TypeError, audioop.adpcm2lin, b'\0', 1, 555) - self.assertRaises(TypeError, audioop.lin2adpcm, b'\0', 1, 555) - # Issues #24456, #24457: index out of range - self.assertRaises(ValueError, audioop.adpcm2lin, b'\0', 1, (0, -1)) - self.assertRaises(ValueError, audioop.adpcm2lin, b'\0', 1, (0, 89)) - self.assertRaises(ValueError, audioop.lin2adpcm, b'\0', 1, (0, -1)) - self.assertRaises(ValueError, audioop.lin2adpcm, b'\0', 1, (0, 89)) - # value out of range - self.assertRaises(ValueError, audioop.adpcm2lin, b'\0', 1, (-0x8001, 0)) - self.assertRaises(ValueError, audioop.adpcm2lin, b'\0', 1, (0x8000, 0)) - self.assertRaises(ValueError, audioop.lin2adpcm, b'\0', 1, (-0x8001, 0)) - self.assertRaises(ValueError, audioop.lin2adpcm, b'\0', 1, (0x8000, 0)) - - def test_lin2alaw(self): - self.assertEqual(audioop.lin2alaw(datas[1], 1), - b'\xd5\x87\xa4\x24\xaa\x2a\x5a') - self.assertEqual(audioop.lin2alaw(bytearray(datas[1]), 1), - b'\xd5\x87\xa4\x24\xaa\x2a\x5a') - self.assertEqual(audioop.lin2alaw(memoryview(datas[1]), 1), - b'\xd5\x87\xa4\x24\xaa\x2a\x5a') - for w in 2, 3, 4: - self.assertEqual(audioop.lin2alaw(datas[w], w), - b'\xd5\x87\xa4\x24\xaa\x2a\x55') - - def test_alaw2lin(self): - encoded = b'\x00\x03\x24\x2a\x51\x54\x55\x58\x6b\x71\x7f'\ - b'\x80\x83\xa4\xaa\xd1\xd4\xd5\xd8\xeb\xf1\xff' - src = [-688, -720, -2240, -4032, -9, -3, -1, -27, -244, -82, -106, - 688, 720, 2240, 4032, 9, 3, 1, 27, 244, 82, 106] - for w in 1, 2, 3, 4: - decoded = packs[w](*(x << (w * 8) >> 13 for x in src)) - self.assertEqual(audioop.alaw2lin(encoded, w), decoded) - self.assertEqual(audioop.alaw2lin(bytearray(encoded), w), decoded) - self.assertEqual(audioop.alaw2lin(memoryview(encoded), w), decoded) - - encoded = bytes(range(256)) - for w in 2, 3, 4: - decoded = audioop.alaw2lin(encoded, w) - self.assertEqual(audioop.lin2alaw(decoded, w), encoded) - - def test_lin2ulaw(self): - self.assertEqual(audioop.lin2ulaw(datas[1], 1), - b'\xff\xad\x8e\x0e\x80\x00\x67') - self.assertEqual(audioop.lin2ulaw(bytearray(datas[1]), 1), - b'\xff\xad\x8e\x0e\x80\x00\x67') - self.assertEqual(audioop.lin2ulaw(memoryview(datas[1]), 1), - b'\xff\xad\x8e\x0e\x80\x00\x67') - for w in 2, 3, 4: - self.assertEqual(audioop.lin2ulaw(datas[w], w), - b'\xff\xad\x8e\x0e\x80\x00\x7e') - - def test_ulaw2lin(self): - encoded = b'\x00\x0e\x28\x3f\x57\x6a\x76\x7c\x7e\x7f'\ - b'\x80\x8e\xa8\xbf\xd7\xea\xf6\xfc\xfe\xff' - src = [-8031, -4447, -1471, -495, -163, -53, -18, -6, -2, 0, - 8031, 4447, 1471, 495, 163, 53, 18, 6, 2, 0] - for w in 1, 2, 3, 4: - decoded = packs[w](*(x << (w * 8) >> 14 for x in src)) - self.assertEqual(audioop.ulaw2lin(encoded, w), decoded) - self.assertEqual(audioop.ulaw2lin(bytearray(encoded), w), decoded) - self.assertEqual(audioop.ulaw2lin(memoryview(encoded), w), decoded) - - # Current u-law implementation has two codes fo 0: 0x7f and 0xff. - encoded = bytes(range(127)) + bytes(range(128, 256)) - for w in 2, 3, 4: - decoded = audioop.ulaw2lin(encoded, w) - self.assertEqual(audioop.lin2ulaw(decoded, w), encoded) - - def test_mul(self): - for w in 1, 2, 3, 4: - self.assertEqual(audioop.mul(b'', w, 2), b'') - self.assertEqual(audioop.mul(bytearray(), w, 2), b'') - self.assertEqual(audioop.mul(memoryview(b''), w, 2), b'') - self.assertEqual(audioop.mul(datas[w], w, 0), - b'\0' * len(datas[w])) - self.assertEqual(audioop.mul(datas[w], w, 1), - datas[w]) - self.assertEqual(audioop.mul(datas[1], 1, 2), - b'\x00\x24\x7f\x80\x7f\x80\xfe') - self.assertEqual(audioop.mul(datas[2], 2, 2), - packs[2](0, 0x2468, 0x7fff, -0x8000, 0x7fff, -0x8000, -2)) - self.assertEqual(audioop.mul(datas[3], 3, 2), - packs[3](0, 0x2468ac, 0x7fffff, -0x800000, - 0x7fffff, -0x800000, -2)) - self.assertEqual(audioop.mul(datas[4], 4, 2), - packs[4](0, 0x2468acf0, 0x7fffffff, -0x80000000, - 0x7fffffff, -0x80000000, -2)) - - def test_ratecv(self): - for w in 1, 2, 3, 4: - self.assertEqual(audioop.ratecv(b'', w, 1, 8000, 8000, None), - (b'', (-1, ((0, 0),)))) - self.assertEqual(audioop.ratecv(bytearray(), w, 1, 8000, 8000, None), - (b'', (-1, ((0, 0),)))) - self.assertEqual(audioop.ratecv(memoryview(b''), w, 1, 8000, 8000, None), - (b'', (-1, ((0, 0),)))) - self.assertEqual(audioop.ratecv(b'', w, 5, 8000, 8000, None), - (b'', (-1, ((0, 0),) * 5))) - self.assertEqual(audioop.ratecv(b'', w, 1, 8000, 16000, None), - (b'', (-2, ((0, 0),)))) - self.assertEqual(audioop.ratecv(datas[w], w, 1, 8000, 8000, None)[0], - datas[w]) - self.assertEqual(audioop.ratecv(datas[w], w, 1, 8000, 8000, None, 1, 0)[0], - datas[w]) - - state = None - d1, state = audioop.ratecv(b'\x00\x01\x02', 1, 1, 8000, 16000, state) - d2, state = audioop.ratecv(b'\x00\x01\x02', 1, 1, 8000, 16000, state) - self.assertEqual(d1 + d2, b'\000\000\001\001\002\001\000\000\001\001\002') - - for w in 1, 2, 3, 4: - d0, state0 = audioop.ratecv(datas[w], w, 1, 8000, 16000, None) - d, state = b'', None - for i in range(0, len(datas[w]), w): - d1, state = audioop.ratecv(datas[w][i:i + w], w, 1, - 8000, 16000, state) - d += d1 - self.assertEqual(d, d0) - self.assertEqual(state, state0) - - expected = { - 1: packs[1](0, 0x0d, 0x37, -0x26, 0x55, -0x4b, -0x14), - 2: packs[2](0, 0x0da7, 0x3777, -0x2630, 0x5673, -0x4a64, -0x129a), - 3: packs[3](0, 0x0da740, 0x377776, -0x262fca, - 0x56740c, -0x4a62fd, -0x1298c0), - 4: packs[4](0, 0x0da740da, 0x37777776, -0x262fc962, - 0x56740da6, -0x4a62fc96, -0x1298bf26), - } - for w in 1, 2, 3, 4: - self.assertEqual(audioop.ratecv(datas[w], w, 1, 8000, 8000, None, 3, 1)[0], - expected[w]) - self.assertEqual(audioop.ratecv(datas[w], w, 1, 8000, 8000, None, 30, 10)[0], - expected[w]) - - self.assertRaises(TypeError, audioop.ratecv, b'', 1, 1, 8000, 8000, 42) - self.assertRaises(TypeError, audioop.ratecv, - b'', 1, 1, 8000, 8000, (1, (42,))) - - def test_reverse(self): - for w in 1, 2, 3, 4: - self.assertEqual(audioop.reverse(b'', w), b'') - self.assertEqual(audioop.reverse(bytearray(), w), b'') - self.assertEqual(audioop.reverse(memoryview(b''), w), b'') - self.assertEqual(audioop.reverse(packs[w](0, 1, 2), w), - packs[w](2, 1, 0)) - - def test_tomono(self): - for w in 1, 2, 3, 4: - data1 = datas[w] - data2 = bytearray(2 * len(data1)) - for k in range(w): - data2[k::2*w] = data1[k::w] - self.assertEqual(audioop.tomono(data2, w, 1, 0), data1) - self.assertEqual(audioop.tomono(data2, w, 0, 1), b'\0' * len(data1)) - for k in range(w): - data2[k+w::2*w] = data1[k::w] - self.assertEqual(audioop.tomono(data2, w, 0.5, 0.5), data1) - self.assertEqual(audioop.tomono(bytearray(data2), w, 0.5, 0.5), - data1) - self.assertEqual(audioop.tomono(memoryview(data2), w, 0.5, 0.5), - data1) - - def test_tostereo(self): - for w in 1, 2, 3, 4: - data1 = datas[w] - data2 = bytearray(2 * len(data1)) - for k in range(w): - data2[k::2*w] = data1[k::w] - self.assertEqual(audioop.tostereo(data1, w, 1, 0), data2) - self.assertEqual(audioop.tostereo(data1, w, 0, 0), b'\0' * len(data2)) - for k in range(w): - data2[k+w::2*w] = data1[k::w] - self.assertEqual(audioop.tostereo(data1, w, 1, 1), data2) - self.assertEqual(audioop.tostereo(bytearray(data1), w, 1, 1), data2) - self.assertEqual(audioop.tostereo(memoryview(data1), w, 1, 1), - data2) - - def test_findfactor(self): - self.assertEqual(audioop.findfactor(datas[2], datas[2]), 1.0) - self.assertEqual(audioop.findfactor(bytearray(datas[2]), - bytearray(datas[2])), 1.0) - self.assertEqual(audioop.findfactor(memoryview(datas[2]), - memoryview(datas[2])), 1.0) - self.assertEqual(audioop.findfactor(b'\0' * len(datas[2]), datas[2]), - 0.0) - - def test_findfit(self): - self.assertEqual(audioop.findfit(datas[2], datas[2]), (0, 1.0)) - self.assertEqual(audioop.findfit(bytearray(datas[2]), - bytearray(datas[2])), (0, 1.0)) - self.assertEqual(audioop.findfit(memoryview(datas[2]), - memoryview(datas[2])), (0, 1.0)) - self.assertEqual(audioop.findfit(datas[2], packs[2](1, 2, 0)), - (1, 8038.8)) - self.assertEqual(audioop.findfit(datas[2][:-2] * 5 + datas[2], datas[2]), - (30, 1.0)) - - def test_findmax(self): - self.assertEqual(audioop.findmax(datas[2], 1), 5) - self.assertEqual(audioop.findmax(bytearray(datas[2]), 1), 5) - self.assertEqual(audioop.findmax(memoryview(datas[2]), 1), 5) - - def test_getsample(self): - for w in 1, 2, 3, 4: - data = packs[w](0, 1, -1, maxvalues[w], minvalues[w]) - self.assertEqual(audioop.getsample(data, w, 0), 0) - self.assertEqual(audioop.getsample(bytearray(data), w, 0), 0) - self.assertEqual(audioop.getsample(memoryview(data), w, 0), 0) - self.assertEqual(audioop.getsample(data, w, 1), 1) - self.assertEqual(audioop.getsample(data, w, 2), -1) - self.assertEqual(audioop.getsample(data, w, 3), maxvalues[w]) - self.assertEqual(audioop.getsample(data, w, 4), minvalues[w]) - - def test_byteswap(self): - swapped_datas = { - 1: datas[1], - 2: packs[2](0, 0x3412, 0x6745, -0x6646, -0x81, 0x80, -1), - 3: packs[3](0, 0x563412, -0x7698bb, 0x7798ba, -0x81, 0x80, -1), - 4: packs[4](0, 0x78563412, -0x547698bb, 0x557698ba, - -0x81, 0x80, -1), - } - for w in 1, 2, 3, 4: - self.assertEqual(audioop.byteswap(b'', w), b'') - self.assertEqual(audioop.byteswap(datas[w], w), swapped_datas[w]) - self.assertEqual(audioop.byteswap(swapped_datas[w], w), datas[w]) - self.assertEqual(audioop.byteswap(bytearray(datas[w]), w), - swapped_datas[w]) - self.assertEqual(audioop.byteswap(memoryview(datas[w]), w), - swapped_datas[w]) - - def test_negativelen(self): - # from issue 3306, previously it segfaulted - self.assertRaises(audioop.error, - audioop.findmax, bytes(range(256)), -2392392) - - def test_issue7673(self): - state = None - for data, size in INVALID_DATA: - size2 = size - self.assertRaises(audioop.error, audioop.getsample, data, size, 0) - self.assertRaises(audioop.error, audioop.max, data, size) - self.assertRaises(audioop.error, audioop.minmax, data, size) - self.assertRaises(audioop.error, audioop.avg, data, size) - self.assertRaises(audioop.error, audioop.rms, data, size) - self.assertRaises(audioop.error, audioop.avgpp, data, size) - self.assertRaises(audioop.error, audioop.maxpp, data, size) - self.assertRaises(audioop.error, audioop.cross, data, size) - self.assertRaises(audioop.error, audioop.mul, data, size, 1.0) - self.assertRaises(audioop.error, audioop.tomono, data, size, 0.5, 0.5) - self.assertRaises(audioop.error, audioop.tostereo, data, size, 0.5, 0.5) - self.assertRaises(audioop.error, audioop.add, data, data, size) - self.assertRaises(audioop.error, audioop.bias, data, size, 0) - self.assertRaises(audioop.error, audioop.reverse, data, size) - self.assertRaises(audioop.error, audioop.lin2lin, data, size, size2) - self.assertRaises(audioop.error, audioop.ratecv, data, size, 1, 1, 1, state) - self.assertRaises(audioop.error, audioop.lin2ulaw, data, size) - self.assertRaises(audioop.error, audioop.lin2alaw, data, size) - self.assertRaises(audioop.error, audioop.lin2adpcm, data, size, state) - - def test_string(self): - data = 'abcd' - size = 2 - self.assertRaises(TypeError, audioop.getsample, data, size, 0) - self.assertRaises(TypeError, audioop.max, data, size) - self.assertRaises(TypeError, audioop.minmax, data, size) - self.assertRaises(TypeError, audioop.avg, data, size) - self.assertRaises(TypeError, audioop.rms, data, size) - self.assertRaises(TypeError, audioop.avgpp, data, size) - self.assertRaises(TypeError, audioop.maxpp, data, size) - self.assertRaises(TypeError, audioop.cross, data, size) - self.assertRaises(TypeError, audioop.mul, data, size, 1.0) - self.assertRaises(TypeError, audioop.tomono, data, size, 0.5, 0.5) - self.assertRaises(TypeError, audioop.tostereo, data, size, 0.5, 0.5) - self.assertRaises(TypeError, audioop.add, data, data, size) - self.assertRaises(TypeError, audioop.bias, data, size, 0) - self.assertRaises(TypeError, audioop.reverse, data, size) - self.assertRaises(TypeError, audioop.lin2lin, data, size, size) - self.assertRaises(TypeError, audioop.ratecv, data, size, 1, 1, 1, None) - self.assertRaises(TypeError, audioop.lin2ulaw, data, size) - self.assertRaises(TypeError, audioop.lin2alaw, data, size) - self.assertRaises(TypeError, audioop.lin2adpcm, data, size, None) - - def test_wrongsize(self): - data = b'abcdefgh' - state = None - for size in (-1, 0, 5, 1024): - self.assertRaises(audioop.error, audioop.ulaw2lin, data, size) - self.assertRaises(audioop.error, audioop.alaw2lin, data, size) - self.assertRaises(audioop.error, audioop.adpcm2lin, data, size, state) - - if __name__ == '__main__': - unittest.main() diff --git a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_audit.yaml b/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_audit.yaml deleted file mode 100644 index 92e23aca3..000000000 --- a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_audit.yaml +++ /dev/null @@ -1,133 +0,0 @@ -python: | - """Tests for sys.audit and sys.addaudithook - """ - - import subprocess - import sys - import unittest - from test import support - - if not hasattr(sys, "addaudithook") or not hasattr(sys, "audit"): - raise unittest.SkipTest("test only relevant when sys.audit is available") - - AUDIT_TESTS_PY = support.findfile("audit-tests.py") - - - class AuditTest(unittest.TestCase): - def do_test(self, *args): - with subprocess.Popen( - [sys.executable, "-X utf8", AUDIT_TESTS_PY, *args], - encoding="utf-8", - stdout=subprocess.PIPE, - stderr=subprocess.PIPE, - ) as p: - p.wait() - sys.stdout.writelines(p.stdout) - sys.stderr.writelines(p.stderr) - if p.returncode: - self.fail("".join(p.stderr)) - - def run_python(self, *args): - events = [] - with subprocess.Popen( - [sys.executable, "-X utf8", AUDIT_TESTS_PY, *args], - encoding="utf-8", - stdout=subprocess.PIPE, - stderr=subprocess.PIPE, - ) as p: - p.wait() - sys.stderr.writelines(p.stderr) - return ( - p.returncode, - [line.strip().partition(" ") for line in p.stdout], - "".join(p.stderr), - ) - - def test_basic(self): - self.do_test("test_basic") - - def test_block_add_hook(self): - self.do_test("test_block_add_hook") - - def test_block_add_hook_baseexception(self): - self.do_test("test_block_add_hook_baseexception") - - def test_pickle(self): - support.import_module("pickle") - - self.do_test("test_pickle") - - def test_monkeypatch(self): - self.do_test("test_monkeypatch") - - def test_open(self): - self.do_test("test_open", support.TESTFN) - - def test_cantrace(self): - self.do_test("test_cantrace") - - def test_mmap(self): - self.do_test("test_mmap") - - def test_excepthook(self): - returncode, events, stderr = self.run_python("test_excepthook") - if not returncode: - self.fail(f"Expected fatal exception\n{stderr}") - - self.assertSequenceEqual( - [("sys.excepthook", " ", "RuntimeError('fatal-error')")], events - ) - - def test_unraisablehook(self): - returncode, events, stderr = self.run_python("test_unraisablehook") - if returncode: - self.fail(stderr) - - self.assertEqual(events[0][0], "sys.unraisablehook") - self.assertEqual( - events[0][2], - "RuntimeError('nonfatal-error') Exception ignored for audit hook test", - ) - - def test_winreg(self): - support.import_module("winreg") - returncode, events, stderr = self.run_python("test_winreg") - if returncode: - self.fail(stderr) - - self.assertEqual(events[0][0], "winreg.OpenKey") - self.assertEqual(events[1][0], "winreg.OpenKey/result") - expected = events[1][2] - self.assertTrue(expected) - self.assertSequenceEqual(["winreg.EnumKey", " ", f"{expected} 0"], events[2]) - self.assertSequenceEqual(["winreg.EnumKey", " ", f"{expected} 10000"], events[3]) - self.assertSequenceEqual(["winreg.PyHKEY.Detach", " ", expected], events[4]) - - def test_socket(self): - support.import_module("socket") - returncode, events, stderr = self.run_python("test_socket") - if returncode: - self.fail(stderr) - - if support.verbose: - print(*events, sep='\n') - self.assertEqual(events[0][0], "socket.gethostname") - self.assertEqual(events[1][0], "socket.__new__") - self.assertEqual(events[2][0], "socket.bind") - self.assertTrue(events[2][2].endswith("('127.0.0.1', 8080)")) - - def test_gc(self): - returncode, events, stderr = self.run_python("test_gc") - if returncode: - self.fail(stderr) - - if support.verbose: - print(*events, sep='\n') - self.assertEqual( - [event[0] for event in events], - ["gc.get_objects", "gc.get_referrers", "gc.get_referents"] - ) - - - if __name__ == "__main__": - unittest.main() diff --git a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_augassign.yaml b/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_augassign.yaml deleted file mode 100644 index 0d0af9091..000000000 --- a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_augassign.yaml +++ /dev/null @@ -1,327 +0,0 @@ -python: | - # Augmented assignment test. - - import unittest - - - class AugAssignTest(unittest.TestCase): - def testBasic(self): - x = 2 - x += 1 - x *= 2 - x **= 2 - x -= 8 - x //= 5 - x %= 3 - x &= 2 - x |= 5 - x ^= 1 - x /= 2 - self.assertEqual(x, 3.0) - - def test_with_unpacking(self): - self.assertRaises(SyntaxError, compile, "x, b += 3", "", "exec") - - def testInList(self): - x = [2] - x[0] += 1 - x[0] *= 2 - x[0] **= 2 - x[0] -= 8 - x[0] //= 5 - x[0] %= 3 - x[0] &= 2 - x[0] |= 5 - x[0] ^= 1 - x[0] /= 2 - self.assertEqual(x[0], 3.0) - - def testInDict(self): - x = {0: 2} - x[0] += 1 - x[0] *= 2 - x[0] **= 2 - x[0] -= 8 - x[0] //= 5 - x[0] %= 3 - x[0] &= 2 - x[0] |= 5 - x[0] ^= 1 - x[0] /= 2 - self.assertEqual(x[0], 3.0) - - def testSequences(self): - x = [1,2] - x += [3,4] - x *= 2 - - self.assertEqual(x, [1, 2, 3, 4, 1, 2, 3, 4]) - - x = [1, 2, 3] - y = x - x[1:2] *= 2 - y[1:2] += [1] - - self.assertEqual(x, [1, 2, 1, 2, 3]) - self.assertTrue(x is y) - - def testCustomMethods1(self): - - class aug_test: - def __init__(self, value): - self.val = value - def __radd__(self, val): - return self.val + val - def __add__(self, val): - return aug_test(self.val + val) - - class aug_test2(aug_test): - def __iadd__(self, val): - self.val = self.val + val - return self - - class aug_test3(aug_test): - def __iadd__(self, val): - return aug_test3(self.val + val) - - class aug_test4(aug_test3): - """Blocks inheritance, and fallback to __add__""" - __iadd__ = None - - x = aug_test(1) - y = x - x += 10 - - self.assertIsInstance(x, aug_test) - self.assertTrue(y is not x) - self.assertEqual(x.val, 11) - - x = aug_test2(2) - y = x - x += 10 - - self.assertTrue(y is x) - self.assertEqual(x.val, 12) - - x = aug_test3(3) - y = x - x += 10 - - self.assertIsInstance(x, aug_test3) - self.assertTrue(y is not x) - self.assertEqual(x.val, 13) - - x = aug_test4(4) - with self.assertRaises(TypeError): - x += 10 - - - def testCustomMethods2(test_self): - output = [] - - class testall: - def __add__(self, val): - output.append("__add__ called") - def __radd__(self, val): - output.append("__radd__ called") - def __iadd__(self, val): - output.append("__iadd__ called") - return self - - def __sub__(self, val): - output.append("__sub__ called") - def __rsub__(self, val): - output.append("__rsub__ called") - def __isub__(self, val): - output.append("__isub__ called") - return self - - def __mul__(self, val): - output.append("__mul__ called") - def __rmul__(self, val): - output.append("__rmul__ called") - def __imul__(self, val): - output.append("__imul__ called") - return self - - def __matmul__(self, val): - output.append("__matmul__ called") - def __rmatmul__(self, val): - output.append("__rmatmul__ called") - def __imatmul__(self, val): - output.append("__imatmul__ called") - return self - - def __floordiv__(self, val): - output.append("__floordiv__ called") - return self - def __ifloordiv__(self, val): - output.append("__ifloordiv__ called") - return self - def __rfloordiv__(self, val): - output.append("__rfloordiv__ called") - return self - - def __truediv__(self, val): - output.append("__truediv__ called") - return self - def __rtruediv__(self, val): - output.append("__rtruediv__ called") - return self - def __itruediv__(self, val): - output.append("__itruediv__ called") - return self - - def __mod__(self, val): - output.append("__mod__ called") - def __rmod__(self, val): - output.append("__rmod__ called") - def __imod__(self, val): - output.append("__imod__ called") - return self - - def __pow__(self, val): - output.append("__pow__ called") - def __rpow__(self, val): - output.append("__rpow__ called") - def __ipow__(self, val): - output.append("__ipow__ called") - return self - - def __or__(self, val): - output.append("__or__ called") - def __ror__(self, val): - output.append("__ror__ called") - def __ior__(self, val): - output.append("__ior__ called") - return self - - def __and__(self, val): - output.append("__and__ called") - def __rand__(self, val): - output.append("__rand__ called") - def __iand__(self, val): - output.append("__iand__ called") - return self - - def __xor__(self, val): - output.append("__xor__ called") - def __rxor__(self, val): - output.append("__rxor__ called") - def __ixor__(self, val): - output.append("__ixor__ called") - return self - - def __rshift__(self, val): - output.append("__rshift__ called") - def __rrshift__(self, val): - output.append("__rrshift__ called") - def __irshift__(self, val): - output.append("__irshift__ called") - return self - - def __lshift__(self, val): - output.append("__lshift__ called") - def __rlshift__(self, val): - output.append("__rlshift__ called") - def __ilshift__(self, val): - output.append("__ilshift__ called") - return self - - x = testall() - x + 1 - 1 + x - x += 1 - - x - 1 - 1 - x - x -= 1 - - x * 1 - 1 * x - x *= 1 - - x @ 1 - 1 @ x - x @= 1 - - x / 1 - 1 / x - x /= 1 - - x // 1 - 1 // x - x //= 1 - - x % 1 - 1 % x - x %= 1 - - x ** 1 - 1 ** x - x **= 1 - - x | 1 - 1 | x - x |= 1 - - x & 1 - 1 & x - x &= 1 - - x ^ 1 - 1 ^ x - x ^= 1 - - x >> 1 - 1 >> x - x >>= 1 - - x << 1 - 1 << x - x <<= 1 - - test_self.assertEqual(output, '''\ - __add__ called - __radd__ called - __iadd__ called - __sub__ called - __rsub__ called - __isub__ called - __mul__ called - __rmul__ called - __imul__ called - __matmul__ called - __rmatmul__ called - __imatmul__ called - __truediv__ called - __rtruediv__ called - __itruediv__ called - __floordiv__ called - __rfloordiv__ called - __ifloordiv__ called - __mod__ called - __rmod__ called - __imod__ called - __pow__ called - __rpow__ called - __ipow__ called - __or__ called - __ror__ called - __ior__ called - __and__ called - __rand__ called - __iand__ called - __xor__ called - __rxor__ called - __ixor__ called - __rshift__ called - __rrshift__ called - __irshift__ called - __lshift__ called - __rlshift__ called - __ilshift__ called - '''.splitlines()) - - if __name__ == '__main__': - unittest.main() diff --git a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_base64.yaml b/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_base64.yaml deleted file mode 100644 index a20d82229..000000000 --- a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_base64.yaml +++ /dev/null @@ -1,692 +0,0 @@ -python: | - import unittest - from test import support - import base64 - import binascii - import os - from array import array - from test.support import script_helper - - - class LegacyBase64TestCase(unittest.TestCase): - - # Legacy API is not as permissive as the modern API - def check_type_errors(self, f): - self.assertRaises(TypeError, f, "") - self.assertRaises(TypeError, f, []) - multidimensional = memoryview(b"1234").cast('B', (2, 2)) - self.assertRaises(TypeError, f, multidimensional) - int_data = memoryview(b"1234").cast('I') - self.assertRaises(TypeError, f, int_data) - - def test_encodestring_warns(self): - with self.assertWarns(DeprecationWarning): - base64.encodestring(b"www.python.org") - - def test_decodestring_warns(self): - with self.assertWarns(DeprecationWarning): - base64.decodestring(b"d3d3LnB5dGhvbi5vcmc=\n") - - def test_encodebytes(self): - eq = self.assertEqual - eq(base64.encodebytes(b"www.python.org"), b"d3d3LnB5dGhvbi5vcmc=\n") - eq(base64.encodebytes(b"a"), b"YQ==\n") - eq(base64.encodebytes(b"ab"), b"YWI=\n") - eq(base64.encodebytes(b"abc"), b"YWJj\n") - eq(base64.encodebytes(b""), b"") - eq(base64.encodebytes(b"abcdefghijklmnopqrstuvwxyz" - b"ABCDEFGHIJKLMNOPQRSTUVWXYZ" - b"0123456789!@#0^&*();:<>,. []{}"), - b"YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpBQkNE" - b"RUZHSElKS0xNTk9QUVJTVFVWV1hZWjAxMjM0\nNT" - b"Y3ODkhQCMwXiYqKCk7Ojw+LC4gW117fQ==\n") - # Non-bytes - eq(base64.encodebytes(bytearray(b'abc')), b'YWJj\n') - eq(base64.encodebytes(memoryview(b'abc')), b'YWJj\n') - eq(base64.encodebytes(array('B', b'abc')), b'YWJj\n') - self.check_type_errors(base64.encodebytes) - - def test_decodebytes(self): - eq = self.assertEqual - eq(base64.decodebytes(b"d3d3LnB5dGhvbi5vcmc=\n"), b"www.python.org") - eq(base64.decodebytes(b"YQ==\n"), b"a") - eq(base64.decodebytes(b"YWI=\n"), b"ab") - eq(base64.decodebytes(b"YWJj\n"), b"abc") - eq(base64.decodebytes(b"YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpBQkNE" - b"RUZHSElKS0xNTk9QUVJTVFVWV1hZWjAxMjM0\nNT" - b"Y3ODkhQCMwXiYqKCk7Ojw+LC4gW117fQ==\n"), - b"abcdefghijklmnopqrstuvwxyz" - b"ABCDEFGHIJKLMNOPQRSTUVWXYZ" - b"0123456789!@#0^&*();:<>,. []{}") - eq(base64.decodebytes(b''), b'') - # Non-bytes - eq(base64.decodebytes(bytearray(b'YWJj\n')), b'abc') - eq(base64.decodebytes(memoryview(b'YWJj\n')), b'abc') - eq(base64.decodebytes(array('B', b'YWJj\n')), b'abc') - self.check_type_errors(base64.decodebytes) - - def test_encode(self): - eq = self.assertEqual - from io import BytesIO, StringIO - infp = BytesIO(b'abcdefghijklmnopqrstuvwxyz' - b'ABCDEFGHIJKLMNOPQRSTUVWXYZ' - b'0123456789!@#0^&*();:<>,. []{}') - outfp = BytesIO() - base64.encode(infp, outfp) - eq(outfp.getvalue(), - b'YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpBQkNE' - b'RUZHSElKS0xNTk9QUVJTVFVWV1hZWjAxMjM0\nNT' - b'Y3ODkhQCMwXiYqKCk7Ojw+LC4gW117fQ==\n') - # Non-binary files - self.assertRaises(TypeError, base64.encode, StringIO('abc'), BytesIO()) - self.assertRaises(TypeError, base64.encode, BytesIO(b'abc'), StringIO()) - self.assertRaises(TypeError, base64.encode, StringIO('abc'), StringIO()) - - def test_decode(self): - from io import BytesIO, StringIO - infp = BytesIO(b'd3d3LnB5dGhvbi5vcmc=') - outfp = BytesIO() - base64.decode(infp, outfp) - self.assertEqual(outfp.getvalue(), b'www.python.org') - # Non-binary files - self.assertRaises(TypeError, base64.encode, StringIO('YWJj\n'), BytesIO()) - self.assertRaises(TypeError, base64.encode, BytesIO(b'YWJj\n'), StringIO()) - self.assertRaises(TypeError, base64.encode, StringIO('YWJj\n'), StringIO()) - - - class BaseXYTestCase(unittest.TestCase): - - # Modern API completely ignores exported dimension and format data and - # treats any buffer as a stream of bytes - def check_encode_type_errors(self, f): - self.assertRaises(TypeError, f, "") - self.assertRaises(TypeError, f, []) - - def check_decode_type_errors(self, f): - self.assertRaises(TypeError, f, []) - - def check_other_types(self, f, bytes_data, expected): - eq = self.assertEqual - b = bytearray(bytes_data) - eq(f(b), expected) - # The bytearray wasn't mutated - eq(b, bytes_data) - eq(f(memoryview(bytes_data)), expected) - eq(f(array('B', bytes_data)), expected) - # XXX why is b64encode hardcoded here? - self.check_nonbyte_element_format(base64.b64encode, bytes_data) - self.check_multidimensional(base64.b64encode, bytes_data) - - def check_multidimensional(self, f, data): - padding = b"\x00" if len(data) % 2 else b"" - bytes_data = data + padding # Make sure cast works - shape = (len(bytes_data) // 2, 2) - multidimensional = memoryview(bytes_data).cast('B', shape) - self.assertEqual(f(multidimensional), f(bytes_data)) - - def check_nonbyte_element_format(self, f, data): - padding = b"\x00" * ((4 - len(data)) % 4) - bytes_data = data + padding # Make sure cast works - int_data = memoryview(bytes_data).cast('I') - self.assertEqual(f(int_data), f(bytes_data)) - - - def test_b64encode(self): - eq = self.assertEqual - # Test default alphabet - eq(base64.b64encode(b"www.python.org"), b"d3d3LnB5dGhvbi5vcmc=") - eq(base64.b64encode(b'\x00'), b'AA==') - eq(base64.b64encode(b"a"), b"YQ==") - eq(base64.b64encode(b"ab"), b"YWI=") - eq(base64.b64encode(b"abc"), b"YWJj") - eq(base64.b64encode(b""), b"") - eq(base64.b64encode(b"abcdefghijklmnopqrstuvwxyz" - b"ABCDEFGHIJKLMNOPQRSTUVWXYZ" - b"0123456789!@#0^&*();:<>,. []{}"), - b"YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpBQkNE" - b"RUZHSElKS0xNTk9QUVJTVFVWV1hZWjAxMjM0NT" - b"Y3ODkhQCMwXiYqKCk7Ojw+LC4gW117fQ==") - # Test with arbitrary alternative characters - eq(base64.b64encode(b'\xd3V\xbeo\xf7\x1d', altchars=b'*$'), b'01a*b$cd') - eq(base64.b64encode(b'\xd3V\xbeo\xf7\x1d', altchars=bytearray(b'*$')), - b'01a*b$cd') - eq(base64.b64encode(b'\xd3V\xbeo\xf7\x1d', altchars=memoryview(b'*$')), - b'01a*b$cd') - eq(base64.b64encode(b'\xd3V\xbeo\xf7\x1d', altchars=array('B', b'*$')), - b'01a*b$cd') - # Non-bytes - self.check_other_types(base64.b64encode, b'abcd', b'YWJjZA==') - self.check_encode_type_errors(base64.b64encode) - self.assertRaises(TypeError, base64.b64encode, b"", altchars="*$") - # Test standard alphabet - eq(base64.standard_b64encode(b"www.python.org"), b"d3d3LnB5dGhvbi5vcmc=") - eq(base64.standard_b64encode(b"a"), b"YQ==") - eq(base64.standard_b64encode(b"ab"), b"YWI=") - eq(base64.standard_b64encode(b"abc"), b"YWJj") - eq(base64.standard_b64encode(b""), b"") - eq(base64.standard_b64encode(b"abcdefghijklmnopqrstuvwxyz" - b"ABCDEFGHIJKLMNOPQRSTUVWXYZ" - b"0123456789!@#0^&*();:<>,. []{}"), - b"YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpBQkNE" - b"RUZHSElKS0xNTk9QUVJTVFVWV1hZWjAxMjM0NT" - b"Y3ODkhQCMwXiYqKCk7Ojw+LC4gW117fQ==") - # Non-bytes - self.check_other_types(base64.standard_b64encode, - b'abcd', b'YWJjZA==') - self.check_encode_type_errors(base64.standard_b64encode) - # Test with 'URL safe' alternative characters - eq(base64.urlsafe_b64encode(b'\xd3V\xbeo\xf7\x1d'), b'01a-b_cd') - # Non-bytes - self.check_other_types(base64.urlsafe_b64encode, - b'\xd3V\xbeo\xf7\x1d', b'01a-b_cd') - self.check_encode_type_errors(base64.urlsafe_b64encode) - - def test_b64decode(self): - eq = self.assertEqual - - tests = {b"d3d3LnB5dGhvbi5vcmc=": b"www.python.org", - b'AA==': b'\x00', - b"YQ==": b"a", - b"YWI=": b"ab", - b"YWJj": b"abc", - b"YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpBQkNE" - b"RUZHSElKS0xNTk9QUVJTVFVWV1hZWjAxMjM0\nNT" - b"Y3ODkhQCMwXiYqKCk7Ojw+LC4gW117fQ==": - - b"abcdefghijklmnopqrstuvwxyz" - b"ABCDEFGHIJKLMNOPQRSTUVWXYZ" - b"0123456789!@#0^&*();:<>,. []{}", - b'': b'', - } - for data, res in tests.items(): - eq(base64.b64decode(data), res) - eq(base64.b64decode(data.decode('ascii')), res) - # Non-bytes - self.check_other_types(base64.b64decode, b"YWJj", b"abc") - self.check_decode_type_errors(base64.b64decode) - - # Test with arbitrary alternative characters - tests_altchars = {(b'01a*b$cd', b'*$'): b'\xd3V\xbeo\xf7\x1d', - } - for (data, altchars), res in tests_altchars.items(): - data_str = data.decode('ascii') - altchars_str = altchars.decode('ascii') - - eq(base64.b64decode(data, altchars=altchars), res) - eq(base64.b64decode(data_str, altchars=altchars), res) - eq(base64.b64decode(data, altchars=altchars_str), res) - eq(base64.b64decode(data_str, altchars=altchars_str), res) - - # Test standard alphabet - for data, res in tests.items(): - eq(base64.standard_b64decode(data), res) - eq(base64.standard_b64decode(data.decode('ascii')), res) - # Non-bytes - self.check_other_types(base64.standard_b64decode, b"YWJj", b"abc") - self.check_decode_type_errors(base64.standard_b64decode) - - # Test with 'URL safe' alternative characters - tests_urlsafe = {b'01a-b_cd': b'\xd3V\xbeo\xf7\x1d', - b'': b'', - } - for data, res in tests_urlsafe.items(): - eq(base64.urlsafe_b64decode(data), res) - eq(base64.urlsafe_b64decode(data.decode('ascii')), res) - # Non-bytes - self.check_other_types(base64.urlsafe_b64decode, b'01a-b_cd', - b'\xd3V\xbeo\xf7\x1d') - self.check_decode_type_errors(base64.urlsafe_b64decode) - - def test_b64decode_padding_error(self): - self.assertRaises(binascii.Error, base64.b64decode, b'abc') - self.assertRaises(binascii.Error, base64.b64decode, 'abc') - - def test_b64decode_invalid_chars(self): - # issue 1466065: Test some invalid characters. - tests = ((b'%3d==', b'\xdd'), - (b'$3d==', b'\xdd'), - (b'[==', b''), - (b'YW]3=', b'am'), - (b'3{d==', b'\xdd'), - (b'3d}==', b'\xdd'), - (b'@@', b''), - (b'!', b''), - (b"YWJj\n", b"abc"), - (b'YWJj\nYWI=', b'abcab')) - funcs = ( - base64.b64decode, - base64.standard_b64decode, - base64.urlsafe_b64decode, - ) - for bstr, res in tests: - for func in funcs: - with self.subTest(bstr=bstr, func=func): - self.assertEqual(func(bstr), res) - self.assertEqual(func(bstr.decode('ascii')), res) - with self.assertRaises(binascii.Error): - base64.b64decode(bstr, validate=True) - with self.assertRaises(binascii.Error): - base64.b64decode(bstr.decode('ascii'), validate=True) - - # Normal alphabet characters not discarded when alternative given - res = b'\xFB\xEF\xBE\xFF\xFF\xFF' - self.assertEqual(base64.b64decode(b'++[[//]]', b'[]'), res) - self.assertEqual(base64.urlsafe_b64decode(b'++--//__'), res) - - def test_b32encode(self): - eq = self.assertEqual - eq(base64.b32encode(b''), b'') - eq(base64.b32encode(b'\x00'), b'AA======') - eq(base64.b32encode(b'a'), b'ME======') - eq(base64.b32encode(b'ab'), b'MFRA====') - eq(base64.b32encode(b'abc'), b'MFRGG===') - eq(base64.b32encode(b'abcd'), b'MFRGGZA=') - eq(base64.b32encode(b'abcde'), b'MFRGGZDF') - # Non-bytes - self.check_other_types(base64.b32encode, b'abcd', b'MFRGGZA=') - self.check_encode_type_errors(base64.b32encode) - - def test_b32decode(self): - eq = self.assertEqual - tests = {b'': b'', - b'AA======': b'\x00', - b'ME======': b'a', - b'MFRA====': b'ab', - b'MFRGG===': b'abc', - b'MFRGGZA=': b'abcd', - b'MFRGGZDF': b'abcde', - } - for data, res in tests.items(): - eq(base64.b32decode(data), res) - eq(base64.b32decode(data.decode('ascii')), res) - # Non-bytes - self.check_other_types(base64.b32decode, b'MFRGG===', b"abc") - self.check_decode_type_errors(base64.b32decode) - - def test_b32decode_casefold(self): - eq = self.assertEqual - tests = {b'': b'', - b'ME======': b'a', - b'MFRA====': b'ab', - b'MFRGG===': b'abc', - b'MFRGGZA=': b'abcd', - b'MFRGGZDF': b'abcde', - # Lower cases - b'me======': b'a', - b'mfra====': b'ab', - b'mfrgg===': b'abc', - b'mfrggza=': b'abcd', - b'mfrggzdf': b'abcde', - } - - for data, res in tests.items(): - eq(base64.b32decode(data, True), res) - eq(base64.b32decode(data.decode('ascii'), True), res) - - self.assertRaises(binascii.Error, base64.b32decode, b'me======') - self.assertRaises(binascii.Error, base64.b32decode, 'me======') - - # Mapping zero and one - eq(base64.b32decode(b'MLO23456'), b'b\xdd\xad\xf3\xbe') - eq(base64.b32decode('MLO23456'), b'b\xdd\xad\xf3\xbe') - - map_tests = {(b'M1023456', b'L'): b'b\xdd\xad\xf3\xbe', - (b'M1023456', b'I'): b'b\x1d\xad\xf3\xbe', - } - for (data, map01), res in map_tests.items(): - data_str = data.decode('ascii') - map01_str = map01.decode('ascii') - - eq(base64.b32decode(data, map01=map01), res) - eq(base64.b32decode(data_str, map01=map01), res) - eq(base64.b32decode(data, map01=map01_str), res) - eq(base64.b32decode(data_str, map01=map01_str), res) - self.assertRaises(binascii.Error, base64.b32decode, data) - self.assertRaises(binascii.Error, base64.b32decode, data_str) - - def test_b32decode_error(self): - tests = [b'abc', b'ABCDEF==', b'==ABCDEF'] - prefixes = [b'M', b'ME', b'MFRA', b'MFRGG', b'MFRGGZA', b'MFRGGZDF'] - for i in range(0, 17): - if i: - tests.append(b'='*i) - for prefix in prefixes: - if len(prefix) + i != 8: - tests.append(prefix + b'='*i) - for data in tests: - with self.subTest(data=data): - with self.assertRaises(binascii.Error): - base64.b32decode(data) - with self.assertRaises(binascii.Error): - base64.b32decode(data.decode('ascii')) - - def test_b16encode(self): - eq = self.assertEqual - eq(base64.b16encode(b'\x01\x02\xab\xcd\xef'), b'0102ABCDEF') - eq(base64.b16encode(b'\x00'), b'00') - # Non-bytes - self.check_other_types(base64.b16encode, b'\x01\x02\xab\xcd\xef', - b'0102ABCDEF') - self.check_encode_type_errors(base64.b16encode) - - def test_b16decode(self): - eq = self.assertEqual - eq(base64.b16decode(b'0102ABCDEF'), b'\x01\x02\xab\xcd\xef') - eq(base64.b16decode('0102ABCDEF'), b'\x01\x02\xab\xcd\xef') - eq(base64.b16decode(b'00'), b'\x00') - eq(base64.b16decode('00'), b'\x00') - # Lower case is not allowed without a flag - self.assertRaises(binascii.Error, base64.b16decode, b'0102abcdef') - self.assertRaises(binascii.Error, base64.b16decode, '0102abcdef') - # Case fold - eq(base64.b16decode(b'0102abcdef', True), b'\x01\x02\xab\xcd\xef') - eq(base64.b16decode('0102abcdef', True), b'\x01\x02\xab\xcd\xef') - # Non-bytes - self.check_other_types(base64.b16decode, b"0102ABCDEF", - b'\x01\x02\xab\xcd\xef') - self.check_decode_type_errors(base64.b16decode) - eq(base64.b16decode(bytearray(b"0102abcdef"), True), - b'\x01\x02\xab\xcd\xef') - eq(base64.b16decode(memoryview(b"0102abcdef"), True), - b'\x01\x02\xab\xcd\xef') - eq(base64.b16decode(array('B', b"0102abcdef"), True), - b'\x01\x02\xab\xcd\xef') - # Non-alphabet characters - self.assertRaises(binascii.Error, base64.b16decode, '0102AG') - # Incorrect "padding" - self.assertRaises(binascii.Error, base64.b16decode, '010') - - def test_a85encode(self): - eq = self.assertEqual - - tests = { - b'': b'', - b"www.python.org": b'GB\\6`E-ZP=Df.1GEb>', - bytes(range(255)): b"""!!*-'"9eu7#RLhG$k3[W&.oNg'GVB"(`=52*$$""" - b"""(B+<_pR,UFcb-n-Vr/1iJ-0JP==1c70M3&s#]4?Ykm5X@_(6q'R884cE""" - b"""H9MJ8X:f1+h<)lt#=BSg3>[:ZC?t!MSA7]@cBPD3sCi+'.E,fo>FEMbN""" - b"""G^4U^I!pHnJ:W<)KS>/9Ll%"IN/`jYOHG]iPa.Q$R$jD4S=Q7DTV8*TU""" - b"""nsrdW2ZetXKAY/Yd(L?['d?O\\@K2_]Y2%o^qmn*`5Ta:aN;TJbg"GZd""" - b"""*^:jeCE.%f\\,!5gtgiEi8N\\UjQ5OekiqBum-X60nF?)@o_%qPq"ad`""" - b"""r;HT""", - b"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" - b"0123456789!@#0^&*();:<>,. []{}": - b'@:E_WAS,RgBkhF"D/O92EH6,BF`qtRH$VbC6UX@47n?3D92&&T' - b":Jand;cHat='/U/0JP==1c70M3&r-I,;,E,oN2F(oQ1z', - b"zero compression\0\0\0": b'H=_,8+Cf>,E,oN2F(oQ1!!!!', - b"Boundary:\0\0\0\0": b'6>q!aA79M(3WK-[!!', - b"Space compr: ": b';fH/TAKYK$D/aMV+', data) - - self.check_other_types(base64.a85encode, b"www.python.org", - b'GB\\6`E-ZP=Df.1GEb>') - - self.assertRaises(TypeError, base64.a85encode, "") - - eq(base64.a85encode(b"www.python.org", wrapcol=7, adobe=False), - b'GB\\6`E-\nZP=Df.1\nGEb>') - eq(base64.a85encode(b"\0\0\0\0www.python.org", wrapcol=7, adobe=False), - b'zGB\\6`E\n-ZP=Df.\n1GEb>') - eq(base64.a85encode(b"www.python.org", wrapcol=7, adobe=True), - b'<~GB\\6`\nE-ZP=Df\n.1GEb>\n~>') - - eq(base64.a85encode(b' '*8, foldspaces=True, adobe=False), b'yy') - eq(base64.a85encode(b' '*7, foldspaces=True, adobe=False), b'y+}2SXo+ITwPvYU}0ioWMyV&XlZI|Y;A6DaB*^Tbai%j""" - b"""czJqze0_d@fPsR8goTEOh>41ejE#,. []{}""": - b"""VPa!sWoBn+X=-b1ZEkOHadLBXb#`}nd3r%YLqtVJM@UIZOH55pPf$@(""" - b"""Q&d$}S6EqEFflSSG&MFiI5{CeBQRbjDkv#CIy^osE+AW7dwl""", - b'no padding..': b'Zf_uPVPs@!Zf7no', - b'zero compression\x00\x00\x00\x00': b'dS!BNAY*TBaB^jHb7^mG00000', - b'zero compression\x00\x00\x00': b'dS!BNAY*TBaB^jHb7^mG0000', - b"""Boundary:\x00\x00\x00\x00""": b"""LT`0$WMOi7IsgCw00""", - b'Space compr: ': b'Q*dEpWgug3ZE$irARr(h', - b'\xff': b'{{', - b'\xff'*2: b'|Nj', - b'\xff'*3: b'|Ns9', - b'\xff'*4: b'|NsC0', - } - - for data, res in tests.items(): - eq(base64.b85encode(data), res) - - self.check_other_types(base64.b85encode, b"www.python.org", - b'cXxL#aCvlSZ*DGca%T') - - def test_a85decode(self): - eq = self.assertEqual - - tests = { - b'': b'', - b'GB\\6`E-ZP=Df.1GEb>': b'www.python.org', - b"""! ! * -'"\n\t\t9eu\r\n7# RL\vhG$k3[W&.oNg'GVB"(`=52*$$""" - b"""(B+<_pR,UFcb-n-Vr/1iJ-0JP==1c70M3&s#]4?Ykm5X@_(6q'R884cE""" - b"""H9MJ8X:f1+h<)lt#=BSg3>[:ZC?t!MSA7]@cBPD3sCi+'.E,fo>FEMbN""" - b"""G^4U^I!pHnJ:W<)KS>/9Ll%"IN/`jYOHG]iPa.Q$R$jD4S=Q7DTV8*TU""" - b"""nsrdW2ZetXKAY/Yd(L?['d?O\\@K2_]Y2%o^qmn*`5Ta:aN;TJbg"GZd""" - b"""*^:jeCE.%f\\,!5gtgiEi8N\\UjQ5OekiqBum-X60nF?)@o_%qPq"ad`""" - b"""r;HT""": bytes(range(255)), - b"""@:E_WAS,RgBkhF"D/O92EH6,BF`qtRH$VbC6UX@47n?3D92&&T:Jand;c""" - b"""Hat='/U/0JP==1c70M3&r-I,;,. []{}', - b'DJpY:@:Wn_DJ(RS': b'no padding..', - b'H=_,8+Cf>,E,oN2F(oQ1z': b'zero compression\x00\x00\x00\x00', - b'H=_,8+Cf>,E,oN2F(oQ1!!!!': b'zero compression\x00\x00\x00', - b'6>q!aA79M(3WK-[!!': b"Boundary:\x00\x00\x00\x00", - b';fH/TAKYK$D/aMV+', adobe=True), res, data) - eq(base64.a85decode(data + b'~>', adobe=True), res, data) - eq(base64.a85decode('<~%s~>' % data.decode("ascii"), adobe=True), - res, data) - - eq(base64.a85decode(b'yy', foldspaces=True, adobe=False), b' '*8) - eq(base64.a85decode(b'y+', - b"www.python.org") - - def test_b85decode(self): - eq = self.assertEqual - - tests = { - b'': b'', - b'cXxL#aCvlSZ*DGca%T': b'www.python.org', - b"""009C61O)~M2nh-c3=Iws5D^j+6crX17#SKH9337X""" - b"""AR!_nBqb&%C@Cr{EG;fCFflSSG&MFiI5|2yJUu=?KtV!7L`6nNNJ&ad""" - b"""OifNtP*GA-R8>}2SXo+ITwPvYU}0ioWMyV&XlZI|Y;A6DaB*^Tbai%j""" - b"""czJqze0_d@fPsR8goTEOh>41ejE#,. []{}""", - b'Zf_uPVPs@!Zf7no': b'no padding..', - b'dS!BNAY*TBaB^jHb7^mG00000': b'zero compression\x00\x00\x00\x00', - b'dS!BNAY*TBaB^jHb7^mG0000': b'zero compression\x00\x00\x00', - b"""LT`0$WMOi7IsgCw00""": b"""Boundary:\x00\x00\x00\x00""", - b'Q*dEpWgug3ZE$irARr(h': b'Space compr: ', - b'{{': b'\xff', - b'|Nj': b'\xff'*2, - b'|Ns9': b'\xff'*3, - b'|NsC0': b'\xff'*4, - } - - for data, res in tests.items(): - eq(base64.b85decode(data), res) - eq(base64.b85decode(data.decode("ascii")), res) - - self.check_other_types(base64.b85decode, b'cXxL#aCvlSZ*DGca%T', - b"www.python.org") - - def test_a85_padding(self): - eq = self.assertEqual - - eq(base64.a85encode(b"x", pad=True), b'GQ7^D') - eq(base64.a85encode(b"xx", pad=True), b"G^'2g") - eq(base64.a85encode(b"xxx", pad=True), b'G^+H5') - eq(base64.a85encode(b"xxxx", pad=True), b'G^+IX') - eq(base64.a85encode(b"xxxxx", pad=True), b'G^+IXGQ7^D') - - eq(base64.a85decode(b'GQ7^D'), b"x\x00\x00\x00") - eq(base64.a85decode(b"G^'2g"), b"xx\x00\x00") - eq(base64.a85decode(b'G^+H5'), b"xxx\x00") - eq(base64.a85decode(b'G^+IX'), b"xxxx") - eq(base64.a85decode(b'G^+IXGQ7^D'), b"xxxxx\x00\x00\x00") - - def test_b85_padding(self): - eq = self.assertEqual - - eq(base64.b85encode(b"x", pad=True), b'cmMzZ') - eq(base64.b85encode(b"xx", pad=True), b'cz6H+') - eq(base64.b85encode(b"xxx", pad=True), b'czAdK') - eq(base64.b85encode(b"xxxx", pad=True), b'czAet') - eq(base64.b85encode(b"xxxxx", pad=True), b'czAetcmMzZ') - - eq(base64.b85decode(b'cmMzZ'), b"x\x00\x00\x00") - eq(base64.b85decode(b'cz6H+'), b"xx\x00\x00") - eq(base64.b85decode(b'czAdK'), b"xxx\x00") - eq(base64.b85decode(b'czAet'), b"xxxx") - eq(base64.b85decode(b'czAetcmMzZ'), b"xxxxx\x00\x00\x00") - - def test_a85decode_errors(self): - illegal = (set(range(32)) | set(range(118, 256))) - set(b' \t\n\r\v') - for c in illegal: - with self.assertRaises(ValueError, msg=bytes([c])): - base64.a85decode(b'!!!!' + bytes([c])) - with self.assertRaises(ValueError, msg=bytes([c])): - base64.a85decode(b'!!!!' + bytes([c]), adobe=False) - with self.assertRaises(ValueError, msg=bytes([c])): - base64.a85decode(b'<~!!!!' + bytes([c]) + b'~>', adobe=True) - - self.assertRaises(ValueError, base64.a85decode, - b"malformed", adobe=True) - self.assertRaises(ValueError, base64.a85decode, - b"<~still malformed", adobe=True) - - # With adobe=False (the default), Adobe framing markers are disallowed - self.assertRaises(ValueError, base64.a85decode, - b"<~~>") - self.assertRaises(ValueError, base64.a85decode, - b"<~~>", adobe=False) - base64.a85decode(b"<~~>", adobe=True) # sanity check - - self.assertRaises(ValueError, base64.a85decode, - b"abcx", adobe=False) - self.assertRaises(ValueError, base64.a85decode, - b"abcdey", adobe=False) - self.assertRaises(ValueError, base64.a85decode, - b"a b\nc", adobe=False, ignorechars=b"") - - self.assertRaises(ValueError, base64.a85decode, b's', adobe=False) - self.assertRaises(ValueError, base64.a85decode, b's8', adobe=False) - self.assertRaises(ValueError, base64.a85decode, b's8W', adobe=False) - self.assertRaises(ValueError, base64.a85decode, b's8W-', adobe=False) - self.assertRaises(ValueError, base64.a85decode, b's8W-"', adobe=False) - - def test_b85decode_errors(self): - illegal = list(range(33)) + \ - list(b'"\',./:[\\]') + \ - list(range(128, 256)) - for c in illegal: - with self.assertRaises(ValueError, msg=bytes([c])): - base64.b85decode(b'0000' + bytes([c])) - - self.assertRaises(ValueError, base64.b85decode, b'|') - self.assertRaises(ValueError, base64.b85decode, b'|N') - self.assertRaises(ValueError, base64.b85decode, b'|Ns') - self.assertRaises(ValueError, base64.b85decode, b'|NsC') - self.assertRaises(ValueError, base64.b85decode, b'|NsC1') - - def test_decode_nonascii_str(self): - decode_funcs = (base64.b64decode, - base64.standard_b64decode, - base64.urlsafe_b64decode, - base64.b32decode, - base64.b16decode, - base64.b85decode, - base64.a85decode) - for f in decode_funcs: - self.assertRaises(ValueError, f, 'with non-ascii \xcb') - - def test_ErrorHeritage(self): - self.assertTrue(issubclass(binascii.Error, ValueError)) - - - class TestMain(unittest.TestCase): - def tearDown(self): - if os.path.exists(support.TESTFN): - os.unlink(support.TESTFN) - - def get_output(self, *args): - return script_helper.assert_python_ok('-m', 'base64', *args).out - - def test_encode_decode(self): - output = self.get_output('-t') - self.assertSequenceEqual(output.splitlines(), ( - b"b'Aladdin:open sesame'", - br"b'QWxhZGRpbjpvcGVuIHNlc2FtZQ==\n'", - b"b'Aladdin:open sesame'", - )) - - def test_encode_file(self): - with open(support.TESTFN, 'wb') as fp: - fp.write(b'a\xffb\n') - output = self.get_output('-e', support.TESTFN) - self.assertEqual(output.rstrip(), b'Yf9iCg==') - - def test_encode_from_stdin(self): - with script_helper.spawn_python('-m', 'base64', '-e') as proc: - out, err = proc.communicate(b'a\xffb\n') - self.assertEqual(out.rstrip(), b'Yf9iCg==') - self.assertIsNone(err) - - def test_decode(self): - with open(support.TESTFN, 'wb') as fp: - fp.write(b'Yf9iCg==') - output = self.get_output('-d', support.TESTFN) - self.assertEqual(output.rstrip(), b'a\xffb') - - if __name__ == '__main__': - unittest.main() diff --git a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_baseexception.yaml b/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_baseexception.yaml deleted file mode 100644 index 2880c4329..000000000 --- a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_baseexception.yaml +++ /dev/null @@ -1,184 +0,0 @@ -python: | - import unittest - import builtins - import os - from platform import system as platform_system - - - class ExceptionClassTests(unittest.TestCase): - - """Tests for anything relating to exception objects themselves (e.g., - inheritance hierarchy)""" - - def test_builtins_new_style(self): - self.assertTrue(issubclass(Exception, object)) - - def verify_instance_interface(self, ins): - for attr in ("args", "__str__", "__repr__"): - self.assertTrue(hasattr(ins, attr), - "%s missing %s attribute" % - (ins.__class__.__name__, attr)) - - def test_inheritance(self): - # Make sure the inheritance hierarchy matches the documentation - exc_set = set() - for object_ in builtins.__dict__.values(): - try: - if issubclass(object_, BaseException): - exc_set.add(object_.__name__) - except TypeError: - pass - - inheritance_tree = open(os.path.join(os.path.split(__file__)[0], - 'exception_hierarchy.txt')) - try: - superclass_name = inheritance_tree.readline().rstrip() - try: - last_exc = getattr(builtins, superclass_name) - except AttributeError: - self.fail("base class %s not a built-in" % superclass_name) - self.assertIn(superclass_name, exc_set, - '%s not found' % superclass_name) - exc_set.discard(superclass_name) - superclasses = [] # Loop will insert base exception - last_depth = 0 - for exc_line in inheritance_tree: - exc_line = exc_line.rstrip() - depth = exc_line.rindex('-') - exc_name = exc_line[depth+2:] # Slice past space - if '(' in exc_name: - paren_index = exc_name.index('(') - platform_name = exc_name[paren_index+1:-1] - exc_name = exc_name[:paren_index-1] # Slice off space - if platform_system() != platform_name: - exc_set.discard(exc_name) - continue - if '[' in exc_name: - left_bracket = exc_name.index('[') - exc_name = exc_name[:left_bracket-1] # cover space - try: - exc = getattr(builtins, exc_name) - except AttributeError: - self.fail("%s not a built-in exception" % exc_name) - if last_depth < depth: - superclasses.append((last_depth, last_exc)) - elif last_depth > depth: - while superclasses[-1][0] >= depth: - superclasses.pop() - self.assertTrue(issubclass(exc, superclasses[-1][1]), - "%s is not a subclass of %s" % (exc.__name__, - superclasses[-1][1].__name__)) - try: # Some exceptions require arguments; just skip them - self.verify_instance_interface(exc()) - except TypeError: - pass - self.assertIn(exc_name, exc_set) - exc_set.discard(exc_name) - last_exc = exc - last_depth = depth - finally: - inheritance_tree.close() - self.assertEqual(len(exc_set), 0, "%s not accounted for" % exc_set) - - interface_tests = ("length", "args", "str", "repr") - - def interface_test_driver(self, results): - for test_name, (given, expected) in zip(self.interface_tests, results): - self.assertEqual(given, expected, "%s: %s != %s" % (test_name, - given, expected)) - - def test_interface_single_arg(self): - # Make sure interface works properly when given a single argument - arg = "spam" - exc = Exception(arg) - results = ([len(exc.args), 1], [exc.args[0], arg], - [str(exc), str(arg)], - [repr(exc), '%s(%r)' % (exc.__class__.__name__, arg)]) - self.interface_test_driver(results) - - def test_interface_multi_arg(self): - # Make sure interface correct when multiple arguments given - arg_count = 3 - args = tuple(range(arg_count)) - exc = Exception(*args) - results = ([len(exc.args), arg_count], [exc.args, args], - [str(exc), str(args)], - [repr(exc), exc.__class__.__name__ + repr(exc.args)]) - self.interface_test_driver(results) - - def test_interface_no_arg(self): - # Make sure that with no args that interface is correct - exc = Exception() - results = ([len(exc.args), 0], [exc.args, tuple()], - [str(exc), ''], - [repr(exc), exc.__class__.__name__ + '()']) - self.interface_test_driver(results) - - class UsageTests(unittest.TestCase): - - """Test usage of exceptions""" - - def raise_fails(self, object_): - """Make sure that raising 'object_' triggers a TypeError.""" - try: - raise object_ - except TypeError: - return # What is expected. - self.fail("TypeError expected for raising %s" % type(object_)) - - def catch_fails(self, object_): - """Catching 'object_' should raise a TypeError.""" - try: - try: - raise Exception - except object_: - pass - except TypeError: - pass - except Exception: - self.fail("TypeError expected when catching %s" % type(object_)) - - try: - try: - raise Exception - except (object_,): - pass - except TypeError: - return - except Exception: - self.fail("TypeError expected when catching %s as specified in a " - "tuple" % type(object_)) - - def test_raise_new_style_non_exception(self): - # You cannot raise a new-style class that does not inherit from - # BaseException; the ability was not possible until BaseException's - # introduction so no need to support new-style objects that do not - # inherit from it. - class NewStyleClass(object): - pass - self.raise_fails(NewStyleClass) - self.raise_fails(NewStyleClass()) - - def test_raise_string(self): - # Raising a string raises TypeError. - self.raise_fails("spam") - - def test_catch_non_BaseException(self): - # Trying to catch an object that does not inherit from BaseException - # is not allowed. - class NonBaseException(object): - pass - self.catch_fails(NonBaseException) - self.catch_fails(NonBaseException()) - - def test_catch_BaseException_instance(self): - # Catching an instance of a BaseException subclass won't work. - self.catch_fails(BaseException()) - - def test_catch_string(self): - # Catching a string is bad. - self.catch_fails("spam") - - - if __name__ == '__main__': - unittest.main() diff --git a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_bdb.yaml b/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_bdb.yaml deleted file mode 100644 index 384724e43..000000000 --- a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_bdb.yaml +++ /dev/null @@ -1,1162 +0,0 @@ -python: | - """ Test the bdb module. - - A test defines a list of tuples that may be seen as paired tuples, each - pair being defined by 'expect_tuple, set_tuple' as follows: - - ([event, [lineno[, co_name[, eargs]]]]), (set_type, [sargs]) - - * 'expect_tuple' describes the expected current state of the Bdb instance. - It may be the empty tuple and no check is done in that case. - * 'set_tuple' defines the set_*() method to be invoked when the Bdb - instance reaches this state. - - Example of an 'expect_tuple, set_tuple' pair: - - ('line', 2, 'tfunc_main'), ('step', ) - - Definitions of the members of the 'expect_tuple': - event: - Name of the trace event. The set methods that do not give back - control to the tracer [1] do not trigger a tracer event and in - that case the next 'event' may be 'None' by convention, its value - is not checked. - [1] Methods that trigger a trace event are set_step(), set_next(), - set_return(), set_until() and set_continue(). - lineno: - Line number. Line numbers are relative to the start of the - function when tracing a function in the test_bdb module (i.e. this - module). - co_name: - Name of the function being currently traced. - eargs: - A tuple: - * On an 'exception' event the tuple holds a class object, the - current exception must be an instance of this class. - * On a 'line' event, the tuple holds a dictionary and a list. The - dictionary maps each breakpoint number that has been hit on this - line to its hits count. The list holds the list of breakpoint - number temporaries that are being deleted. - - Definitions of the members of the 'set_tuple': - set_type: - The type of the set method to be invoked. This may - be the type of one of the Bdb set methods: 'step', 'next', - 'until', 'return', 'continue', 'break', 'quit', or the type of one - of the set methods added by test_bdb.Bdb: 'ignore', 'enable', - 'disable', 'clear', 'up', 'down'. - sargs: - The arguments of the set method if any, packed in a tuple. - """ - - import bdb as _bdb - import sys - import os - import unittest - import textwrap - import importlib - import linecache - from contextlib import contextmanager - from itertools import islice, repeat - import test.support - - class BdbException(Exception): pass - class BdbError(BdbException): """Error raised by the Bdb instance.""" - class BdbSyntaxError(BdbException): """Syntax error in the test case.""" - class BdbNotExpectedError(BdbException): """Unexpected result.""" - - # When 'dry_run' is set to true, expect tuples are ignored and the actual - # state of the tracer is printed after running each set_*() method of the test - # case. The full list of breakpoints and their attributes is also printed - # after each 'line' event where a breakpoint has been hit. - dry_run = 0 - - def reset_Breakpoint(): - _bdb.Breakpoint.next = 1 - _bdb.Breakpoint.bplist = {} - _bdb.Breakpoint.bpbynumber = [None] - - def info_breakpoints(): - bp_list = [bp for bp in _bdb.Breakpoint.bpbynumber if bp] - if not bp_list: - return '' - - header_added = False - for bp in bp_list: - if not header_added: - info = 'BpNum Temp Enb Hits Ignore Where\n' - header_added = True - - disp = 'yes ' if bp.temporary else 'no ' - enab = 'yes' if bp.enabled else 'no ' - info += ('%-5d %s %s %-4d %-6d at %s:%d' % - (bp.number, disp, enab, bp.hits, bp.ignore, - os.path.basename(bp.file), bp.line)) - if bp.cond: - info += '\n\tstop only if %s' % (bp.cond,) - info += '\n' - return info - - class Bdb(_bdb.Bdb): - """Extend Bdb to enhance test coverage.""" - - def trace_dispatch(self, frame, event, arg): - self.currentbp = None - return super().trace_dispatch(frame, event, arg) - - def set_break(self, filename, lineno, temporary=False, cond=None, - funcname=None): - if isinstance(funcname, str): - if filename == __file__: - globals_ = globals() - else: - module = importlib.import_module(filename[:-3]) - globals_ = module.__dict__ - func = eval(funcname, globals_) - code = func.__code__ - filename = code.co_filename - lineno = code.co_firstlineno - funcname = code.co_name - - res = super().set_break(filename, lineno, temporary=temporary, - cond=cond, funcname=funcname) - if isinstance(res, str): - raise BdbError(res) - return res - - def get_stack(self, f, t): - self.stack, self.index = super().get_stack(f, t) - self.frame = self.stack[self.index][0] - return self.stack, self.index - - def set_ignore(self, bpnum): - """Increment the ignore count of Breakpoint number 'bpnum'.""" - bp = self.get_bpbynumber(bpnum) - bp.ignore += 1 - - def set_enable(self, bpnum): - bp = self.get_bpbynumber(bpnum) - bp.enabled = True - - def set_disable(self, bpnum): - bp = self.get_bpbynumber(bpnum) - bp.enabled = False - - def set_clear(self, fname, lineno): - err = self.clear_break(fname, lineno) - if err: - raise BdbError(err) - - def set_up(self): - """Move up in the frame stack.""" - if not self.index: - raise BdbError('Oldest frame') - self.index -= 1 - self.frame = self.stack[self.index][0] - - def set_down(self): - """Move down in the frame stack.""" - if self.index + 1 == len(self.stack): - raise BdbError('Newest frame') - self.index += 1 - self.frame = self.stack[self.index][0] - - class Tracer(Bdb): - """A tracer for testing the bdb module.""" - - def __init__(self, expect_set, skip=None, dry_run=False, test_case=None): - super().__init__(skip=skip) - self.expect_set = expect_set - self.dry_run = dry_run - self.header = ('Dry-run results for %s:' % test_case if - test_case is not None else None) - self.init_test() - - def init_test(self): - self.cur_except = None - self.expect_set_no = 0 - self.breakpoint_hits = None - self.expected_list = list(islice(self.expect_set, 0, None, 2)) - self.set_list = list(islice(self.expect_set, 1, None, 2)) - - def trace_dispatch(self, frame, event, arg): - # On an 'exception' event, call_exc_trace() in Python/ceval.c discards - # a BdbException raised by the Tracer instance, so we raise it on the - # next trace_dispatch() call that occurs unless the set_quit() or - # set_continue() method has been invoked on the 'exception' event. - if self.cur_except is not None: - raise self.cur_except - - if event == 'exception': - try: - res = super().trace_dispatch(frame, event, arg) - return res - except BdbException as e: - self.cur_except = e - return self.trace_dispatch - else: - return super().trace_dispatch(frame, event, arg) - - def user_call(self, frame, argument_list): - # Adopt the same behavior as pdb and, as a side effect, skip also the - # first 'call' event when the Tracer is started with Tracer.runcall() - # which may be possibly considered as a bug. - if not self.stop_here(frame): - return - self.process_event('call', frame, argument_list) - self.next_set_method() - - def user_line(self, frame): - self.process_event('line', frame) - - if self.dry_run and self.breakpoint_hits: - info = info_breakpoints().strip('\n') - # Indent each line. - for line in info.split('\n'): - print(' ' + line) - self.delete_temporaries() - self.breakpoint_hits = None - - self.next_set_method() - - def user_return(self, frame, return_value): - self.process_event('return', frame, return_value) - self.next_set_method() - - def user_exception(self, frame, exc_info): - self.exc_info = exc_info - self.process_event('exception', frame) - self.next_set_method() - - def do_clear(self, arg): - # The temporary breakpoints are deleted in user_line(). - bp_list = [self.currentbp] - self.breakpoint_hits = (bp_list, bp_list) - - def delete_temporaries(self): - if self.breakpoint_hits: - for n in self.breakpoint_hits[1]: - self.clear_bpbynumber(n) - - def pop_next(self): - self.expect_set_no += 1 - try: - self.expect = self.expected_list.pop(0) - except IndexError: - raise BdbNotExpectedError( - 'expect_set list exhausted, cannot pop item %d' % - self.expect_set_no) - self.set_tuple = self.set_list.pop(0) - - def process_event(self, event, frame, *args): - # Call get_stack() to enable walking the stack with set_up() and - # set_down(). - tb = None - if event == 'exception': - tb = self.exc_info[2] - self.get_stack(frame, tb) - - # A breakpoint has been hit and it is not a temporary. - if self.currentbp is not None and not self.breakpoint_hits: - bp_list = [self.currentbp] - self.breakpoint_hits = (bp_list, []) - - # Pop next event. - self.event= event - self.pop_next() - if self.dry_run: - self.print_state(self.header) - return - - # Validate the expected results. - if self.expect: - self.check_equal(self.expect[0], event, 'Wrong event type') - self.check_lno_name() - - if event in ('call', 'return'): - self.check_expect_max_size(3) - elif len(self.expect) > 3: - if event == 'line': - bps, temporaries = self.expect[3] - bpnums = sorted(bps.keys()) - if not self.breakpoint_hits: - self.raise_not_expected( - 'No breakpoints hit at expect_set item %d' % - self.expect_set_no) - self.check_equal(bpnums, self.breakpoint_hits[0], - 'Breakpoint numbers do not match') - self.check_equal([bps[n] for n in bpnums], - [self.get_bpbynumber(n).hits for - n in self.breakpoint_hits[0]], - 'Wrong breakpoint hit count') - self.check_equal(sorted(temporaries), self.breakpoint_hits[1], - 'Wrong temporary breakpoints') - - elif event == 'exception': - if not isinstance(self.exc_info[1], self.expect[3]): - self.raise_not_expected( - "Wrong exception at expect_set item %d, got '%s'" % - (self.expect_set_no, self.exc_info)) - - def check_equal(self, expected, result, msg): - if expected == result: - return - self.raise_not_expected("%s at expect_set item %d, got '%s'" % - (msg, self.expect_set_no, result)) - - def check_lno_name(self): - """Check the line number and function co_name.""" - s = len(self.expect) - if s > 1: - lineno = self.lno_abs2rel() - self.check_equal(self.expect[1], lineno, 'Wrong line number') - if s > 2: - self.check_equal(self.expect[2], self.frame.f_code.co_name, - 'Wrong function name') - - def check_expect_max_size(self, size): - if len(self.expect) > size: - raise BdbSyntaxError('Invalid size of the %s expect tuple: %s' % - (self.event, self.expect)) - - def lno_abs2rel(self): - fname = self.canonic(self.frame.f_code.co_filename) - lineno = self.frame.f_lineno - return ((lineno - self.frame.f_code.co_firstlineno + 1) - if fname == self.canonic(__file__) else lineno) - - def lno_rel2abs(self, fname, lineno): - return (self.frame.f_code.co_firstlineno + lineno - 1 - if (lineno and self.canonic(fname) == self.canonic(__file__)) - else lineno) - - def get_state(self): - lineno = self.lno_abs2rel() - co_name = self.frame.f_code.co_name - state = "('%s', %d, '%s'" % (self.event, lineno, co_name) - if self.breakpoint_hits: - bps = '{' - for n in self.breakpoint_hits[0]: - if bps != '{': - bps += ', ' - bps += '%s: %s' % (n, self.get_bpbynumber(n).hits) - bps += '}' - bps = '(' + bps + ', ' + str(self.breakpoint_hits[1]) + ')' - state += ', ' + bps - elif self.event == 'exception': - state += ', ' + self.exc_info[0].__name__ - state += '), ' - return state.ljust(32) + str(self.set_tuple) + ',' - - def print_state(self, header=None): - if header is not None and self.expect_set_no == 1: - print() - print(header) - print('%d: %s' % (self.expect_set_no, self.get_state())) - - def raise_not_expected(self, msg): - msg += '\n' - msg += ' Expected: %s\n' % str(self.expect) - msg += ' Got: ' + self.get_state() - raise BdbNotExpectedError(msg) - - def next_set_method(self): - set_type = self.set_tuple[0] - args = self.set_tuple[1] if len(self.set_tuple) == 2 else None - set_method = getattr(self, 'set_' + set_type) - - # The following set methods give back control to the tracer. - if set_type in ('step', 'continue', 'quit'): - set_method() - return - elif set_type in ('next', 'return'): - set_method(self.frame) - return - elif set_type == 'until': - lineno = None - if args: - lineno = self.lno_rel2abs(self.frame.f_code.co_filename, - args[0]) - set_method(self.frame, lineno) - return - - # The following set methods do not give back control to the tracer and - # next_set_method() is called recursively. - if (args and set_type in ('break', 'clear', 'ignore', 'enable', - 'disable')) or set_type in ('up', 'down'): - if set_type in ('break', 'clear'): - fname, lineno, *remain = args - lineno = self.lno_rel2abs(fname, lineno) - args = [fname, lineno] - args.extend(remain) - set_method(*args) - elif set_type in ('ignore', 'enable', 'disable'): - set_method(*args) - elif set_type in ('up', 'down'): - set_method() - - # Process the next expect_set item. - # It is not expected that a test may reach the recursion limit. - self.event= None - self.pop_next() - if self.dry_run: - self.print_state() - else: - if self.expect: - self.check_lno_name() - self.check_expect_max_size(3) - self.next_set_method() - else: - raise BdbSyntaxError('"%s" is an invalid set_tuple' % - self.set_tuple) - - class TracerRun(): - """Provide a context for running a Tracer instance with a test case.""" - - def __init__(self, test_case, skip=None): - self.test_case = test_case - self.dry_run = test_case.dry_run - self.tracer = Tracer(test_case.expect_set, skip=skip, - dry_run=self.dry_run, test_case=test_case.id()) - self._original_tracer = None - - def __enter__(self): - # test_pdb does not reset Breakpoint class attributes on exit :-( - reset_Breakpoint() - self._original_tracer = sys.gettrace() - return self.tracer - - def __exit__(self, type_=None, value=None, traceback=None): - reset_Breakpoint() - sys.settrace(self._original_tracer) - - not_empty = '' - if self.tracer.set_list: - not_empty += 'All paired tuples have not been processed, ' - not_empty += ('the last one was number %d' % - self.tracer.expect_set_no) - - # Make a BdbNotExpectedError a unittest failure. - if type_ is not None and issubclass(BdbNotExpectedError, type_): - if isinstance(value, BaseException) and value.args: - err_msg = value.args[0] - if not_empty: - err_msg += '\n' + not_empty - if self.dry_run: - print(err_msg) - return True - else: - self.test_case.fail(err_msg) - else: - assert False, 'BdbNotExpectedError with empty args' - - if not_empty: - if self.dry_run: - print(not_empty) - else: - self.test_case.fail(not_empty) - - def run_test(modules, set_list, skip=None): - """Run a test and print the dry-run results. - - 'modules': A dictionary mapping module names to their source code as a - string. The dictionary MUST include one module named - 'test_module' with a main() function. - 'set_list': A list of set_type tuples to be run on the module. - - For example, running the following script outputs the following results: - - ***************************** SCRIPT ******************************** - - from test.test_bdb import run_test, break_in_func - - code = ''' - def func(): - lno = 3 - - def main(): - func() - lno = 7 - ''' - - set_list = [ - break_in_func('func', 'test_module.py'), - ('continue', ), - ('step', ), - ('step', ), - ('step', ), - ('quit', ), - ] - - modules = { 'test_module': code } - run_test(modules, set_list) - - **************************** results ******************************** - - 1: ('line', 2, 'tfunc_import'), ('next',), - 2: ('line', 3, 'tfunc_import'), ('step',), - 3: ('call', 5, 'main'), ('break', ('test_module.py', None, False, None, 'func')), - 4: ('None', 5, 'main'), ('continue',), - 5: ('line', 3, 'func', ({1: 1}, [])), ('step',), - BpNum Temp Enb Hits Ignore Where - 1 no yes 1 0 at test_module.py:2 - 6: ('return', 3, 'func'), ('step',), - 7: ('line', 7, 'main'), ('step',), - 8: ('return', 7, 'main'), ('quit',), - - ************************************************************************* - - """ - def gen(a, b): - try: - while 1: - x = next(a) - y = next(b) - yield x - yield y - except StopIteration: - return - - # Step over the import statement in tfunc_import using 'next' and step - # into main() in test_module. - sl = [('next', ), ('step', )] - sl.extend(set_list) - - test = BaseTestCase() - test.dry_run = True - test.id = lambda : None - test.expect_set = list(gen(repeat(()), iter(sl))) - with create_modules(modules): - with TracerRun(test, skip=skip) as tracer: - tracer.runcall(tfunc_import) - - @contextmanager - def create_modules(modules): - with test.support.temp_cwd(): - sys.path.append(os.getcwd()) - try: - for m in modules: - fname = m + '.py' - with open(fname, 'w') as f: - f.write(textwrap.dedent(modules[m])) - linecache.checkcache(fname) - importlib.invalidate_caches() - yield - finally: - for m in modules: - test.support.forget(m) - sys.path.pop() - - def break_in_func(funcname, fname=__file__, temporary=False, cond=None): - return 'break', (fname, None, temporary, cond, funcname) - - TEST_MODULE = 'test_module_for_bdb' - TEST_MODULE_FNAME = TEST_MODULE + '.py' - def tfunc_import(): - import test_module_for_bdb - test_module_for_bdb.main() - - def tfunc_main(): - lno = 2 - tfunc_first() - tfunc_second() - lno = 5 - lno = 6 - lno = 7 - - def tfunc_first(): - lno = 2 - lno = 3 - lno = 4 - - def tfunc_second(): - lno = 2 - - class BaseTestCase(unittest.TestCase): - """Base class for all tests.""" - - dry_run = dry_run - - def fail(self, msg=None): - # Override fail() to use 'raise from None' to avoid repetition of the - # error message and traceback. - raise self.failureException(msg) from None - - class StateTestCase(BaseTestCase): - """Test the step, next, return, until and quit 'set_' methods.""" - - def test_step(self): - self.expect_set = [ - ('line', 2, 'tfunc_main'), ('step', ), - ('line', 3, 'tfunc_main'), ('step', ), - ('call', 1, 'tfunc_first'), ('step', ), - ('line', 2, 'tfunc_first'), ('quit', ), - ] - with TracerRun(self) as tracer: - tracer.runcall(tfunc_main) - - def test_step_next_on_last_statement(self): - for set_type in ('step', 'next'): - with self.subTest(set_type=set_type): - self.expect_set = [ - ('line', 2, 'tfunc_main'), ('step', ), - ('line', 3, 'tfunc_main'), ('step', ), - ('call', 1, 'tfunc_first'), ('break', (__file__, 3)), - ('None', 1, 'tfunc_first'), ('continue', ), - ('line', 3, 'tfunc_first', ({1:1}, [])), (set_type, ), - ('line', 4, 'tfunc_first'), ('quit', ), - ] - with TracerRun(self) as tracer: - tracer.runcall(tfunc_main) - - def test_next(self): - self.expect_set = [ - ('line', 2, 'tfunc_main'), ('step', ), - ('line', 3, 'tfunc_main'), ('next', ), - ('line', 4, 'tfunc_main'), ('step', ), - ('call', 1, 'tfunc_second'), ('step', ), - ('line', 2, 'tfunc_second'), ('quit', ), - ] - with TracerRun(self) as tracer: - tracer.runcall(tfunc_main) - - def test_next_over_import(self): - code = """ - def main(): - lno = 3 - """ - modules = { TEST_MODULE: code } - with create_modules(modules): - self.expect_set = [ - ('line', 2, 'tfunc_import'), ('next', ), - ('line', 3, 'tfunc_import'), ('quit', ), - ] - with TracerRun(self) as tracer: - tracer.runcall(tfunc_import) - - def test_next_on_plain_statement(self): - # Check that set_next() is equivalent to set_step() on a plain - # statement. - self.expect_set = [ - ('line', 2, 'tfunc_main'), ('step', ), - ('line', 3, 'tfunc_main'), ('step', ), - ('call', 1, 'tfunc_first'), ('next', ), - ('line', 2, 'tfunc_first'), ('quit', ), - ] - with TracerRun(self) as tracer: - tracer.runcall(tfunc_main) - - def test_next_in_caller_frame(self): - # Check that set_next() in the caller frame causes the tracer - # to stop next in the caller frame. - self.expect_set = [ - ('line', 2, 'tfunc_main'), ('step', ), - ('line', 3, 'tfunc_main'), ('step', ), - ('call', 1, 'tfunc_first'), ('up', ), - ('None', 3, 'tfunc_main'), ('next', ), - ('line', 4, 'tfunc_main'), ('quit', ), - ] - with TracerRun(self) as tracer: - tracer.runcall(tfunc_main) - - def test_return(self): - self.expect_set = [ - ('line', 2, 'tfunc_main'), ('step', ), - ('line', 3, 'tfunc_main'), ('step', ), - ('call', 1, 'tfunc_first'), ('step', ), - ('line', 2, 'tfunc_first'), ('return', ), - ('return', 4, 'tfunc_first'), ('step', ), - ('line', 4, 'tfunc_main'), ('quit', ), - ] - with TracerRun(self) as tracer: - tracer.runcall(tfunc_main) - - def test_return_in_caller_frame(self): - self.expect_set = [ - ('line', 2, 'tfunc_main'), ('step', ), - ('line', 3, 'tfunc_main'), ('step', ), - ('call', 1, 'tfunc_first'), ('up', ), - ('None', 3, 'tfunc_main'), ('return', ), - ('return', 7, 'tfunc_main'), ('quit', ), - ] - with TracerRun(self) as tracer: - tracer.runcall(tfunc_main) - - def test_until(self): - self.expect_set = [ - ('line', 2, 'tfunc_main'), ('step', ), - ('line', 3, 'tfunc_main'), ('step', ), - ('call', 1, 'tfunc_first'), ('step', ), - ('line', 2, 'tfunc_first'), ('until', (4, )), - ('line', 4, 'tfunc_first'), ('quit', ), - ] - with TracerRun(self) as tracer: - tracer.runcall(tfunc_main) - - def test_until_with_too_large_count(self): - self.expect_set = [ - ('line', 2, 'tfunc_main'), break_in_func('tfunc_first'), - ('None', 2, 'tfunc_main'), ('continue', ), - ('line', 2, 'tfunc_first', ({1:1}, [])), ('until', (9999, )), - ('return', 4, 'tfunc_first'), ('quit', ), - ] - with TracerRun(self) as tracer: - tracer.runcall(tfunc_main) - - def test_until_in_caller_frame(self): - self.expect_set = [ - ('line', 2, 'tfunc_main'), ('step', ), - ('line', 3, 'tfunc_main'), ('step', ), - ('call', 1, 'tfunc_first'), ('up', ), - ('None', 3, 'tfunc_main'), ('until', (6, )), - ('line', 6, 'tfunc_main'), ('quit', ), - ] - with TracerRun(self) as tracer: - tracer.runcall(tfunc_main) - - def test_skip(self): - # Check that tracing is skipped over the import statement in - # 'tfunc_import()'. - code = """ - def main(): - lno = 3 - """ - modules = { TEST_MODULE: code } - with create_modules(modules): - self.expect_set = [ - ('line', 2, 'tfunc_import'), ('step', ), - ('line', 3, 'tfunc_import'), ('quit', ), - ] - skip = ('importlib*', 'zipimport', 'encodings.*', TEST_MODULE) - with TracerRun(self, skip=skip) as tracer: - tracer.runcall(tfunc_import) - - def test_skip_with_no_name_module(self): - # some frames have `globals` with no `__name__` - # for instance the second frame in this traceback - # exec(compile('raise ValueError()', '', 'exec'), {}) - bdb = Bdb(skip=['anything*']) - self.assertIs(bdb.is_skipped_module(None), False) - - def test_down(self): - # Check that set_down() raises BdbError at the newest frame. - self.expect_set = [ - ('line', 2, 'tfunc_main'), ('down', ), - ] - with TracerRun(self) as tracer: - self.assertRaises(BdbError, tracer.runcall, tfunc_main) - - def test_up(self): - self.expect_set = [ - ('line', 2, 'tfunc_main'), ('step', ), - ('line', 3, 'tfunc_main'), ('step', ), - ('call', 1, 'tfunc_first'), ('up', ), - ('None', 3, 'tfunc_main'), ('quit', ), - ] - with TracerRun(self) as tracer: - tracer.runcall(tfunc_main) - - class BreakpointTestCase(BaseTestCase): - """Test the breakpoint set method.""" - - def test_bp_on_non_existent_module(self): - self.expect_set = [ - ('line', 2, 'tfunc_import'), ('break', ('/non/existent/module.py', 1)) - ] - with TracerRun(self) as tracer: - self.assertRaises(BdbError, tracer.runcall, tfunc_import) - - def test_bp_after_last_statement(self): - code = """ - def main(): - lno = 3 - """ - modules = { TEST_MODULE: code } - with create_modules(modules): - self.expect_set = [ - ('line', 2, 'tfunc_import'), ('break', (TEST_MODULE_FNAME, 4)) - ] - with TracerRun(self) as tracer: - self.assertRaises(BdbError, tracer.runcall, tfunc_import) - - def test_temporary_bp(self): - code = """ - def func(): - lno = 3 - - def main(): - for i in range(2): - func() - """ - modules = { TEST_MODULE: code } - with create_modules(modules): - self.expect_set = [ - ('line', 2, 'tfunc_import'), - break_in_func('func', TEST_MODULE_FNAME, True), - ('None', 2, 'tfunc_import'), - break_in_func('func', TEST_MODULE_FNAME, True), - ('None', 2, 'tfunc_import'), ('continue', ), - ('line', 3, 'func', ({1:1}, [1])), ('continue', ), - ('line', 3, 'func', ({2:1}, [2])), ('quit', ), - ] - with TracerRun(self) as tracer: - tracer.runcall(tfunc_import) - - def test_disabled_temporary_bp(self): - code = """ - def func(): - lno = 3 - - def main(): - for i in range(3): - func() - """ - modules = { TEST_MODULE: code } - with create_modules(modules): - self.expect_set = [ - ('line', 2, 'tfunc_import'), - break_in_func('func', TEST_MODULE_FNAME), - ('None', 2, 'tfunc_import'), - break_in_func('func', TEST_MODULE_FNAME, True), - ('None', 2, 'tfunc_import'), ('disable', (2, )), - ('None', 2, 'tfunc_import'), ('continue', ), - ('line', 3, 'func', ({1:1}, [])), ('enable', (2, )), - ('None', 3, 'func'), ('disable', (1, )), - ('None', 3, 'func'), ('continue', ), - ('line', 3, 'func', ({2:1}, [2])), ('enable', (1, )), - ('None', 3, 'func'), ('continue', ), - ('line', 3, 'func', ({1:2}, [])), ('quit', ), - ] - with TracerRun(self) as tracer: - tracer.runcall(tfunc_import) - - def test_bp_condition(self): - code = """ - def func(a): - lno = 3 - - def main(): - for i in range(3): - func(i) - """ - modules = { TEST_MODULE: code } - with create_modules(modules): - self.expect_set = [ - ('line', 2, 'tfunc_import'), - break_in_func('func', TEST_MODULE_FNAME, False, 'a == 2'), - ('None', 2, 'tfunc_import'), ('continue', ), - ('line', 3, 'func', ({1:3}, [])), ('quit', ), - ] - with TracerRun(self) as tracer: - tracer.runcall(tfunc_import) - - def test_bp_exception_on_condition_evaluation(self): - code = """ - def func(a): - lno = 3 - - def main(): - func(0) - """ - modules = { TEST_MODULE: code } - with create_modules(modules): - self.expect_set = [ - ('line', 2, 'tfunc_import'), - break_in_func('func', TEST_MODULE_FNAME, False, '1 / 0'), - ('None', 2, 'tfunc_import'), ('continue', ), - ('line', 3, 'func', ({1:1}, [])), ('quit', ), - ] - with TracerRun(self) as tracer: - tracer.runcall(tfunc_import) - - def test_bp_ignore_count(self): - code = """ - def func(): - lno = 3 - - def main(): - for i in range(2): - func() - """ - modules = { TEST_MODULE: code } - with create_modules(modules): - self.expect_set = [ - ('line', 2, 'tfunc_import'), - break_in_func('func', TEST_MODULE_FNAME), - ('None', 2, 'tfunc_import'), ('ignore', (1, )), - ('None', 2, 'tfunc_import'), ('continue', ), - ('line', 3, 'func', ({1:2}, [])), ('quit', ), - ] - with TracerRun(self) as tracer: - tracer.runcall(tfunc_import) - - def test_ignore_count_on_disabled_bp(self): - code = """ - def func(): - lno = 3 - - def main(): - for i in range(3): - func() - """ - modules = { TEST_MODULE: code } - with create_modules(modules): - self.expect_set = [ - ('line', 2, 'tfunc_import'), - break_in_func('func', TEST_MODULE_FNAME), - ('None', 2, 'tfunc_import'), - break_in_func('func', TEST_MODULE_FNAME), - ('None', 2, 'tfunc_import'), ('ignore', (1, )), - ('None', 2, 'tfunc_import'), ('disable', (1, )), - ('None', 2, 'tfunc_import'), ('continue', ), - ('line', 3, 'func', ({2:1}, [])), ('enable', (1, )), - ('None', 3, 'func'), ('continue', ), - ('line', 3, 'func', ({2:2}, [])), ('continue', ), - ('line', 3, 'func', ({1:2}, [])), ('quit', ), - ] - with TracerRun(self) as tracer: - tracer.runcall(tfunc_import) - - def test_clear_two_bp_on_same_line(self): - code = """ - def func(): - lno = 3 - lno = 4 - - def main(): - for i in range(3): - func() - """ - modules = { TEST_MODULE: code } - with create_modules(modules): - self.expect_set = [ - ('line', 2, 'tfunc_import'), ('break', (TEST_MODULE_FNAME, 3)), - ('None', 2, 'tfunc_import'), ('break', (TEST_MODULE_FNAME, 3)), - ('None', 2, 'tfunc_import'), ('break', (TEST_MODULE_FNAME, 4)), - ('None', 2, 'tfunc_import'), ('continue', ), - ('line', 3, 'func', ({1:1}, [])), ('continue', ), - ('line', 4, 'func', ({3:1}, [])), ('clear', (TEST_MODULE_FNAME, 3)), - ('None', 4, 'func'), ('continue', ), - ('line', 4, 'func', ({3:2}, [])), ('quit', ), - ] - with TracerRun(self) as tracer: - tracer.runcall(tfunc_import) - - def test_clear_at_no_bp(self): - self.expect_set = [ - ('line', 2, 'tfunc_import'), ('clear', (__file__, 1)) - ] - with TracerRun(self) as tracer: - self.assertRaises(BdbError, tracer.runcall, tfunc_import) - - class RunTestCase(BaseTestCase): - """Test run, runeval and set_trace.""" - - def test_run_step(self): - # Check that the bdb 'run' method stops at the first line event. - code = """ - lno = 2 - """ - self.expect_set = [ - ('line', 2, ''), ('step', ), - ('return', 2, ''), ('quit', ), - ] - with TracerRun(self) as tracer: - tracer.run(compile(textwrap.dedent(code), '', 'exec')) - - def test_runeval_step(self): - # Test bdb 'runeval'. - code = """ - def main(): - lno = 3 - """ - modules = { TEST_MODULE: code } - with create_modules(modules): - self.expect_set = [ - ('line', 1, ''), ('step', ), - ('call', 2, 'main'), ('step', ), - ('line', 3, 'main'), ('step', ), - ('return', 3, 'main'), ('step', ), - ('return', 1, ''), ('quit', ), - ] - import test_module_for_bdb - with TracerRun(self) as tracer: - tracer.runeval('test_module_for_bdb.main()', globals(), locals()) - - class IssuesTestCase(BaseTestCase): - """Test fixed bdb issues.""" - - def test_step_at_return_with_no_trace_in_caller(self): - # Issue #13183. - # Check that the tracer does step into the caller frame when the - # trace function is not set in that frame. - code_1 = """ - from test_module_for_bdb_2 import func - def main(): - func() - lno = 5 - """ - code_2 = """ - def func(): - lno = 3 - """ - modules = { - TEST_MODULE: code_1, - 'test_module_for_bdb_2': code_2, - } - with create_modules(modules): - self.expect_set = [ - ('line', 2, 'tfunc_import'), - break_in_func('func', 'test_module_for_bdb_2.py'), - ('None', 2, 'tfunc_import'), ('continue', ), - ('line', 3, 'func', ({1:1}, [])), ('step', ), - ('return', 3, 'func'), ('step', ), - ('line', 5, 'main'), ('quit', ), - ] - with TracerRun(self) as tracer: - tracer.runcall(tfunc_import) - - def test_next_until_return_in_generator(self): - # Issue #16596. - # Check that set_next(), set_until() and set_return() do not treat the - # `yield` and `yield from` statements as if they were returns and stop - # instead in the current frame. - code = """ - def test_gen(): - yield 0 - lno = 4 - return 123 - - def main(): - it = test_gen() - next(it) - next(it) - lno = 11 - """ - modules = { TEST_MODULE: code } - for set_type in ('next', 'until', 'return'): - with self.subTest(set_type=set_type): - with create_modules(modules): - self.expect_set = [ - ('line', 2, 'tfunc_import'), - break_in_func('test_gen', TEST_MODULE_FNAME), - ('None', 2, 'tfunc_import'), ('continue', ), - ('line', 3, 'test_gen', ({1:1}, [])), (set_type, ), - ] - - if set_type == 'return': - self.expect_set.extend( - [('exception', 10, 'main', StopIteration), ('step',), - ('return', 10, 'main'), ('quit', ), - ] - ) - else: - self.expect_set.extend( - [('line', 4, 'test_gen'), ('quit', ),] - ) - with TracerRun(self) as tracer: - tracer.runcall(tfunc_import) - - def test_next_command_in_generator_for_loop(self): - # Issue #16596. - code = """ - def test_gen(): - yield 0 - lno = 4 - yield 1 - return 123 - - def main(): - for i in test_gen(): - lno = 10 - lno = 11 - """ - modules = { TEST_MODULE: code } - with create_modules(modules): - self.expect_set = [ - ('line', 2, 'tfunc_import'), - break_in_func('test_gen', TEST_MODULE_FNAME), - ('None', 2, 'tfunc_import'), ('continue', ), - ('line', 3, 'test_gen', ({1:1}, [])), ('next', ), - ('line', 4, 'test_gen'), ('next', ), - ('line', 5, 'test_gen'), ('next', ), - ('line', 6, 'test_gen'), ('next', ), - ('exception', 9, 'main', StopIteration), ('step', ), - ('line', 11, 'main'), ('quit', ), - - ] - with TracerRun(self) as tracer: - tracer.runcall(tfunc_import) - - def test_next_command_in_generator_with_subiterator(self): - # Issue #16596. - code = """ - def test_subgen(): - yield 0 - return 123 - - def test_gen(): - x = yield from test_subgen() - return 456 - - def main(): - for i in test_gen(): - lno = 12 - lno = 13 - """ - modules = { TEST_MODULE: code } - with create_modules(modules): - self.expect_set = [ - ('line', 2, 'tfunc_import'), - break_in_func('test_gen', TEST_MODULE_FNAME), - ('None', 2, 'tfunc_import'), ('continue', ), - ('line', 7, 'test_gen', ({1:1}, [])), ('next', ), - ('line', 8, 'test_gen'), ('next', ), - ('exception', 11, 'main', StopIteration), ('step', ), - ('line', 13, 'main'), ('quit', ), - - ] - with TracerRun(self) as tracer: - tracer.runcall(tfunc_import) - - def test_return_command_in_generator_with_subiterator(self): - # Issue #16596. - code = """ - def test_subgen(): - yield 0 - return 123 - - def test_gen(): - x = yield from test_subgen() - return 456 - - def main(): - for i in test_gen(): - lno = 12 - lno = 13 - """ - modules = { TEST_MODULE: code } - with create_modules(modules): - self.expect_set = [ - ('line', 2, 'tfunc_import'), - break_in_func('test_subgen', TEST_MODULE_FNAME), - ('None', 2, 'tfunc_import'), ('continue', ), - ('line', 3, 'test_subgen', ({1:1}, [])), ('return', ), - ('exception', 7, 'test_gen', StopIteration), ('return', ), - ('exception', 11, 'main', StopIteration), ('step', ), - ('line', 13, 'main'), ('quit', ), - - ] - with TracerRun(self) as tracer: - tracer.runcall(tfunc_import) - - def test_main(): - test.support.run_unittest( - StateTestCase, - RunTestCase, - BreakpointTestCase, - IssuesTestCase, - ) - - if __name__ == "__main__": - test_main() diff --git a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_bigaddrspace.yaml b/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_bigaddrspace.yaml deleted file mode 100644 index 950ed5c82..000000000 --- a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_bigaddrspace.yaml +++ /dev/null @@ -1,102 +0,0 @@ -python: | - """ - These tests are meant to exercise that requests to create objects bigger - than what the address space allows are properly met with an OverflowError - (rather than crash weirdly). - - Primarily, this means 32-bit builds with at least 2 GiB of available memory. - You need to pass the -M option to regrtest (e.g. "-M 2.1G") for tests to - be enabled. - """ - - from test import support - from test.support import bigaddrspacetest, MAX_Py_ssize_t - - import unittest - import operator - import sys - - - class BytesTest(unittest.TestCase): - - @bigaddrspacetest - def test_concat(self): - # Allocate a bytestring that's near the maximum size allowed by - # the address space, and then try to build a new, larger one through - # concatenation. - try: - x = b"x" * (MAX_Py_ssize_t - 128) - self.assertRaises(OverflowError, operator.add, x, b"x" * 128) - finally: - x = None - - @bigaddrspacetest - def test_optimized_concat(self): - try: - x = b"x" * (MAX_Py_ssize_t - 128) - - with self.assertRaises(OverflowError) as cm: - # this statement used a fast path in ceval.c - x = x + b"x" * 128 - - with self.assertRaises(OverflowError) as cm: - # this statement used a fast path in ceval.c - x += b"x" * 128 - finally: - x = None - - @bigaddrspacetest - def test_repeat(self): - try: - x = b"x" * (MAX_Py_ssize_t - 128) - self.assertRaises(OverflowError, operator.mul, x, 128) - finally: - x = None - - - class StrTest(unittest.TestCase): - - unicodesize = 2 if sys.maxunicode < 65536 else 4 - - @bigaddrspacetest - def test_concat(self): - try: - # Create a string that would fill almost the address space - x = "x" * int(MAX_Py_ssize_t // (1.1 * self.unicodesize)) - # Unicode objects trigger MemoryError in case an operation that's - # going to cause a size overflow is executed - self.assertRaises(MemoryError, operator.add, x, x) - finally: - x = None - - @bigaddrspacetest - def test_optimized_concat(self): - try: - x = "x" * int(MAX_Py_ssize_t // (1.1 * self.unicodesize)) - - with self.assertRaises(MemoryError) as cm: - # this statement uses a fast path in ceval.c - x = x + x - - with self.assertRaises(MemoryError) as cm: - # this statement uses a fast path in ceval.c - x += x - finally: - x = None - - @bigaddrspacetest - def test_repeat(self): - try: - x = "x" * int(MAX_Py_ssize_t // (1.1 * self.unicodesize)) - self.assertRaises(MemoryError, operator.mul, x, 2) - finally: - x = None - - - def test_main(): - support.run_unittest(BytesTest, StrTest) - - if __name__ == '__main__': - if len(sys.argv) > 1: - support.set_memlimit(sys.argv[1]) - test_main() diff --git a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_bigmem.yaml b/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_bigmem.yaml deleted file mode 100644 index 6fe7c75c8..000000000 --- a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_bigmem.yaml +++ /dev/null @@ -1,1258 +0,0 @@ -python: | - """Bigmem tests - tests for the 32-bit boundary in containers. - - These tests try to exercise the 32-bit boundary that is sometimes, if - rarely, exceeded in practice, but almost never tested. They are really only - meaningful on 64-bit builds on machines with a *lot* of memory, but the - tests are always run, usually with very low memory limits to make sure the - tests themselves don't suffer from bitrot. To run them for real, pass a - high memory limit to regrtest, with the -M option. - """ - - from test import support - from test.support import bigmemtest, _1G, _2G, _4G - - import unittest - import operator - import sys - - # These tests all use one of the bigmemtest decorators to indicate how much - # memory they use and how much memory they need to be even meaningful. The - # decorators take two arguments: a 'memuse' indicator declaring - # (approximate) bytes per size-unit the test will use (at peak usage), and a - # 'minsize' indicator declaring a minimum *useful* size. A test that - # allocates a bytestring to test various operations near the end will have a - # minsize of at least 2Gb (or it wouldn't reach the 32-bit limit, so the - # test wouldn't be very useful) and a memuse of 1 (one byte per size-unit, - # if it allocates only one big string at a time.) - # - # When run with a memory limit set, both decorators skip tests that need - # more memory than available to be meaningful. The precisionbigmemtest will - # always pass minsize as size, even if there is much more memory available. - # The bigmemtest decorator will scale size upward to fill available memory. - # - # Bigmem testing houserules: - # - # - Try not to allocate too many large objects. It's okay to rely on - # refcounting semantics, and don't forget that 's = create_largestring()' - # doesn't release the old 's' (if it exists) until well after its new - # value has been created. Use 'del s' before the create_largestring call. - # - # - Do *not* compare large objects using assertEqual, assertIn or similar. - # It's a lengthy operation and the errormessage will be utterly useless - # due to its size. To make sure whether a result has the right contents, - # better to use the strip or count methods, or compare meaningful slices. - # - # - Don't forget to test for large indices, offsets and results and such, - # in addition to large sizes. Anything that probes the 32-bit boundary. - # - # - When repeating an object (say, a substring, or a small list) to create - # a large object, make the subobject of a length that is not a power of - # 2. That way, int-wrapping problems are more easily detected. - # - # - Despite the bigmemtest decorator, all tests will actually be called - # with a much smaller number too, in the normal test run (5Kb currently.) - # This is so the tests themselves get frequent testing. - # Consequently, always make all large allocations based on the - # passed-in 'size', and don't rely on the size being very large. Also, - # memuse-per-size should remain sane (less than a few thousand); if your - # test uses more, adjust 'size' upward, instead. - - # BEWARE: it seems that one failing test can yield other subsequent tests to - # fail as well. I do not know whether it is due to memory fragmentation - # issues, or other specifics of the platform malloc() routine. - - ascii_char_size = 1 - ucs2_char_size = 2 - ucs4_char_size = 4 - pointer_size = 4 if sys.maxsize < 2**32 else 8 - - - class BaseStrTest: - - def _test_capitalize(self, size): - _ = self.from_latin1 - SUBSTR = self.from_latin1(' abc def ghi') - s = _('-') * size + SUBSTR - caps = s.capitalize() - self.assertEqual(caps[-len(SUBSTR):], - SUBSTR.capitalize()) - self.assertEqual(caps.lstrip(_('-')), SUBSTR) - - @bigmemtest(size=_2G + 10, memuse=1) - def test_center(self, size): - SUBSTR = self.from_latin1(' abc def ghi') - s = SUBSTR.center(size) - self.assertEqual(len(s), size) - lpadsize = rpadsize = (len(s) - len(SUBSTR)) // 2 - if len(s) % 2: - lpadsize += 1 - self.assertEqual(s[lpadsize:-rpadsize], SUBSTR) - self.assertEqual(s.strip(), SUBSTR.strip()) - - @bigmemtest(size=_2G, memuse=2) - def test_count(self, size): - _ = self.from_latin1 - SUBSTR = _(' abc def ghi') - s = _('.') * size + SUBSTR - self.assertEqual(s.count(_('.')), size) - s += _('.') - self.assertEqual(s.count(_('.')), size + 1) - self.assertEqual(s.count(_(' ')), 3) - self.assertEqual(s.count(_('i')), 1) - self.assertEqual(s.count(_('j')), 0) - - @bigmemtest(size=_2G, memuse=2) - def test_endswith(self, size): - _ = self.from_latin1 - SUBSTR = _(' abc def ghi') - s = _('-') * size + SUBSTR - self.assertTrue(s.endswith(SUBSTR)) - self.assertTrue(s.endswith(s)) - s2 = _('...') + s - self.assertTrue(s2.endswith(s)) - self.assertFalse(s.endswith(_('a') + SUBSTR)) - self.assertFalse(SUBSTR.endswith(s)) - - @bigmemtest(size=_2G + 10, memuse=2) - def test_expandtabs(self, size): - _ = self.from_latin1 - s = _('-') * size - tabsize = 8 - self.assertTrue(s.expandtabs() == s) - del s - slen, remainder = divmod(size, tabsize) - s = _(' \t') * slen - s = s.expandtabs(tabsize) - self.assertEqual(len(s), size - remainder) - self.assertEqual(len(s.strip(_(' '))), 0) - - @bigmemtest(size=_2G, memuse=2) - def test_find(self, size): - _ = self.from_latin1 - SUBSTR = _(' abc def ghi') - sublen = len(SUBSTR) - s = _('').join([SUBSTR, _('-') * size, SUBSTR]) - self.assertEqual(s.find(_(' ')), 0) - self.assertEqual(s.find(SUBSTR), 0) - self.assertEqual(s.find(_(' '), sublen), sublen + size) - self.assertEqual(s.find(SUBSTR, len(SUBSTR)), sublen + size) - self.assertEqual(s.find(_('i')), SUBSTR.find(_('i'))) - self.assertEqual(s.find(_('i'), sublen), - sublen + size + SUBSTR.find(_('i'))) - self.assertEqual(s.find(_('i'), size), - sublen + size + SUBSTR.find(_('i'))) - self.assertEqual(s.find(_('j')), -1) - - @bigmemtest(size=_2G, memuse=2) - def test_index(self, size): - _ = self.from_latin1 - SUBSTR = _(' abc def ghi') - sublen = len(SUBSTR) - s = _('').join([SUBSTR, _('-') * size, SUBSTR]) - self.assertEqual(s.index(_(' ')), 0) - self.assertEqual(s.index(SUBSTR), 0) - self.assertEqual(s.index(_(' '), sublen), sublen + size) - self.assertEqual(s.index(SUBSTR, sublen), sublen + size) - self.assertEqual(s.index(_('i')), SUBSTR.index(_('i'))) - self.assertEqual(s.index(_('i'), sublen), - sublen + size + SUBSTR.index(_('i'))) - self.assertEqual(s.index(_('i'), size), - sublen + size + SUBSTR.index(_('i'))) - self.assertRaises(ValueError, s.index, _('j')) - - @bigmemtest(size=_2G, memuse=2) - def test_isalnum(self, size): - _ = self.from_latin1 - SUBSTR = _('123456') - s = _('a') * size + SUBSTR - self.assertTrue(s.isalnum()) - s += _('.') - self.assertFalse(s.isalnum()) - - @bigmemtest(size=_2G, memuse=2) - def test_isalpha(self, size): - _ = self.from_latin1 - SUBSTR = _('zzzzzzz') - s = _('a') * size + SUBSTR - self.assertTrue(s.isalpha()) - s += _('.') - self.assertFalse(s.isalpha()) - - @bigmemtest(size=_2G, memuse=2) - def test_isdigit(self, size): - _ = self.from_latin1 - SUBSTR = _('123456') - s = _('9') * size + SUBSTR - self.assertTrue(s.isdigit()) - s += _('z') - self.assertFalse(s.isdigit()) - - @bigmemtest(size=_2G, memuse=2) - def test_islower(self, size): - _ = self.from_latin1 - chars = _(''.join( - chr(c) for c in range(255) if not chr(c).isupper())) - repeats = size // len(chars) + 2 - s = chars * repeats - self.assertTrue(s.islower()) - s += _('A') - self.assertFalse(s.islower()) - - @bigmemtest(size=_2G, memuse=2) - def test_isspace(self, size): - _ = self.from_latin1 - whitespace = _(' \f\n\r\t\v') - repeats = size // len(whitespace) + 2 - s = whitespace * repeats - self.assertTrue(s.isspace()) - s += _('j') - self.assertFalse(s.isspace()) - - @bigmemtest(size=_2G, memuse=2) - def test_istitle(self, size): - _ = self.from_latin1 - SUBSTR = _('123456') - s = _('').join([_('A'), _('a') * size, SUBSTR]) - self.assertTrue(s.istitle()) - s += _('A') - self.assertTrue(s.istitle()) - s += _('aA') - self.assertFalse(s.istitle()) - - @bigmemtest(size=_2G, memuse=2) - def test_isupper(self, size): - _ = self.from_latin1 - chars = _(''.join( - chr(c) for c in range(255) if not chr(c).islower())) - repeats = size // len(chars) + 2 - s = chars * repeats - self.assertTrue(s.isupper()) - s += _('a') - self.assertFalse(s.isupper()) - - @bigmemtest(size=_2G, memuse=2) - def test_join(self, size): - _ = self.from_latin1 - s = _('A') * size - x = s.join([_('aaaaa'), _('bbbbb')]) - self.assertEqual(x.count(_('a')), 5) - self.assertEqual(x.count(_('b')), 5) - self.assertTrue(x.startswith(_('aaaaaA'))) - self.assertTrue(x.endswith(_('Abbbbb'))) - - @bigmemtest(size=_2G + 10, memuse=1) - def test_ljust(self, size): - _ = self.from_latin1 - SUBSTR = _(' abc def ghi') - s = SUBSTR.ljust(size) - self.assertTrue(s.startswith(SUBSTR + _(' '))) - self.assertEqual(len(s), size) - self.assertEqual(s.strip(), SUBSTR.strip()) - - @bigmemtest(size=_2G + 10, memuse=2) - def test_lower(self, size): - _ = self.from_latin1 - s = _('A') * size - s = s.lower() - self.assertEqual(len(s), size) - self.assertEqual(s.count(_('a')), size) - - @bigmemtest(size=_2G + 10, memuse=1) - def test_lstrip(self, size): - _ = self.from_latin1 - SUBSTR = _('abc def ghi') - s = SUBSTR.rjust(size) - self.assertEqual(len(s), size) - self.assertEqual(s.lstrip(), SUBSTR.lstrip()) - del s - s = SUBSTR.ljust(size) - self.assertEqual(len(s), size) - # Type-specific optimization - if isinstance(s, (str, bytes)): - stripped = s.lstrip() - self.assertTrue(stripped is s) - - @bigmemtest(size=_2G + 10, memuse=2) - def test_replace(self, size): - _ = self.from_latin1 - replacement = _('a') - s = _(' ') * size - s = s.replace(_(' '), replacement) - self.assertEqual(len(s), size) - self.assertEqual(s.count(replacement), size) - s = s.replace(replacement, _(' '), size - 4) - self.assertEqual(len(s), size) - self.assertEqual(s.count(replacement), 4) - self.assertEqual(s[-10:], _(' aaaa')) - - @bigmemtest(size=_2G, memuse=2) - def test_rfind(self, size): - _ = self.from_latin1 - SUBSTR = _(' abc def ghi') - sublen = len(SUBSTR) - s = _('').join([SUBSTR, _('-') * size, SUBSTR]) - self.assertEqual(s.rfind(_(' ')), sublen + size + SUBSTR.rfind(_(' '))) - self.assertEqual(s.rfind(SUBSTR), sublen + size) - self.assertEqual(s.rfind(_(' '), 0, size), SUBSTR.rfind(_(' '))) - self.assertEqual(s.rfind(SUBSTR, 0, sublen + size), 0) - self.assertEqual(s.rfind(_('i')), sublen + size + SUBSTR.rfind(_('i'))) - self.assertEqual(s.rfind(_('i'), 0, sublen), SUBSTR.rfind(_('i'))) - self.assertEqual(s.rfind(_('i'), 0, sublen + size), - SUBSTR.rfind(_('i'))) - self.assertEqual(s.rfind(_('j')), -1) - - @bigmemtest(size=_2G, memuse=2) - def test_rindex(self, size): - _ = self.from_latin1 - SUBSTR = _(' abc def ghi') - sublen = len(SUBSTR) - s = _('').join([SUBSTR, _('-') * size, SUBSTR]) - self.assertEqual(s.rindex(_(' ')), - sublen + size + SUBSTR.rindex(_(' '))) - self.assertEqual(s.rindex(SUBSTR), sublen + size) - self.assertEqual(s.rindex(_(' '), 0, sublen + size - 1), - SUBSTR.rindex(_(' '))) - self.assertEqual(s.rindex(SUBSTR, 0, sublen + size), 0) - self.assertEqual(s.rindex(_('i')), - sublen + size + SUBSTR.rindex(_('i'))) - self.assertEqual(s.rindex(_('i'), 0, sublen), SUBSTR.rindex(_('i'))) - self.assertEqual(s.rindex(_('i'), 0, sublen + size), - SUBSTR.rindex(_('i'))) - self.assertRaises(ValueError, s.rindex, _('j')) - - @bigmemtest(size=_2G + 10, memuse=1) - def test_rjust(self, size): - _ = self.from_latin1 - SUBSTR = _(' abc def ghi') - s = SUBSTR.ljust(size) - self.assertTrue(s.startswith(SUBSTR + _(' '))) - self.assertEqual(len(s), size) - self.assertEqual(s.strip(), SUBSTR.strip()) - - @bigmemtest(size=_2G + 10, memuse=1) - def test_rstrip(self, size): - _ = self.from_latin1 - SUBSTR = _(' abc def ghi') - s = SUBSTR.ljust(size) - self.assertEqual(len(s), size) - self.assertEqual(s.rstrip(), SUBSTR.rstrip()) - del s - s = SUBSTR.rjust(size) - self.assertEqual(len(s), size) - # Type-specific optimization - if isinstance(s, (str, bytes)): - stripped = s.rstrip() - self.assertTrue(stripped is s) - - # The test takes about size bytes to build a string, and then about - # sqrt(size) substrings of sqrt(size) in size and a list to - # hold sqrt(size) items. It's close but just over 2x size. - @bigmemtest(size=_2G, memuse=2.1) - def test_split_small(self, size): - _ = self.from_latin1 - # Crudely calculate an estimate so that the result of s.split won't - # take up an inordinate amount of memory - chunksize = int(size ** 0.5 + 2) - SUBSTR = _('a') + _(' ') * chunksize - s = SUBSTR * chunksize - l = s.split() - self.assertEqual(len(l), chunksize) - expected = _('a') - for item in l: - self.assertEqual(item, expected) - del l - l = s.split(_('a')) - self.assertEqual(len(l), chunksize + 1) - expected = _(' ') * chunksize - for item in filter(None, l): - self.assertEqual(item, expected) - - # Allocates a string of twice size (and briefly two) and a list of - # size. Because of internal affairs, the s.split() call produces a - # list of size times the same one-character string, so we only - # suffer for the list size. (Otherwise, it'd cost another 48 times - # size in bytes!) Nevertheless, a list of size takes - # 8*size bytes. - @bigmemtest(size=_2G + 5, memuse=ascii_char_size * 2 + pointer_size) - def test_split_large(self, size): - _ = self.from_latin1 - s = _(' a') * size + _(' ') - l = s.split() - self.assertEqual(len(l), size) - self.assertEqual(set(l), set([_('a')])) - del l - l = s.split(_('a')) - self.assertEqual(len(l), size + 1) - self.assertEqual(set(l), set([_(' ')])) - - @bigmemtest(size=_2G, memuse=2.1) - def test_splitlines(self, size): - _ = self.from_latin1 - # Crudely calculate an estimate so that the result of s.split won't - # take up an inordinate amount of memory - chunksize = int(size ** 0.5 + 2) // 2 - SUBSTR = _(' ') * chunksize + _('\n') + _(' ') * chunksize + _('\r\n') - s = SUBSTR * (chunksize * 2) - l = s.splitlines() - self.assertEqual(len(l), chunksize * 4) - expected = _(' ') * chunksize - for item in l: - self.assertEqual(item, expected) - - @bigmemtest(size=_2G, memuse=2) - def test_startswith(self, size): - _ = self.from_latin1 - SUBSTR = _(' abc def ghi') - s = _('-') * size + SUBSTR - self.assertTrue(s.startswith(s)) - self.assertTrue(s.startswith(_('-') * size)) - self.assertFalse(s.startswith(SUBSTR)) - - @bigmemtest(size=_2G, memuse=1) - def test_strip(self, size): - _ = self.from_latin1 - SUBSTR = _(' abc def ghi ') - s = SUBSTR.rjust(size) - self.assertEqual(len(s), size) - self.assertEqual(s.strip(), SUBSTR.strip()) - del s - s = SUBSTR.ljust(size) - self.assertEqual(len(s), size) - self.assertEqual(s.strip(), SUBSTR.strip()) - - def _test_swapcase(self, size): - _ = self.from_latin1 - SUBSTR = _("aBcDeFG12.'\xa9\x00") - sublen = len(SUBSTR) - repeats = size // sublen + 2 - s = SUBSTR * repeats - s = s.swapcase() - self.assertEqual(len(s), sublen * repeats) - self.assertEqual(s[:sublen * 3], SUBSTR.swapcase() * 3) - self.assertEqual(s[-sublen * 3:], SUBSTR.swapcase() * 3) - - def _test_title(self, size): - _ = self.from_latin1 - SUBSTR = _('SpaaHAaaAaham') - s = SUBSTR * (size // len(SUBSTR) + 2) - s = s.title() - self.assertTrue(s.startswith((SUBSTR * 3).title())) - self.assertTrue(s.endswith(SUBSTR.lower() * 3)) - - @bigmemtest(size=_2G, memuse=2) - def test_translate(self, size): - _ = self.from_latin1 - SUBSTR = _('aZz.z.Aaz.') - trans = bytes.maketrans(b'.aZ', b'-!$') - sublen = len(SUBSTR) - repeats = size // sublen + 2 - s = SUBSTR * repeats - s = s.translate(trans) - self.assertEqual(len(s), repeats * sublen) - self.assertEqual(s[:sublen], SUBSTR.translate(trans)) - self.assertEqual(s[-sublen:], SUBSTR.translate(trans)) - self.assertEqual(s.count(_('.')), 0) - self.assertEqual(s.count(_('!')), repeats * 2) - self.assertEqual(s.count(_('z')), repeats * 3) - - @bigmemtest(size=_2G + 5, memuse=2) - def test_upper(self, size): - _ = self.from_latin1 - s = _('a') * size - s = s.upper() - self.assertEqual(len(s), size) - self.assertEqual(s.count(_('A')), size) - - @bigmemtest(size=_2G + 20, memuse=1) - def test_zfill(self, size): - _ = self.from_latin1 - SUBSTR = _('-568324723598234') - s = SUBSTR.zfill(size) - self.assertTrue(s.endswith(_('0') + SUBSTR[1:])) - self.assertTrue(s.startswith(_('-0'))) - self.assertEqual(len(s), size) - self.assertEqual(s.count(_('0')), size - len(SUBSTR)) - - # This test is meaningful even with size < 2G, as long as the - # doubled string is > 2G (but it tests more if both are > 2G :) - @bigmemtest(size=_1G + 2, memuse=3) - def test_concat(self, size): - _ = self.from_latin1 - s = _('.') * size - self.assertEqual(len(s), size) - s = s + s - self.assertEqual(len(s), size * 2) - self.assertEqual(s.count(_('.')), size * 2) - - # This test is meaningful even with size < 2G, as long as the - # repeated string is > 2G (but it tests more if both are > 2G :) - @bigmemtest(size=_1G + 2, memuse=3) - def test_repeat(self, size): - _ = self.from_latin1 - s = _('.') * size - self.assertEqual(len(s), size) - s = s * 2 - self.assertEqual(len(s), size * 2) - self.assertEqual(s.count(_('.')), size * 2) - - @bigmemtest(size=_2G + 20, memuse=2) - def test_slice_and_getitem(self, size): - _ = self.from_latin1 - SUBSTR = _('0123456789') - sublen = len(SUBSTR) - s = SUBSTR * (size // sublen) - stepsize = len(s) // 100 - stepsize = stepsize - (stepsize % sublen) - for i in range(0, len(s) - stepsize, stepsize): - self.assertEqual(s[i], SUBSTR[0]) - self.assertEqual(s[i:i + sublen], SUBSTR) - self.assertEqual(s[i:i + sublen:2], SUBSTR[::2]) - if i > 0: - self.assertEqual(s[i + sublen - 1:i - 1:-3], - SUBSTR[sublen::-3]) - # Make sure we do some slicing and indexing near the end of the - # string, too. - self.assertEqual(s[len(s) - 1], SUBSTR[-1]) - self.assertEqual(s[-1], SUBSTR[-1]) - self.assertEqual(s[len(s) - 10], SUBSTR[0]) - self.assertEqual(s[-sublen], SUBSTR[0]) - self.assertEqual(s[len(s):], _('')) - self.assertEqual(s[len(s) - 1:], SUBSTR[-1:]) - self.assertEqual(s[-1:], SUBSTR[-1:]) - self.assertEqual(s[len(s) - sublen:], SUBSTR) - self.assertEqual(s[-sublen:], SUBSTR) - self.assertEqual(len(s[:]), len(s)) - self.assertEqual(len(s[:len(s) - 5]), len(s) - 5) - self.assertEqual(len(s[5:-5]), len(s) - 10) - - self.assertRaises(IndexError, operator.getitem, s, len(s)) - self.assertRaises(IndexError, operator.getitem, s, len(s) + 1) - self.assertRaises(IndexError, operator.getitem, s, len(s) + 1<<31) - - @bigmemtest(size=_2G, memuse=2) - def test_contains(self, size): - _ = self.from_latin1 - SUBSTR = _('0123456789') - edge = _('-') * (size // 2) - s = _('').join([edge, SUBSTR, edge]) - del edge - self.assertTrue(SUBSTR in s) - self.assertFalse(SUBSTR * 2 in s) - self.assertTrue(_('-') in s) - self.assertFalse(_('a') in s) - s += _('a') - self.assertTrue(_('a') in s) - - @bigmemtest(size=_2G + 10, memuse=2) - def test_compare(self, size): - _ = self.from_latin1 - s1 = _('-') * size - s2 = _('-') * size - self.assertTrue(s1 == s2) - del s2 - s2 = s1 + _('a') - self.assertFalse(s1 == s2) - del s2 - s2 = _('.') * size - self.assertFalse(s1 == s2) - - @bigmemtest(size=_2G + 10, memuse=1) - def test_hash(self, size): - # Not sure if we can do any meaningful tests here... Even if we - # start relying on the exact algorithm used, the result will be - # different depending on the size of the C 'long int'. Even this - # test is dodgy (there's no *guarantee* that the two things should - # have a different hash, even if they, in the current - # implementation, almost always do.) - _ = self.from_latin1 - s = _('\x00') * size - h1 = hash(s) - del s - s = _('\x00') * (size + 1) - self.assertNotEqual(h1, hash(s)) - - - class StrTest(unittest.TestCase, BaseStrTest): - - def from_latin1(self, s): - return s - - def basic_encode_test(self, size, enc, c='.', expectedsize=None): - if expectedsize is None: - expectedsize = size - try: - s = c * size - self.assertEqual(len(s.encode(enc)), expectedsize) - finally: - s = None - - def setUp(self): - # HACK: adjust memory use of tests inherited from BaseStrTest - # according to character size. - self._adjusted = {} - for name in dir(BaseStrTest): - if not name.startswith('test_'): - continue - meth = getattr(type(self), name) - try: - memuse = meth.memuse - except AttributeError: - continue - meth.memuse = ascii_char_size * memuse - self._adjusted[name] = memuse - - def tearDown(self): - for name, memuse in self._adjusted.items(): - getattr(type(self), name).memuse = memuse - - @bigmemtest(size=_2G, memuse=ucs4_char_size * 3 + ascii_char_size * 2) - def test_capitalize(self, size): - self._test_capitalize(size) - - @bigmemtest(size=_2G, memuse=ucs4_char_size * 3 + ascii_char_size * 2) - def test_title(self, size): - self._test_title(size) - - @bigmemtest(size=_2G, memuse=ucs4_char_size * 3 + ascii_char_size * 2) - def test_swapcase(self, size): - self._test_swapcase(size) - - # Many codecs convert to the legacy representation first, explaining - # why we add 'ucs4_char_size' to the 'memuse' below. - - @bigmemtest(size=_2G + 2, memuse=ascii_char_size + 1) - def test_encode(self, size): - return self.basic_encode_test(size, 'utf-8') - - @bigmemtest(size=_4G // 6 + 2, memuse=ascii_char_size + ucs4_char_size + 1) - def test_encode_raw_unicode_escape(self, size): - try: - return self.basic_encode_test(size, 'raw_unicode_escape') - except MemoryError: - pass # acceptable on 32-bit - - @bigmemtest(size=_4G // 5 + 70, memuse=ascii_char_size + 8 + 1) - def test_encode_utf7(self, size): - try: - return self.basic_encode_test(size, 'utf7') - except MemoryError: - pass # acceptable on 32-bit - - @bigmemtest(size=_4G // 4 + 5, memuse=ascii_char_size + ucs4_char_size + 4) - def test_encode_utf32(self, size): - try: - return self.basic_encode_test(size, 'utf32', expectedsize=4 * size + 4) - except MemoryError: - pass # acceptable on 32-bit - - @bigmemtest(size=_2G - 1, memuse=ascii_char_size + 1) - def test_encode_ascii(self, size): - return self.basic_encode_test(size, 'ascii', c='A') - - # str % (...) uses a Py_UCS4 intermediate representation - - @bigmemtest(size=_2G + 10, memuse=ascii_char_size * 2 + ucs4_char_size) - def test_format(self, size): - s = '-' * size - sf = '%s' % (s,) - self.assertTrue(s == sf) - del sf - sf = '..%s..' % (s,) - self.assertEqual(len(sf), len(s) + 4) - self.assertTrue(sf.startswith('..-')) - self.assertTrue(sf.endswith('-..')) - del s, sf - - size //= 2 - edge = '-' * size - s = ''.join([edge, '%s', edge]) - del edge - s = s % '...' - self.assertEqual(len(s), size * 2 + 3) - self.assertEqual(s.count('.'), 3) - self.assertEqual(s.count('-'), size * 2) - - @bigmemtest(size=_2G + 10, memuse=ascii_char_size * 2) - def test_repr_small(self, size): - s = '-' * size - s = repr(s) - self.assertEqual(len(s), size + 2) - self.assertEqual(s[0], "'") - self.assertEqual(s[-1], "'") - self.assertEqual(s.count('-'), size) - del s - # repr() will create a string four times as large as this 'binary - # string', but we don't want to allocate much more than twice - # size in total. (We do extra testing in test_repr_large()) - size = size // 5 * 2 - s = '\x00' * size - s = repr(s) - self.assertEqual(len(s), size * 4 + 2) - self.assertEqual(s[0], "'") - self.assertEqual(s[-1], "'") - self.assertEqual(s.count('\\'), size) - self.assertEqual(s.count('0'), size * 2) - - @bigmemtest(size=_2G + 10, memuse=ascii_char_size * 5) - def test_repr_large(self, size): - s = '\x00' * size - s = repr(s) - self.assertEqual(len(s), size * 4 + 2) - self.assertEqual(s[0], "'") - self.assertEqual(s[-1], "'") - self.assertEqual(s.count('\\'), size) - self.assertEqual(s.count('0'), size * 2) - - # ascii() calls encode('ascii', 'backslashreplace'), which itself - # creates a temporary Py_UNICODE representation in addition to the - # original (Py_UCS2) one - # There's also some overallocation when resizing the ascii() result - # that isn't taken into account here. - @bigmemtest(size=_2G // 5 + 1, memuse=ucs2_char_size + - ucs4_char_size + ascii_char_size * 6) - def test_unicode_repr(self, size): - # Use an assigned, but not printable code point. - # It is in the range of the low surrogates \uDC00-\uDFFF. - char = "\uDCBA" - s = char * size - try: - for f in (repr, ascii): - r = f(s) - self.assertEqual(len(r), 2 + (len(f(char)) - 2) * size) - self.assertTrue(r.endswith(r"\udcba'"), r[-10:]) - r = None - finally: - r = s = None - - @bigmemtest(size=_2G // 5 + 1, memuse=ucs4_char_size * 2 + ascii_char_size * 10) - def test_unicode_repr_wide(self, size): - char = "\U0001DCBA" - s = char * size - try: - for f in (repr, ascii): - r = f(s) - self.assertEqual(len(r), 2 + (len(f(char)) - 2) * size) - self.assertTrue(r.endswith(r"\U0001dcba'"), r[-12:]) - r = None - finally: - r = s = None - - # The original test_translate is overridden here, so as to get the - # correct size estimate: str.translate() uses an intermediate Py_UCS4 - # representation. - - @bigmemtest(size=_2G, memuse=ascii_char_size * 2 + ucs4_char_size) - def test_translate(self, size): - _ = self.from_latin1 - SUBSTR = _('aZz.z.Aaz.') - trans = { - ord(_('.')): _('-'), - ord(_('a')): _('!'), - ord(_('Z')): _('$'), - } - sublen = len(SUBSTR) - repeats = size // sublen + 2 - s = SUBSTR * repeats - s = s.translate(trans) - self.assertEqual(len(s), repeats * sublen) - self.assertEqual(s[:sublen], SUBSTR.translate(trans)) - self.assertEqual(s[-sublen:], SUBSTR.translate(trans)) - self.assertEqual(s.count(_('.')), 0) - self.assertEqual(s.count(_('!')), repeats * 2) - self.assertEqual(s.count(_('z')), repeats * 3) - - - class BytesTest(unittest.TestCase, BaseStrTest): - - def from_latin1(self, s): - return s.encode("latin-1") - - @bigmemtest(size=_2G + 2, memuse=1 + ascii_char_size) - def test_decode(self, size): - s = self.from_latin1('.') * size - self.assertEqual(len(s.decode('utf-8')), size) - - @bigmemtest(size=_2G, memuse=2) - def test_capitalize(self, size): - self._test_capitalize(size) - - @bigmemtest(size=_2G, memuse=2) - def test_title(self, size): - self._test_title(size) - - @bigmemtest(size=_2G, memuse=2) - def test_swapcase(self, size): - self._test_swapcase(size) - - - class BytearrayTest(unittest.TestCase, BaseStrTest): - - def from_latin1(self, s): - return bytearray(s.encode("latin-1")) - - @bigmemtest(size=_2G + 2, memuse=1 + ascii_char_size) - def test_decode(self, size): - s = self.from_latin1('.') * size - self.assertEqual(len(s.decode('utf-8')), size) - - @bigmemtest(size=_2G, memuse=2) - def test_capitalize(self, size): - self._test_capitalize(size) - - @bigmemtest(size=_2G, memuse=2) - def test_title(self, size): - self._test_title(size) - - @bigmemtest(size=_2G, memuse=2) - def test_swapcase(self, size): - self._test_swapcase(size) - - test_hash = None - test_split_large = None - - class TupleTest(unittest.TestCase): - - # Tuples have a small, fixed-sized head and an array of pointers to - # data. Since we're testing 64-bit addressing, we can assume that the - # pointers are 8 bytes, and that thus that the tuples take up 8 bytes - # per size. - - # As a side-effect of testing long tuples, these tests happen to test - # having more than 2<<31 references to any given object. Hence the - # use of different types of objects as contents in different tests. - - @bigmemtest(size=_2G + 2, memuse=pointer_size * 2) - def test_compare(self, size): - t1 = ('',) * size - t2 = ('',) * size - self.assertTrue(t1 == t2) - del t2 - t2 = ('',) * (size + 1) - self.assertFalse(t1 == t2) - del t2 - t2 = (1,) * size - self.assertFalse(t1 == t2) - - # Test concatenating into a single tuple of more than 2G in length, - # and concatenating a tuple of more than 2G in length separately, so - # the smaller test still gets run even if there isn't memory for the - # larger test (but we still let the tester know the larger test is - # skipped, in verbose mode.) - def basic_concat_test(self, size): - t = ((),) * size - self.assertEqual(len(t), size) - t = t + t - self.assertEqual(len(t), size * 2) - - @bigmemtest(size=_2G // 2 + 2, memuse=pointer_size * 3) - def test_concat_small(self, size): - return self.basic_concat_test(size) - - @bigmemtest(size=_2G + 2, memuse=pointer_size * 3) - def test_concat_large(self, size): - return self.basic_concat_test(size) - - @bigmemtest(size=_2G // 5 + 10, memuse=pointer_size * 5) - def test_contains(self, size): - t = (1, 2, 3, 4, 5) * size - self.assertEqual(len(t), size * 5) - self.assertTrue(5 in t) - self.assertFalse((1, 2, 3, 4, 5) in t) - self.assertFalse(0 in t) - - @bigmemtest(size=_2G + 10, memuse=pointer_size) - def test_hash(self, size): - t1 = (0,) * size - h1 = hash(t1) - del t1 - t2 = (0,) * (size + 1) - self.assertFalse(h1 == hash(t2)) - - @bigmemtest(size=_2G + 10, memuse=pointer_size) - def test_index_and_slice(self, size): - t = (None,) * size - self.assertEqual(len(t), size) - self.assertEqual(t[-1], None) - self.assertEqual(t[5], None) - self.assertEqual(t[size - 1], None) - self.assertRaises(IndexError, operator.getitem, t, size) - self.assertEqual(t[:5], (None,) * 5) - self.assertEqual(t[-5:], (None,) * 5) - self.assertEqual(t[20:25], (None,) * 5) - self.assertEqual(t[-25:-20], (None,) * 5) - self.assertEqual(t[size - 5:], (None,) * 5) - self.assertEqual(t[size - 5:size], (None,) * 5) - self.assertEqual(t[size - 6:size - 2], (None,) * 4) - self.assertEqual(t[size:size], ()) - self.assertEqual(t[size:size+5], ()) - - # Like test_concat, split in two. - def basic_test_repeat(self, size): - t = ('',) * size - self.assertEqual(len(t), size) - t = t * 2 - self.assertEqual(len(t), size * 2) - - @bigmemtest(size=_2G // 2 + 2, memuse=pointer_size * 3) - def test_repeat_small(self, size): - return self.basic_test_repeat(size) - - @bigmemtest(size=_2G + 2, memuse=pointer_size * 3) - def test_repeat_large(self, size): - return self.basic_test_repeat(size) - - @bigmemtest(size=_1G - 1, memuse=12) - def test_repeat_large_2(self, size): - return self.basic_test_repeat(size) - - @bigmemtest(size=_1G - 1, memuse=pointer_size * 2) - def test_from_2G_generator(self, size): - try: - t = tuple(iter([42]*size)) - except MemoryError: - pass # acceptable on 32-bit - else: - self.assertEqual(len(t), size) - self.assertEqual(t[:10], (42,) * 10) - self.assertEqual(t[-10:], (42,) * 10) - - @bigmemtest(size=_1G - 25, memuse=pointer_size * 2) - def test_from_almost_2G_generator(self, size): - try: - t = tuple(iter([42]*size)) - except MemoryError: - pass # acceptable on 32-bit - else: - self.assertEqual(len(t), size) - self.assertEqual(t[:10], (42,) * 10) - self.assertEqual(t[-10:], (42,) * 10) - - # Like test_concat, split in two. - def basic_test_repr(self, size): - t = (False,) * size - s = repr(t) - # The repr of a tuple of Falses is exactly 7 times the tuple length. - self.assertEqual(len(s), size * 7) - self.assertEqual(s[:10], '(False, Fa') - self.assertEqual(s[-10:], 'se, False)') - - @bigmemtest(size=_2G // 7 + 2, memuse=pointer_size + ascii_char_size * 7) - def test_repr_small(self, size): - return self.basic_test_repr(size) - - @bigmemtest(size=_2G + 2, memuse=pointer_size + ascii_char_size * 7) - def test_repr_large(self, size): - return self.basic_test_repr(size) - - class ListTest(unittest.TestCase): - - # Like tuples, lists have a small, fixed-sized head and an array of - # pointers to data, so 8 bytes per size. Also like tuples, we make the - # lists hold references to various objects to test their refcount - # limits. - - @bigmemtest(size=_2G + 2, memuse=pointer_size * 2) - def test_compare(self, size): - l1 = [''] * size - l2 = [''] * size - self.assertTrue(l1 == l2) - del l2 - l2 = [''] * (size + 1) - self.assertFalse(l1 == l2) - del l2 - l2 = [2] * size - self.assertFalse(l1 == l2) - - # Test concatenating into a single list of more than 2G in length, - # and concatenating a list of more than 2G in length separately, so - # the smaller test still gets run even if there isn't memory for the - # larger test (but we still let the tester know the larger test is - # skipped, in verbose mode.) - def basic_test_concat(self, size): - l = [[]] * size - self.assertEqual(len(l), size) - l = l + l - self.assertEqual(len(l), size * 2) - - @bigmemtest(size=_2G // 2 + 2, memuse=pointer_size * 3) - def test_concat_small(self, size): - return self.basic_test_concat(size) - - @bigmemtest(size=_2G + 2, memuse=pointer_size * 3) - def test_concat_large(self, size): - return self.basic_test_concat(size) - - # XXX This tests suffers from overallocation, just like test_append. - # This should be fixed in future. - def basic_test_inplace_concat(self, size): - l = [sys.stdout] * size - l += l - self.assertEqual(len(l), size * 2) - self.assertTrue(l[0] is l[-1]) - self.assertTrue(l[size - 1] is l[size + 1]) - - @bigmemtest(size=_2G // 2 + 2, memuse=pointer_size * 2 * 9/8) - def test_inplace_concat_small(self, size): - return self.basic_test_inplace_concat(size) - - @bigmemtest(size=_2G + 2, memuse=pointer_size * 2 * 9/8) - def test_inplace_concat_large(self, size): - return self.basic_test_inplace_concat(size) - - @bigmemtest(size=_2G // 5 + 10, memuse=pointer_size * 5) - def test_contains(self, size): - l = [1, 2, 3, 4, 5] * size - self.assertEqual(len(l), size * 5) - self.assertTrue(5 in l) - self.assertFalse([1, 2, 3, 4, 5] in l) - self.assertFalse(0 in l) - - @bigmemtest(size=_2G + 10, memuse=pointer_size) - def test_hash(self, size): - l = [0] * size - self.assertRaises(TypeError, hash, l) - - @bigmemtest(size=_2G + 10, memuse=pointer_size) - def test_index_and_slice(self, size): - l = [None] * size - self.assertEqual(len(l), size) - self.assertEqual(l[-1], None) - self.assertEqual(l[5], None) - self.assertEqual(l[size - 1], None) - self.assertRaises(IndexError, operator.getitem, l, size) - self.assertEqual(l[:5], [None] * 5) - self.assertEqual(l[-5:], [None] * 5) - self.assertEqual(l[20:25], [None] * 5) - self.assertEqual(l[-25:-20], [None] * 5) - self.assertEqual(l[size - 5:], [None] * 5) - self.assertEqual(l[size - 5:size], [None] * 5) - self.assertEqual(l[size - 6:size - 2], [None] * 4) - self.assertEqual(l[size:size], []) - self.assertEqual(l[size:size+5], []) - - l[size - 2] = 5 - self.assertEqual(len(l), size) - self.assertEqual(l[-3:], [None, 5, None]) - self.assertEqual(l.count(5), 1) - self.assertRaises(IndexError, operator.setitem, l, size, 6) - self.assertEqual(len(l), size) - - l[size - 7:] = [1, 2, 3, 4, 5] - size -= 2 - self.assertEqual(len(l), size) - self.assertEqual(l[-7:], [None, None, 1, 2, 3, 4, 5]) - - l[:7] = [1, 2, 3, 4, 5] - size -= 2 - self.assertEqual(len(l), size) - self.assertEqual(l[:7], [1, 2, 3, 4, 5, None, None]) - - del l[size - 1] - size -= 1 - self.assertEqual(len(l), size) - self.assertEqual(l[-1], 4) - - del l[-2:] - size -= 2 - self.assertEqual(len(l), size) - self.assertEqual(l[-1], 2) - - del l[0] - size -= 1 - self.assertEqual(len(l), size) - self.assertEqual(l[0], 2) - - del l[:2] - size -= 2 - self.assertEqual(len(l), size) - self.assertEqual(l[0], 4) - - # Like test_concat, split in two. - def basic_test_repeat(self, size): - l = [] * size - self.assertFalse(l) - l = [''] * size - self.assertEqual(len(l), size) - l = l * 2 - self.assertEqual(len(l), size * 2) - - @bigmemtest(size=_2G // 2 + 2, memuse=pointer_size * 3) - def test_repeat_small(self, size): - return self.basic_test_repeat(size) - - @bigmemtest(size=_2G + 2, memuse=pointer_size * 3) - def test_repeat_large(self, size): - return self.basic_test_repeat(size) - - # XXX This tests suffers from overallocation, just like test_append. - # This should be fixed in future. - def basic_test_inplace_repeat(self, size): - l = [''] - l *= size - self.assertEqual(len(l), size) - self.assertTrue(l[0] is l[-1]) - del l - - l = [''] * size - l *= 2 - self.assertEqual(len(l), size * 2) - self.assertTrue(l[size - 1] is l[-1]) - - @bigmemtest(size=_2G // 2 + 2, memuse=pointer_size * 2 * 9/8) - def test_inplace_repeat_small(self, size): - return self.basic_test_inplace_repeat(size) - - @bigmemtest(size=_2G + 2, memuse=pointer_size * 2 * 9/8) - def test_inplace_repeat_large(self, size): - return self.basic_test_inplace_repeat(size) - - def basic_test_repr(self, size): - l = [False] * size - s = repr(l) - # The repr of a list of Falses is exactly 7 times the list length. - self.assertEqual(len(s), size * 7) - self.assertEqual(s[:10], '[False, Fa') - self.assertEqual(s[-10:], 'se, False]') - self.assertEqual(s.count('F'), size) - - @bigmemtest(size=_2G // 7 + 2, memuse=pointer_size + ascii_char_size * 7) - def test_repr_small(self, size): - return self.basic_test_repr(size) - - @bigmemtest(size=_2G + 2, memuse=pointer_size + ascii_char_size * 7) - def test_repr_large(self, size): - return self.basic_test_repr(size) - - # list overallocates ~1/8th of the total size (on first expansion) so - # the single list.append call puts memuse at 9 bytes per size. - @bigmemtest(size=_2G, memuse=pointer_size * 9/8) - def test_append(self, size): - l = [object()] * size - l.append(object()) - self.assertEqual(len(l), size+1) - self.assertTrue(l[-3] is l[-2]) - self.assertFalse(l[-2] is l[-1]) - - @bigmemtest(size=_2G // 5 + 2, memuse=pointer_size * 5) - def test_count(self, size): - l = [1, 2, 3, 4, 5] * size - self.assertEqual(l.count(1), size) - self.assertEqual(l.count("1"), 0) - - # XXX This tests suffers from overallocation, just like test_append. - # This should be fixed in future. - def basic_test_extend(self, size): - l = [object] * size - l.extend(l) - self.assertEqual(len(l), size * 2) - self.assertTrue(l[0] is l[-1]) - self.assertTrue(l[size - 1] is l[size + 1]) - - @bigmemtest(size=_2G // 2 + 2, memuse=pointer_size * 2 * 9/8) - def test_extend_small(self, size): - return self.basic_test_extend(size) - - @bigmemtest(size=_2G + 2, memuse=pointer_size * 2 * 9/8) - def test_extend_large(self, size): - return self.basic_test_extend(size) - - @bigmemtest(size=_2G // 5 + 2, memuse=pointer_size * 5) - def test_index(self, size): - l = [1, 2, 3, 4, 5] * size - size *= 5 - self.assertEqual(l.index(1), 0) - self.assertEqual(l.index(5, size - 5), size - 1) - self.assertEqual(l.index(5, size - 5, size), size - 1) - self.assertRaises(ValueError, l.index, 1, size - 4, size) - self.assertRaises(ValueError, l.index, 6) - - # This tests suffers from overallocation, just like test_append. - @bigmemtest(size=_2G + 10, memuse=pointer_size * 9/8) - def test_insert(self, size): - l = [1.0] * size - l.insert(size - 1, "A") - size += 1 - self.assertEqual(len(l), size) - self.assertEqual(l[-3:], [1.0, "A", 1.0]) - - l.insert(size + 1, "B") - size += 1 - self.assertEqual(len(l), size) - self.assertEqual(l[-3:], ["A", 1.0, "B"]) - - l.insert(1, "C") - size += 1 - self.assertEqual(len(l), size) - self.assertEqual(l[:3], [1.0, "C", 1.0]) - self.assertEqual(l[size - 3:], ["A", 1.0, "B"]) - - @bigmemtest(size=_2G // 5 + 4, memuse=pointer_size * 5) - def test_pop(self, size): - l = ["a", "b", "c", "d", "e"] * size - size *= 5 - self.assertEqual(len(l), size) - - item = l.pop() - size -= 1 - self.assertEqual(len(l), size) - self.assertEqual(item, "e") - self.assertEqual(l[-2:], ["c", "d"]) - - item = l.pop(0) - size -= 1 - self.assertEqual(len(l), size) - self.assertEqual(item, "a") - self.assertEqual(l[:2], ["b", "c"]) - - item = l.pop(size - 2) - size -= 1 - self.assertEqual(len(l), size) - self.assertEqual(item, "c") - self.assertEqual(l[-2:], ["b", "d"]) - - @bigmemtest(size=_2G + 10, memuse=pointer_size) - def test_remove(self, size): - l = [10] * size - self.assertEqual(len(l), size) - - l.remove(10) - size -= 1 - self.assertEqual(len(l), size) - - # Because of the earlier l.remove(), this append doesn't trigger - # a resize. - l.append(5) - size += 1 - self.assertEqual(len(l), size) - self.assertEqual(l[-2:], [10, 5]) - l.remove(5) - size -= 1 - self.assertEqual(len(l), size) - self.assertEqual(l[-2:], [10, 10]) - - @bigmemtest(size=_2G // 5 + 2, memuse=pointer_size * 5) - def test_reverse(self, size): - l = [1, 2, 3, 4, 5] * size - l.reverse() - self.assertEqual(len(l), size * 5) - self.assertEqual(l[-5:], [5, 4, 3, 2, 1]) - self.assertEqual(l[:5], [5, 4, 3, 2, 1]) - - @bigmemtest(size=_2G // 5 + 2, memuse=pointer_size * 5 * 1.5) - def test_sort(self, size): - l = [1, 2, 3, 4, 5] * size - l.sort() - self.assertEqual(len(l), size * 5) - self.assertEqual(l.count(1), size) - self.assertEqual(l[:10], [1] * 10) - self.assertEqual(l[-10:], [5] * 10) - - def test_main(): - support.run_unittest(StrTest, BytesTest, BytearrayTest, - TupleTest, ListTest) - - if __name__ == '__main__': - if len(sys.argv) > 1: - support.set_memlimit(sys.argv[1]) - test_main() diff --git a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_binascii.yaml b/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_binascii.yaml deleted file mode 100644 index 469e4c6d8..000000000 --- a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_binascii.yaml +++ /dev/null @@ -1,435 +0,0 @@ -python: | - """Test the binascii C module.""" - - import unittest - import binascii - import array - import re - - # Note: "*_hex" functions are aliases for "(un)hexlify" - b2a_functions = ['b2a_base64', 'b2a_hex', 'b2a_hqx', 'b2a_qp', 'b2a_uu', - 'hexlify', 'rlecode_hqx'] - a2b_functions = ['a2b_base64', 'a2b_hex', 'a2b_hqx', 'a2b_qp', 'a2b_uu', - 'unhexlify', 'rledecode_hqx'] - all_functions = a2b_functions + b2a_functions + ['crc32', 'crc_hqx'] - - - class BinASCIITest(unittest.TestCase): - - type2test = bytes - # Create binary test data - rawdata = b"The quick brown fox jumps over the lazy dog.\r\n" - # Be slow so we don't depend on other modules - rawdata += bytes(range(256)) - rawdata += b"\r\nHello world.\n" - - def setUp(self): - self.data = self.type2test(self.rawdata) - - def test_exceptions(self): - # Check module exceptions - self.assertTrue(issubclass(binascii.Error, Exception)) - self.assertTrue(issubclass(binascii.Incomplete, Exception)) - - def test_functions(self): - # Check presence of all functions - for name in all_functions: - self.assertTrue(hasattr(getattr(binascii, name), '__call__')) - self.assertRaises(TypeError, getattr(binascii, name)) - - def test_returned_value(self): - # Limit to the minimum of all limits (b2a_uu) - MAX_ALL = 45 - raw = self.rawdata[:MAX_ALL] - for fa, fb in zip(a2b_functions, b2a_functions): - a2b = getattr(binascii, fa) - b2a = getattr(binascii, fb) - try: - a = b2a(self.type2test(raw)) - res = a2b(self.type2test(a)) - except Exception as err: - self.fail("{}/{} conversion raises {!r}".format(fb, fa, err)) - if fb == 'b2a_hqx': - # b2a_hqx returns a tuple - res, _ = res - self.assertEqual(res, raw, "{}/{} conversion: " - "{!r} != {!r}".format(fb, fa, res, raw)) - self.assertIsInstance(res, bytes) - self.assertIsInstance(a, bytes) - self.assertLess(max(a), 128) - self.assertIsInstance(binascii.crc_hqx(raw, 0), int) - self.assertIsInstance(binascii.crc32(raw), int) - - def test_base64valid(self): - # Test base64 with valid data - MAX_BASE64 = 57 - lines = [] - for i in range(0, len(self.rawdata), MAX_BASE64): - b = self.type2test(self.rawdata[i:i+MAX_BASE64]) - a = binascii.b2a_base64(b) - lines.append(a) - res = bytes() - for line in lines: - a = self.type2test(line) - b = binascii.a2b_base64(a) - res += b - self.assertEqual(res, self.rawdata) - - def test_base64invalid(self): - # Test base64 with random invalid characters sprinkled throughout - # (This requires a new version of binascii.) - MAX_BASE64 = 57 - lines = [] - for i in range(0, len(self.data), MAX_BASE64): - b = self.type2test(self.rawdata[i:i+MAX_BASE64]) - a = binascii.b2a_base64(b) - lines.append(a) - - fillers = bytearray() - valid = b"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/" - for i in range(256): - if i not in valid: - fillers.append(i) - def addnoise(line): - noise = fillers - ratio = len(line) // len(noise) - res = bytearray() - while line and noise: - if len(line) // len(noise) > ratio: - c, line = line[0], line[1:] - else: - c, noise = noise[0], noise[1:] - res.append(c) - return res + noise + line - res = bytearray() - for line in map(addnoise, lines): - a = self.type2test(line) - b = binascii.a2b_base64(a) - res += b - self.assertEqual(res, self.rawdata) - - # Test base64 with just invalid characters, which should return - # empty strings. TBD: shouldn't it raise an exception instead ? - self.assertEqual(binascii.a2b_base64(self.type2test(fillers)), b'') - - def test_base64errors(self): - # Test base64 with invalid padding - def assertIncorrectPadding(data): - with self.assertRaisesRegex(binascii.Error, r'(?i)Incorrect padding'): - binascii.a2b_base64(self.type2test(data)) - - assertIncorrectPadding(b'ab') - assertIncorrectPadding(b'ab=') - assertIncorrectPadding(b'abc') - assertIncorrectPadding(b'abcdef') - assertIncorrectPadding(b'abcdef=') - assertIncorrectPadding(b'abcdefg') - assertIncorrectPadding(b'a=b=') - assertIncorrectPadding(b'a\nb=') - - # Test base64 with invalid number of valid characters (1 mod 4) - def assertInvalidLength(data): - n_data_chars = len(re.sub(br'[^A-Za-z0-9/+]', br'', data)) - expected_errmsg_re = \ - r'(?i)Invalid.+number of data characters.+' + str(n_data_chars) - with self.assertRaisesRegex(binascii.Error, expected_errmsg_re): - binascii.a2b_base64(self.type2test(data)) - - assertInvalidLength(b'a') - assertInvalidLength(b'a=') - assertInvalidLength(b'a==') - assertInvalidLength(b'a===') - assertInvalidLength(b'a' * 5) - assertInvalidLength(b'a' * (4 * 87 + 1)) - assertInvalidLength(b'A\tB\nC ??DE') # only 5 valid characters - - def test_uu(self): - MAX_UU = 45 - for backtick in (True, False): - lines = [] - for i in range(0, len(self.data), MAX_UU): - b = self.type2test(self.rawdata[i:i+MAX_UU]) - a = binascii.b2a_uu(b, backtick=backtick) - lines.append(a) - res = bytes() - for line in lines: - a = self.type2test(line) - b = binascii.a2b_uu(a) - res += b - self.assertEqual(res, self.rawdata) - - self.assertEqual(binascii.a2b_uu(b"\x7f"), b"\x00"*31) - self.assertEqual(binascii.a2b_uu(b"\x80"), b"\x00"*32) - self.assertEqual(binascii.a2b_uu(b"\xff"), b"\x00"*31) - self.assertRaises(binascii.Error, binascii.a2b_uu, b"\xff\x00") - self.assertRaises(binascii.Error, binascii.a2b_uu, b"!!!!") - self.assertRaises(binascii.Error, binascii.b2a_uu, 46*b"!") - - # Issue #7701 (crash on a pydebug build) - self.assertEqual(binascii.b2a_uu(b'x'), b'!> \n') - - self.assertEqual(binascii.b2a_uu(b''), b' \n') - self.assertEqual(binascii.b2a_uu(b'', backtick=True), b'`\n') - self.assertEqual(binascii.a2b_uu(b' \n'), b'') - self.assertEqual(binascii.a2b_uu(b'`\n'), b'') - self.assertEqual(binascii.b2a_uu(b'\x00Cat'), b'$ $-A= \n') - self.assertEqual(binascii.b2a_uu(b'\x00Cat', backtick=True), - b'$`$-A=```\n') - self.assertEqual(binascii.a2b_uu(b'$`$-A=```\n'), - binascii.a2b_uu(b'$ $-A= \n')) - with self.assertRaises(TypeError): - binascii.b2a_uu(b"", True) - - def test_crc_hqx(self): - crc = binascii.crc_hqx(self.type2test(b"Test the CRC-32 of"), 0) - crc = binascii.crc_hqx(self.type2test(b" this string."), crc) - self.assertEqual(crc, 14290) - - self.assertRaises(TypeError, binascii.crc_hqx) - self.assertRaises(TypeError, binascii.crc_hqx, self.type2test(b'')) - - for crc in 0, 1, 0x1234, 0x12345, 0x12345678, -1: - self.assertEqual(binascii.crc_hqx(self.type2test(b''), crc), - crc & 0xffff) - - def test_crc32(self): - crc = binascii.crc32(self.type2test(b"Test the CRC-32 of")) - crc = binascii.crc32(self.type2test(b" this string."), crc) - self.assertEqual(crc, 1571220330) - - self.assertRaises(TypeError, binascii.crc32) - - def test_hqx(self): - # Perform binhex4 style RLE-compression - # Then calculate the hexbin4 binary-to-ASCII translation - rle = binascii.rlecode_hqx(self.data) - a = binascii.b2a_hqx(self.type2test(rle)) - - b, _ = binascii.a2b_hqx(self.type2test(a)) - res = binascii.rledecode_hqx(b) - self.assertEqual(res, self.rawdata) - - def test_rle(self): - # test repetition with a repetition longer than the limit of 255 - data = (b'a' * 100 + b'b' + b'c' * 300) - - encoded = binascii.rlecode_hqx(data) - self.assertEqual(encoded, - (b'a\x90d' # 'a' * 100 - b'b' # 'b' - b'c\x90\xff' # 'c' * 255 - b'c\x90-')) # 'c' * 45 - - decoded = binascii.rledecode_hqx(encoded) - self.assertEqual(decoded, data) - - def test_hex(self): - # test hexlification - s = b'{s\005\000\000\000worldi\002\000\000\000s\005\000\000\000helloi\001\000\000\0000' - t = binascii.b2a_hex(self.type2test(s)) - u = binascii.a2b_hex(self.type2test(t)) - self.assertEqual(s, u) - self.assertRaises(binascii.Error, binascii.a2b_hex, t[:-1]) - self.assertRaises(binascii.Error, binascii.a2b_hex, t[:-1] + b'q') - self.assertRaises(binascii.Error, binascii.a2b_hex, bytes([255, 255])) - self.assertRaises(binascii.Error, binascii.a2b_hex, b'0G') - self.assertRaises(binascii.Error, binascii.a2b_hex, b'0g') - self.assertRaises(binascii.Error, binascii.a2b_hex, b'G0') - self.assertRaises(binascii.Error, binascii.a2b_hex, b'g0') - - # Confirm that b2a_hex == hexlify and a2b_hex == unhexlify - self.assertEqual(binascii.hexlify(self.type2test(s)), t) - self.assertEqual(binascii.unhexlify(self.type2test(t)), u) - - def test_hex_separator(self): - """Test that hexlify and b2a_hex are binary versions of bytes.hex.""" - # Logic of separators is tested in test_bytes.py. This checks that - # arg parsing works and exercises the direct to bytes object code - # path within pystrhex.c. - s = b'{s\005\000\000\000worldi\002\000\000\000s\005\000\000\000helloi\001\000\000\0000' - self.assertEqual(binascii.hexlify(self.type2test(s)), s.hex().encode('ascii')) - expected8 = s.hex('.', 8).encode('ascii') - self.assertEqual(binascii.hexlify(self.type2test(s), '.', 8), expected8) - expected1 = s.hex(':').encode('ascii') - self.assertEqual(binascii.b2a_hex(self.type2test(s), ':'), expected1) - - def test_qp(self): - type2test = self.type2test - a2b_qp = binascii.a2b_qp - b2a_qp = binascii.b2a_qp - - a2b_qp(data=b"", header=False) # Keyword arguments allowed - - # A test for SF bug 534347 (segfaults without the proper fix) - try: - a2b_qp(b"", **{1:1}) - except TypeError: - pass - else: - self.fail("binascii.a2b_qp(**{1:1}) didn't raise TypeError") - - self.assertEqual(a2b_qp(type2test(b"=")), b"") - self.assertEqual(a2b_qp(type2test(b"= ")), b"= ") - self.assertEqual(a2b_qp(type2test(b"==")), b"=") - self.assertEqual(a2b_qp(type2test(b"=\nAB")), b"AB") - self.assertEqual(a2b_qp(type2test(b"=\r\nAB")), b"AB") - self.assertEqual(a2b_qp(type2test(b"=\rAB")), b"") # ? - self.assertEqual(a2b_qp(type2test(b"=\rAB\nCD")), b"CD") # ? - self.assertEqual(a2b_qp(type2test(b"=AB")), b"\xab") - self.assertEqual(a2b_qp(type2test(b"=ab")), b"\xab") - self.assertEqual(a2b_qp(type2test(b"=AX")), b"=AX") - self.assertEqual(a2b_qp(type2test(b"=XA")), b"=XA") - self.assertEqual(a2b_qp(type2test(b"=AB")[:-1]), b"=A") - - self.assertEqual(a2b_qp(type2test(b'_')), b'_') - self.assertEqual(a2b_qp(type2test(b'_'), header=True), b' ') - - self.assertRaises(TypeError, b2a_qp, foo="bar") - self.assertEqual(a2b_qp(type2test(b"=00\r\n=00")), b"\x00\r\n\x00") - self.assertEqual(b2a_qp(type2test(b"\xff\r\n\xff\n\xff")), - b"=FF\r\n=FF\r\n=FF") - self.assertEqual(b2a_qp(type2test(b"0"*75+b"\xff\r\n\xff\r\n\xff")), - b"0"*75+b"=\r\n=FF\r\n=FF\r\n=FF") - - self.assertEqual(b2a_qp(type2test(b'\x7f')), b'=7F') - self.assertEqual(b2a_qp(type2test(b'=')), b'=3D') - - self.assertEqual(b2a_qp(type2test(b'_')), b'_') - self.assertEqual(b2a_qp(type2test(b'_'), header=True), b'=5F') - self.assertEqual(b2a_qp(type2test(b'x y'), header=True), b'x_y') - self.assertEqual(b2a_qp(type2test(b'x '), header=True), b'x=20') - self.assertEqual(b2a_qp(type2test(b'x y'), header=True, quotetabs=True), - b'x=20y') - self.assertEqual(b2a_qp(type2test(b'x\ty'), header=True), b'x\ty') - - self.assertEqual(b2a_qp(type2test(b' ')), b'=20') - self.assertEqual(b2a_qp(type2test(b'\t')), b'=09') - self.assertEqual(b2a_qp(type2test(b' x')), b' x') - self.assertEqual(b2a_qp(type2test(b'\tx')), b'\tx') - self.assertEqual(b2a_qp(type2test(b' x')[:-1]), b'=20') - self.assertEqual(b2a_qp(type2test(b'\tx')[:-1]), b'=09') - self.assertEqual(b2a_qp(type2test(b'\0')), b'=00') - - self.assertEqual(b2a_qp(type2test(b'\0\n')), b'=00\n') - self.assertEqual(b2a_qp(type2test(b'\0\n'), quotetabs=True), b'=00\n') - - self.assertEqual(b2a_qp(type2test(b'x y\tz')), b'x y\tz') - self.assertEqual(b2a_qp(type2test(b'x y\tz'), quotetabs=True), - b'x=20y=09z') - self.assertEqual(b2a_qp(type2test(b'x y\tz'), istext=False), - b'x y\tz') - self.assertEqual(b2a_qp(type2test(b'x \ny\t\n')), - b'x=20\ny=09\n') - self.assertEqual(b2a_qp(type2test(b'x \ny\t\n'), quotetabs=True), - b'x=20\ny=09\n') - self.assertEqual(b2a_qp(type2test(b'x \ny\t\n'), istext=False), - b'x =0Ay\t=0A') - self.assertEqual(b2a_qp(type2test(b'x \ry\t\r')), - b'x \ry\t\r') - self.assertEqual(b2a_qp(type2test(b'x \ry\t\r'), quotetabs=True), - b'x=20\ry=09\r') - self.assertEqual(b2a_qp(type2test(b'x \ry\t\r'), istext=False), - b'x =0Dy\t=0D') - self.assertEqual(b2a_qp(type2test(b'x \r\ny\t\r\n')), - b'x=20\r\ny=09\r\n') - self.assertEqual(b2a_qp(type2test(b'x \r\ny\t\r\n'), quotetabs=True), - b'x=20\r\ny=09\r\n') - self.assertEqual(b2a_qp(type2test(b'x \r\ny\t\r\n'), istext=False), - b'x =0D=0Ay\t=0D=0A') - - self.assertEqual(b2a_qp(type2test(b'x \r\n')[:-1]), b'x \r') - self.assertEqual(b2a_qp(type2test(b'x\t\r\n')[:-1]), b'x\t\r') - self.assertEqual(b2a_qp(type2test(b'x \r\n')[:-1], quotetabs=True), - b'x=20\r') - self.assertEqual(b2a_qp(type2test(b'x\t\r\n')[:-1], quotetabs=True), - b'x=09\r') - self.assertEqual(b2a_qp(type2test(b'x \r\n')[:-1], istext=False), - b'x =0D') - self.assertEqual(b2a_qp(type2test(b'x\t\r\n')[:-1], istext=False), - b'x\t=0D') - - self.assertEqual(b2a_qp(type2test(b'.')), b'=2E') - self.assertEqual(b2a_qp(type2test(b'.\n')), b'=2E\n') - self.assertEqual(b2a_qp(type2test(b'.\r')), b'=2E\r') - self.assertEqual(b2a_qp(type2test(b'.\0')), b'=2E=00') - self.assertEqual(b2a_qp(type2test(b'a.\n')), b'a.\n') - self.assertEqual(b2a_qp(type2test(b'.a')[:-1]), b'=2E') - - def test_empty_string(self): - # A test for SF bug #1022953. Make sure SystemError is not raised. - empty = self.type2test(b'') - for func in all_functions: - if func == 'crc_hqx': - # crc_hqx needs 2 arguments - binascii.crc_hqx(empty, 0) - continue - f = getattr(binascii, func) - try: - f(empty) - except Exception as err: - self.fail("{}({!r}) raises {!r}".format(func, empty, err)) - - def test_unicode_b2a(self): - # Unicode strings are not accepted by b2a_* functions. - for func in set(all_functions) - set(a2b_functions) | {'rledecode_hqx'}: - try: - self.assertRaises(TypeError, getattr(binascii, func), "test") - except Exception as err: - self.fail('{}("test") raises {!r}'.format(func, err)) - # crc_hqx needs 2 arguments - self.assertRaises(TypeError, binascii.crc_hqx, "test", 0) - - def test_unicode_a2b(self): - # Unicode strings are accepted by a2b_* functions. - MAX_ALL = 45 - raw = self.rawdata[:MAX_ALL] - for fa, fb in zip(a2b_functions, b2a_functions): - if fa == 'rledecode_hqx': - # Takes non-ASCII data - continue - a2b = getattr(binascii, fa) - b2a = getattr(binascii, fb) - try: - a = b2a(self.type2test(raw)) - binary_res = a2b(a) - a = a.decode('ascii') - res = a2b(a) - except Exception as err: - self.fail("{}/{} conversion raises {!r}".format(fb, fa, err)) - if fb == 'b2a_hqx': - # b2a_hqx returns a tuple - res, _ = res - binary_res, _ = binary_res - self.assertEqual(res, raw, "{}/{} conversion: " - "{!r} != {!r}".format(fb, fa, res, raw)) - self.assertEqual(res, binary_res) - self.assertIsInstance(res, bytes) - # non-ASCII string - self.assertRaises(ValueError, a2b, "\x80") - - def test_b2a_base64_newline(self): - # Issue #25357: test newline parameter - b = self.type2test(b'hello') - self.assertEqual(binascii.b2a_base64(b), - b'aGVsbG8=\n') - self.assertEqual(binascii.b2a_base64(b, newline=True), - b'aGVsbG8=\n') - self.assertEqual(binascii.b2a_base64(b, newline=False), - b'aGVsbG8=') - - - class ArrayBinASCIITest(BinASCIITest): - def type2test(self, s): - return array.array('B', list(s)) - - - class BytearrayBinASCIITest(BinASCIITest): - type2test = bytearray - - - class MemoryviewBinASCIITest(BinASCIITest): - type2test = memoryview - - - if __name__ == "__main__": - unittest.main() diff --git a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_binhex.yaml b/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_binhex.yaml deleted file mode 100644 index 27445d78f..000000000 --- a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_binhex.yaml +++ /dev/null @@ -1,66 +0,0 @@ -python: | - """Test script for the binhex C module - - Uses the mechanism of the python binhex module - Based on an original test by Roger E. Masse. - """ - import binhex - import unittest - from test import support - - - class BinHexTestCase(unittest.TestCase): - - def setUp(self): - self.fname1 = support.TESTFN + "1" - self.fname2 = support.TESTFN + "2" - self.fname3 = support.TESTFN + "very_long_filename__very_long_filename__very_long_filename__very_long_filename__" - - def tearDown(self): - support.unlink(self.fname1) - support.unlink(self.fname2) - support.unlink(self.fname3) - - DATA = b'Jack is my hero' - - def test_binhex(self): - with open(self.fname1, 'wb') as f: - f.write(self.DATA) - - binhex.binhex(self.fname1, self.fname2) - - binhex.hexbin(self.fname2, self.fname1) - - with open(self.fname1, 'rb') as f: - finish = f.readline() - - self.assertEqual(self.DATA, finish) - - def test_binhex_error_on_long_filename(self): - """ - The testcase fails if no exception is raised when a filename parameter provided to binhex.binhex() - is too long, or if the exception raised in binhex.binhex() is not an instance of binhex.Error. - """ - f3 = open(self.fname3, 'wb') - f3.close() - - self.assertRaises(binhex.Error, binhex.binhex, self.fname3, self.fname2) - - def test_binhex_line_endings(self): - # bpo-29566: Ensure the line endings are those for macOS 9 - with open(self.fname1, 'wb') as f: - f.write(self.DATA) - - binhex.binhex(self.fname1, self.fname2) - - with open(self.fname2, 'rb') as fp: - contents = fp.read() - - self.assertNotIn(b'\n', contents) - - def test_main(): - support.run_unittest(BinHexTestCase) - - - if __name__ == "__main__": - test_main() diff --git a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_binop.yaml b/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_binop.yaml deleted file mode 100644 index 3aeae3b26..000000000 --- a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_binop.yaml +++ /dev/null @@ -1,441 +0,0 @@ -python: | - """Tests for binary operators on subtypes of built-in types.""" - - import unittest - from operator import eq, le, ne - from abc import ABCMeta - - def gcd(a, b): - """Greatest common divisor using Euclid's algorithm.""" - while a: - a, b = b%a, a - return b - - def isint(x): - """Test whether an object is an instance of int.""" - return isinstance(x, int) - - def isnum(x): - """Test whether an object is an instance of a built-in numeric type.""" - for T in int, float, complex: - if isinstance(x, T): - return 1 - return 0 - - def isRat(x): - """Test whether an object is an instance of the Rat class.""" - return isinstance(x, Rat) - - class Rat(object): - - """Rational number implemented as a normalized pair of ints.""" - - __slots__ = ['_Rat__num', '_Rat__den'] - - def __init__(self, num=0, den=1): - """Constructor: Rat([num[, den]]). - - The arguments must be ints, and default to (0, 1).""" - if not isint(num): - raise TypeError("Rat numerator must be int (%r)" % num) - if not isint(den): - raise TypeError("Rat denominator must be int (%r)" % den) - # But the zero is always on - if den == 0: - raise ZeroDivisionError("zero denominator") - g = gcd(den, num) - self.__num = int(num//g) - self.__den = int(den//g) - - def _get_num(self): - """Accessor function for read-only 'num' attribute of Rat.""" - return self.__num - num = property(_get_num, None) - - def _get_den(self): - """Accessor function for read-only 'den' attribute of Rat.""" - return self.__den - den = property(_get_den, None) - - def __repr__(self): - """Convert a Rat to a string resembling a Rat constructor call.""" - return "Rat(%d, %d)" % (self.__num, self.__den) - - def __str__(self): - """Convert a Rat to a string resembling a decimal numeric value.""" - return str(float(self)) - - def __float__(self): - """Convert a Rat to a float.""" - return self.__num*1.0/self.__den - - def __int__(self): - """Convert a Rat to an int; self.den must be 1.""" - if self.__den == 1: - try: - return int(self.__num) - except OverflowError: - raise OverflowError("%s too large to convert to int" % - repr(self)) - raise ValueError("can't convert %s to int" % repr(self)) - - def __add__(self, other): - """Add two Rats, or a Rat and a number.""" - if isint(other): - other = Rat(other) - if isRat(other): - return Rat(self.__num*other.__den + other.__num*self.__den, - self.__den*other.__den) - if isnum(other): - return float(self) + other - return NotImplemented - - __radd__ = __add__ - - def __sub__(self, other): - """Subtract two Rats, or a Rat and a number.""" - if isint(other): - other = Rat(other) - if isRat(other): - return Rat(self.__num*other.__den - other.__num*self.__den, - self.__den*other.__den) - if isnum(other): - return float(self) - other - return NotImplemented - - def __rsub__(self, other): - """Subtract two Rats, or a Rat and a number (reversed args).""" - if isint(other): - other = Rat(other) - if isRat(other): - return Rat(other.__num*self.__den - self.__num*other.__den, - self.__den*other.__den) - if isnum(other): - return other - float(self) - return NotImplemented - - def __mul__(self, other): - """Multiply two Rats, or a Rat and a number.""" - if isRat(other): - return Rat(self.__num*other.__num, self.__den*other.__den) - if isint(other): - return Rat(self.__num*other, self.__den) - if isnum(other): - return float(self)*other - return NotImplemented - - __rmul__ = __mul__ - - def __truediv__(self, other): - """Divide two Rats, or a Rat and a number.""" - if isRat(other): - return Rat(self.__num*other.__den, self.__den*other.__num) - if isint(other): - return Rat(self.__num, self.__den*other) - if isnum(other): - return float(self) / other - return NotImplemented - - def __rtruediv__(self, other): - """Divide two Rats, or a Rat and a number (reversed args).""" - if isRat(other): - return Rat(other.__num*self.__den, other.__den*self.__num) - if isint(other): - return Rat(other*self.__den, self.__num) - if isnum(other): - return other / float(self) - return NotImplemented - - def __floordiv__(self, other): - """Divide two Rats, returning the floored result.""" - if isint(other): - other = Rat(other) - elif not isRat(other): - return NotImplemented - x = self/other - return x.__num // x.__den - - def __rfloordiv__(self, other): - """Divide two Rats, returning the floored result (reversed args).""" - x = other/self - return x.__num // x.__den - - def __divmod__(self, other): - """Divide two Rats, returning quotient and remainder.""" - if isint(other): - other = Rat(other) - elif not isRat(other): - return NotImplemented - x = self//other - return (x, self - other * x) - - def __rdivmod__(self, other): - """Divide two Rats, returning quotient and remainder (reversed args).""" - if isint(other): - other = Rat(other) - elif not isRat(other): - return NotImplemented - return divmod(other, self) - - def __mod__(self, other): - """Take one Rat modulo another.""" - return divmod(self, other)[1] - - def __rmod__(self, other): - """Take one Rat modulo another (reversed args).""" - return divmod(other, self)[1] - - def __eq__(self, other): - """Compare two Rats for equality.""" - if isint(other): - return self.__den == 1 and self.__num == other - if isRat(other): - return self.__num == other.__num and self.__den == other.__den - if isnum(other): - return float(self) == other - return NotImplemented - - class RatTestCase(unittest.TestCase): - """Unit tests for Rat class and its support utilities.""" - - def test_gcd(self): - self.assertEqual(gcd(10, 12), 2) - self.assertEqual(gcd(10, 15), 5) - self.assertEqual(gcd(10, 11), 1) - self.assertEqual(gcd(100, 15), 5) - self.assertEqual(gcd(-10, 2), -2) - self.assertEqual(gcd(10, -2), 2) - self.assertEqual(gcd(-10, -2), -2) - for i in range(1, 20): - for j in range(1, 20): - self.assertTrue(gcd(i, j) > 0) - self.assertTrue(gcd(-i, j) < 0) - self.assertTrue(gcd(i, -j) > 0) - self.assertTrue(gcd(-i, -j) < 0) - - def test_constructor(self): - a = Rat(10, 15) - self.assertEqual(a.num, 2) - self.assertEqual(a.den, 3) - a = Rat(10, -15) - self.assertEqual(a.num, -2) - self.assertEqual(a.den, 3) - a = Rat(-10, 15) - self.assertEqual(a.num, -2) - self.assertEqual(a.den, 3) - a = Rat(-10, -15) - self.assertEqual(a.num, 2) - self.assertEqual(a.den, 3) - a = Rat(7) - self.assertEqual(a.num, 7) - self.assertEqual(a.den, 1) - try: - a = Rat(1, 0) - except ZeroDivisionError: - pass - else: - self.fail("Rat(1, 0) didn't raise ZeroDivisionError") - for bad in "0", 0.0, 0j, (), [], {}, None, Rat, unittest: - try: - a = Rat(bad) - except TypeError: - pass - else: - self.fail("Rat(%r) didn't raise TypeError" % bad) - try: - a = Rat(1, bad) - except TypeError: - pass - else: - self.fail("Rat(1, %r) didn't raise TypeError" % bad) - - def test_add(self): - self.assertEqual(Rat(2, 3) + Rat(1, 3), 1) - self.assertEqual(Rat(2, 3) + 1, Rat(5, 3)) - self.assertEqual(1 + Rat(2, 3), Rat(5, 3)) - self.assertEqual(1.0 + Rat(1, 2), 1.5) - self.assertEqual(Rat(1, 2) + 1.0, 1.5) - - def test_sub(self): - self.assertEqual(Rat(7, 2) - Rat(7, 5), Rat(21, 10)) - self.assertEqual(Rat(7, 5) - 1, Rat(2, 5)) - self.assertEqual(1 - Rat(3, 5), Rat(2, 5)) - self.assertEqual(Rat(3, 2) - 1.0, 0.5) - self.assertEqual(1.0 - Rat(1, 2), 0.5) - - def test_mul(self): - self.assertEqual(Rat(2, 3) * Rat(5, 7), Rat(10, 21)) - self.assertEqual(Rat(10, 3) * 3, 10) - self.assertEqual(3 * Rat(10, 3), 10) - self.assertEqual(Rat(10, 5) * 0.5, 1.0) - self.assertEqual(0.5 * Rat(10, 5), 1.0) - - def test_div(self): - self.assertEqual(Rat(10, 3) / Rat(5, 7), Rat(14, 3)) - self.assertEqual(Rat(10, 3) / 3, Rat(10, 9)) - self.assertEqual(2 / Rat(5), Rat(2, 5)) - self.assertEqual(3.0 * Rat(1, 2), 1.5) - self.assertEqual(Rat(1, 2) * 3.0, 1.5) - - def test_floordiv(self): - self.assertEqual(Rat(10) // Rat(4), 2) - self.assertEqual(Rat(10, 3) // Rat(4, 3), 2) - self.assertEqual(Rat(10) // 4, 2) - self.assertEqual(10 // Rat(4), 2) - - def test_eq(self): - self.assertEqual(Rat(10), Rat(20, 2)) - self.assertEqual(Rat(10), 10) - self.assertEqual(10, Rat(10)) - self.assertEqual(Rat(10), 10.0) - self.assertEqual(10.0, Rat(10)) - - def test_true_div(self): - self.assertEqual(Rat(10, 3) / Rat(5, 7), Rat(14, 3)) - self.assertEqual(Rat(10, 3) / 3, Rat(10, 9)) - self.assertEqual(2 / Rat(5), Rat(2, 5)) - self.assertEqual(3.0 * Rat(1, 2), 1.5) - self.assertEqual(Rat(1, 2) * 3.0, 1.5) - self.assertEqual(eval('1/2'), 0.5) - - # XXX Ran out of steam; TO DO: divmod, div, future division - - - class OperationLogger: - """Base class for classes with operation logging.""" - def __init__(self, logger): - self.logger = logger - def log_operation(self, *args): - self.logger(*args) - - def op_sequence(op, *classes): - """Return the sequence of operations that results from applying - the operation `op` to instances of the given classes.""" - log = [] - instances = [] - for c in classes: - instances.append(c(log.append)) - - try: - op(*instances) - except TypeError: - pass - return log - - class A(OperationLogger): - def __eq__(self, other): - self.log_operation('A.__eq__') - return NotImplemented - def __le__(self, other): - self.log_operation('A.__le__') - return NotImplemented - def __ge__(self, other): - self.log_operation('A.__ge__') - return NotImplemented - - class B(OperationLogger, metaclass=ABCMeta): - def __eq__(self, other): - self.log_operation('B.__eq__') - return NotImplemented - def __le__(self, other): - self.log_operation('B.__le__') - return NotImplemented - def __ge__(self, other): - self.log_operation('B.__ge__') - return NotImplemented - - class C(B): - def __eq__(self, other): - self.log_operation('C.__eq__') - return NotImplemented - def __le__(self, other): - self.log_operation('C.__le__') - return NotImplemented - def __ge__(self, other): - self.log_operation('C.__ge__') - return NotImplemented - - class V(OperationLogger): - """Virtual subclass of B""" - def __eq__(self, other): - self.log_operation('V.__eq__') - return NotImplemented - def __le__(self, other): - self.log_operation('V.__le__') - return NotImplemented - def __ge__(self, other): - self.log_operation('V.__ge__') - return NotImplemented - B.register(V) - - - class OperationOrderTests(unittest.TestCase): - def test_comparison_orders(self): - self.assertEqual(op_sequence(eq, A, A), ['A.__eq__', 'A.__eq__']) - self.assertEqual(op_sequence(eq, A, B), ['A.__eq__', 'B.__eq__']) - self.assertEqual(op_sequence(eq, B, A), ['B.__eq__', 'A.__eq__']) - # C is a subclass of B, so C.__eq__ is called first - self.assertEqual(op_sequence(eq, B, C), ['C.__eq__', 'B.__eq__']) - self.assertEqual(op_sequence(eq, C, B), ['C.__eq__', 'B.__eq__']) - - self.assertEqual(op_sequence(le, A, A), ['A.__le__', 'A.__ge__']) - self.assertEqual(op_sequence(le, A, B), ['A.__le__', 'B.__ge__']) - self.assertEqual(op_sequence(le, B, A), ['B.__le__', 'A.__ge__']) - self.assertEqual(op_sequence(le, B, C), ['C.__ge__', 'B.__le__']) - self.assertEqual(op_sequence(le, C, B), ['C.__le__', 'B.__ge__']) - - self.assertTrue(issubclass(V, B)) - self.assertEqual(op_sequence(eq, B, V), ['B.__eq__', 'V.__eq__']) - self.assertEqual(op_sequence(le, B, V), ['B.__le__', 'V.__ge__']) - - class SupEq(object): - """Class that can test equality""" - def __eq__(self, other): - return True - - class S(SupEq): - """Subclass of SupEq that should fail""" - __eq__ = None - - class F(object): - """Independent class that should fall back""" - - class X(object): - """Independent class that should fail""" - __eq__ = None - - class SN(SupEq): - """Subclass of SupEq that can test equality, but not non-equality""" - __ne__ = None - - class XN: - """Independent class that can test equality, but not non-equality""" - def __eq__(self, other): - return True - __ne__ = None - - class FallbackBlockingTests(unittest.TestCase): - """Unit tests for None method blocking""" - - def test_fallback_rmethod_blocking(self): - e, f, s, x = SupEq(), F(), S(), X() - self.assertEqual(e, e) - self.assertEqual(e, f) - self.assertEqual(f, e) - # left operand is checked first - self.assertEqual(e, x) - self.assertRaises(TypeError, eq, x, e) - # S is a subclass, so it's always checked first - self.assertRaises(TypeError, eq, e, s) - self.assertRaises(TypeError, eq, s, e) - - def test_fallback_ne_blocking(self): - e, sn, xn = SupEq(), SN(), XN() - self.assertFalse(e != e) - self.assertRaises(TypeError, ne, e, sn) - self.assertRaises(TypeError, ne, sn, e) - self.assertFalse(e != xn) - self.assertRaises(TypeError, ne, xn, e) - - if __name__ == "__main__": - unittest.main() diff --git a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_bisect.yaml b/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_bisect.yaml deleted file mode 100644 index 35379934f..000000000 --- a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_bisect.yaml +++ /dev/null @@ -1,329 +0,0 @@ -python: | - import sys - import unittest - from test import support - from collections import UserList - - py_bisect = support.import_fresh_module('bisect', blocked=['_bisect']) - c_bisect = support.import_fresh_module('bisect', fresh=['_bisect']) - - class Range(object): - """A trivial range()-like object that has an insert() method.""" - def __init__(self, start, stop): - self.start = start - self.stop = stop - self.last_insert = None - - def __len__(self): - return self.stop - self.start - - def __getitem__(self, idx): - n = self.stop - self.start - if idx < 0: - idx += n - if idx >= n: - raise IndexError(idx) - return self.start + idx - - def insert(self, idx, item): - self.last_insert = idx, item - - - class TestBisect: - def setUp(self): - self.precomputedCases = [ - (self.module.bisect_right, [], 1, 0), - (self.module.bisect_right, [1], 0, 0), - (self.module.bisect_right, [1], 1, 1), - (self.module.bisect_right, [1], 2, 1), - (self.module.bisect_right, [1, 1], 0, 0), - (self.module.bisect_right, [1, 1], 1, 2), - (self.module.bisect_right, [1, 1], 2, 2), - (self.module.bisect_right, [1, 1, 1], 0, 0), - (self.module.bisect_right, [1, 1, 1], 1, 3), - (self.module.bisect_right, [1, 1, 1], 2, 3), - (self.module.bisect_right, [1, 1, 1, 1], 0, 0), - (self.module.bisect_right, [1, 1, 1, 1], 1, 4), - (self.module.bisect_right, [1, 1, 1, 1], 2, 4), - (self.module.bisect_right, [1, 2], 0, 0), - (self.module.bisect_right, [1, 2], 1, 1), - (self.module.bisect_right, [1, 2], 1.5, 1), - (self.module.bisect_right, [1, 2], 2, 2), - (self.module.bisect_right, [1, 2], 3, 2), - (self.module.bisect_right, [1, 1, 2, 2], 0, 0), - (self.module.bisect_right, [1, 1, 2, 2], 1, 2), - (self.module.bisect_right, [1, 1, 2, 2], 1.5, 2), - (self.module.bisect_right, [1, 1, 2, 2], 2, 4), - (self.module.bisect_right, [1, 1, 2, 2], 3, 4), - (self.module.bisect_right, [1, 2, 3], 0, 0), - (self.module.bisect_right, [1, 2, 3], 1, 1), - (self.module.bisect_right, [1, 2, 3], 1.5, 1), - (self.module.bisect_right, [1, 2, 3], 2, 2), - (self.module.bisect_right, [1, 2, 3], 2.5, 2), - (self.module.bisect_right, [1, 2, 3], 3, 3), - (self.module.bisect_right, [1, 2, 3], 4, 3), - (self.module.bisect_right, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 0, 0), - (self.module.bisect_right, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 1, 1), - (self.module.bisect_right, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 1.5, 1), - (self.module.bisect_right, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 2, 3), - (self.module.bisect_right, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 2.5, 3), - (self.module.bisect_right, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 3, 6), - (self.module.bisect_right, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 3.5, 6), - (self.module.bisect_right, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 4, 10), - (self.module.bisect_right, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 5, 10), - - (self.module.bisect_left, [], 1, 0), - (self.module.bisect_left, [1], 0, 0), - (self.module.bisect_left, [1], 1, 0), - (self.module.bisect_left, [1], 2, 1), - (self.module.bisect_left, [1, 1], 0, 0), - (self.module.bisect_left, [1, 1], 1, 0), - (self.module.bisect_left, [1, 1], 2, 2), - (self.module.bisect_left, [1, 1, 1], 0, 0), - (self.module.bisect_left, [1, 1, 1], 1, 0), - (self.module.bisect_left, [1, 1, 1], 2, 3), - (self.module.bisect_left, [1, 1, 1, 1], 0, 0), - (self.module.bisect_left, [1, 1, 1, 1], 1, 0), - (self.module.bisect_left, [1, 1, 1, 1], 2, 4), - (self.module.bisect_left, [1, 2], 0, 0), - (self.module.bisect_left, [1, 2], 1, 0), - (self.module.bisect_left, [1, 2], 1.5, 1), - (self.module.bisect_left, [1, 2], 2, 1), - (self.module.bisect_left, [1, 2], 3, 2), - (self.module.bisect_left, [1, 1, 2, 2], 0, 0), - (self.module.bisect_left, [1, 1, 2, 2], 1, 0), - (self.module.bisect_left, [1, 1, 2, 2], 1.5, 2), - (self.module.bisect_left, [1, 1, 2, 2], 2, 2), - (self.module.bisect_left, [1, 1, 2, 2], 3, 4), - (self.module.bisect_left, [1, 2, 3], 0, 0), - (self.module.bisect_left, [1, 2, 3], 1, 0), - (self.module.bisect_left, [1, 2, 3], 1.5, 1), - (self.module.bisect_left, [1, 2, 3], 2, 1), - (self.module.bisect_left, [1, 2, 3], 2.5, 2), - (self.module.bisect_left, [1, 2, 3], 3, 2), - (self.module.bisect_left, [1, 2, 3], 4, 3), - (self.module.bisect_left, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 0, 0), - (self.module.bisect_left, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 1, 0), - (self.module.bisect_left, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 1.5, 1), - (self.module.bisect_left, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 2, 1), - (self.module.bisect_left, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 2.5, 3), - (self.module.bisect_left, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 3, 3), - (self.module.bisect_left, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 3.5, 6), - (self.module.bisect_left, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 4, 6), - (self.module.bisect_left, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 5, 10) - ] - - def test_precomputed(self): - for func, data, elem, expected in self.precomputedCases: - self.assertEqual(func(data, elem), expected) - self.assertEqual(func(UserList(data), elem), expected) - - def test_negative_lo(self): - # Issue 3301 - mod = self.module - self.assertRaises(ValueError, mod.bisect_left, [1, 2, 3], 5, -1, 3) - self.assertRaises(ValueError, mod.bisect_right, [1, 2, 3], 5, -1, 3) - self.assertRaises(ValueError, mod.insort_left, [1, 2, 3], 5, -1, 3) - self.assertRaises(ValueError, mod.insort_right, [1, 2, 3], 5, -1, 3) - - def test_large_range(self): - # Issue 13496 - mod = self.module - n = sys.maxsize - data = range(n-1) - self.assertEqual(mod.bisect_left(data, n-3), n-3) - self.assertEqual(mod.bisect_right(data, n-3), n-2) - self.assertEqual(mod.bisect_left(data, n-3, n-10, n), n-3) - self.assertEqual(mod.bisect_right(data, n-3, n-10, n), n-2) - - def test_large_pyrange(self): - # Same as above, but without C-imposed limits on range() parameters - mod = self.module - n = sys.maxsize - data = Range(0, n-1) - self.assertEqual(mod.bisect_left(data, n-3), n-3) - self.assertEqual(mod.bisect_right(data, n-3), n-2) - self.assertEqual(mod.bisect_left(data, n-3, n-10, n), n-3) - self.assertEqual(mod.bisect_right(data, n-3, n-10, n), n-2) - x = n - 100 - mod.insort_left(data, x, x - 50, x + 50) - self.assertEqual(data.last_insert, (x, x)) - x = n - 200 - mod.insort_right(data, x, x - 50, x + 50) - self.assertEqual(data.last_insert, (x + 1, x)) - - def test_random(self, n=25): - from random import randrange - for i in range(n): - data = [randrange(0, n, 2) for j in range(i)] - data.sort() - elem = randrange(-1, n+1) - ip = self.module.bisect_left(data, elem) - if ip < len(data): - self.assertTrue(elem <= data[ip]) - if ip > 0: - self.assertTrue(data[ip-1] < elem) - ip = self.module.bisect_right(data, elem) - if ip < len(data): - self.assertTrue(elem < data[ip]) - if ip > 0: - self.assertTrue(data[ip-1] <= elem) - - def test_optionalSlicing(self): - for func, data, elem, expected in self.precomputedCases: - for lo in range(4): - lo = min(len(data), lo) - for hi in range(3,8): - hi = min(len(data), hi) - ip = func(data, elem, lo, hi) - self.assertTrue(lo <= ip <= hi) - if func is self.module.bisect_left and ip < hi: - self.assertTrue(elem <= data[ip]) - if func is self.module.bisect_left and ip > lo: - self.assertTrue(data[ip-1] < elem) - if func is self.module.bisect_right and ip < hi: - self.assertTrue(elem < data[ip]) - if func is self.module.bisect_right and ip > lo: - self.assertTrue(data[ip-1] <= elem) - self.assertEqual(ip, max(lo, min(hi, expected))) - - def test_backcompatibility(self): - self.assertEqual(self.module.bisect, self.module.bisect_right) - - def test_keyword_args(self): - data = [10, 20, 30, 40, 50] - self.assertEqual(self.module.bisect_left(a=data, x=25, lo=1, hi=3), 2) - self.assertEqual(self.module.bisect_right(a=data, x=25, lo=1, hi=3), 2) - self.assertEqual(self.module.bisect(a=data, x=25, lo=1, hi=3), 2) - self.module.insort_left(a=data, x=25, lo=1, hi=3) - self.module.insort_right(a=data, x=25, lo=1, hi=3) - self.module.insort(a=data, x=25, lo=1, hi=3) - self.assertEqual(data, [10, 20, 25, 25, 25, 30, 40, 50]) - - class TestBisectPython(TestBisect, unittest.TestCase): - module = py_bisect - - class TestBisectC(TestBisect, unittest.TestCase): - module = c_bisect - - #============================================================================== - - class TestInsort: - def test_vsBuiltinSort(self, n=500): - from random import choice - for insorted in (list(), UserList()): - for i in range(n): - digit = choice("0123456789") - if digit in "02468": - f = self.module.insort_left - else: - f = self.module.insort_right - f(insorted, digit) - self.assertEqual(sorted(insorted), insorted) - - def test_backcompatibility(self): - self.assertEqual(self.module.insort, self.module.insort_right) - - def test_listDerived(self): - class List(list): - data = [] - def insert(self, index, item): - self.data.insert(index, item) - - lst = List() - self.module.insort_left(lst, 10) - self.module.insort_right(lst, 5) - self.assertEqual([5, 10], lst.data) - - class TestInsortPython(TestInsort, unittest.TestCase): - module = py_bisect - - class TestInsortC(TestInsort, unittest.TestCase): - module = c_bisect - - #============================================================================== - - class LenOnly: - "Dummy sequence class defining __len__ but not __getitem__." - def __len__(self): - return 10 - - class GetOnly: - "Dummy sequence class defining __getitem__ but not __len__." - def __getitem__(self, ndx): - return 10 - - class CmpErr: - "Dummy element that always raises an error during comparison" - def __lt__(self, other): - raise ZeroDivisionError - __gt__ = __lt__ - __le__ = __lt__ - __ge__ = __lt__ - __eq__ = __lt__ - __ne__ = __lt__ - - class TestErrorHandling: - def test_non_sequence(self): - for f in (self.module.bisect_left, self.module.bisect_right, - self.module.insort_left, self.module.insort_right): - self.assertRaises(TypeError, f, 10, 10) - - def test_len_only(self): - for f in (self.module.bisect_left, self.module.bisect_right, - self.module.insort_left, self.module.insort_right): - self.assertRaises(TypeError, f, LenOnly(), 10) - - def test_get_only(self): - for f in (self.module.bisect_left, self.module.bisect_right, - self.module.insort_left, self.module.insort_right): - self.assertRaises(TypeError, f, GetOnly(), 10) - - def test_cmp_err(self): - seq = [CmpErr(), CmpErr(), CmpErr()] - for f in (self.module.bisect_left, self.module.bisect_right, - self.module.insort_left, self.module.insort_right): - self.assertRaises(ZeroDivisionError, f, seq, 10) - - def test_arg_parsing(self): - for f in (self.module.bisect_left, self.module.bisect_right, - self.module.insort_left, self.module.insort_right): - self.assertRaises(TypeError, f, 10) - - class TestErrorHandlingPython(TestErrorHandling, unittest.TestCase): - module = py_bisect - - class TestErrorHandlingC(TestErrorHandling, unittest.TestCase): - module = c_bisect - - #============================================================================== - - class TestDocExample: - def test_grades(self): - def grade(score, breakpoints=[60, 70, 80, 90], grades='FDCBA'): - i = self.module.bisect(breakpoints, score) - return grades[i] - - result = [grade(score) for score in [33, 99, 77, 70, 89, 90, 100]] - self.assertEqual(result, ['F', 'A', 'C', 'C', 'B', 'A', 'A']) - - def test_colors(self): - data = [('red', 5), ('blue', 1), ('yellow', 8), ('black', 0)] - data.sort(key=lambda r: r[1]) - keys = [r[1] for r in data] - bisect_left = self.module.bisect_left - self.assertEqual(data[bisect_left(keys, 0)], ('black', 0)) - self.assertEqual(data[bisect_left(keys, 1)], ('blue', 1)) - self.assertEqual(data[bisect_left(keys, 5)], ('red', 5)) - self.assertEqual(data[bisect_left(keys, 8)], ('yellow', 8)) - - class TestDocExamplePython(TestDocExample, unittest.TestCase): - module = py_bisect - - class TestDocExampleC(TestDocExample, unittest.TestCase): - module = c_bisect - - #------------------------------------------------------------------------------ - - if __name__ == "__main__": - unittest.main() diff --git a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_bool.yaml b/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_bool.yaml deleted file mode 100644 index fc1036bc2..000000000 --- a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_bool.yaml +++ /dev/null @@ -1,370 +0,0 @@ -python: | - # Test properties of bool promised by PEP 285 - - import unittest - from test import support - - import os - - class BoolTest(unittest.TestCase): - - def test_subclass(self): - try: - class C(bool): - pass - except TypeError: - pass - else: - self.fail("bool should not be subclassable") - - self.assertRaises(TypeError, int.__new__, bool, 0) - - def test_print(self): - try: - with open(support.TESTFN, "w") as fo: - print(False, True, file=fo) - with open(support.TESTFN, "r") as fi: - self.assertEqual(fi.read(), 'False True\n') - finally: - os.remove(support.TESTFN) - - def test_repr(self): - self.assertEqual(repr(False), 'False') - self.assertEqual(repr(True), 'True') - self.assertEqual(eval(repr(False)), False) - self.assertEqual(eval(repr(True)), True) - - def test_str(self): - self.assertEqual(str(False), 'False') - self.assertEqual(str(True), 'True') - - def test_int(self): - self.assertEqual(int(False), 0) - self.assertIsNot(int(False), False) - self.assertEqual(int(True), 1) - self.assertIsNot(int(True), True) - - def test_float(self): - self.assertEqual(float(False), 0.0) - self.assertIsNot(float(False), False) - self.assertEqual(float(True), 1.0) - self.assertIsNot(float(True), True) - - def test_math(self): - self.assertEqual(+False, 0) - self.assertIsNot(+False, False) - self.assertEqual(-False, 0) - self.assertIsNot(-False, False) - self.assertEqual(abs(False), 0) - self.assertIsNot(abs(False), False) - self.assertEqual(+True, 1) - self.assertIsNot(+True, True) - self.assertEqual(-True, -1) - self.assertEqual(abs(True), 1) - self.assertIsNot(abs(True), True) - self.assertEqual(~False, -1) - self.assertEqual(~True, -2) - - self.assertEqual(False+2, 2) - self.assertEqual(True+2, 3) - self.assertEqual(2+False, 2) - self.assertEqual(2+True, 3) - - self.assertEqual(False+False, 0) - self.assertIsNot(False+False, False) - self.assertEqual(False+True, 1) - self.assertIsNot(False+True, True) - self.assertEqual(True+False, 1) - self.assertIsNot(True+False, True) - self.assertEqual(True+True, 2) - - self.assertEqual(True-True, 0) - self.assertIsNot(True-True, False) - self.assertEqual(False-False, 0) - self.assertIsNot(False-False, False) - self.assertEqual(True-False, 1) - self.assertIsNot(True-False, True) - self.assertEqual(False-True, -1) - - self.assertEqual(True*1, 1) - self.assertEqual(False*1, 0) - self.assertIsNot(False*1, False) - - self.assertEqual(True/1, 1) - self.assertIsNot(True/1, True) - self.assertEqual(False/1, 0) - self.assertIsNot(False/1, False) - - self.assertEqual(True%1, 0) - self.assertIsNot(True%1, False) - self.assertEqual(True%2, 1) - self.assertIsNot(True%2, True) - self.assertEqual(False%1, 0) - self.assertIsNot(False%1, False) - - for b in False, True: - for i in 0, 1, 2: - self.assertEqual(b**i, int(b)**i) - self.assertIsNot(b**i, bool(int(b)**i)) - - for a in False, True: - for b in False, True: - self.assertIs(a&b, bool(int(a)&int(b))) - self.assertIs(a|b, bool(int(a)|int(b))) - self.assertIs(a^b, bool(int(a)^int(b))) - self.assertEqual(a&int(b), int(a)&int(b)) - self.assertIsNot(a&int(b), bool(int(a)&int(b))) - self.assertEqual(a|int(b), int(a)|int(b)) - self.assertIsNot(a|int(b), bool(int(a)|int(b))) - self.assertEqual(a^int(b), int(a)^int(b)) - self.assertIsNot(a^int(b), bool(int(a)^int(b))) - self.assertEqual(int(a)&b, int(a)&int(b)) - self.assertIsNot(int(a)&b, bool(int(a)&int(b))) - self.assertEqual(int(a)|b, int(a)|int(b)) - self.assertIsNot(int(a)|b, bool(int(a)|int(b))) - self.assertEqual(int(a)^b, int(a)^int(b)) - self.assertIsNot(int(a)^b, bool(int(a)^int(b))) - - self.assertIs(1==1, True) - self.assertIs(1==0, False) - self.assertIs(0<1, True) - self.assertIs(1<0, False) - self.assertIs(0<=0, True) - self.assertIs(1<=0, False) - self.assertIs(1>0, True) - self.assertIs(1>1, False) - self.assertIs(1>=1, True) - self.assertIs(0>=1, False) - self.assertIs(0!=1, True) - self.assertIs(0!=0, False) - - x = [1] - self.assertIs(x is x, True) - self.assertIs(x is not x, False) - - self.assertIs(1 in x, True) - self.assertIs(0 in x, False) - self.assertIs(1 not in x, False) - self.assertIs(0 not in x, True) - - x = {1: 2} - self.assertIs(x is x, True) - self.assertIs(x is not x, False) - - self.assertIs(1 in x, True) - self.assertIs(0 in x, False) - self.assertIs(1 not in x, False) - self.assertIs(0 not in x, True) - - self.assertIs(not True, False) - self.assertIs(not False, True) - - def test_convert(self): - self.assertRaises(TypeError, bool, 42, 42) - self.assertIs(bool(10), True) - self.assertIs(bool(1), True) - self.assertIs(bool(-1), True) - self.assertIs(bool(0), False) - self.assertIs(bool("hello"), True) - self.assertIs(bool(""), False) - self.assertIs(bool(), False) - - def test_keyword_args(self): - with self.assertRaisesRegex(TypeError, 'keyword argument'): - bool(x=10) - - def test_format(self): - self.assertEqual("%d" % False, "0") - self.assertEqual("%d" % True, "1") - self.assertEqual("%x" % False, "0") - self.assertEqual("%x" % True, "1") - - def test_hasattr(self): - self.assertIs(hasattr([], "append"), True) - self.assertIs(hasattr([], "wobble"), False) - - def test_callable(self): - self.assertIs(callable(len), True) - self.assertIs(callable(1), False) - - def test_isinstance(self): - self.assertIs(isinstance(True, bool), True) - self.assertIs(isinstance(False, bool), True) - self.assertIs(isinstance(True, int), True) - self.assertIs(isinstance(False, int), True) - self.assertIs(isinstance(1, bool), False) - self.assertIs(isinstance(0, bool), False) - - def test_issubclass(self): - self.assertIs(issubclass(bool, int), True) - self.assertIs(issubclass(int, bool), False) - - def test_contains(self): - self.assertIs(1 in {}, False) - self.assertIs(1 in {1:1}, True) - - def test_string(self): - self.assertIs("xyz".endswith("z"), True) - self.assertIs("xyz".endswith("x"), False) - self.assertIs("xyz0123".isalnum(), True) - self.assertIs("@#$%".isalnum(), False) - self.assertIs("xyz".isalpha(), True) - self.assertIs("@#$%".isalpha(), False) - self.assertIs("0123".isdigit(), True) - self.assertIs("xyz".isdigit(), False) - self.assertIs("xyz".islower(), True) - self.assertIs("XYZ".islower(), False) - self.assertIs("0123".isdecimal(), True) - self.assertIs("xyz".isdecimal(), False) - self.assertIs("0123".isnumeric(), True) - self.assertIs("xyz".isnumeric(), False) - self.assertIs(" ".isspace(), True) - self.assertIs("\xa0".isspace(), True) - self.assertIs("\u3000".isspace(), True) - self.assertIs("XYZ".isspace(), False) - self.assertIs("X".istitle(), True) - self.assertIs("x".istitle(), False) - self.assertIs("XYZ".isupper(), True) - self.assertIs("xyz".isupper(), False) - self.assertIs("xyz".startswith("x"), True) - self.assertIs("xyz".startswith("z"), False) - - def test_boolean(self): - self.assertEqual(True & 1, 1) - self.assertNotIsInstance(True & 1, bool) - self.assertIs(True & True, True) - - self.assertEqual(True | 1, 1) - self.assertNotIsInstance(True | 1, bool) - self.assertIs(True | True, True) - - self.assertEqual(True ^ 1, 0) - self.assertNotIsInstance(True ^ 1, bool) - self.assertIs(True ^ True, False) - - def test_fileclosed(self): - try: - with open(support.TESTFN, "w") as f: - self.assertIs(f.closed, False) - self.assertIs(f.closed, True) - finally: - os.remove(support.TESTFN) - - def test_types(self): - # types are always true. - for t in [bool, complex, dict, float, int, list, object, - set, str, tuple, type]: - self.assertIs(bool(t), True) - - def test_operator(self): - import operator - self.assertIs(operator.truth(0), False) - self.assertIs(operator.truth(1), True) - self.assertIs(operator.not_(1), False) - self.assertIs(operator.not_(0), True) - self.assertIs(operator.contains([], 1), False) - self.assertIs(operator.contains([1], 1), True) - self.assertIs(operator.lt(0, 0), False) - self.assertIs(operator.lt(0, 1), True) - self.assertIs(operator.is_(True, True), True) - self.assertIs(operator.is_(True, False), False) - self.assertIs(operator.is_not(True, True), False) - self.assertIs(operator.is_not(True, False), True) - - def test_marshal(self): - import marshal - self.assertIs(marshal.loads(marshal.dumps(True)), True) - self.assertIs(marshal.loads(marshal.dumps(False)), False) - - def test_pickle(self): - import pickle - for proto in range(pickle.HIGHEST_PROTOCOL + 1): - self.assertIs(pickle.loads(pickle.dumps(True, proto)), True) - self.assertIs(pickle.loads(pickle.dumps(False, proto)), False) - - def test_picklevalues(self): - # Test for specific backwards-compatible pickle values - import pickle - self.assertEqual(pickle.dumps(True, protocol=0), b"I01\n.") - self.assertEqual(pickle.dumps(False, protocol=0), b"I00\n.") - self.assertEqual(pickle.dumps(True, protocol=1), b"I01\n.") - self.assertEqual(pickle.dumps(False, protocol=1), b"I00\n.") - self.assertEqual(pickle.dumps(True, protocol=2), b'\x80\x02\x88.') - self.assertEqual(pickle.dumps(False, protocol=2), b'\x80\x02\x89.') - - def test_convert_to_bool(self): - # Verify that TypeError occurs when bad things are returned - # from __bool__(). This isn't really a bool test, but - # it's related. - check = lambda o: self.assertRaises(TypeError, bool, o) - class Foo(object): - def __bool__(self): - return self - check(Foo()) - - class Bar(object): - def __bool__(self): - return "Yes" - check(Bar()) - - class Baz(int): - def __bool__(self): - return self - check(Baz()) - - # __bool__() must return a bool not an int - class Spam(int): - def __bool__(self): - return 1 - check(Spam()) - - class Eggs: - def __len__(self): - return -1 - self.assertRaises(ValueError, bool, Eggs()) - - def test_from_bytes(self): - self.assertIs(bool.from_bytes(b'\x00'*8, 'big'), False) - self.assertIs(bool.from_bytes(b'abcd', 'little'), True) - - def test_sane_len(self): - # this test just tests our assumptions about __len__ - # this will start failing if __len__ changes assertions - for badval in ['illegal', -1, 1 << 32]: - class A: - def __len__(self): - return badval - try: - bool(A()) - except (Exception) as e_bool: - try: - len(A()) - except (Exception) as e_len: - self.assertEqual(str(e_bool), str(e_len)) - - def test_blocked(self): - class A: - __bool__ = None - self.assertRaises(TypeError, bool, A()) - - class B: - def __len__(self): - return 10 - __bool__ = None - self.assertRaises(TypeError, bool, B()) - - def test_real_and_imag(self): - self.assertEqual(True.real, 1) - self.assertEqual(True.imag, 0) - self.assertIs(type(True.real), int) - self.assertIs(type(True.imag), int) - self.assertEqual(False.real, 0) - self.assertEqual(False.imag, 0) - self.assertIs(type(False.real), int) - self.assertIs(type(False.imag), int) - - def test_main(): - support.run_unittest(BoolTest) - - if __name__ == "__main__": - test_main() diff --git a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_buffer.yaml b/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_buffer.yaml deleted file mode 100644 index 1bb8c823f..000000000 --- a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_buffer.yaml +++ /dev/null @@ -1,4424 +0,0 @@ -python: | - # - # The ndarray object from _testbuffer.c is a complete implementation of - # a PEP-3118 buffer provider. It is independent from NumPy's ndarray - # and the tests don't require NumPy. - # - # If NumPy is present, some tests check both ndarray implementations - # against each other. - # - # Most ndarray tests also check that memoryview(ndarray) behaves in - # the same way as the original. Thus, a substantial part of the - # memoryview tests is now in this module. - # - # Written and designed by Stefan Krah for Python 3.3. - # - - import contextlib - import unittest - from test import support - from itertools import permutations, product - from random import randrange, sample, choice - import warnings - import sys, array, io, os - from decimal import Decimal - from fractions import Fraction - - try: - from _testbuffer import * - except ImportError: - ndarray = None - - try: - import struct - except ImportError: - struct = None - - try: - import ctypes - except ImportError: - ctypes = None - - try: - with support.EnvironmentVarGuard() as os.environ, \ - warnings.catch_warnings(): - from numpy import ndarray as numpy_array - except ImportError: - numpy_array = None - - - SHORT_TEST = True - - - # ====================================================================== - # Random lists by format specifier - # ====================================================================== - - # Native format chars and their ranges. - NATIVE = { - '?':0, 'c':0, 'b':0, 'B':0, - 'h':0, 'H':0, 'i':0, 'I':0, - 'l':0, 'L':0, 'n':0, 'N':0, - 'f':0, 'd':0, 'P':0 - } - - # NumPy does not have 'n' or 'N': - if numpy_array: - del NATIVE['n'] - del NATIVE['N'] - - if struct: - try: - # Add "qQ" if present in native mode. - struct.pack('Q', 2**64-1) - NATIVE['q'] = 0 - NATIVE['Q'] = 0 - except struct.error: - pass - - # Standard format chars and their ranges. - STANDARD = { - '?':(0, 2), 'c':(0, 1<<8), - 'b':(-(1<<7), 1<<7), 'B':(0, 1<<8), - 'h':(-(1<<15), 1<<15), 'H':(0, 1<<16), - 'i':(-(1<<31), 1<<31), 'I':(0, 1<<32), - 'l':(-(1<<31), 1<<31), 'L':(0, 1<<32), - 'q':(-(1<<63), 1<<63), 'Q':(0, 1<<64), - 'f':(-(1<<63), 1<<63), 'd':(-(1<<1023), 1<<1023) - } - - def native_type_range(fmt): - """Return range of a native type.""" - if fmt == 'c': - lh = (0, 256) - elif fmt == '?': - lh = (0, 2) - elif fmt == 'f': - lh = (-(1<<63), 1<<63) - elif fmt == 'd': - lh = (-(1<<1023), 1<<1023) - else: - for exp in (128, 127, 64, 63, 32, 31, 16, 15, 8, 7): - try: - struct.pack(fmt, (1<':STANDARD, - '=':STANDARD, - '!':STANDARD - } - - if struct: - for fmt in fmtdict['@']: - fmtdict['@'][fmt] = native_type_range(fmt) - - MEMORYVIEW = NATIVE.copy() - ARRAY = NATIVE.copy() - for k in NATIVE: - if not k in "bBhHiIlLfd": - del ARRAY[k] - - BYTEFMT = NATIVE.copy() - for k in NATIVE: - if not k in "Bbc": - del BYTEFMT[k] - - fmtdict['m'] = MEMORYVIEW - fmtdict['@m'] = MEMORYVIEW - fmtdict['a'] = ARRAY - fmtdict['b'] = BYTEFMT - fmtdict['@b'] = BYTEFMT - - # Capabilities of the test objects: - MODE = 0 - MULT = 1 - cap = { # format chars # multiplier - 'ndarray': (['', '@', '<', '>', '=', '!'], ['', '1', '2', '3']), - 'array': (['a'], ['']), - 'numpy': ([''], ['']), - 'memoryview': (['@m', 'm'], ['']), - 'bytefmt': (['@b', 'b'], ['']), - } - - def randrange_fmt(mode, char, obj): - """Return random item for a type specified by a mode and a single - format character.""" - x = randrange(*fmtdict[mode][char]) - if char == 'c': - x = bytes([x]) - if obj == 'numpy' and x == b'\x00': - # http://projects.scipy.org/numpy/ticket/1925 - x = b'\x01' - if char == '?': - x = bool(x) - if char == 'f' or char == 'd': - x = struct.pack(char, x) - x = struct.unpack(char, x)[0] - return x - - def gen_item(fmt, obj): - """Return single random item.""" - mode, chars = fmt.split('#') - x = [] - for c in chars: - x.append(randrange_fmt(mode, c, obj)) - return x[0] if len(x) == 1 else tuple(x) - - def gen_items(n, fmt, obj): - """Return a list of random items (or a scalar).""" - if n == 0: - return gen_item(fmt, obj) - lst = [0] * n - for i in range(n): - lst[i] = gen_item(fmt, obj) - return lst - - def struct_items(n, obj): - mode = choice(cap[obj][MODE]) - xfmt = mode + '#' - fmt = mode.strip('amb') - nmemb = randrange(2, 10) # number of struct members - for _ in range(nmemb): - char = choice(tuple(fmtdict[mode])) - multiplier = choice(cap[obj][MULT]) - xfmt += (char * int(multiplier if multiplier else 1)) - fmt += (multiplier + char) - items = gen_items(n, xfmt, obj) - item = gen_item(xfmt, obj) - return fmt, items, item - - def randitems(n, obj='ndarray', mode=None, char=None): - """Return random format, items, item.""" - if mode is None: - mode = choice(cap[obj][MODE]) - if char is None: - char = choice(tuple(fmtdict[mode])) - multiplier = choice(cap[obj][MULT]) - fmt = mode + '#' + char * int(multiplier if multiplier else 1) - items = gen_items(n, fmt, obj) - item = gen_item(fmt, obj) - fmt = mode.strip('amb') + multiplier + char - return fmt, items, item - - def iter_mode(n, obj='ndarray'): - """Iterate through supported mode/char combinations.""" - for mode in cap[obj][MODE]: - for char in fmtdict[mode]: - yield randitems(n, obj, mode, char) - - def iter_format(nitems, testobj='ndarray'): - """Yield (format, items, item) for all possible modes and format - characters plus one random compound format string.""" - for t in iter_mode(nitems, testobj): - yield t - if testobj != 'ndarray': - return - yield struct_items(nitems, testobj) - - - def is_byte_format(fmt): - return 'c' in fmt or 'b' in fmt or 'B' in fmt - - def is_memoryview_format(fmt): - """format suitable for memoryview""" - x = len(fmt) - return ((x == 1 or (x == 2 and fmt[0] == '@')) and - fmt[x-1] in MEMORYVIEW) - - NON_BYTE_FORMAT = [c for c in fmtdict['@'] if not is_byte_format(c)] - - - # ====================================================================== - # Multi-dimensional tolist(), slicing and slice assignments - # ====================================================================== - - def atomp(lst): - """Tuple items (representing structs) are regarded as atoms.""" - return not isinstance(lst, list) - - def listp(lst): - return isinstance(lst, list) - - def prod(lst): - """Product of list elements.""" - if len(lst) == 0: - return 0 - x = lst[0] - for v in lst[1:]: - x *= v - return x - - def strides_from_shape(ndim, shape, itemsize, layout): - """Calculate strides of a contiguous array. Layout is 'C' or - 'F' (Fortran).""" - if ndim == 0: - return () - if layout == 'C': - strides = list(shape[1:]) + [itemsize] - for i in range(ndim-2, -1, -1): - strides[i] *= strides[i+1] - else: - strides = [itemsize] + list(shape[:-1]) - for i in range(1, ndim): - strides[i] *= strides[i-1] - return strides - - def _ca(items, s): - """Convert flat item list to the nested list representation of a - multidimensional C array with shape 's'.""" - if atomp(items): - return items - if len(s) == 0: - return items[0] - lst = [0] * s[0] - stride = len(items) // s[0] if s[0] else 0 - for i in range(s[0]): - start = i*stride - lst[i] = _ca(items[start:start+stride], s[1:]) - return lst - - def _fa(items, s): - """Convert flat item list to the nested list representation of a - multidimensional Fortran array with shape 's'.""" - if atomp(items): - return items - if len(s) == 0: - return items[0] - lst = [0] * s[0] - stride = s[0] - for i in range(s[0]): - lst[i] = _fa(items[i::stride], s[1:]) - return lst - - def carray(items, shape): - if listp(items) and not 0 in shape and prod(shape) != len(items): - raise ValueError("prod(shape) != len(items)") - return _ca(items, shape) - - def farray(items, shape): - if listp(items) and not 0 in shape and prod(shape) != len(items): - raise ValueError("prod(shape) != len(items)") - return _fa(items, shape) - - def indices(shape): - """Generate all possible tuples of indices.""" - iterables = [range(v) for v in shape] - return product(*iterables) - - def getindex(ndim, ind, strides): - """Convert multi-dimensional index to the position in the flat list.""" - ret = 0 - for i in range(ndim): - ret += strides[i] * ind[i] - return ret - - def transpose(src, shape): - """Transpose flat item list that is regarded as a multi-dimensional - matrix defined by shape: dest...[k][j][i] = src[i][j][k]... """ - if not shape: - return src - ndim = len(shape) - sstrides = strides_from_shape(ndim, shape, 1, 'C') - dstrides = strides_from_shape(ndim, shape[::-1], 1, 'C') - dest = [0] * len(src) - for ind in indices(shape): - fr = getindex(ndim, ind, sstrides) - to = getindex(ndim, ind[::-1], dstrides) - dest[to] = src[fr] - return dest - - def _flatten(lst): - """flatten list""" - if lst == []: - return lst - if atomp(lst): - return [lst] - return _flatten(lst[0]) + _flatten(lst[1:]) - - def flatten(lst): - """flatten list or return scalar""" - if atomp(lst): # scalar - return lst - return _flatten(lst) - - def slice_shape(lst, slices): - """Get the shape of lst after slicing: slices is a list of slice - objects.""" - if atomp(lst): - return [] - return [len(lst[slices[0]])] + slice_shape(lst[0], slices[1:]) - - def multislice(lst, slices): - """Multi-dimensional slicing: slices is a list of slice objects.""" - if atomp(lst): - return lst - return [multislice(sublst, slices[1:]) for sublst in lst[slices[0]]] - - def m_assign(llst, rlst, lslices, rslices): - """Multi-dimensional slice assignment: llst and rlst are the operands, - lslices and rslices are lists of slice objects. llst and rlst must - have the same structure. - - For a two-dimensional example, this is not implemented in Python: - - llst[0:3:2, 0:3:2] = rlst[1:3:1, 1:3:1] - - Instead we write: - - lslices = [slice(0,3,2), slice(0,3,2)] - rslices = [slice(1,3,1), slice(1,3,1)] - multislice_assign(llst, rlst, lslices, rslices) - """ - if atomp(rlst): - return rlst - rlst = [m_assign(l, r, lslices[1:], rslices[1:]) - for l, r in zip(llst[lslices[0]], rlst[rslices[0]])] - llst[lslices[0]] = rlst - return llst - - def cmp_structure(llst, rlst, lslices, rslices): - """Compare the structure of llst[lslices] and rlst[rslices].""" - lshape = slice_shape(llst, lslices) - rshape = slice_shape(rlst, rslices) - if (len(lshape) != len(rshape)): - return -1 - for i in range(len(lshape)): - if lshape[i] != rshape[i]: - return -1 - if lshape[i] == 0: - return 0 - return 0 - - def multislice_assign(llst, rlst, lslices, rslices): - """Return llst after assigning: llst[lslices] = rlst[rslices]""" - if cmp_structure(llst, rlst, lslices, rslices) < 0: - raise ValueError("lvalue and rvalue have different structures") - return m_assign(llst, rlst, lslices, rslices) - - - # ====================================================================== - # Random structures - # ====================================================================== - - # - # PEP-3118 is very permissive with respect to the contents of a - # Py_buffer. In particular: - # - # - shape can be zero - # - strides can be any integer, including zero - # - offset can point to any location in the underlying - # memory block, provided that it is a multiple of - # itemsize. - # - # The functions in this section test and verify random structures - # in full generality. A structure is valid iff it fits in the - # underlying memory block. - # - # The structure 't' (short for 'tuple') is fully defined by: - # - # t = (memlen, itemsize, ndim, shape, strides, offset) - # - - def verify_structure(memlen, itemsize, ndim, shape, strides, offset): - """Verify that the parameters represent a valid array within - the bounds of the allocated memory: - char *mem: start of the physical memory block - memlen: length of the physical memory block - offset: (char *)buf - mem - """ - if offset % itemsize: - return False - if offset < 0 or offset+itemsize > memlen: - return False - if any(v % itemsize for v in strides): - return False - - if ndim <= 0: - return ndim == 0 and not shape and not strides - if 0 in shape: - return True - - imin = sum(strides[j]*(shape[j]-1) for j in range(ndim) - if strides[j] <= 0) - imax = sum(strides[j]*(shape[j]-1) for j in range(ndim) - if strides[j] > 0) - - return 0 <= offset+imin and offset+imax+itemsize <= memlen - - def get_item(lst, indices): - for i in indices: - lst = lst[i] - return lst - - def memory_index(indices, t): - """Location of an item in the underlying memory.""" - memlen, itemsize, ndim, shape, strides, offset = t - p = offset - for i in range(ndim): - p += strides[i]*indices[i] - return p - - def is_overlapping(t): - """The structure 't' is overlapping if at least one memory location - is visited twice while iterating through all possible tuples of - indices.""" - memlen, itemsize, ndim, shape, strides, offset = t - visited = 1<= 95 and valid: - minshape = 0 - elif n >= 90: - minshape = 1 - shape = [0] * ndim - - for i in range(ndim): - shape[i] = randrange(minshape, maxshape+1) - else: - ndim = len(shape) - - maxstride = 5 - n = randrange(100) - zero_stride = True if n >= 95 and n & 1 else False - - strides = [0] * ndim - strides[ndim-1] = itemsize * randrange(-maxstride, maxstride+1) - if not zero_stride and strides[ndim-1] == 0: - strides[ndim-1] = itemsize - - for i in range(ndim-2, -1, -1): - maxstride *= shape[i+1] if shape[i+1] else 1 - if zero_stride: - strides[i] = itemsize * randrange(-maxstride, maxstride+1) - else: - strides[i] = ((1,-1)[randrange(2)] * - itemsize * randrange(1, maxstride+1)) - - imin = imax = 0 - if not 0 in shape: - imin = sum(strides[j]*(shape[j]-1) for j in range(ndim) - if strides[j] <= 0) - imax = sum(strides[j]*(shape[j]-1) for j in range(ndim) - if strides[j] > 0) - - nitems = imax - imin - if valid: - offset = -imin * itemsize - memlen = offset + (imax+1) * itemsize - else: - memlen = (-imin + imax) * itemsize - offset = -imin-itemsize if randrange(2) == 0 else memlen - return memlen, itemsize, ndim, shape, strides, offset - - def randslice_from_slicelen(slicelen, listlen): - """Create a random slice of len slicelen that fits into listlen.""" - maxstart = listlen - slicelen - start = randrange(maxstart+1) - maxstep = (listlen - start) // slicelen if slicelen else 1 - step = randrange(1, maxstep+1) - stop = start + slicelen * step - s = slice(start, stop, step) - _, _, _, control = slice_indices(s, listlen) - if control != slicelen: - raise RuntimeError - return s - - def randslice_from_shape(ndim, shape): - """Create two sets of slices for an array x with shape 'shape' - such that shapeof(x[lslices]) == shapeof(x[rslices]).""" - lslices = [0] * ndim - rslices = [0] * ndim - for n in range(ndim): - l = shape[n] - slicelen = randrange(1, l+1) if l > 0 else 0 - lslices[n] = randslice_from_slicelen(slicelen, l) - rslices[n] = randslice_from_slicelen(slicelen, l) - return tuple(lslices), tuple(rslices) - - def rand_aligned_slices(maxdim=5, maxshape=16): - """Create (lshape, rshape, tuple(lslices), tuple(rslices)) such that - shapeof(x[lslices]) == shapeof(y[rslices]), where x is an array - with shape 'lshape' and y is an array with shape 'rshape'.""" - ndim = randrange(1, maxdim+1) - minshape = 2 - n = randrange(100) - if n >= 95: - minshape = 0 - elif n >= 90: - minshape = 1 - all_random = True if randrange(100) >= 80 else False - lshape = [0]*ndim; rshape = [0]*ndim - lslices = [0]*ndim; rslices = [0]*ndim - - for n in range(ndim): - small = randrange(minshape, maxshape+1) - big = randrange(minshape, maxshape+1) - if big < small: - big, small = small, big - - # Create a slice that fits the smaller value. - if all_random: - start = randrange(-small, small+1) - stop = randrange(-small, small+1) - step = (1,-1)[randrange(2)] * randrange(1, small+2) - s_small = slice(start, stop, step) - _, _, _, slicelen = slice_indices(s_small, small) - else: - slicelen = randrange(1, small+1) if small > 0 else 0 - s_small = randslice_from_slicelen(slicelen, small) - - # Create a slice of the same length for the bigger value. - s_big = randslice_from_slicelen(slicelen, big) - if randrange(2) == 0: - rshape[n], lshape[n] = big, small - rslices[n], lslices[n] = s_big, s_small - else: - rshape[n], lshape[n] = small, big - rslices[n], lslices[n] = s_small, s_big - - return lshape, rshape, tuple(lslices), tuple(rslices) - - def randitems_from_structure(fmt, t): - """Return a list of random items for structure 't' with format - 'fmtchar'.""" - memlen, itemsize, _, _, _, _ = t - return gen_items(memlen//itemsize, '#'+fmt, 'numpy') - - def ndarray_from_structure(items, fmt, t, flags=0): - """Return ndarray from the tuple returned by rand_structure()""" - memlen, itemsize, ndim, shape, strides, offset = t - return ndarray(items, shape=shape, strides=strides, format=fmt, - offset=offset, flags=ND_WRITABLE|flags) - - def numpy_array_from_structure(items, fmt, t): - """Return numpy_array from the tuple returned by rand_structure()""" - memlen, itemsize, ndim, shape, strides, offset = t - buf = bytearray(memlen) - for j, v in enumerate(items): - struct.pack_into(fmt, buf, j*itemsize, v) - return numpy_array(buffer=buf, shape=shape, strides=strides, - dtype=fmt, offset=offset) - - - # ====================================================================== - # memoryview casts - # ====================================================================== - - def cast_items(exporter, fmt, itemsize, shape=None): - """Interpret the raw memory of 'exporter' as a list of items with - size 'itemsize'. If shape=None, the new structure is assumed to - be 1-D with n * itemsize = bytelen. If shape is given, the usual - constraint for contiguous arrays prod(shape) * itemsize = bytelen - applies. On success, return (items, shape). If the constraints - cannot be met, return (None, None). If a chunk of bytes is interpreted - as NaN as a result of float conversion, return ('nan', None).""" - bytelen = exporter.nbytes - if shape: - if prod(shape) * itemsize != bytelen: - return None, shape - elif shape == []: - if exporter.ndim == 0 or itemsize != bytelen: - return None, shape - else: - n, r = divmod(bytelen, itemsize) - shape = [n] - if r != 0: - return None, shape - - mem = exporter.tobytes() - byteitems = [mem[i:i+itemsize] for i in range(0, len(mem), itemsize)] - - items = [] - for v in byteitems: - item = struct.unpack(fmt, v)[0] - if item != item: - return 'nan', shape - items.append(item) - - return (items, shape) if shape != [] else (items[0], shape) - - def gencastshapes(): - """Generate shapes to test casting.""" - for n in range(32): - yield [n] - ndim = randrange(4, 6) - minshape = 1 if randrange(100) > 80 else 2 - yield [randrange(minshape, 5) for _ in range(ndim)] - ndim = randrange(2, 4) - minshape = 1 if randrange(100) > 80 else 2 - yield [randrange(minshape, 5) for _ in range(ndim)] - - - # ====================================================================== - # Actual tests - # ====================================================================== - - def genslices(n): - """Generate all possible slices for a single dimension.""" - return product(range(-n, n+1), range(-n, n+1), range(-n, n+1)) - - def genslices_ndim(ndim, shape): - """Generate all possible slice tuples for 'shape'.""" - iterables = [genslices(shape[n]) for n in range(ndim)] - return product(*iterables) - - def rslice(n, allow_empty=False): - """Generate random slice for a single dimension of length n. - If zero=True, the slices may be empty, otherwise they will - be non-empty.""" - minlen = 0 if allow_empty or n == 0 else 1 - slicelen = randrange(minlen, n+1) - return randslice_from_slicelen(slicelen, n) - - def rslices(n, allow_empty=False): - """Generate random slices for a single dimension.""" - for _ in range(5): - yield rslice(n, allow_empty) - - def rslices_ndim(ndim, shape, iterations=5): - """Generate random slice tuples for 'shape'.""" - # non-empty slices - for _ in range(iterations): - yield tuple(rslice(shape[n]) for n in range(ndim)) - # possibly empty slices - for _ in range(iterations): - yield tuple(rslice(shape[n], allow_empty=True) for n in range(ndim)) - # invalid slices - yield tuple(slice(0,1,0) for _ in range(ndim)) - - def rpermutation(iterable, r=None): - pool = tuple(iterable) - r = len(pool) if r is None else r - yield tuple(sample(pool, r)) - - def ndarray_print(nd): - """Print ndarray for debugging.""" - try: - x = nd.tolist() - except (TypeError, NotImplementedError): - x = nd.tobytes() - if isinstance(nd, ndarray): - offset = nd.offset - flags = nd.flags - else: - offset = 'unknown' - flags = 'unknown' - print("ndarray(%s, shape=%s, strides=%s, suboffsets=%s, offset=%s, " - "format='%s', itemsize=%s, flags=%s)" % - (x, nd.shape, nd.strides, nd.suboffsets, offset, - nd.format, nd.itemsize, flags)) - sys.stdout.flush() - - - ITERATIONS = 100 - MAXDIM = 5 - MAXSHAPE = 10 - - if SHORT_TEST: - ITERATIONS = 10 - MAXDIM = 3 - MAXSHAPE = 4 - genslices = rslices - genslices_ndim = rslices_ndim - permutations = rpermutation - - - @unittest.skipUnless(struct, 'struct module required for this test.') - @unittest.skipUnless(ndarray, 'ndarray object required for this test') - class TestBufferProtocol(unittest.TestCase): - - def setUp(self): - # The suboffsets tests need sizeof(void *). - self.sizeof_void_p = get_sizeof_void_p() - - def verify(self, result, *, obj, - itemsize, fmt, readonly, - ndim, shape, strides, - lst, sliced=False, cast=False): - # Verify buffer contents against expected values. - if shape: - expected_len = prod(shape)*itemsize - else: - if not fmt: # array has been implicitly cast to unsigned bytes - expected_len = len(lst) - else: # ndim = 0 - expected_len = itemsize - - # Reconstruct suboffsets from strides. Support for slicing - # could be added, but is currently only needed for test_getbuf(). - suboffsets = () - if result.suboffsets: - self.assertGreater(ndim, 0) - - suboffset0 = 0 - for n in range(1, ndim): - if shape[n] == 0: - break - if strides[n] <= 0: - suboffset0 += -strides[n] * (shape[n]-1) - - suboffsets = [suboffset0] + [-1 for v in range(ndim-1)] - - # Not correct if slicing has occurred in the first dimension. - stride0 = self.sizeof_void_p - if strides[0] < 0: - stride0 = -stride0 - strides = [stride0] + list(strides[1:]) - - self.assertIs(result.obj, obj) - self.assertEqual(result.nbytes, expected_len) - self.assertEqual(result.itemsize, itemsize) - self.assertEqual(result.format, fmt) - self.assertIs(result.readonly, readonly) - self.assertEqual(result.ndim, ndim) - self.assertEqual(result.shape, tuple(shape)) - if not (sliced and suboffsets): - self.assertEqual(result.strides, tuple(strides)) - self.assertEqual(result.suboffsets, tuple(suboffsets)) - - if isinstance(result, ndarray) or is_memoryview_format(fmt): - rep = result.tolist() if fmt else result.tobytes() - self.assertEqual(rep, lst) - - if not fmt: # array has been cast to unsigned bytes, - return # the remaining tests won't work. - - # PyBuffer_GetPointer() is the definition how to access an item. - # If PyBuffer_GetPointer(indices) is correct for all possible - # combinations of indices, the buffer is correct. - # - # Also test tobytes() against the flattened 'lst', with all items - # packed to bytes. - if not cast: # casts chop up 'lst' in different ways - b = bytearray() - buf_err = None - for ind in indices(shape): - try: - item1 = get_pointer(result, ind) - item2 = get_item(lst, ind) - if isinstance(item2, tuple): - x = struct.pack(fmt, *item2) - else: - x = struct.pack(fmt, item2) - b.extend(x) - except BufferError: - buf_err = True # re-exporter does not provide full buffer - break - self.assertEqual(item1, item2) - - if not buf_err: - # test tobytes() - self.assertEqual(result.tobytes(), b) - - # test hex() - m = memoryview(result) - h = "".join("%02x" % c for c in b) - self.assertEqual(m.hex(), h) - - # lst := expected multi-dimensional logical representation - # flatten(lst) := elements in C-order - ff = fmt if fmt else 'B' - flattened = flatten(lst) - - # Rules for 'A': if the array is already contiguous, return - # the array unaltered. Otherwise, return a contiguous 'C' - # representation. - for order in ['C', 'F', 'A']: - expected = result - if order == 'F': - if not is_contiguous(result, 'A') or \ - is_contiguous(result, 'C'): - # For constructing the ndarray, convert the - # flattened logical representation to Fortran order. - trans = transpose(flattened, shape) - expected = ndarray(trans, shape=shape, format=ff, - flags=ND_FORTRAN) - else: # 'C', 'A' - if not is_contiguous(result, 'A') or \ - is_contiguous(result, 'F') and order == 'C': - # The flattened list is already in C-order. - expected = ndarray(flattened, shape=shape, format=ff) - - contig = get_contiguous(result, PyBUF_READ, order) - self.assertEqual(contig.tobytes(), b) - self.assertTrue(cmp_contig(contig, expected)) - - if ndim == 0: - continue - - nmemb = len(flattened) - ro = 0 if readonly else ND_WRITABLE - - ### See comment in test_py_buffer_to_contiguous for an - ### explanation why these tests are valid. - - # To 'C' - contig = py_buffer_to_contiguous(result, 'C', PyBUF_FULL_RO) - self.assertEqual(len(contig), nmemb * itemsize) - initlst = [struct.unpack_from(fmt, contig, n*itemsize) - for n in range(nmemb)] - if len(initlst[0]) == 1: - initlst = [v[0] for v in initlst] - - y = ndarray(initlst, shape=shape, flags=ro, format=fmt) - self.assertEqual(memoryview(y), memoryview(result)) - - contig_bytes = memoryview(result).tobytes() - self.assertEqual(contig_bytes, contig) - - contig_bytes = memoryview(result).tobytes(order=None) - self.assertEqual(contig_bytes, contig) - - contig_bytes = memoryview(result).tobytes(order='C') - self.assertEqual(contig_bytes, contig) - - # To 'F' - contig = py_buffer_to_contiguous(result, 'F', PyBUF_FULL_RO) - self.assertEqual(len(contig), nmemb * itemsize) - initlst = [struct.unpack_from(fmt, contig, n*itemsize) - for n in range(nmemb)] - if len(initlst[0]) == 1: - initlst = [v[0] for v in initlst] - - y = ndarray(initlst, shape=shape, flags=ro|ND_FORTRAN, - format=fmt) - self.assertEqual(memoryview(y), memoryview(result)) - - contig_bytes = memoryview(result).tobytes(order='F') - self.assertEqual(contig_bytes, contig) - - # To 'A' - contig = py_buffer_to_contiguous(result, 'A', PyBUF_FULL_RO) - self.assertEqual(len(contig), nmemb * itemsize) - initlst = [struct.unpack_from(fmt, contig, n*itemsize) - for n in range(nmemb)] - if len(initlst[0]) == 1: - initlst = [v[0] for v in initlst] - - f = ND_FORTRAN if is_contiguous(result, 'F') else 0 - y = ndarray(initlst, shape=shape, flags=f|ro, format=fmt) - self.assertEqual(memoryview(y), memoryview(result)) - - contig_bytes = memoryview(result).tobytes(order='A') - self.assertEqual(contig_bytes, contig) - - if is_memoryview_format(fmt): - try: - m = memoryview(result) - except BufferError: # re-exporter does not provide full information - return - ex = result.obj if isinstance(result, memoryview) else result - - def check_memoryview(m, expected_readonly=readonly): - self.assertIs(m.obj, ex) - self.assertEqual(m.nbytes, expected_len) - self.assertEqual(m.itemsize, itemsize) - self.assertEqual(m.format, fmt) - self.assertEqual(m.readonly, expected_readonly) - self.assertEqual(m.ndim, ndim) - self.assertEqual(m.shape, tuple(shape)) - if not (sliced and suboffsets): - self.assertEqual(m.strides, tuple(strides)) - self.assertEqual(m.suboffsets, tuple(suboffsets)) - - n = 1 if ndim == 0 else len(lst) - self.assertEqual(len(m), n) - - rep = result.tolist() if fmt else result.tobytes() - self.assertEqual(rep, lst) - self.assertEqual(m, result) - - check_memoryview(m) - with m.toreadonly() as mm: - check_memoryview(mm, expected_readonly=True) - m.tobytes() # Releasing mm didn't release m - - def verify_getbuf(self, orig_ex, ex, req, sliced=False): - def simple_fmt(ex): - return ex.format == '' or ex.format == 'B' - def match(req, flag): - return ((req&flag) == flag) - - if (# writable request to read-only exporter - (ex.readonly and match(req, PyBUF_WRITABLE)) or - # cannot match explicit contiguity request - (match(req, PyBUF_C_CONTIGUOUS) and not ex.c_contiguous) or - (match(req, PyBUF_F_CONTIGUOUS) and not ex.f_contiguous) or - (match(req, PyBUF_ANY_CONTIGUOUS) and not ex.contiguous) or - # buffer needs suboffsets - (not match(req, PyBUF_INDIRECT) and ex.suboffsets) or - # buffer without strides must be C-contiguous - (not match(req, PyBUF_STRIDES) and not ex.c_contiguous) or - # PyBUF_SIMPLE|PyBUF_FORMAT and PyBUF_WRITABLE|PyBUF_FORMAT - (not match(req, PyBUF_ND) and match(req, PyBUF_FORMAT))): - - self.assertRaises(BufferError, ndarray, ex, getbuf=req) - return - - if isinstance(ex, ndarray) or is_memoryview_format(ex.format): - lst = ex.tolist() - else: - nd = ndarray(ex, getbuf=PyBUF_FULL_RO) - lst = nd.tolist() - - # The consumer may have requested default values or a NULL format. - ro = False if match(req, PyBUF_WRITABLE) else ex.readonly - fmt = ex.format - itemsize = ex.itemsize - ndim = ex.ndim - if not match(req, PyBUF_FORMAT): - # itemsize refers to the original itemsize before the cast. - # The equality product(shape) * itemsize = len still holds. - # The equality calcsize(format) = itemsize does _not_ hold. - fmt = '' - lst = orig_ex.tobytes() # Issue 12834 - if not match(req, PyBUF_ND): - ndim = 1 - shape = orig_ex.shape if match(req, PyBUF_ND) else () - strides = orig_ex.strides if match(req, PyBUF_STRIDES) else () - - nd = ndarray(ex, getbuf=req) - self.verify(nd, obj=ex, - itemsize=itemsize, fmt=fmt, readonly=ro, - ndim=ndim, shape=shape, strides=strides, - lst=lst, sliced=sliced) - - def test_ndarray_getbuf(self): - requests = ( - # distinct flags - PyBUF_INDIRECT, PyBUF_STRIDES, PyBUF_ND, PyBUF_SIMPLE, - PyBUF_C_CONTIGUOUS, PyBUF_F_CONTIGUOUS, PyBUF_ANY_CONTIGUOUS, - # compound requests - PyBUF_FULL, PyBUF_FULL_RO, - PyBUF_RECORDS, PyBUF_RECORDS_RO, - PyBUF_STRIDED, PyBUF_STRIDED_RO, - PyBUF_CONTIG, PyBUF_CONTIG_RO, - ) - # items and format - items_fmt = ( - ([True if x % 2 else False for x in range(12)], '?'), - ([1,2,3,4,5,6,7,8,9,10,11,12], 'b'), - ([1,2,3,4,5,6,7,8,9,10,11,12], 'B'), - ([(2**31-x) if x % 2 else (-2**31+x) for x in range(12)], 'l') - ) - # shape, strides, offset - structure = ( - ([], [], 0), - ([1,3,1], [], 0), - ([12], [], 0), - ([12], [-1], 11), - ([6], [2], 0), - ([6], [-2], 11), - ([3, 4], [], 0), - ([3, 4], [-4, -1], 11), - ([2, 2], [4, 1], 4), - ([2, 2], [-4, -1], 8) - ) - # ndarray creation flags - ndflags = ( - 0, ND_WRITABLE, ND_FORTRAN, ND_FORTRAN|ND_WRITABLE, - ND_PIL, ND_PIL|ND_WRITABLE - ) - # flags that can actually be used as flags - real_flags = (0, PyBUF_WRITABLE, PyBUF_FORMAT, - PyBUF_WRITABLE|PyBUF_FORMAT) - - for items, fmt in items_fmt: - itemsize = struct.calcsize(fmt) - for shape, strides, offset in structure: - strides = [v * itemsize for v in strides] - offset *= itemsize - for flags in ndflags: - - if strides and (flags&ND_FORTRAN): - continue - if not shape and (flags&ND_PIL): - continue - - _items = items if shape else items[0] - ex1 = ndarray(_items, format=fmt, flags=flags, - shape=shape, strides=strides, offset=offset) - ex2 = ex1[::-2] if shape else None - - m1 = memoryview(ex1) - if ex2: - m2 = memoryview(ex2) - if ex1.ndim == 0 or (ex1.ndim == 1 and shape and strides): - self.assertEqual(m1, ex1) - if ex2 and ex2.ndim == 1 and shape and strides: - self.assertEqual(m2, ex2) - - for req in requests: - for bits in real_flags: - self.verify_getbuf(ex1, ex1, req|bits) - self.verify_getbuf(ex1, m1, req|bits) - if ex2: - self.verify_getbuf(ex2, ex2, req|bits, - sliced=True) - self.verify_getbuf(ex2, m2, req|bits, - sliced=True) - - items = [1,2,3,4,5,6,7,8,9,10,11,12] - - # ND_GETBUF_FAIL - ex = ndarray(items, shape=[12], flags=ND_GETBUF_FAIL) - self.assertRaises(BufferError, ndarray, ex) - - # Request complex structure from a simple exporter. In this - # particular case the test object is not PEP-3118 compliant. - base = ndarray([9], [1]) - ex = ndarray(base, getbuf=PyBUF_SIMPLE) - self.assertRaises(BufferError, ndarray, ex, getbuf=PyBUF_WRITABLE) - self.assertRaises(BufferError, ndarray, ex, getbuf=PyBUF_ND) - self.assertRaises(BufferError, ndarray, ex, getbuf=PyBUF_STRIDES) - self.assertRaises(BufferError, ndarray, ex, getbuf=PyBUF_C_CONTIGUOUS) - self.assertRaises(BufferError, ndarray, ex, getbuf=PyBUF_F_CONTIGUOUS) - self.assertRaises(BufferError, ndarray, ex, getbuf=PyBUF_ANY_CONTIGUOUS) - nd = ndarray(ex, getbuf=PyBUF_SIMPLE) - - # Issue #22445: New precise contiguity definition. - for shape in [1,12,1], [7,0,7]: - for order in 0, ND_FORTRAN: - ex = ndarray(items, shape=shape, flags=order|ND_WRITABLE) - self.assertTrue(is_contiguous(ex, 'F')) - self.assertTrue(is_contiguous(ex, 'C')) - - for flags in requests: - nd = ndarray(ex, getbuf=flags) - self.assertTrue(is_contiguous(nd, 'F')) - self.assertTrue(is_contiguous(nd, 'C')) - - def test_ndarray_exceptions(self): - nd = ndarray([9], [1]) - ndm = ndarray([9], [1], flags=ND_VAREXPORT) - - # Initialization of a new ndarray or mutation of an existing array. - for c in (ndarray, nd.push, ndm.push): - # Invalid types. - self.assertRaises(TypeError, c, {1,2,3}) - self.assertRaises(TypeError, c, [1,2,'3']) - self.assertRaises(TypeError, c, [1,2,(3,4)]) - self.assertRaises(TypeError, c, [1,2,3], shape={3}) - self.assertRaises(TypeError, c, [1,2,3], shape=[3], strides={1}) - self.assertRaises(TypeError, c, [1,2,3], shape=[3], offset=[]) - self.assertRaises(TypeError, c, [1], shape=[1], format={}) - self.assertRaises(TypeError, c, [1], shape=[1], flags={}) - self.assertRaises(TypeError, c, [1], shape=[1], getbuf={}) - - # ND_FORTRAN flag is only valid without strides. - self.assertRaises(TypeError, c, [1], shape=[1], strides=[1], - flags=ND_FORTRAN) - - # ND_PIL flag is only valid with ndim > 0. - self.assertRaises(TypeError, c, [1], shape=[], flags=ND_PIL) - - # Invalid items. - self.assertRaises(ValueError, c, [], shape=[1]) - self.assertRaises(ValueError, c, ['XXX'], shape=[1], format="L") - # Invalid combination of items and format. - self.assertRaises(struct.error, c, [1000], shape=[1], format="B") - self.assertRaises(ValueError, c, [1,(2,3)], shape=[2], format="B") - self.assertRaises(ValueError, c, [1,2,3], shape=[3], format="QL") - - # Invalid ndim. - n = ND_MAX_NDIM+1 - self.assertRaises(ValueError, c, [1]*n, shape=[1]*n) - - # Invalid shape. - self.assertRaises(ValueError, c, [1], shape=[-1]) - self.assertRaises(ValueError, c, [1,2,3], shape=['3']) - self.assertRaises(OverflowError, c, [1], shape=[2**128]) - # prod(shape) * itemsize != len(items) - self.assertRaises(ValueError, c, [1,2,3,4,5], shape=[2,2], offset=3) - - # Invalid strides. - self.assertRaises(ValueError, c, [1,2,3], shape=[3], strides=['1']) - self.assertRaises(OverflowError, c, [1], shape=[1], - strides=[2**128]) - - # Invalid combination of strides and shape. - self.assertRaises(ValueError, c, [1,2], shape=[2,1], strides=[1]) - # Invalid combination of strides and format. - self.assertRaises(ValueError, c, [1,2,3,4], shape=[2], strides=[3], - format="L") - - # Invalid offset. - self.assertRaises(ValueError, c, [1,2,3], shape=[3], offset=4) - self.assertRaises(ValueError, c, [1,2,3], shape=[1], offset=3, - format="L") - - # Invalid format. - self.assertRaises(ValueError, c, [1,2,3], shape=[3], format="") - self.assertRaises(struct.error, c, [(1,2,3)], shape=[1], - format="@#$") - - # Striding out of the memory bounds. - items = [1,2,3,4,5,6,7,8,9,10] - self.assertRaises(ValueError, c, items, shape=[2,3], - strides=[-3, -2], offset=5) - - # Constructing consumer: format argument invalid. - self.assertRaises(TypeError, c, bytearray(), format="Q") - - # Constructing original base object: getbuf argument invalid. - self.assertRaises(TypeError, c, [1], shape=[1], getbuf=PyBUF_FULL) - - # Shape argument is mandatory for original base objects. - self.assertRaises(TypeError, c, [1]) - - - # PyBUF_WRITABLE request to read-only provider. - self.assertRaises(BufferError, ndarray, b'123', getbuf=PyBUF_WRITABLE) - - # ND_VAREXPORT can only be specified during construction. - nd = ndarray([9], [1], flags=ND_VAREXPORT) - self.assertRaises(ValueError, nd.push, [1], [1], flags=ND_VAREXPORT) - - # Invalid operation for consumers: push/pop - nd = ndarray(b'123') - self.assertRaises(BufferError, nd.push, [1], [1]) - self.assertRaises(BufferError, nd.pop) - - # ND_VAREXPORT not set: push/pop fail with exported buffers - nd = ndarray([9], [1]) - nd.push([1], [1]) - m = memoryview(nd) - self.assertRaises(BufferError, nd.push, [1], [1]) - self.assertRaises(BufferError, nd.pop) - m.release() - nd.pop() - - # Single remaining buffer: pop fails - self.assertRaises(BufferError, nd.pop) - del nd - - # get_pointer() - self.assertRaises(TypeError, get_pointer, {}, [1,2,3]) - self.assertRaises(TypeError, get_pointer, b'123', {}) - - nd = ndarray(list(range(100)), shape=[1]*100) - self.assertRaises(ValueError, get_pointer, nd, [5]) - - nd = ndarray(list(range(12)), shape=[3,4]) - self.assertRaises(ValueError, get_pointer, nd, [2,3,4]) - self.assertRaises(ValueError, get_pointer, nd, [3,3]) - self.assertRaises(ValueError, get_pointer, nd, [-3,3]) - self.assertRaises(OverflowError, get_pointer, nd, [1<<64,3]) - - # tolist() needs format - ex = ndarray([1,2,3], shape=[3], format='L') - nd = ndarray(ex, getbuf=PyBUF_SIMPLE) - self.assertRaises(ValueError, nd.tolist) - - # memoryview_from_buffer() - ex1 = ndarray([1,2,3], shape=[3], format='L') - ex2 = ndarray(ex1) - nd = ndarray(ex2) - self.assertRaises(TypeError, nd.memoryview_from_buffer) - - nd = ndarray([(1,)*200], shape=[1], format='L'*200) - self.assertRaises(TypeError, nd.memoryview_from_buffer) - - n = ND_MAX_NDIM - nd = ndarray(list(range(n)), shape=[1]*n) - self.assertRaises(ValueError, nd.memoryview_from_buffer) - - # get_contiguous() - nd = ndarray([1], shape=[1]) - self.assertRaises(TypeError, get_contiguous, 1, 2, 3, 4, 5) - self.assertRaises(TypeError, get_contiguous, nd, "xyz", 'C') - self.assertRaises(OverflowError, get_contiguous, nd, 2**64, 'C') - self.assertRaises(TypeError, get_contiguous, nd, PyBUF_READ, 961) - self.assertRaises(UnicodeEncodeError, get_contiguous, nd, PyBUF_READ, - '\u2007') - self.assertRaises(ValueError, get_contiguous, nd, PyBUF_READ, 'Z') - self.assertRaises(ValueError, get_contiguous, nd, 255, 'A') - - # cmp_contig() - nd = ndarray([1], shape=[1]) - self.assertRaises(TypeError, cmp_contig, 1, 2, 3, 4, 5) - self.assertRaises(TypeError, cmp_contig, {}, nd) - self.assertRaises(TypeError, cmp_contig, nd, {}) - - # is_contiguous() - nd = ndarray([1], shape=[1]) - self.assertRaises(TypeError, is_contiguous, 1, 2, 3, 4, 5) - self.assertRaises(TypeError, is_contiguous, {}, 'A') - self.assertRaises(TypeError, is_contiguous, nd, 201) - - def test_ndarray_linked_list(self): - for perm in permutations(range(5)): - m = [0]*5 - nd = ndarray([1,2,3], shape=[3], flags=ND_VAREXPORT) - m[0] = memoryview(nd) - - for i in range(1, 5): - nd.push([1,2,3], shape=[3]) - m[i] = memoryview(nd) - - for i in range(5): - m[perm[i]].release() - - self.assertRaises(BufferError, nd.pop) - del nd - - def test_ndarray_format_scalar(self): - # ndim = 0: scalar - for fmt, scalar, _ in iter_format(0): - itemsize = struct.calcsize(fmt) - nd = ndarray(scalar, shape=(), format=fmt) - self.verify(nd, obj=None, - itemsize=itemsize, fmt=fmt, readonly=True, - ndim=0, shape=(), strides=(), - lst=scalar) - - def test_ndarray_format_shape(self): - # ndim = 1, shape = [n] - nitems = randrange(1, 10) - for fmt, items, _ in iter_format(nitems): - itemsize = struct.calcsize(fmt) - for flags in (0, ND_PIL): - nd = ndarray(items, shape=[nitems], format=fmt, flags=flags) - self.verify(nd, obj=None, - itemsize=itemsize, fmt=fmt, readonly=True, - ndim=1, shape=(nitems,), strides=(itemsize,), - lst=items) - - def test_ndarray_format_strides(self): - # ndim = 1, strides - nitems = randrange(1, 30) - for fmt, items, _ in iter_format(nitems): - itemsize = struct.calcsize(fmt) - for step in range(-5, 5): - if step == 0: - continue - - shape = [len(items[::step])] - strides = [step*itemsize] - offset = itemsize*(nitems-1) if step < 0 else 0 - - for flags in (0, ND_PIL): - nd = ndarray(items, shape=shape, strides=strides, - format=fmt, offset=offset, flags=flags) - self.verify(nd, obj=None, - itemsize=itemsize, fmt=fmt, readonly=True, - ndim=1, shape=shape, strides=strides, - lst=items[::step]) - - def test_ndarray_fortran(self): - items = [1,2,3,4,5,6,7,8,9,10,11,12] - ex = ndarray(items, shape=(3, 4), strides=(1, 3)) - nd = ndarray(ex, getbuf=PyBUF_F_CONTIGUOUS|PyBUF_FORMAT) - self.assertEqual(nd.tolist(), farray(items, (3, 4))) - - def test_ndarray_multidim(self): - for ndim in range(5): - shape_t = [randrange(2, 10) for _ in range(ndim)] - nitems = prod(shape_t) - for shape in permutations(shape_t): - - fmt, items, _ = randitems(nitems) - itemsize = struct.calcsize(fmt) - - for flags in (0, ND_PIL): - if ndim == 0 and flags == ND_PIL: - continue - - # C array - nd = ndarray(items, shape=shape, format=fmt, flags=flags) - - strides = strides_from_shape(ndim, shape, itemsize, 'C') - lst = carray(items, shape) - self.verify(nd, obj=None, - itemsize=itemsize, fmt=fmt, readonly=True, - ndim=ndim, shape=shape, strides=strides, - lst=lst) - - if is_memoryview_format(fmt): - # memoryview: reconstruct strides - ex = ndarray(items, shape=shape, format=fmt) - nd = ndarray(ex, getbuf=PyBUF_CONTIG_RO|PyBUF_FORMAT) - self.assertTrue(nd.strides == ()) - mv = nd.memoryview_from_buffer() - self.verify(mv, obj=None, - itemsize=itemsize, fmt=fmt, readonly=True, - ndim=ndim, shape=shape, strides=strides, - lst=lst) - - # Fortran array - nd = ndarray(items, shape=shape, format=fmt, - flags=flags|ND_FORTRAN) - - strides = strides_from_shape(ndim, shape, itemsize, 'F') - lst = farray(items, shape) - self.verify(nd, obj=None, - itemsize=itemsize, fmt=fmt, readonly=True, - ndim=ndim, shape=shape, strides=strides, - lst=lst) - - def test_ndarray_index_invalid(self): - # not writable - nd = ndarray([1], shape=[1]) - self.assertRaises(TypeError, nd.__setitem__, 1, 8) - mv = memoryview(nd) - self.assertEqual(mv, nd) - self.assertRaises(TypeError, mv.__setitem__, 1, 8) - - # cannot be deleted - nd = ndarray([1], shape=[1], flags=ND_WRITABLE) - self.assertRaises(TypeError, nd.__delitem__, 1) - mv = memoryview(nd) - self.assertEqual(mv, nd) - self.assertRaises(TypeError, mv.__delitem__, 1) - - # overflow - nd = ndarray([1], shape=[1], flags=ND_WRITABLE) - self.assertRaises(OverflowError, nd.__getitem__, 1<<64) - self.assertRaises(OverflowError, nd.__setitem__, 1<<64, 8) - mv = memoryview(nd) - self.assertEqual(mv, nd) - self.assertRaises(IndexError, mv.__getitem__, 1<<64) - self.assertRaises(IndexError, mv.__setitem__, 1<<64, 8) - - # format - items = [1,2,3,4,5,6,7,8] - nd = ndarray(items, shape=[len(items)], format="B", flags=ND_WRITABLE) - self.assertRaises(struct.error, nd.__setitem__, 2, 300) - self.assertRaises(ValueError, nd.__setitem__, 1, (100, 200)) - mv = memoryview(nd) - self.assertEqual(mv, nd) - self.assertRaises(ValueError, mv.__setitem__, 2, 300) - self.assertRaises(TypeError, mv.__setitem__, 1, (100, 200)) - - items = [(1,2), (3,4), (5,6)] - nd = ndarray(items, shape=[len(items)], format="LQ", flags=ND_WRITABLE) - self.assertRaises(ValueError, nd.__setitem__, 2, 300) - self.assertRaises(struct.error, nd.__setitem__, 1, (b'\x001', 200)) - - def test_ndarray_index_scalar(self): - # scalar - nd = ndarray(1, shape=(), flags=ND_WRITABLE) - mv = memoryview(nd) - self.assertEqual(mv, nd) - - x = nd[()]; self.assertEqual(x, 1) - x = nd[...]; self.assertEqual(x.tolist(), nd.tolist()) - - x = mv[()]; self.assertEqual(x, 1) - x = mv[...]; self.assertEqual(x.tolist(), nd.tolist()) - - self.assertRaises(TypeError, nd.__getitem__, 0) - self.assertRaises(TypeError, mv.__getitem__, 0) - self.assertRaises(TypeError, nd.__setitem__, 0, 8) - self.assertRaises(TypeError, mv.__setitem__, 0, 8) - - self.assertEqual(nd.tolist(), 1) - self.assertEqual(mv.tolist(), 1) - - nd[()] = 9; self.assertEqual(nd.tolist(), 9) - mv[()] = 9; self.assertEqual(mv.tolist(), 9) - - nd[...] = 5; self.assertEqual(nd.tolist(), 5) - mv[...] = 5; self.assertEqual(mv.tolist(), 5) - - def test_ndarray_index_null_strides(self): - ex = ndarray(list(range(2*4)), shape=[2, 4], flags=ND_WRITABLE) - nd = ndarray(ex, getbuf=PyBUF_CONTIG) - - # Sub-views are only possible for full exporters. - self.assertRaises(BufferError, nd.__getitem__, 1) - # Same for slices. - self.assertRaises(BufferError, nd.__getitem__, slice(3,5,1)) - - def test_ndarray_index_getitem_single(self): - # getitem - for fmt, items, _ in iter_format(5): - nd = ndarray(items, shape=[5], format=fmt) - for i in range(-5, 5): - self.assertEqual(nd[i], items[i]) - - self.assertRaises(IndexError, nd.__getitem__, -6) - self.assertRaises(IndexError, nd.__getitem__, 5) - - if is_memoryview_format(fmt): - mv = memoryview(nd) - self.assertEqual(mv, nd) - for i in range(-5, 5): - self.assertEqual(mv[i], items[i]) - - self.assertRaises(IndexError, mv.__getitem__, -6) - self.assertRaises(IndexError, mv.__getitem__, 5) - - # getitem with null strides - for fmt, items, _ in iter_format(5): - ex = ndarray(items, shape=[5], flags=ND_WRITABLE, format=fmt) - nd = ndarray(ex, getbuf=PyBUF_CONTIG|PyBUF_FORMAT) - - for i in range(-5, 5): - self.assertEqual(nd[i], items[i]) - - if is_memoryview_format(fmt): - mv = nd.memoryview_from_buffer() - self.assertIs(mv.__eq__(nd), NotImplemented) - for i in range(-5, 5): - self.assertEqual(mv[i], items[i]) - - # getitem with null format - items = [1,2,3,4,5] - ex = ndarray(items, shape=[5]) - nd = ndarray(ex, getbuf=PyBUF_CONTIG_RO) - for i in range(-5, 5): - self.assertEqual(nd[i], items[i]) - - # getitem with null shape/strides/format - items = [1,2,3,4,5] - ex = ndarray(items, shape=[5]) - nd = ndarray(ex, getbuf=PyBUF_SIMPLE) - - for i in range(-5, 5): - self.assertEqual(nd[i], items[i]) - - def test_ndarray_index_setitem_single(self): - # assign single value - for fmt, items, single_item in iter_format(5): - nd = ndarray(items, shape=[5], format=fmt, flags=ND_WRITABLE) - for i in range(5): - items[i] = single_item - nd[i] = single_item - self.assertEqual(nd.tolist(), items) - - self.assertRaises(IndexError, nd.__setitem__, -6, single_item) - self.assertRaises(IndexError, nd.__setitem__, 5, single_item) - - if not is_memoryview_format(fmt): - continue - - nd = ndarray(items, shape=[5], format=fmt, flags=ND_WRITABLE) - mv = memoryview(nd) - self.assertEqual(mv, nd) - for i in range(5): - items[i] = single_item - mv[i] = single_item - self.assertEqual(mv.tolist(), items) - - self.assertRaises(IndexError, mv.__setitem__, -6, single_item) - self.assertRaises(IndexError, mv.__setitem__, 5, single_item) - - - # assign single value: lobject = robject - for fmt, items, single_item in iter_format(5): - nd = ndarray(items, shape=[5], format=fmt, flags=ND_WRITABLE) - for i in range(-5, 4): - items[i] = items[i+1] - nd[i] = nd[i+1] - self.assertEqual(nd.tolist(), items) - - if not is_memoryview_format(fmt): - continue - - nd = ndarray(items, shape=[5], format=fmt, flags=ND_WRITABLE) - mv = memoryview(nd) - self.assertEqual(mv, nd) - for i in range(-5, 4): - items[i] = items[i+1] - mv[i] = mv[i+1] - self.assertEqual(mv.tolist(), items) - - def test_ndarray_index_getitem_multidim(self): - shape_t = (2, 3, 5) - nitems = prod(shape_t) - for shape in permutations(shape_t): - - fmt, items, _ = randitems(nitems) - - for flags in (0, ND_PIL): - # C array - nd = ndarray(items, shape=shape, format=fmt, flags=flags) - lst = carray(items, shape) - - for i in range(-shape[0], shape[0]): - self.assertEqual(lst[i], nd[i].tolist()) - for j in range(-shape[1], shape[1]): - self.assertEqual(lst[i][j], nd[i][j].tolist()) - for k in range(-shape[2], shape[2]): - self.assertEqual(lst[i][j][k], nd[i][j][k]) - - # Fortran array - nd = ndarray(items, shape=shape, format=fmt, - flags=flags|ND_FORTRAN) - lst = farray(items, shape) - - for i in range(-shape[0], shape[0]): - self.assertEqual(lst[i], nd[i].tolist()) - for j in range(-shape[1], shape[1]): - self.assertEqual(lst[i][j], nd[i][j].tolist()) - for k in range(shape[2], shape[2]): - self.assertEqual(lst[i][j][k], nd[i][j][k]) - - def test_ndarray_sequence(self): - nd = ndarray(1, shape=()) - self.assertRaises(TypeError, eval, "1 in nd", locals()) - mv = memoryview(nd) - self.assertEqual(mv, nd) - self.assertRaises(TypeError, eval, "1 in mv", locals()) - - for fmt, items, _ in iter_format(5): - nd = ndarray(items, shape=[5], format=fmt) - for i, v in enumerate(nd): - self.assertEqual(v, items[i]) - self.assertTrue(v in nd) - - if is_memoryview_format(fmt): - mv = memoryview(nd) - for i, v in enumerate(mv): - self.assertEqual(v, items[i]) - self.assertTrue(v in mv) - - def test_ndarray_slice_invalid(self): - items = [1,2,3,4,5,6,7,8] - - # rvalue is not an exporter - xl = ndarray(items, shape=[8], flags=ND_WRITABLE) - ml = memoryview(xl) - self.assertRaises(TypeError, xl.__setitem__, slice(0,8,1), items) - self.assertRaises(TypeError, ml.__setitem__, slice(0,8,1), items) - - # rvalue is not a full exporter - xl = ndarray(items, shape=[8], flags=ND_WRITABLE) - ex = ndarray(items, shape=[8], flags=ND_WRITABLE) - xr = ndarray(ex, getbuf=PyBUF_ND) - self.assertRaises(BufferError, xl.__setitem__, slice(0,8,1), xr) - - # zero step - nd = ndarray(items, shape=[8], format="L", flags=ND_WRITABLE) - mv = memoryview(nd) - self.assertRaises(ValueError, nd.__getitem__, slice(0,1,0)) - self.assertRaises(ValueError, mv.__getitem__, slice(0,1,0)) - - nd = ndarray(items, shape=[2,4], format="L", flags=ND_WRITABLE) - mv = memoryview(nd) - - self.assertRaises(ValueError, nd.__getitem__, - (slice(0,1,1), slice(0,1,0))) - self.assertRaises(ValueError, nd.__getitem__, - (slice(0,1,0), slice(0,1,1))) - self.assertRaises(TypeError, nd.__getitem__, "@%$") - self.assertRaises(TypeError, nd.__getitem__, ("@%$", slice(0,1,1))) - self.assertRaises(TypeError, nd.__getitem__, (slice(0,1,1), {})) - - # memoryview: not implemented - self.assertRaises(NotImplementedError, mv.__getitem__, - (slice(0,1,1), slice(0,1,0))) - self.assertRaises(TypeError, mv.__getitem__, "@%$") - - # differing format - xl = ndarray(items, shape=[8], format="B", flags=ND_WRITABLE) - xr = ndarray(items, shape=[8], format="b") - ml = memoryview(xl) - mr = memoryview(xr) - self.assertRaises(ValueError, xl.__setitem__, slice(0,1,1), xr[7:8]) - self.assertEqual(xl.tolist(), items) - self.assertRaises(ValueError, ml.__setitem__, slice(0,1,1), mr[7:8]) - self.assertEqual(ml.tolist(), items) - - # differing itemsize - xl = ndarray(items, shape=[8], format="B", flags=ND_WRITABLE) - yr = ndarray(items, shape=[8], format="L") - ml = memoryview(xl) - mr = memoryview(xr) - self.assertRaises(ValueError, xl.__setitem__, slice(0,1,1), xr[7:8]) - self.assertEqual(xl.tolist(), items) - self.assertRaises(ValueError, ml.__setitem__, slice(0,1,1), mr[7:8]) - self.assertEqual(ml.tolist(), items) - - # differing ndim - xl = ndarray(items, shape=[2, 4], format="b", flags=ND_WRITABLE) - xr = ndarray(items, shape=[8], format="b") - ml = memoryview(xl) - mr = memoryview(xr) - self.assertRaises(ValueError, xl.__setitem__, slice(0,1,1), xr[7:8]) - self.assertEqual(xl.tolist(), [[1,2,3,4], [5,6,7,8]]) - self.assertRaises(NotImplementedError, ml.__setitem__, slice(0,1,1), - mr[7:8]) - - # differing shape - xl = ndarray(items, shape=[8], format="b", flags=ND_WRITABLE) - xr = ndarray(items, shape=[8], format="b") - ml = memoryview(xl) - mr = memoryview(xr) - self.assertRaises(ValueError, xl.__setitem__, slice(0,2,1), xr[7:8]) - self.assertEqual(xl.tolist(), items) - self.assertRaises(ValueError, ml.__setitem__, slice(0,2,1), mr[7:8]) - self.assertEqual(ml.tolist(), items) - - # _testbuffer.c module functions - self.assertRaises(TypeError, slice_indices, slice(0,1,2), {}) - self.assertRaises(TypeError, slice_indices, "###########", 1) - self.assertRaises(ValueError, slice_indices, slice(0,1,0), 4) - - x = ndarray(items, shape=[8], format="b", flags=ND_PIL) - self.assertRaises(TypeError, x.add_suboffsets) - - ex = ndarray(items, shape=[8], format="B") - x = ndarray(ex, getbuf=PyBUF_SIMPLE) - self.assertRaises(TypeError, x.add_suboffsets) - - def test_ndarray_slice_zero_shape(self): - items = [1,2,3,4,5,6,7,8,9,10,11,12] - - x = ndarray(items, shape=[12], format="L", flags=ND_WRITABLE) - y = ndarray(items, shape=[12], format="L") - x[4:4] = y[9:9] - self.assertEqual(x.tolist(), items) - - ml = memoryview(x) - mr = memoryview(y) - self.assertEqual(ml, x) - self.assertEqual(ml, y) - ml[4:4] = mr[9:9] - self.assertEqual(ml.tolist(), items) - - x = ndarray(items, shape=[3, 4], format="L", flags=ND_WRITABLE) - y = ndarray(items, shape=[4, 3], format="L") - x[1:2, 2:2] = y[1:2, 3:3] - self.assertEqual(x.tolist(), carray(items, [3, 4])) - - def test_ndarray_slice_multidim(self): - shape_t = (2, 3, 5) - ndim = len(shape_t) - nitems = prod(shape_t) - for shape in permutations(shape_t): - - fmt, items, _ = randitems(nitems) - itemsize = struct.calcsize(fmt) - - for flags in (0, ND_PIL): - nd = ndarray(items, shape=shape, format=fmt, flags=flags) - lst = carray(items, shape) - - for slices in rslices_ndim(ndim, shape): - - listerr = None - try: - sliced = multislice(lst, slices) - except Exception as e: - listerr = e.__class__ - - nderr = None - try: - ndsliced = nd[slices] - except Exception as e: - nderr = e.__class__ - - if nderr or listerr: - self.assertIs(nderr, listerr) - else: - self.assertEqual(ndsliced.tolist(), sliced) - - def test_ndarray_slice_redundant_suboffsets(self): - shape_t = (2, 3, 5, 2) - ndim = len(shape_t) - nitems = prod(shape_t) - for shape in permutations(shape_t): - - fmt, items, _ = randitems(nitems) - itemsize = struct.calcsize(fmt) - - nd = ndarray(items, shape=shape, format=fmt) - nd.add_suboffsets() - ex = ndarray(items, shape=shape, format=fmt) - ex.add_suboffsets() - mv = memoryview(ex) - lst = carray(items, shape) - - for slices in rslices_ndim(ndim, shape): - - listerr = None - try: - sliced = multislice(lst, slices) - except Exception as e: - listerr = e.__class__ - - nderr = None - try: - ndsliced = nd[slices] - except Exception as e: - nderr = e.__class__ - - if nderr or listerr: - self.assertIs(nderr, listerr) - else: - self.assertEqual(ndsliced.tolist(), sliced) - - def test_ndarray_slice_assign_single(self): - for fmt, items, _ in iter_format(5): - for lslice in genslices(5): - for rslice in genslices(5): - for flags in (0, ND_PIL): - - f = flags|ND_WRITABLE - nd = ndarray(items, shape=[5], format=fmt, flags=f) - ex = ndarray(items, shape=[5], format=fmt, flags=f) - mv = memoryview(ex) - - lsterr = None - diff_structure = None - lst = items[:] - try: - lval = lst[lslice] - rval = lst[rslice] - lst[lslice] = lst[rslice] - diff_structure = len(lval) != len(rval) - except Exception as e: - lsterr = e.__class__ - - nderr = None - try: - nd[lslice] = nd[rslice] - except Exception as e: - nderr = e.__class__ - - if diff_structure: # ndarray cannot change shape - self.assertIs(nderr, ValueError) - else: - self.assertEqual(nd.tolist(), lst) - self.assertIs(nderr, lsterr) - - if not is_memoryview_format(fmt): - continue - - mverr = None - try: - mv[lslice] = mv[rslice] - except Exception as e: - mverr = e.__class__ - - if diff_structure: # memoryview cannot change shape - self.assertIs(mverr, ValueError) - else: - self.assertEqual(mv.tolist(), lst) - self.assertEqual(mv, nd) - self.assertIs(mverr, lsterr) - self.verify(mv, obj=ex, - itemsize=nd.itemsize, fmt=fmt, readonly=False, - ndim=nd.ndim, shape=nd.shape, strides=nd.strides, - lst=nd.tolist()) - - def test_ndarray_slice_assign_multidim(self): - shape_t = (2, 3, 5) - ndim = len(shape_t) - nitems = prod(shape_t) - for shape in permutations(shape_t): - - fmt, items, _ = randitems(nitems) - - for flags in (0, ND_PIL): - for _ in range(ITERATIONS): - lslices, rslices = randslice_from_shape(ndim, shape) - - nd = ndarray(items, shape=shape, format=fmt, - flags=flags|ND_WRITABLE) - lst = carray(items, shape) - - listerr = None - try: - result = multislice_assign(lst, lst, lslices, rslices) - except Exception as e: - listerr = e.__class__ - - nderr = None - try: - nd[lslices] = nd[rslices] - except Exception as e: - nderr = e.__class__ - - if nderr or listerr: - self.assertIs(nderr, listerr) - else: - self.assertEqual(nd.tolist(), result) - - def test_ndarray_random(self): - # construction of valid arrays - for _ in range(ITERATIONS): - for fmt in fmtdict['@']: - itemsize = struct.calcsize(fmt) - - t = rand_structure(itemsize, True, maxdim=MAXDIM, - maxshape=MAXSHAPE) - self.assertTrue(verify_structure(*t)) - items = randitems_from_structure(fmt, t) - - x = ndarray_from_structure(items, fmt, t) - xlist = x.tolist() - - mv = memoryview(x) - if is_memoryview_format(fmt): - mvlist = mv.tolist() - self.assertEqual(mvlist, xlist) - - if t[2] > 0: - # ndim > 0: test against suboffsets representation. - y = ndarray_from_structure(items, fmt, t, flags=ND_PIL) - ylist = y.tolist() - self.assertEqual(xlist, ylist) - - mv = memoryview(y) - if is_memoryview_format(fmt): - self.assertEqual(mv, y) - mvlist = mv.tolist() - self.assertEqual(mvlist, ylist) - - if numpy_array: - shape = t[3] - if 0 in shape: - continue # http://projects.scipy.org/numpy/ticket/1910 - z = numpy_array_from_structure(items, fmt, t) - self.verify(x, obj=None, - itemsize=z.itemsize, fmt=fmt, readonly=False, - ndim=z.ndim, shape=z.shape, strides=z.strides, - lst=z.tolist()) - - def test_ndarray_random_invalid(self): - # exceptions during construction of invalid arrays - for _ in range(ITERATIONS): - for fmt in fmtdict['@']: - itemsize = struct.calcsize(fmt) - - t = rand_structure(itemsize, False, maxdim=MAXDIM, - maxshape=MAXSHAPE) - self.assertFalse(verify_structure(*t)) - items = randitems_from_structure(fmt, t) - - nderr = False - try: - x = ndarray_from_structure(items, fmt, t) - except Exception as e: - nderr = e.__class__ - self.assertTrue(nderr) - - if numpy_array: - numpy_err = False - try: - y = numpy_array_from_structure(items, fmt, t) - except Exception as e: - numpy_err = e.__class__ - - if 0: # http://projects.scipy.org/numpy/ticket/1910 - self.assertTrue(numpy_err) - - def test_ndarray_random_slice_assign(self): - # valid slice assignments - for _ in range(ITERATIONS): - for fmt in fmtdict['@']: - itemsize = struct.calcsize(fmt) - - lshape, rshape, lslices, rslices = \ - rand_aligned_slices(maxdim=MAXDIM, maxshape=MAXSHAPE) - tl = rand_structure(itemsize, True, shape=lshape) - tr = rand_structure(itemsize, True, shape=rshape) - self.assertTrue(verify_structure(*tl)) - self.assertTrue(verify_structure(*tr)) - litems = randitems_from_structure(fmt, tl) - ritems = randitems_from_structure(fmt, tr) - - xl = ndarray_from_structure(litems, fmt, tl) - xr = ndarray_from_structure(ritems, fmt, tr) - xl[lslices] = xr[rslices] - xllist = xl.tolist() - xrlist = xr.tolist() - - ml = memoryview(xl) - mr = memoryview(xr) - self.assertEqual(ml.tolist(), xllist) - self.assertEqual(mr.tolist(), xrlist) - - if tl[2] > 0 and tr[2] > 0: - # ndim > 0: test against suboffsets representation. - yl = ndarray_from_structure(litems, fmt, tl, flags=ND_PIL) - yr = ndarray_from_structure(ritems, fmt, tr, flags=ND_PIL) - yl[lslices] = yr[rslices] - yllist = yl.tolist() - yrlist = yr.tolist() - self.assertEqual(xllist, yllist) - self.assertEqual(xrlist, yrlist) - - ml = memoryview(yl) - mr = memoryview(yr) - self.assertEqual(ml.tolist(), yllist) - self.assertEqual(mr.tolist(), yrlist) - - if numpy_array: - if 0 in lshape or 0 in rshape: - continue # http://projects.scipy.org/numpy/ticket/1910 - - zl = numpy_array_from_structure(litems, fmt, tl) - zr = numpy_array_from_structure(ritems, fmt, tr) - zl[lslices] = zr[rslices] - - if not is_overlapping(tl) and not is_overlapping(tr): - # Slice assignment of overlapping structures - # is undefined in NumPy. - self.verify(xl, obj=None, - itemsize=zl.itemsize, fmt=fmt, readonly=False, - ndim=zl.ndim, shape=zl.shape, - strides=zl.strides, lst=zl.tolist()) - - self.verify(xr, obj=None, - itemsize=zr.itemsize, fmt=fmt, readonly=False, - ndim=zr.ndim, shape=zr.shape, - strides=zr.strides, lst=zr.tolist()) - - def test_ndarray_re_export(self): - items = [1,2,3,4,5,6,7,8,9,10,11,12] - - nd = ndarray(items, shape=[3,4], flags=ND_PIL) - ex = ndarray(nd) - - self.assertTrue(ex.flags & ND_PIL) - self.assertIs(ex.obj, nd) - self.assertEqual(ex.suboffsets, (0, -1)) - self.assertFalse(ex.c_contiguous) - self.assertFalse(ex.f_contiguous) - self.assertFalse(ex.contiguous) - - def test_ndarray_zero_shape(self): - # zeros in shape - for flags in (0, ND_PIL): - nd = ndarray([1,2,3], shape=[0], flags=flags) - mv = memoryview(nd) - self.assertEqual(mv, nd) - self.assertEqual(nd.tolist(), []) - self.assertEqual(mv.tolist(), []) - - nd = ndarray([1,2,3], shape=[0,3,3], flags=flags) - self.assertEqual(nd.tolist(), []) - - nd = ndarray([1,2,3], shape=[3,0,3], flags=flags) - self.assertEqual(nd.tolist(), [[], [], []]) - - nd = ndarray([1,2,3], shape=[3,3,0], flags=flags) - self.assertEqual(nd.tolist(), - [[[], [], []], [[], [], []], [[], [], []]]) - - def test_ndarray_zero_strides(self): - # zero strides - for flags in (0, ND_PIL): - nd = ndarray([1], shape=[5], strides=[0], flags=flags) - mv = memoryview(nd) - self.assertEqual(mv, nd) - self.assertEqual(nd.tolist(), [1, 1, 1, 1, 1]) - self.assertEqual(mv.tolist(), [1, 1, 1, 1, 1]) - - def test_ndarray_offset(self): - nd = ndarray(list(range(20)), shape=[3], offset=7) - self.assertEqual(nd.offset, 7) - self.assertEqual(nd.tolist(), [7,8,9]) - - def test_ndarray_memoryview_from_buffer(self): - for flags in (0, ND_PIL): - nd = ndarray(list(range(3)), shape=[3], flags=flags) - m = nd.memoryview_from_buffer() - self.assertEqual(m, nd) - - def test_ndarray_get_pointer(self): - for flags in (0, ND_PIL): - nd = ndarray(list(range(3)), shape=[3], flags=flags) - for i in range(3): - self.assertEqual(nd[i], get_pointer(nd, [i])) - - def test_ndarray_tolist_null_strides(self): - ex = ndarray(list(range(20)), shape=[2,2,5]) - - nd = ndarray(ex, getbuf=PyBUF_ND|PyBUF_FORMAT) - self.assertEqual(nd.tolist(), ex.tolist()) - - m = memoryview(ex) - self.assertEqual(m.tolist(), ex.tolist()) - - def test_ndarray_cmp_contig(self): - - self.assertFalse(cmp_contig(b"123", b"456")) - - x = ndarray(list(range(12)), shape=[3,4]) - y = ndarray(list(range(12)), shape=[4,3]) - self.assertFalse(cmp_contig(x, y)) - - x = ndarray([1], shape=[1], format="B") - self.assertTrue(cmp_contig(x, b'\x01')) - self.assertTrue(cmp_contig(b'\x01', x)) - - def test_ndarray_hash(self): - - a = array.array('L', [1,2,3]) - nd = ndarray(a) - self.assertRaises(ValueError, hash, nd) - - # one-dimensional - b = bytes(list(range(12))) - - nd = ndarray(list(range(12)), shape=[12]) - self.assertEqual(hash(nd), hash(b)) - - # C-contiguous - nd = ndarray(list(range(12)), shape=[3,4]) - self.assertEqual(hash(nd), hash(b)) - - nd = ndarray(list(range(12)), shape=[3,2,2]) - self.assertEqual(hash(nd), hash(b)) - - # Fortran contiguous - b = bytes(transpose(list(range(12)), shape=[4,3])) - nd = ndarray(list(range(12)), shape=[3,4], flags=ND_FORTRAN) - self.assertEqual(hash(nd), hash(b)) - - b = bytes(transpose(list(range(12)), shape=[2,3,2])) - nd = ndarray(list(range(12)), shape=[2,3,2], flags=ND_FORTRAN) - self.assertEqual(hash(nd), hash(b)) - - # suboffsets - b = bytes(list(range(12))) - nd = ndarray(list(range(12)), shape=[2,2,3], flags=ND_PIL) - self.assertEqual(hash(nd), hash(b)) - - # non-byte formats - nd = ndarray(list(range(12)), shape=[2,2,3], format='L') - self.assertEqual(hash(nd), hash(nd.tobytes())) - - def test_py_buffer_to_contiguous(self): - - # The requests are used in _testbuffer.c:py_buffer_to_contiguous - # to generate buffers without full information for testing. - requests = ( - # distinct flags - PyBUF_INDIRECT, PyBUF_STRIDES, PyBUF_ND, PyBUF_SIMPLE, - # compound requests - PyBUF_FULL, PyBUF_FULL_RO, - PyBUF_RECORDS, PyBUF_RECORDS_RO, - PyBUF_STRIDED, PyBUF_STRIDED_RO, - PyBUF_CONTIG, PyBUF_CONTIG_RO, - ) - - # no buffer interface - self.assertRaises(TypeError, py_buffer_to_contiguous, {}, 'F', - PyBUF_FULL_RO) - - # scalar, read-only request - nd = ndarray(9, shape=(), format="L", flags=ND_WRITABLE) - for order in ['C', 'F', 'A']: - for request in requests: - b = py_buffer_to_contiguous(nd, order, request) - self.assertEqual(b, nd.tobytes()) - - # zeros in shape - nd = ndarray([1], shape=[0], format="L", flags=ND_WRITABLE) - for order in ['C', 'F', 'A']: - for request in requests: - b = py_buffer_to_contiguous(nd, order, request) - self.assertEqual(b, b'') - - nd = ndarray(list(range(8)), shape=[2, 0, 7], format="L", - flags=ND_WRITABLE) - for order in ['C', 'F', 'A']: - for request in requests: - b = py_buffer_to_contiguous(nd, order, request) - self.assertEqual(b, b'') - - ### One-dimensional arrays are trivial, since Fortran and C order - ### are the same. - - # one-dimensional - for f in [0, ND_FORTRAN]: - nd = ndarray([1], shape=[1], format="h", flags=f|ND_WRITABLE) - ndbytes = nd.tobytes() - for order in ['C', 'F', 'A']: - for request in requests: - b = py_buffer_to_contiguous(nd, order, request) - self.assertEqual(b, ndbytes) - - nd = ndarray([1, 2, 3], shape=[3], format="b", flags=f|ND_WRITABLE) - ndbytes = nd.tobytes() - for order in ['C', 'F', 'A']: - for request in requests: - b = py_buffer_to_contiguous(nd, order, request) - self.assertEqual(b, ndbytes) - - # one-dimensional, non-contiguous input - nd = ndarray([1, 2, 3], shape=[2], strides=[2], flags=ND_WRITABLE) - ndbytes = nd.tobytes() - for order in ['C', 'F', 'A']: - for request in [PyBUF_STRIDES, PyBUF_FULL]: - b = py_buffer_to_contiguous(nd, order, request) - self.assertEqual(b, ndbytes) - - nd = nd[::-1] - ndbytes = nd.tobytes() - for order in ['C', 'F', 'A']: - for request in requests: - try: - b = py_buffer_to_contiguous(nd, order, request) - except BufferError: - continue - self.assertEqual(b, ndbytes) - - ### - ### Multi-dimensional arrays: - ### - ### The goal here is to preserve the logical representation of the - ### input array but change the physical representation if necessary. - ### - ### _testbuffer example: - ### ==================== - ### - ### C input array: - ### -------------- - ### >>> nd = ndarray(list(range(12)), shape=[3, 4]) - ### >>> nd.tolist() - ### [[0, 1, 2, 3], - ### [4, 5, 6, 7], - ### [8, 9, 10, 11]] - ### - ### Fortran output: - ### --------------- - ### >>> py_buffer_to_contiguous(nd, 'F', PyBUF_FULL_RO) - ### >>> b'\x00\x04\x08\x01\x05\t\x02\x06\n\x03\x07\x0b' - ### - ### The return value corresponds to this input list for - ### _testbuffer's ndarray: - ### >>> nd = ndarray([0,4,8,1,5,9,2,6,10,3,7,11], shape=[3,4], - ### flags=ND_FORTRAN) - ### >>> nd.tolist() - ### [[0, 1, 2, 3], - ### [4, 5, 6, 7], - ### [8, 9, 10, 11]] - ### - ### The logical array is the same, but the values in memory are now - ### in Fortran order. - ### - ### NumPy example: - ### ============== - ### _testbuffer's ndarray takes lists to initialize the memory. - ### Here's the same sequence in NumPy: - ### - ### C input: - ### -------- - ### >>> nd = ndarray(buffer=bytearray(list(range(12))), - ### shape=[3, 4], dtype='B') - ### >>> nd - ### array([[ 0, 1, 2, 3], - ### [ 4, 5, 6, 7], - ### [ 8, 9, 10, 11]], dtype=uint8) - ### - ### Fortran output: - ### --------------- - ### >>> fortran_buf = nd.tostring(order='F') - ### >>> fortran_buf - ### b'\x00\x04\x08\x01\x05\t\x02\x06\n\x03\x07\x0b' - ### - ### >>> nd = ndarray(buffer=fortran_buf, shape=[3, 4], - ### dtype='B', order='F') - ### - ### >>> nd - ### array([[ 0, 1, 2, 3], - ### [ 4, 5, 6, 7], - ### [ 8, 9, 10, 11]], dtype=uint8) - ### - - # multi-dimensional, contiguous input - lst = list(range(12)) - for f in [0, ND_FORTRAN]: - nd = ndarray(lst, shape=[3, 4], flags=f|ND_WRITABLE) - if numpy_array: - na = numpy_array(buffer=bytearray(lst), - shape=[3, 4], dtype='B', - order='C' if f == 0 else 'F') - - # 'C' request - if f == ND_FORTRAN: # 'F' to 'C' - x = ndarray(transpose(lst, [4, 3]), shape=[3, 4], - flags=ND_WRITABLE) - expected = x.tobytes() - else: - expected = nd.tobytes() - for request in requests: - try: - b = py_buffer_to_contiguous(nd, 'C', request) - except BufferError: - continue - - self.assertEqual(b, expected) - - # Check that output can be used as the basis for constructing - # a C array that is logically identical to the input array. - y = ndarray([v for v in b], shape=[3, 4], flags=ND_WRITABLE) - self.assertEqual(memoryview(y), memoryview(nd)) - - if numpy_array: - self.assertEqual(b, na.tostring(order='C')) - - # 'F' request - if f == 0: # 'C' to 'F' - x = ndarray(transpose(lst, [3, 4]), shape=[4, 3], - flags=ND_WRITABLE) - else: - x = ndarray(lst, shape=[3, 4], flags=ND_WRITABLE) - expected = x.tobytes() - for request in [PyBUF_FULL, PyBUF_FULL_RO, PyBUF_INDIRECT, - PyBUF_STRIDES, PyBUF_ND]: - try: - b = py_buffer_to_contiguous(nd, 'F', request) - except BufferError: - continue - self.assertEqual(b, expected) - - # Check that output can be used as the basis for constructing - # a Fortran array that is logically identical to the input array. - y = ndarray([v for v in b], shape=[3, 4], flags=ND_FORTRAN|ND_WRITABLE) - self.assertEqual(memoryview(y), memoryview(nd)) - - if numpy_array: - self.assertEqual(b, na.tostring(order='F')) - - # 'A' request - if f == ND_FORTRAN: - x = ndarray(lst, shape=[3, 4], flags=ND_WRITABLE) - expected = x.tobytes() - else: - expected = nd.tobytes() - for request in [PyBUF_FULL, PyBUF_FULL_RO, PyBUF_INDIRECT, - PyBUF_STRIDES, PyBUF_ND]: - try: - b = py_buffer_to_contiguous(nd, 'A', request) - except BufferError: - continue - - self.assertEqual(b, expected) - - # Check that output can be used as the basis for constructing - # an array with order=f that is logically identical to the input - # array. - y = ndarray([v for v in b], shape=[3, 4], flags=f|ND_WRITABLE) - self.assertEqual(memoryview(y), memoryview(nd)) - - if numpy_array: - self.assertEqual(b, na.tostring(order='A')) - - # multi-dimensional, non-contiguous input - nd = ndarray(list(range(12)), shape=[3, 4], flags=ND_WRITABLE|ND_PIL) - - # 'C' - b = py_buffer_to_contiguous(nd, 'C', PyBUF_FULL_RO) - self.assertEqual(b, nd.tobytes()) - y = ndarray([v for v in b], shape=[3, 4], flags=ND_WRITABLE) - self.assertEqual(memoryview(y), memoryview(nd)) - - # 'F' - b = py_buffer_to_contiguous(nd, 'F', PyBUF_FULL_RO) - x = ndarray(transpose(lst, [3, 4]), shape=[4, 3], flags=ND_WRITABLE) - self.assertEqual(b, x.tobytes()) - y = ndarray([v for v in b], shape=[3, 4], flags=ND_FORTRAN|ND_WRITABLE) - self.assertEqual(memoryview(y), memoryview(nd)) - - # 'A' - b = py_buffer_to_contiguous(nd, 'A', PyBUF_FULL_RO) - self.assertEqual(b, nd.tobytes()) - y = ndarray([v for v in b], shape=[3, 4], flags=ND_WRITABLE) - self.assertEqual(memoryview(y), memoryview(nd)) - - def test_memoryview_construction(self): - - items_shape = [(9, []), ([1,2,3], [3]), (list(range(2*3*5)), [2,3,5])] - - # NumPy style, C-contiguous: - for items, shape in items_shape: - - # From PEP-3118 compliant exporter: - ex = ndarray(items, shape=shape) - m = memoryview(ex) - self.assertTrue(m.c_contiguous) - self.assertTrue(m.contiguous) - - ndim = len(shape) - strides = strides_from_shape(ndim, shape, 1, 'C') - lst = carray(items, shape) - - self.verify(m, obj=ex, - itemsize=1, fmt='B', readonly=True, - ndim=ndim, shape=shape, strides=strides, - lst=lst) - - # From memoryview: - m2 = memoryview(m) - self.verify(m2, obj=ex, - itemsize=1, fmt='B', readonly=True, - ndim=ndim, shape=shape, strides=strides, - lst=lst) - - # PyMemoryView_FromBuffer(): no strides - nd = ndarray(ex, getbuf=PyBUF_CONTIG_RO|PyBUF_FORMAT) - self.assertEqual(nd.strides, ()) - m = nd.memoryview_from_buffer() - self.verify(m, obj=None, - itemsize=1, fmt='B', readonly=True, - ndim=ndim, shape=shape, strides=strides, - lst=lst) - - # PyMemoryView_FromBuffer(): no format, shape, strides - nd = ndarray(ex, getbuf=PyBUF_SIMPLE) - self.assertEqual(nd.format, '') - self.assertEqual(nd.shape, ()) - self.assertEqual(nd.strides, ()) - m = nd.memoryview_from_buffer() - - lst = [items] if ndim == 0 else items - self.verify(m, obj=None, - itemsize=1, fmt='B', readonly=True, - ndim=1, shape=[ex.nbytes], strides=(1,), - lst=lst) - - # NumPy style, Fortran contiguous: - for items, shape in items_shape: - - # From PEP-3118 compliant exporter: - ex = ndarray(items, shape=shape, flags=ND_FORTRAN) - m = memoryview(ex) - self.assertTrue(m.f_contiguous) - self.assertTrue(m.contiguous) - - ndim = len(shape) - strides = strides_from_shape(ndim, shape, 1, 'F') - lst = farray(items, shape) - - self.verify(m, obj=ex, - itemsize=1, fmt='B', readonly=True, - ndim=ndim, shape=shape, strides=strides, - lst=lst) - - # From memoryview: - m2 = memoryview(m) - self.verify(m2, obj=ex, - itemsize=1, fmt='B', readonly=True, - ndim=ndim, shape=shape, strides=strides, - lst=lst) - - # PIL style: - for items, shape in items_shape[1:]: - - # From PEP-3118 compliant exporter: - ex = ndarray(items, shape=shape, flags=ND_PIL) - m = memoryview(ex) - - ndim = len(shape) - lst = carray(items, shape) - - self.verify(m, obj=ex, - itemsize=1, fmt='B', readonly=True, - ndim=ndim, shape=shape, strides=ex.strides, - lst=lst) - - # From memoryview: - m2 = memoryview(m) - self.verify(m2, obj=ex, - itemsize=1, fmt='B', readonly=True, - ndim=ndim, shape=shape, strides=ex.strides, - lst=lst) - - # Invalid number of arguments: - self.assertRaises(TypeError, memoryview, b'9', 'x') - # Not a buffer provider: - self.assertRaises(TypeError, memoryview, {}) - # Non-compliant buffer provider: - ex = ndarray([1,2,3], shape=[3]) - nd = ndarray(ex, getbuf=PyBUF_SIMPLE) - self.assertRaises(BufferError, memoryview, nd) - nd = ndarray(ex, getbuf=PyBUF_CONTIG_RO|PyBUF_FORMAT) - self.assertRaises(BufferError, memoryview, nd) - - # ndim > 64 - nd = ndarray([1]*128, shape=[1]*128, format='L') - self.assertRaises(ValueError, memoryview, nd) - self.assertRaises(ValueError, nd.memoryview_from_buffer) - self.assertRaises(ValueError, get_contiguous, nd, PyBUF_READ, 'C') - self.assertRaises(ValueError, get_contiguous, nd, PyBUF_READ, 'F') - self.assertRaises(ValueError, get_contiguous, nd[::-1], PyBUF_READ, 'C') - - def test_memoryview_cast_zero_shape(self): - # Casts are undefined if buffer is multidimensional and shape - # contains zeros. These arrays are regarded as C-contiguous by - # Numpy and PyBuffer_GetContiguous(), so they are not caught by - # the test for C-contiguity in memory_cast(). - items = [1,2,3] - for shape in ([0,3,3], [3,0,3], [0,3,3]): - ex = ndarray(items, shape=shape) - self.assertTrue(ex.c_contiguous) - msrc = memoryview(ex) - self.assertRaises(TypeError, msrc.cast, 'c') - # Monodimensional empty view can be cast (issue #19014). - for fmt, _, _ in iter_format(1, 'memoryview'): - msrc = memoryview(b'') - m = msrc.cast(fmt) - self.assertEqual(m.tobytes(), b'') - self.assertEqual(m.tolist(), []) - - check_sizeof = support.check_sizeof - - def test_memoryview_sizeof(self): - check = self.check_sizeof - vsize = support.calcvobjsize - base_struct = 'Pnin 2P2n2i5P P' - per_dim = '3n' - - items = list(range(8)) - check(memoryview(b''), vsize(base_struct + 1 * per_dim)) - a = ndarray(items, shape=[2, 4], format="b") - check(memoryview(a), vsize(base_struct + 2 * per_dim)) - a = ndarray(items, shape=[2, 2, 2], format="b") - check(memoryview(a), vsize(base_struct + 3 * per_dim)) - - def test_memoryview_struct_module(self): - - class INT(object): - def __init__(self, val): - self.val = val - def __int__(self): - return self.val - - class IDX(object): - def __init__(self, val): - self.val = val - def __index__(self): - return self.val - - def f(): return 7 - - values = [INT(9), IDX(9), - 2.2+3j, Decimal("-21.1"), 12.2, Fraction(5, 2), - [1,2,3], {4,5,6}, {7:8}, (), (9,), - True, False, None, NotImplemented, - b'a', b'abc', bytearray(b'a'), bytearray(b'abc'), - 'a', 'abc', r'a', r'abc', - f, lambda x: x] - - for fmt, items, item in iter_format(10, 'memoryview'): - ex = ndarray(items, shape=[10], format=fmt, flags=ND_WRITABLE) - nd = ndarray(items, shape=[10], format=fmt, flags=ND_WRITABLE) - m = memoryview(ex) - - struct.pack_into(fmt, nd, 0, item) - m[0] = item - self.assertEqual(m[0], nd[0]) - - itemsize = struct.calcsize(fmt) - if 'P' in fmt: - continue - - for v in values: - struct_err = None - try: - struct.pack_into(fmt, nd, itemsize, v) - except struct.error: - struct_err = struct.error - - mv_err = None - try: - m[1] = v - except (TypeError, ValueError) as e: - mv_err = e.__class__ - - if struct_err or mv_err: - self.assertIsNot(struct_err, None) - self.assertIsNot(mv_err, None) - else: - self.assertEqual(m[1], nd[1]) - - def test_memoryview_cast_zero_strides(self): - # Casts are undefined if strides contains zeros. These arrays are - # (sometimes!) regarded as C-contiguous by Numpy, but not by - # PyBuffer_GetContiguous(). - ex = ndarray([1,2,3], shape=[3], strides=[0]) - self.assertFalse(ex.c_contiguous) - msrc = memoryview(ex) - self.assertRaises(TypeError, msrc.cast, 'c') - - def test_memoryview_cast_invalid(self): - # invalid format - for sfmt in NON_BYTE_FORMAT: - sformat = '@' + sfmt if randrange(2) else sfmt - ssize = struct.calcsize(sformat) - for dfmt in NON_BYTE_FORMAT: - dformat = '@' + dfmt if randrange(2) else dfmt - dsize = struct.calcsize(dformat) - ex = ndarray(list(range(32)), shape=[32//ssize], format=sformat) - msrc = memoryview(ex) - self.assertRaises(TypeError, msrc.cast, dfmt, [32//dsize]) - - for sfmt, sitems, _ in iter_format(1): - ex = ndarray(sitems, shape=[1], format=sfmt) - msrc = memoryview(ex) - for dfmt, _, _ in iter_format(1): - if not is_memoryview_format(dfmt): - self.assertRaises(ValueError, msrc.cast, dfmt, - [32//dsize]) - else: - if not is_byte_format(sfmt) and not is_byte_format(dfmt): - self.assertRaises(TypeError, msrc.cast, dfmt, - [32//dsize]) - - # invalid shape - size_h = struct.calcsize('h') - size_d = struct.calcsize('d') - ex = ndarray(list(range(2*2*size_d)), shape=[2,2,size_d], format='h') - msrc = memoryview(ex) - self.assertRaises(TypeError, msrc.cast, shape=[2,2,size_h], format='d') - - ex = ndarray(list(range(120)), shape=[1,2,3,4,5]) - m = memoryview(ex) - - # incorrect number of args - self.assertRaises(TypeError, m.cast) - self.assertRaises(TypeError, m.cast, 1, 2, 3) - - # incorrect dest format type - self.assertRaises(TypeError, m.cast, {}) - - # incorrect dest format - self.assertRaises(ValueError, m.cast, "X") - self.assertRaises(ValueError, m.cast, "@X") - self.assertRaises(ValueError, m.cast, "@XY") - - # dest format not implemented - self.assertRaises(ValueError, m.cast, "=B") - self.assertRaises(ValueError, m.cast, "!L") - self.assertRaises(ValueError, m.cast, "l") - self.assertRaises(ValueError, m.cast, "BI") - self.assertRaises(ValueError, m.cast, "xBI") - - # src format not implemented - ex = ndarray([(1,2), (3,4)], shape=[2], format="II") - m = memoryview(ex) - self.assertRaises(NotImplementedError, m.__getitem__, 0) - self.assertRaises(NotImplementedError, m.__setitem__, 0, 8) - self.assertRaises(NotImplementedError, m.tolist) - - # incorrect shape type - ex = ndarray(list(range(120)), shape=[1,2,3,4,5]) - m = memoryview(ex) - self.assertRaises(TypeError, m.cast, "B", shape={}) - - # incorrect shape elements - ex = ndarray(list(range(120)), shape=[2*3*4*5]) - m = memoryview(ex) - self.assertRaises(OverflowError, m.cast, "B", shape=[2**64]) - self.assertRaises(ValueError, m.cast, "B", shape=[-1]) - self.assertRaises(ValueError, m.cast, "B", shape=[2,3,4,5,6,7,-1]) - self.assertRaises(ValueError, m.cast, "B", shape=[2,3,4,5,6,7,0]) - self.assertRaises(TypeError, m.cast, "B", shape=[2,3,4,5,6,7,'x']) - - # N-D -> N-D cast - ex = ndarray(list([9 for _ in range(3*5*7*11)]), shape=[3,5,7,11]) - m = memoryview(ex) - self.assertRaises(TypeError, m.cast, "I", shape=[2,3,4,5]) - - # cast with ndim > 64 - nd = ndarray(list(range(128)), shape=[128], format='I') - m = memoryview(nd) - self.assertRaises(ValueError, m.cast, 'I', [1]*128) - - # view->len not a multiple of itemsize - ex = ndarray(list([9 for _ in range(3*5*7*11)]), shape=[3*5*7*11]) - m = memoryview(ex) - self.assertRaises(TypeError, m.cast, "I", shape=[2,3,4,5]) - - # product(shape) * itemsize != buffer size - ex = ndarray(list([9 for _ in range(3*5*7*11)]), shape=[3*5*7*11]) - m = memoryview(ex) - self.assertRaises(TypeError, m.cast, "B", shape=[2,3,4,5]) - - # product(shape) * itemsize overflow - nd = ndarray(list(range(128)), shape=[128], format='I') - m1 = memoryview(nd) - nd = ndarray(list(range(128)), shape=[128], format='B') - m2 = memoryview(nd) - if sys.maxsize == 2**63-1: - self.assertRaises(TypeError, m1.cast, 'B', - [7, 7, 73, 127, 337, 92737, 649657]) - self.assertRaises(ValueError, m1.cast, 'B', - [2**20, 2**20, 2**10, 2**10, 2**3]) - self.assertRaises(ValueError, m2.cast, 'I', - [2**20, 2**20, 2**10, 2**10, 2**1]) - else: - self.assertRaises(TypeError, m1.cast, 'B', - [1, 2147483647]) - self.assertRaises(ValueError, m1.cast, 'B', - [2**10, 2**10, 2**5, 2**5, 2**1]) - self.assertRaises(ValueError, m2.cast, 'I', - [2**10, 2**10, 2**5, 2**3, 2**1]) - - def test_memoryview_cast(self): - bytespec = ( - ('B', lambda ex: list(ex.tobytes())), - ('b', lambda ex: [x-256 if x > 127 else x for x in list(ex.tobytes())]), - ('c', lambda ex: [bytes(chr(x), 'latin-1') for x in list(ex.tobytes())]), - ) - - def iter_roundtrip(ex, m, items, fmt): - srcsize = struct.calcsize(fmt) - for bytefmt, to_bytelist in bytespec: - - m2 = m.cast(bytefmt) - lst = to_bytelist(ex) - self.verify(m2, obj=ex, - itemsize=1, fmt=bytefmt, readonly=False, - ndim=1, shape=[31*srcsize], strides=(1,), - lst=lst, cast=True) - - m3 = m2.cast(fmt) - self.assertEqual(m3, ex) - lst = ex.tolist() - self.verify(m3, obj=ex, - itemsize=srcsize, fmt=fmt, readonly=False, - ndim=1, shape=[31], strides=(srcsize,), - lst=lst, cast=True) - - # cast from ndim = 0 to ndim = 1 - srcsize = struct.calcsize('I') - ex = ndarray(9, shape=[], format='I') - destitems, destshape = cast_items(ex, 'B', 1) - m = memoryview(ex) - m2 = m.cast('B') - self.verify(m2, obj=ex, - itemsize=1, fmt='B', readonly=True, - ndim=1, shape=destshape, strides=(1,), - lst=destitems, cast=True) - - # cast from ndim = 1 to ndim = 0 - destsize = struct.calcsize('I') - ex = ndarray([9]*destsize, shape=[destsize], format='B') - destitems, destshape = cast_items(ex, 'I', destsize, shape=[]) - m = memoryview(ex) - m2 = m.cast('I', shape=[]) - self.verify(m2, obj=ex, - itemsize=destsize, fmt='I', readonly=True, - ndim=0, shape=(), strides=(), - lst=destitems, cast=True) - - # array.array: roundtrip to/from bytes - for fmt, items, _ in iter_format(31, 'array'): - ex = array.array(fmt, items) - m = memoryview(ex) - iter_roundtrip(ex, m, items, fmt) - - # ndarray: roundtrip to/from bytes - for fmt, items, _ in iter_format(31, 'memoryview'): - ex = ndarray(items, shape=[31], format=fmt, flags=ND_WRITABLE) - m = memoryview(ex) - iter_roundtrip(ex, m, items, fmt) - - def test_memoryview_cast_1D_ND(self): - # Cast between C-contiguous buffers. At least one buffer must - # be 1D, at least one format must be 'c', 'b' or 'B'. - for _tshape in gencastshapes(): - for char in fmtdict['@']: - # Casts to _Bool are undefined if the source contains values - # other than 0 or 1. - if char == "?": - continue - tfmt = ('', '@')[randrange(2)] + char - tsize = struct.calcsize(tfmt) - n = prod(_tshape) * tsize - obj = 'memoryview' if is_byte_format(tfmt) else 'bytefmt' - for fmt, items, _ in iter_format(n, obj): - size = struct.calcsize(fmt) - shape = [n] if n > 0 else [] - tshape = _tshape + [size] - - ex = ndarray(items, shape=shape, format=fmt) - m = memoryview(ex) - - titems, tshape = cast_items(ex, tfmt, tsize, shape=tshape) - - if titems is None: - self.assertRaises(TypeError, m.cast, tfmt, tshape) - continue - if titems == 'nan': - continue # NaNs in lists are a recipe for trouble. - - # 1D -> ND - nd = ndarray(titems, shape=tshape, format=tfmt) - - m2 = m.cast(tfmt, shape=tshape) - ndim = len(tshape) - strides = nd.strides - lst = nd.tolist() - self.verify(m2, obj=ex, - itemsize=tsize, fmt=tfmt, readonly=True, - ndim=ndim, shape=tshape, strides=strides, - lst=lst, cast=True) - - # ND -> 1D - m3 = m2.cast(fmt) - m4 = m2.cast(fmt, shape=shape) - ndim = len(shape) - strides = ex.strides - lst = ex.tolist() - - self.verify(m3, obj=ex, - itemsize=size, fmt=fmt, readonly=True, - ndim=ndim, shape=shape, strides=strides, - lst=lst, cast=True) - - self.verify(m4, obj=ex, - itemsize=size, fmt=fmt, readonly=True, - ndim=ndim, shape=shape, strides=strides, - lst=lst, cast=True) - - if ctypes: - # format: "T{>l:x:>d:y:}" - class BEPoint(ctypes.BigEndianStructure): - _fields_ = [("x", ctypes.c_long), ("y", ctypes.c_double)] - point = BEPoint(100, 200.1) - m1 = memoryview(point) - m2 = m1.cast('B') - self.assertEqual(m2.obj, point) - self.assertEqual(m2.itemsize, 1) - self.assertIs(m2.readonly, False) - self.assertEqual(m2.ndim, 1) - self.assertEqual(m2.shape, (m2.nbytes,)) - self.assertEqual(m2.strides, (1,)) - self.assertEqual(m2.suboffsets, ()) - - x = ctypes.c_double(1.2) - m1 = memoryview(x) - m2 = m1.cast('c') - self.assertEqual(m2.obj, x) - self.assertEqual(m2.itemsize, 1) - self.assertIs(m2.readonly, False) - self.assertEqual(m2.ndim, 1) - self.assertEqual(m2.shape, (m2.nbytes,)) - self.assertEqual(m2.strides, (1,)) - self.assertEqual(m2.suboffsets, ()) - - def test_memoryview_tolist(self): - - # Most tolist() tests are in self.verify() etc. - - a = array.array('h', list(range(-6, 6))) - m = memoryview(a) - self.assertEqual(m, a) - self.assertEqual(m.tolist(), a.tolist()) - - a = a[2::3] - m = m[2::3] - self.assertEqual(m, a) - self.assertEqual(m.tolist(), a.tolist()) - - ex = ndarray(list(range(2*3*5*7*11)), shape=[11,2,7,3,5], format='L') - m = memoryview(ex) - self.assertEqual(m.tolist(), ex.tolist()) - - ex = ndarray([(2, 5), (7, 11)], shape=[2], format='lh') - m = memoryview(ex) - self.assertRaises(NotImplementedError, m.tolist) - - ex = ndarray([b'12345'], shape=[1], format="s") - m = memoryview(ex) - self.assertRaises(NotImplementedError, m.tolist) - - ex = ndarray([b"a",b"b",b"c",b"d",b"e",b"f"], shape=[2,3], format='s') - m = memoryview(ex) - self.assertRaises(NotImplementedError, m.tolist) - - def test_memoryview_repr(self): - m = memoryview(bytearray(9)) - r = m.__repr__() - self.assertTrue(r.startswith("l:x:>l:y:}" - class BEPoint(ctypes.BigEndianStructure): - _fields_ = [("x", ctypes.c_long), ("y", ctypes.c_long)] - point = BEPoint(100, 200) - a = memoryview(point) - b = memoryview(point) - self.assertNotEqual(a, b) - self.assertNotEqual(a, point) - self.assertNotEqual(point, a) - self.assertRaises(NotImplementedError, a.tolist) - - def test_memoryview_compare_ndim_zero(self): - - nd1 = ndarray(1729, shape=[], format='@L') - nd2 = ndarray(1729, shape=[], format='L', flags=ND_WRITABLE) - v = memoryview(nd1) - w = memoryview(nd2) - self.assertEqual(v, w) - self.assertEqual(w, v) - self.assertEqual(v, nd2) - self.assertEqual(nd2, v) - self.assertEqual(w, nd1) - self.assertEqual(nd1, w) - - self.assertFalse(v.__ne__(w)) - self.assertFalse(w.__ne__(v)) - - w[()] = 1728 - self.assertNotEqual(v, w) - self.assertNotEqual(w, v) - self.assertNotEqual(v, nd2) - self.assertNotEqual(nd2, v) - self.assertNotEqual(w, nd1) - self.assertNotEqual(nd1, w) - - self.assertFalse(v.__eq__(w)) - self.assertFalse(w.__eq__(v)) - - nd = ndarray(list(range(12)), shape=[12], flags=ND_WRITABLE|ND_PIL) - ex = ndarray(list(range(12)), shape=[12], flags=ND_WRITABLE|ND_PIL) - m = memoryview(ex) - - self.assertEqual(m, nd) - m[9] = 100 - self.assertNotEqual(m, nd) - - # struct module: equal - nd1 = ndarray((1729, 1.2, b'12345'), shape=[], format='Lf5s') - nd2 = ndarray((1729, 1.2, b'12345'), shape=[], format='hf5s', - flags=ND_WRITABLE) - v = memoryview(nd1) - w = memoryview(nd2) - self.assertEqual(v, w) - self.assertEqual(w, v) - self.assertEqual(v, nd2) - self.assertEqual(nd2, v) - self.assertEqual(w, nd1) - self.assertEqual(nd1, w) - - # struct module: not equal - nd1 = ndarray((1729, 1.2, b'12345'), shape=[], format='Lf5s') - nd2 = ndarray((-1729, 1.2, b'12345'), shape=[], format='hf5s', - flags=ND_WRITABLE) - v = memoryview(nd1) - w = memoryview(nd2) - self.assertNotEqual(v, w) - self.assertNotEqual(w, v) - self.assertNotEqual(v, nd2) - self.assertNotEqual(nd2, v) - self.assertNotEqual(w, nd1) - self.assertNotEqual(nd1, w) - self.assertEqual(v, nd1) - self.assertEqual(w, nd2) - - def test_memoryview_compare_ndim_one(self): - - # contiguous - nd1 = ndarray([-529, 576, -625, 676, -729], shape=[5], format='@h') - nd2 = ndarray([-529, 576, -625, 676, 729], shape=[5], format='@h') - v = memoryview(nd1) - w = memoryview(nd2) - - self.assertEqual(v, nd1) - self.assertEqual(w, nd2) - self.assertNotEqual(v, nd2) - self.assertNotEqual(w, nd1) - self.assertNotEqual(v, w) - - # contiguous, struct module - nd1 = ndarray([-529, 576, -625, 676, -729], shape=[5], format='', '!']: - x = ndarray([2**63]*120, shape=[3,5,2,2,2], format=byteorder+'Q') - y = ndarray([2**63]*120, shape=[3,5,2,2,2], format=byteorder+'Q', - flags=ND_WRITABLE|ND_FORTRAN) - y[2][3][1][1][1] = 1 - a = memoryview(x) - b = memoryview(y) - self.assertEqual(a, x) - self.assertEqual(b, y) - self.assertNotEqual(a, b) - self.assertNotEqual(a, y) - self.assertNotEqual(b, x) - - x = ndarray([(2**63, 2**31, 2**15)]*120, shape=[3,5,2,2,2], - format=byteorder+'QLH') - y = ndarray([(2**63, 2**31, 2**15)]*120, shape=[3,5,2,2,2], - format=byteorder+'QLH', flags=ND_WRITABLE|ND_FORTRAN) - y[2][3][1][1][1] = (1, 1, 1) - a = memoryview(x) - b = memoryview(y) - self.assertEqual(a, x) - self.assertEqual(b, y) - self.assertNotEqual(a, b) - self.assertNotEqual(a, y) - self.assertNotEqual(b, x) - - def test_memoryview_check_released(self): - - a = array.array('d', [1.1, 2.2, 3.3]) - - m = memoryview(a) - m.release() - - # PyMemoryView_FromObject() - self.assertRaises(ValueError, memoryview, m) - # memoryview.cast() - self.assertRaises(ValueError, m.cast, 'c') - # getbuffer() - self.assertRaises(ValueError, ndarray, m) - # memoryview.tolist() - self.assertRaises(ValueError, m.tolist) - # memoryview.tobytes() - self.assertRaises(ValueError, m.tobytes) - # sequence - self.assertRaises(ValueError, eval, "1.0 in m", locals()) - # subscript - self.assertRaises(ValueError, m.__getitem__, 0) - # assignment - self.assertRaises(ValueError, m.__setitem__, 0, 1) - - for attr in ('obj', 'nbytes', 'readonly', 'itemsize', 'format', 'ndim', - 'shape', 'strides', 'suboffsets', 'c_contiguous', - 'f_contiguous', 'contiguous'): - self.assertRaises(ValueError, m.__getattribute__, attr) - - # richcompare - b = array.array('d', [1.1, 2.2, 3.3]) - m1 = memoryview(a) - m2 = memoryview(b) - - self.assertEqual(m1, m2) - m1.release() - self.assertNotEqual(m1, m2) - self.assertNotEqual(m1, a) - self.assertEqual(m1, m1) - - def test_memoryview_tobytes(self): - # Many implicit tests are already in self.verify(). - - t = (-529, 576, -625, 676, -729) - - nd = ndarray(t, shape=[5], format='@h') - m = memoryview(nd) - self.assertEqual(m, nd) - self.assertEqual(m.tobytes(), nd.tobytes()) - - nd = ndarray([t], shape=[1], format='>hQiLl') - m = memoryview(nd) - self.assertEqual(m, nd) - self.assertEqual(m.tobytes(), nd.tobytes()) - - nd = ndarray([t for _ in range(12)], shape=[2,2,3], format='=hQiLl') - m = memoryview(nd) - self.assertEqual(m, nd) - self.assertEqual(m.tobytes(), nd.tobytes()) - - nd = ndarray([t for _ in range(120)], shape=[5,2,2,3,2], - format='l:x:>l:y:}" - class BEPoint(ctypes.BigEndianStructure): - _fields_ = [("x", ctypes.c_long), ("y", ctypes.c_long)] - point = BEPoint(100, 200) - a = memoryview(point) - self.assertEqual(a.tobytes(), bytes(point)) - - def test_memoryview_get_contiguous(self): - # Many implicit tests are already in self.verify(). - - # no buffer interface - self.assertRaises(TypeError, get_contiguous, {}, PyBUF_READ, 'F') - - # writable request to read-only object - self.assertRaises(BufferError, get_contiguous, b'x', PyBUF_WRITE, 'C') - - # writable request to non-contiguous object - nd = ndarray([1, 2, 3], shape=[2], strides=[2]) - self.assertRaises(BufferError, get_contiguous, nd, PyBUF_WRITE, 'A') - - # scalar, read-only request from read-only exporter - nd = ndarray(9, shape=(), format="L") - for order in ['C', 'F', 'A']: - m = get_contiguous(nd, PyBUF_READ, order) - self.assertEqual(m, nd) - self.assertEqual(m[()], 9) - - # scalar, read-only request from writable exporter - nd = ndarray(9, shape=(), format="L", flags=ND_WRITABLE) - for order in ['C', 'F', 'A']: - m = get_contiguous(nd, PyBUF_READ, order) - self.assertEqual(m, nd) - self.assertEqual(m[()], 9) - - # scalar, writable request - for order in ['C', 'F', 'A']: - nd[()] = 9 - m = get_contiguous(nd, PyBUF_WRITE, order) - self.assertEqual(m, nd) - self.assertEqual(m[()], 9) - - m[()] = 10 - self.assertEqual(m[()], 10) - self.assertEqual(nd[()], 10) - - # zeros in shape - nd = ndarray([1], shape=[0], format="L", flags=ND_WRITABLE) - for order in ['C', 'F', 'A']: - m = get_contiguous(nd, PyBUF_READ, order) - self.assertRaises(IndexError, m.__getitem__, 0) - self.assertEqual(m, nd) - self.assertEqual(m.tolist(), []) - - nd = ndarray(list(range(8)), shape=[2, 0, 7], format="L", - flags=ND_WRITABLE) - for order in ['C', 'F', 'A']: - m = get_contiguous(nd, PyBUF_READ, order) - self.assertEqual(ndarray(m).tolist(), [[], []]) - - # one-dimensional - nd = ndarray([1], shape=[1], format="h", flags=ND_WRITABLE) - for order in ['C', 'F', 'A']: - m = get_contiguous(nd, PyBUF_WRITE, order) - self.assertEqual(m, nd) - self.assertEqual(m.tolist(), nd.tolist()) - - nd = ndarray([1, 2, 3], shape=[3], format="b", flags=ND_WRITABLE) - for order in ['C', 'F', 'A']: - m = get_contiguous(nd, PyBUF_WRITE, order) - self.assertEqual(m, nd) - self.assertEqual(m.tolist(), nd.tolist()) - - # one-dimensional, non-contiguous - nd = ndarray([1, 2, 3], shape=[2], strides=[2], flags=ND_WRITABLE) - for order in ['C', 'F', 'A']: - m = get_contiguous(nd, PyBUF_READ, order) - self.assertEqual(m, nd) - self.assertEqual(m.tolist(), nd.tolist()) - self.assertRaises(TypeError, m.__setitem__, 1, 20) - self.assertEqual(m[1], 3) - self.assertEqual(nd[1], 3) - - nd = nd[::-1] - for order in ['C', 'F', 'A']: - m = get_contiguous(nd, PyBUF_READ, order) - self.assertEqual(m, nd) - self.assertEqual(m.tolist(), nd.tolist()) - self.assertRaises(TypeError, m.__setitem__, 1, 20) - self.assertEqual(m[1], 1) - self.assertEqual(nd[1], 1) - - # multi-dimensional, contiguous input - nd = ndarray(list(range(12)), shape=[3, 4], flags=ND_WRITABLE) - for order in ['C', 'A']: - m = get_contiguous(nd, PyBUF_WRITE, order) - self.assertEqual(ndarray(m).tolist(), nd.tolist()) - - self.assertRaises(BufferError, get_contiguous, nd, PyBUF_WRITE, 'F') - m = get_contiguous(nd, PyBUF_READ, order) - self.assertEqual(ndarray(m).tolist(), nd.tolist()) - - nd = ndarray(list(range(12)), shape=[3, 4], - flags=ND_WRITABLE|ND_FORTRAN) - for order in ['F', 'A']: - m = get_contiguous(nd, PyBUF_WRITE, order) - self.assertEqual(ndarray(m).tolist(), nd.tolist()) - - self.assertRaises(BufferError, get_contiguous, nd, PyBUF_WRITE, 'C') - m = get_contiguous(nd, PyBUF_READ, order) - self.assertEqual(ndarray(m).tolist(), nd.tolist()) - - # multi-dimensional, non-contiguous input - nd = ndarray(list(range(12)), shape=[3, 4], flags=ND_WRITABLE|ND_PIL) - for order in ['C', 'F', 'A']: - self.assertRaises(BufferError, get_contiguous, nd, PyBUF_WRITE, - order) - m = get_contiguous(nd, PyBUF_READ, order) - self.assertEqual(ndarray(m).tolist(), nd.tolist()) - - # flags - nd = ndarray([1,2,3,4,5], shape=[3], strides=[2]) - m = get_contiguous(nd, PyBUF_READ, 'C') - self.assertTrue(m.c_contiguous) - - def test_memoryview_serializing(self): - - # C-contiguous - size = struct.calcsize('i') - a = array.array('i', [1,2,3,4,5]) - m = memoryview(a) - buf = io.BytesIO(m) - b = bytearray(5*size) - buf.readinto(b) - self.assertEqual(m.tobytes(), b) - - # C-contiguous, multi-dimensional - size = struct.calcsize('L') - nd = ndarray(list(range(12)), shape=[2,3,2], format="L") - m = memoryview(nd) - buf = io.BytesIO(m) - b = bytearray(2*3*2*size) - buf.readinto(b) - self.assertEqual(m.tobytes(), b) - - # Fortran contiguous, multi-dimensional - #size = struct.calcsize('L') - #nd = ndarray(list(range(12)), shape=[2,3,2], format="L", - # flags=ND_FORTRAN) - #m = memoryview(nd) - #buf = io.BytesIO(m) - #b = bytearray(2*3*2*size) - #buf.readinto(b) - #self.assertEqual(m.tobytes(), b) - - def test_memoryview_hash(self): - - # bytes exporter - b = bytes(list(range(12))) - m = memoryview(b) - self.assertEqual(hash(b), hash(m)) - - # C-contiguous - mc = m.cast('c', shape=[3,4]) - self.assertEqual(hash(mc), hash(b)) - - # non-contiguous - mx = m[::-2] - b = bytes(list(range(12))[::-2]) - self.assertEqual(hash(mx), hash(b)) - - # Fortran contiguous - nd = ndarray(list(range(30)), shape=[3,2,5], flags=ND_FORTRAN) - m = memoryview(nd) - self.assertEqual(hash(m), hash(nd)) - - # multi-dimensional slice - nd = ndarray(list(range(30)), shape=[3,2,5]) - x = nd[::2, ::, ::-1] - m = memoryview(x) - self.assertEqual(hash(m), hash(x)) - - # multi-dimensional slice with suboffsets - nd = ndarray(list(range(30)), shape=[2,5,3], flags=ND_PIL) - x = nd[::2, ::, ::-1] - m = memoryview(x) - self.assertEqual(hash(m), hash(x)) - - # equality-hash invariant - x = ndarray(list(range(12)), shape=[12], format='B') - a = memoryview(x) - - y = ndarray(list(range(12)), shape=[12], format='b') - b = memoryview(y) - - self.assertEqual(a, b) - self.assertEqual(hash(a), hash(b)) - - # non-byte formats - nd = ndarray(list(range(12)), shape=[2,2,3], format='L') - m = memoryview(nd) - self.assertRaises(ValueError, m.__hash__) - - nd = ndarray(list(range(-6, 6)), shape=[2,2,3], format='h') - m = memoryview(nd) - self.assertRaises(ValueError, m.__hash__) - - nd = ndarray(list(range(12)), shape=[2,2,3], format='= L') - m = memoryview(nd) - self.assertRaises(ValueError, m.__hash__) - - nd = ndarray(list(range(-6, 6)), shape=[2,2,3], format='< h') - m = memoryview(nd) - self.assertRaises(ValueError, m.__hash__) - - def test_memoryview_release(self): - - # Create re-exporter from getbuffer(memoryview), then release the view. - a = bytearray([1,2,3]) - m = memoryview(a) - nd = ndarray(m) # re-exporter - self.assertRaises(BufferError, m.release) - del nd - m.release() - - a = bytearray([1,2,3]) - m = memoryview(a) - nd1 = ndarray(m, getbuf=PyBUF_FULL_RO, flags=ND_REDIRECT) - nd2 = ndarray(nd1, getbuf=PyBUF_FULL_RO, flags=ND_REDIRECT) - self.assertIs(nd2.obj, m) - self.assertRaises(BufferError, m.release) - del nd1, nd2 - m.release() - - # chained views - a = bytearray([1,2,3]) - m1 = memoryview(a) - m2 = memoryview(m1) - nd = ndarray(m2) # re-exporter - m1.release() - self.assertRaises(BufferError, m2.release) - del nd - m2.release() - - a = bytearray([1,2,3]) - m1 = memoryview(a) - m2 = memoryview(m1) - nd1 = ndarray(m2, getbuf=PyBUF_FULL_RO, flags=ND_REDIRECT) - nd2 = ndarray(nd1, getbuf=PyBUF_FULL_RO, flags=ND_REDIRECT) - self.assertIs(nd2.obj, m2) - m1.release() - self.assertRaises(BufferError, m2.release) - del nd1, nd2 - m2.release() - - # Allow changing layout while buffers are exported. - nd = ndarray([1,2,3], shape=[3], flags=ND_VAREXPORT) - m1 = memoryview(nd) - - nd.push([4,5,6,7,8], shape=[5]) # mutate nd - m2 = memoryview(nd) - - x = memoryview(m1) - self.assertEqual(x.tolist(), m1.tolist()) - - y = memoryview(m2) - self.assertEqual(y.tolist(), m2.tolist()) - self.assertEqual(y.tolist(), nd.tolist()) - m2.release() - y.release() - - nd.pop() # pop the current view - self.assertEqual(x.tolist(), nd.tolist()) - - del nd - m1.release() - x.release() - - # If multiple memoryviews share the same managed buffer, implicit - # release() in the context manager's __exit__() method should still - # work. - def catch22(b): - with memoryview(b) as m2: - pass - - x = bytearray(b'123') - with memoryview(x) as m1: - catch22(m1) - self.assertEqual(m1[0], ord(b'1')) - - x = ndarray(list(range(12)), shape=[2,2,3], format='l') - y = ndarray(x, getbuf=PyBUF_FULL_RO, flags=ND_REDIRECT) - z = ndarray(y, getbuf=PyBUF_FULL_RO, flags=ND_REDIRECT) - self.assertIs(z.obj, x) - with memoryview(z) as m: - catch22(m) - self.assertEqual(m[0:1].tolist(), [[[0, 1, 2], [3, 4, 5]]]) - - # Test garbage collection. - for flags in (0, ND_REDIRECT): - x = bytearray(b'123') - with memoryview(x) as m1: - del x - y = ndarray(m1, getbuf=PyBUF_FULL_RO, flags=flags) - with memoryview(y) as m2: - del y - z = ndarray(m2, getbuf=PyBUF_FULL_RO, flags=flags) - with memoryview(z) as m3: - del z - catch22(m3) - catch22(m2) - catch22(m1) - self.assertEqual(m1[0], ord(b'1')) - self.assertEqual(m2[1], ord(b'2')) - self.assertEqual(m3[2], ord(b'3')) - del m3 - del m2 - del m1 - - x = bytearray(b'123') - with memoryview(x) as m1: - del x - y = ndarray(m1, getbuf=PyBUF_FULL_RO, flags=flags) - with memoryview(y) as m2: - del y - z = ndarray(m2, getbuf=PyBUF_FULL_RO, flags=flags) - with memoryview(z) as m3: - del z - catch22(m1) - catch22(m2) - catch22(m3) - self.assertEqual(m1[0], ord(b'1')) - self.assertEqual(m2[1], ord(b'2')) - self.assertEqual(m3[2], ord(b'3')) - del m1, m2, m3 - - # memoryview.release() fails if the view has exported buffers. - x = bytearray(b'123') - with self.assertRaises(BufferError): - with memoryview(x) as m: - ex = ndarray(m) - m[0] == ord(b'1') - - def test_memoryview_redirect(self): - - nd = ndarray([1.0 * x for x in range(12)], shape=[12], format='d') - a = array.array('d', [1.0 * x for x in range(12)]) - - for x in (nd, a): - y = ndarray(x, getbuf=PyBUF_FULL_RO, flags=ND_REDIRECT) - z = ndarray(y, getbuf=PyBUF_FULL_RO, flags=ND_REDIRECT) - m = memoryview(z) - - self.assertIs(y.obj, x) - self.assertIs(z.obj, x) - self.assertIs(m.obj, x) - - self.assertEqual(m, x) - self.assertEqual(m, y) - self.assertEqual(m, z) - - self.assertEqual(m[1:3], x[1:3]) - self.assertEqual(m[1:3], y[1:3]) - self.assertEqual(m[1:3], z[1:3]) - del y, z - self.assertEqual(m[1:3], x[1:3]) - - def test_memoryview_from_static_exporter(self): - - fmt = 'B' - lst = [0,1,2,3,4,5,6,7,8,9,10,11] - - # exceptions - self.assertRaises(TypeError, staticarray, 1, 2, 3) - - # view.obj==x - x = staticarray() - y = memoryview(x) - self.verify(y, obj=x, - itemsize=1, fmt=fmt, readonly=True, - ndim=1, shape=[12], strides=[1], - lst=lst) - for i in range(12): - self.assertEqual(y[i], i) - del x - del y - - x = staticarray() - y = memoryview(x) - del y - del x - - x = staticarray() - y = ndarray(x, getbuf=PyBUF_FULL_RO) - z = ndarray(y, getbuf=PyBUF_FULL_RO) - m = memoryview(z) - self.assertIs(y.obj, x) - self.assertIs(m.obj, z) - self.verify(m, obj=z, - itemsize=1, fmt=fmt, readonly=True, - ndim=1, shape=[12], strides=[1], - lst=lst) - del x, y, z, m - - x = staticarray() - y = ndarray(x, getbuf=PyBUF_FULL_RO, flags=ND_REDIRECT) - z = ndarray(y, getbuf=PyBUF_FULL_RO, flags=ND_REDIRECT) - m = memoryview(z) - self.assertIs(y.obj, x) - self.assertIs(z.obj, x) - self.assertIs(m.obj, x) - self.verify(m, obj=x, - itemsize=1, fmt=fmt, readonly=True, - ndim=1, shape=[12], strides=[1], - lst=lst) - del x, y, z, m - - # view.obj==NULL - x = staticarray(legacy_mode=True) - y = memoryview(x) - self.verify(y, obj=None, - itemsize=1, fmt=fmt, readonly=True, - ndim=1, shape=[12], strides=[1], - lst=lst) - for i in range(12): - self.assertEqual(y[i], i) - del x - del y - - x = staticarray(legacy_mode=True) - y = memoryview(x) - del y - del x - - x = staticarray(legacy_mode=True) - y = ndarray(x, getbuf=PyBUF_FULL_RO) - z = ndarray(y, getbuf=PyBUF_FULL_RO) - m = memoryview(z) - self.assertIs(y.obj, None) - self.assertIs(m.obj, z) - self.verify(m, obj=z, - itemsize=1, fmt=fmt, readonly=True, - ndim=1, shape=[12], strides=[1], - lst=lst) - del x, y, z, m - - x = staticarray(legacy_mode=True) - y = ndarray(x, getbuf=PyBUF_FULL_RO, flags=ND_REDIRECT) - z = ndarray(y, getbuf=PyBUF_FULL_RO, flags=ND_REDIRECT) - m = memoryview(z) - # Clearly setting view.obj==NULL is inferior, since it - # messes up the redirection chain: - self.assertIs(y.obj, None) - self.assertIs(z.obj, y) - self.assertIs(m.obj, y) - self.verify(m, obj=y, - itemsize=1, fmt=fmt, readonly=True, - ndim=1, shape=[12], strides=[1], - lst=lst) - del x, y, z, m - - def test_memoryview_getbuffer_undefined(self): - - # getbufferproc does not adhere to the new documentation - nd = ndarray([1,2,3], [3], flags=ND_GETBUF_FAIL|ND_GETBUF_UNDEFINED) - self.assertRaises(BufferError, memoryview, nd) - - def test_issue_7385(self): - x = ndarray([1,2,3], shape=[3], flags=ND_GETBUF_FAIL) - self.assertRaises(BufferError, memoryview, x) - - - if __name__ == "__main__": - unittest.main() diff --git a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_bufio.yaml b/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_bufio.yaml deleted file mode 100644 index e72934d8f..000000000 --- a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_bufio.yaml +++ /dev/null @@ -1,74 +0,0 @@ -python: | - import unittest - from test import support - - import io # C implementation. - import _pyio as pyio # Python implementation. - - # Simple test to ensure that optimizations in the IO library deliver the - # expected results. For best testing, run this under a debug-build Python too - # (to exercise asserts in the C code). - - lengths = list(range(1, 257)) + [512, 1000, 1024, 2048, 4096, 8192, 10000, - 16384, 32768, 65536, 1000000] - - class BufferSizeTest: - def try_one(self, s): - # Write s + "\n" + s to file, then open it and ensure that successive - # .readline()s deliver what we wrote. - - # Ensure we can open TESTFN for writing. - support.unlink(support.TESTFN) - - # Since C doesn't guarantee we can write/read arbitrary bytes in text - # files, use binary mode. - f = self.open(support.TESTFN, "wb") - try: - # write once with \n and once without - f.write(s) - f.write(b"\n") - f.write(s) - f.close() - f = open(support.TESTFN, "rb") - line = f.readline() - self.assertEqual(line, s + b"\n") - line = f.readline() - self.assertEqual(line, s) - line = f.readline() - self.assertFalse(line) # Must be at EOF - f.close() - finally: - support.unlink(support.TESTFN) - - def drive_one(self, pattern): - for length in lengths: - # Repeat string 'pattern' as often as needed to reach total length - # 'length'. Then call try_one with that string, a string one larger - # than that, and a string one smaller than that. Try this with all - # small sizes and various powers of 2, so we exercise all likely - # stdio buffer sizes, and "off by one" errors on both sides. - q, r = divmod(length, len(pattern)) - teststring = pattern * q + pattern[:r] - self.assertEqual(len(teststring), length) - self.try_one(teststring) - self.try_one(teststring + b"x") - self.try_one(teststring[:-1]) - - def test_primepat(self): - # A pattern with prime length, to avoid simple relationships with - # stdio buffer sizes. - self.drive_one(b"1234567890\00\01\02\03\04\05\06") - - def test_nullpat(self): - self.drive_one(b'\0' * 1000) - - - class CBufferSizeTest(BufferSizeTest, unittest.TestCase): - open = io.open - - class PyBufferSizeTest(BufferSizeTest, unittest.TestCase): - open = staticmethod(pyio.open) - - - if __name__ == "__main__": - unittest.main() diff --git a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_builtin.yaml b/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_builtin.yaml deleted file mode 100644 index a60e9dca1..000000000 --- a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_builtin.yaml +++ /dev/null @@ -1,2194 +0,0 @@ -python: | - # Python test set -- built-in functions - - import ast - import asyncio - import builtins - import collections - import decimal - import fractions - import gc - import io - import locale - import os - import pickle - import platform - import random - import re - import sys - import traceback - import types - import unittest - import warnings - from contextlib import ExitStack - from functools import partial - from inspect import CO_COROUTINE - from itertools import product - from textwrap import dedent - from types import AsyncGeneratorType, FunctionType - from operator import neg - from test.support import ( - EnvironmentVarGuard, TESTFN, check_warnings, swap_attr, unlink, - maybe_get_event_loop_policy, cpython_only) - from test.support.script_helper import assert_python_ok - from unittest.mock import MagicMock, patch - try: - import pty, signal - except ImportError: - pty = signal = None - - - class Squares: - - def __init__(self, max): - self.max = max - self.sofar = [] - - def __len__(self): return len(self.sofar) - - def __getitem__(self, i): - if not 0 <= i < self.max: raise IndexError - n = len(self.sofar) - while n <= i: - self.sofar.append(n*n) - n += 1 - return self.sofar[i] - - class StrSquares: - - def __init__(self, max): - self.max = max - self.sofar = [] - - def __len__(self): - return len(self.sofar) - - def __getitem__(self, i): - if not 0 <= i < self.max: - raise IndexError - n = len(self.sofar) - while n <= i: - self.sofar.append(str(n*n)) - n += 1 - return self.sofar[i] - - class BitBucket: - def write(self, line): - pass - - test_conv_no_sign = [ - ('0', 0), - ('1', 1), - ('9', 9), - ('10', 10), - ('99', 99), - ('100', 100), - ('314', 314), - (' 314', 314), - ('314 ', 314), - (' \t\t 314 \t\t ', 314), - (repr(sys.maxsize), sys.maxsize), - (' 1x', ValueError), - (' 1 ', 1), - (' 1\02 ', ValueError), - ('', ValueError), - (' ', ValueError), - (' \t\t ', ValueError), - (str(br'\u0663\u0661\u0664 ','raw-unicode-escape'), 314), - (chr(0x200), ValueError), - ] - - test_conv_sign = [ - ('0', 0), - ('1', 1), - ('9', 9), - ('10', 10), - ('99', 99), - ('100', 100), - ('314', 314), - (' 314', ValueError), - ('314 ', 314), - (' \t\t 314 \t\t ', ValueError), - (repr(sys.maxsize), sys.maxsize), - (' 1x', ValueError), - (' 1 ', ValueError), - (' 1\02 ', ValueError), - ('', ValueError), - (' ', ValueError), - (' \t\t ', ValueError), - (str(br'\u0663\u0661\u0664 ','raw-unicode-escape'), 314), - (chr(0x200), ValueError), - ] - - class TestFailingBool: - def __bool__(self): - raise RuntimeError - - class TestFailingIter: - def __iter__(self): - raise RuntimeError - - def filter_char(arg): - return ord(arg) > ord("d") - - def map_char(arg): - return chr(ord(arg)+1) - - class BuiltinTest(unittest.TestCase): - # Helper to check picklability - def check_iter_pickle(self, it, seq, proto): - itorg = it - d = pickle.dumps(it, proto) - it = pickle.loads(d) - self.assertEqual(type(itorg), type(it)) - self.assertEqual(list(it), seq) - - #test the iterator after dropping one from it - it = pickle.loads(d) - try: - next(it) - except StopIteration: - return - d = pickle.dumps(it, proto) - it = pickle.loads(d) - self.assertEqual(list(it), seq[1:]) - - def test_import(self): - __import__('sys') - __import__('time') - __import__('string') - __import__(name='sys') - __import__(name='time', level=0) - self.assertRaises(ImportError, __import__, 'spamspam') - self.assertRaises(TypeError, __import__, 1, 2, 3, 4) - self.assertRaises(ValueError, __import__, '') - self.assertRaises(TypeError, __import__, 'sys', name='sys') - # Relative import outside of a package with no __package__ or __spec__ (bpo-37409). - with self.assertWarns(ImportWarning): - self.assertRaises(ImportError, __import__, '', - {'__package__': None, '__spec__': None, '__name__': '__main__'}, - locals={}, fromlist=('foo',), level=1) - # embedded null character - self.assertRaises(ModuleNotFoundError, __import__, 'string\x00') - - def test_abs(self): - # int - self.assertEqual(abs(0), 0) - self.assertEqual(abs(1234), 1234) - self.assertEqual(abs(-1234), 1234) - self.assertTrue(abs(-sys.maxsize-1) > 0) - # float - self.assertEqual(abs(0.0), 0.0) - self.assertEqual(abs(3.14), 3.14) - self.assertEqual(abs(-3.14), 3.14) - # str - self.assertRaises(TypeError, abs, 'a') - # bool - self.assertEqual(abs(True), 1) - self.assertEqual(abs(False), 0) - # other - self.assertRaises(TypeError, abs) - self.assertRaises(TypeError, abs, None) - class AbsClass(object): - def __abs__(self): - return -5 - self.assertEqual(abs(AbsClass()), -5) - - def test_all(self): - self.assertEqual(all([2, 4, 6]), True) - self.assertEqual(all([2, None, 6]), False) - self.assertRaises(RuntimeError, all, [2, TestFailingBool(), 6]) - self.assertRaises(RuntimeError, all, TestFailingIter()) - self.assertRaises(TypeError, all, 10) # Non-iterable - self.assertRaises(TypeError, all) # No args - self.assertRaises(TypeError, all, [2, 4, 6], []) # Too many args - self.assertEqual(all([]), True) # Empty iterator - self.assertEqual(all([0, TestFailingBool()]), False)# Short-circuit - S = [50, 60] - self.assertEqual(all(x > 42 for x in S), True) - S = [50, 40, 60] - self.assertEqual(all(x > 42 for x in S), False) - - def test_any(self): - self.assertEqual(any([None, None, None]), False) - self.assertEqual(any([None, 4, None]), True) - self.assertRaises(RuntimeError, any, [None, TestFailingBool(), 6]) - self.assertRaises(RuntimeError, any, TestFailingIter()) - self.assertRaises(TypeError, any, 10) # Non-iterable - self.assertRaises(TypeError, any) # No args - self.assertRaises(TypeError, any, [2, 4, 6], []) # Too many args - self.assertEqual(any([]), False) # Empty iterator - self.assertEqual(any([1, TestFailingBool()]), True) # Short-circuit - S = [40, 60, 30] - self.assertEqual(any(x > 42 for x in S), True) - S = [10, 20, 30] - self.assertEqual(any(x > 42 for x in S), False) - - def test_ascii(self): - self.assertEqual(ascii(''), '\'\'') - self.assertEqual(ascii(0), '0') - self.assertEqual(ascii(()), '()') - self.assertEqual(ascii([]), '[]') - self.assertEqual(ascii({}), '{}') - a = [] - a.append(a) - self.assertEqual(ascii(a), '[[...]]') - a = {} - a[0] = a - self.assertEqual(ascii(a), '{0: {...}}') - # Advanced checks for unicode strings - def _check_uni(s): - self.assertEqual(ascii(s), repr(s)) - _check_uni("'") - _check_uni('"') - _check_uni('"\'') - _check_uni('\0') - _check_uni('\r\n\t .') - # Unprintable non-ASCII characters - _check_uni('\x85') - _check_uni('\u1fff') - _check_uni('\U00012fff') - # Lone surrogates - _check_uni('\ud800') - _check_uni('\udfff') - # Issue #9804: surrogates should be joined even for printable - # wide characters (UCS-2 builds). - self.assertEqual(ascii('\U0001d121'), "'\\U0001d121'") - # All together - s = "'\0\"\n\r\t abcd\x85é\U00012fff\uD800\U0001D121xxx." - self.assertEqual(ascii(s), - r"""'\'\x00"\n\r\t abcd\x85\xe9\U00012fff\ud800\U0001d121xxx.'""") - - def test_neg(self): - x = -sys.maxsize-1 - self.assertTrue(isinstance(x, int)) - self.assertEqual(-x, sys.maxsize+1) - - def test_callable(self): - self.assertTrue(callable(len)) - self.assertFalse(callable("a")) - self.assertTrue(callable(callable)) - self.assertTrue(callable(lambda x, y: x + y)) - self.assertFalse(callable(__builtins__)) - def f(): pass - self.assertTrue(callable(f)) - - class C1: - def meth(self): pass - self.assertTrue(callable(C1)) - c = C1() - self.assertTrue(callable(c.meth)) - self.assertFalse(callable(c)) - - # __call__ is looked up on the class, not the instance - c.__call__ = None - self.assertFalse(callable(c)) - c.__call__ = lambda self: 0 - self.assertFalse(callable(c)) - del c.__call__ - self.assertFalse(callable(c)) - - class C2(object): - def __call__(self): pass - c2 = C2() - self.assertTrue(callable(c2)) - c2.__call__ = None - self.assertTrue(callable(c2)) - class C3(C2): pass - c3 = C3() - self.assertTrue(callable(c3)) - - def test_chr(self): - self.assertEqual(chr(32), ' ') - self.assertEqual(chr(65), 'A') - self.assertEqual(chr(97), 'a') - self.assertEqual(chr(0xff), '\xff') - self.assertRaises(ValueError, chr, 1<<24) - self.assertEqual(chr(sys.maxunicode), - str('\\U0010ffff'.encode("ascii"), 'unicode-escape')) - self.assertRaises(TypeError, chr) - self.assertEqual(chr(0x0000FFFF), "\U0000FFFF") - self.assertEqual(chr(0x00010000), "\U00010000") - self.assertEqual(chr(0x00010001), "\U00010001") - self.assertEqual(chr(0x000FFFFE), "\U000FFFFE") - self.assertEqual(chr(0x000FFFFF), "\U000FFFFF") - self.assertEqual(chr(0x00100000), "\U00100000") - self.assertEqual(chr(0x00100001), "\U00100001") - self.assertEqual(chr(0x0010FFFE), "\U0010FFFE") - self.assertEqual(chr(0x0010FFFF), "\U0010FFFF") - self.assertRaises(ValueError, chr, -1) - self.assertRaises(ValueError, chr, 0x00110000) - self.assertRaises((OverflowError, ValueError), chr, 2**32) - - def test_cmp(self): - self.assertTrue(not hasattr(builtins, "cmp")) - - def test_compile(self): - compile('print(1)\n', '', 'exec') - bom = b'\xef\xbb\xbf' - compile(bom + b'print(1)\n', '', 'exec') - compile(source='pass', filename='?', mode='exec') - compile(dont_inherit=0, filename='tmp', source='0', mode='eval') - compile('pass', '?', dont_inherit=1, mode='exec') - compile(memoryview(b"text"), "name", "exec") - self.assertRaises(TypeError, compile) - self.assertRaises(ValueError, compile, 'print(42)\n', '', 'badmode') - self.assertRaises(ValueError, compile, 'print(42)\n', '', 'single', 0xff) - self.assertRaises(ValueError, compile, chr(0), 'f', 'exec') - self.assertRaises(TypeError, compile, 'pass', '?', 'exec', - mode='eval', source='0', filename='tmp') - compile('print("\xe5")\n', '', 'exec') - self.assertRaises(ValueError, compile, chr(0), 'f', 'exec') - self.assertRaises(ValueError, compile, str('a = 1'), 'f', 'bad') - - # test the optimize argument - - codestr = '''def f(): - """doc""" - debug_enabled = False - if __debug__: - debug_enabled = True - try: - assert False - except AssertionError: - return (True, f.__doc__, debug_enabled, __debug__) - else: - return (False, f.__doc__, debug_enabled, __debug__) - ''' - def f(): """doc""" - values = [(-1, __debug__, f.__doc__, __debug__, __debug__), - (0, True, 'doc', True, True), - (1, False, 'doc', False, False), - (2, False, None, False, False)] - for optval, *expected in values: - # test both direct compilation and compilation via AST - codeobjs = [] - codeobjs.append(compile(codestr, "", "exec", optimize=optval)) - tree = ast.parse(codestr) - codeobjs.append(compile(tree, "", "exec", optimize=optval)) - for code in codeobjs: - ns = {} - exec(code, ns) - rv = ns['f']() - self.assertEqual(rv, tuple(expected)) - - def test_compile_top_level_await_no_coro(self): - """Make sure top level non-await codes get the correct coroutine flags""" - modes = ('single', 'exec') - code_samples = [ - '''def f():pass\n''', - '''[x for x in l]''', - '''{x for x in l}''', - '''(x for x in l)''', - '''{x:x for x in l}''', - ] - for mode, code_sample in product(modes, code_samples): - source = dedent(code_sample) - co = compile(source, - '?', - mode, - flags=ast.PyCF_ALLOW_TOP_LEVEL_AWAIT) - - self.assertNotEqual(co.co_flags & CO_COROUTINE, CO_COROUTINE, - msg=f"source={source} mode={mode}") - - - def test_compile_top_level_await(self): - """Test whether code some top level await can be compiled. - - Make sure it compiles only with the PyCF_ALLOW_TOP_LEVEL_AWAIT flag - set, and make sure the generated code object has the CO_COROUTINE flag - set in order to execute it with `await eval(.....)` instead of exec, - or via a FunctionType. - """ - - # helper function just to check we can run top=level async-for - async def arange(n): - for i in range(n): - yield i - - modes = ('single', 'exec') - code_samples = [ - '''a = await asyncio.sleep(0, result=1)''', - '''async for i in arange(1): - a = 1''', - '''async with asyncio.Lock() as l: - a = 1''', - '''a = [x async for x in arange(2)][1]''', - '''a = 1 in {x async for x in arange(2)}''', - '''a = {x:1 async for x in arange(1)}[0]''', - '''a = [x async for x in arange(2) async for x in arange(2)][1]''', - '''a = [x async for x in (x async for x in arange(5))][1]''', - '''a, = [1 for x in {x async for x in arange(1)}]''', - '''a = [await asyncio.sleep(0, x) async for x in arange(2)][1]''' - ] - policy = maybe_get_event_loop_policy() - try: - for mode, code_sample in product(modes, code_samples): - source = dedent(code_sample) - with self.assertRaises( - SyntaxError, msg=f"source={source} mode={mode}"): - compile(source, '?', mode) - - co = compile(source, - '?', - mode, - flags=ast.PyCF_ALLOW_TOP_LEVEL_AWAIT) - - self.assertEqual(co.co_flags & CO_COROUTINE, CO_COROUTINE, - msg=f"source={source} mode={mode}") - - # test we can create and advance a function type - globals_ = {'asyncio': asyncio, 'a': 0, 'arange': arange} - async_f = FunctionType(co, globals_) - asyncio.run(async_f()) - self.assertEqual(globals_['a'], 1) - - # test we can await-eval, - globals_ = {'asyncio': asyncio, 'a': 0, 'arange': arange} - asyncio.run(eval(co, globals_)) - self.assertEqual(globals_['a'], 1) - finally: - asyncio.set_event_loop_policy(policy) - - def test_compile_top_level_await_invalid_cases(self): - # helper function just to check we can run top=level async-for - async def arange(n): - for i in range(n): - yield i - - modes = ('single', 'exec') - code_samples = [ - '''def f(): await arange(10)\n''', - '''def f(): [x async for x in arange(10)]\n''', - '''def f(): [await x async for x in arange(10)]\n''', - '''def f(): - async for i in arange(1): - a = 1 - ''', - '''def f(): - async with asyncio.Lock() as l: - a = 1 - ''' - ] - policy = maybe_get_event_loop_policy() - try: - for mode, code_sample in product(modes, code_samples): - source = dedent(code_sample) - with self.assertRaises( - SyntaxError, msg=f"source={source} mode={mode}"): - compile(source, '?', mode) - - with self.assertRaises( - SyntaxError, msg=f"source={source} mode={mode}"): - co = compile(source, - '?', - mode, - flags=ast.PyCF_ALLOW_TOP_LEVEL_AWAIT) - finally: - asyncio.set_event_loop_policy(policy) - - - def test_compile_async_generator(self): - """ - With the PyCF_ALLOW_TOP_LEVEL_AWAIT flag added in 3.8, we want to - make sure AsyncGenerators are still properly not marked with the - CO_COROUTINE flag. - """ - code = dedent("""async def ticker(): - for i in range(10): - yield i - await asyncio.sleep(0)""") - - co = compile(code, '?', 'exec', flags=ast.PyCF_ALLOW_TOP_LEVEL_AWAIT) - glob = {} - exec(co, glob) - self.assertEqual(type(glob['ticker']()), AsyncGeneratorType) - - def test_delattr(self): - sys.spam = 1 - delattr(sys, 'spam') - self.assertRaises(TypeError, delattr) - - def test_dir(self): - # dir(wrong number of arguments) - self.assertRaises(TypeError, dir, 42, 42) - - # dir() - local scope - local_var = 1 - self.assertIn('local_var', dir()) - - # dir(module) - self.assertIn('exit', dir(sys)) - - # dir(module_with_invalid__dict__) - class Foo(types.ModuleType): - __dict__ = 8 - f = Foo("foo") - self.assertRaises(TypeError, dir, f) - - # dir(type) - self.assertIn("strip", dir(str)) - self.assertNotIn("__mro__", dir(str)) - - # dir(obj) - class Foo(object): - def __init__(self): - self.x = 7 - self.y = 8 - self.z = 9 - f = Foo() - self.assertIn("y", dir(f)) - - # dir(obj_no__dict__) - class Foo(object): - __slots__ = [] - f = Foo() - self.assertIn("__repr__", dir(f)) - - # dir(obj_no__class__with__dict__) - # (an ugly trick to cause getattr(f, "__class__") to fail) - class Foo(object): - __slots__ = ["__class__", "__dict__"] - def __init__(self): - self.bar = "wow" - f = Foo() - self.assertNotIn("__repr__", dir(f)) - self.assertIn("bar", dir(f)) - - # dir(obj_using __dir__) - class Foo(object): - def __dir__(self): - return ["kan", "ga", "roo"] - f = Foo() - self.assertTrue(dir(f) == ["ga", "kan", "roo"]) - - # dir(obj__dir__tuple) - class Foo(object): - def __dir__(self): - return ("b", "c", "a") - res = dir(Foo()) - self.assertIsInstance(res, list) - self.assertTrue(res == ["a", "b", "c"]) - - # dir(obj__dir__not_sequence) - class Foo(object): - def __dir__(self): - return 7 - f = Foo() - self.assertRaises(TypeError, dir, f) - - # dir(traceback) - try: - raise IndexError - except: - self.assertEqual(len(dir(sys.exc_info()[2])), 4) - - # test that object has a __dir__() - self.assertEqual(sorted([].__dir__()), dir([])) - - def test_divmod(self): - self.assertEqual(divmod(12, 7), (1, 5)) - self.assertEqual(divmod(-12, 7), (-2, 2)) - self.assertEqual(divmod(12, -7), (-2, -2)) - self.assertEqual(divmod(-12, -7), (1, -5)) - - self.assertEqual(divmod(-sys.maxsize-1, -1), (sys.maxsize+1, 0)) - - for num, denom, exp_result in [ (3.25, 1.0, (3.0, 0.25)), - (-3.25, 1.0, (-4.0, 0.75)), - (3.25, -1.0, (-4.0, -0.75)), - (-3.25, -1.0, (3.0, -0.25))]: - result = divmod(num, denom) - self.assertAlmostEqual(result[0], exp_result[0]) - self.assertAlmostEqual(result[1], exp_result[1]) - - self.assertRaises(TypeError, divmod) - - def test_eval(self): - self.assertEqual(eval('1+1'), 2) - self.assertEqual(eval(' 1+1\n'), 2) - globals = {'a': 1, 'b': 2} - locals = {'b': 200, 'c': 300} - self.assertEqual(eval('a', globals) , 1) - self.assertEqual(eval('a', globals, locals), 1) - self.assertEqual(eval('b', globals, locals), 200) - self.assertEqual(eval('c', globals, locals), 300) - globals = {'a': 1, 'b': 2} - locals = {'b': 200, 'c': 300} - bom = b'\xef\xbb\xbf' - self.assertEqual(eval(bom + b'a', globals, locals), 1) - self.assertEqual(eval('"\xe5"', globals), "\xe5") - self.assertRaises(TypeError, eval) - self.assertRaises(TypeError, eval, ()) - self.assertRaises(SyntaxError, eval, bom[:2] + b'a') - - class X: - def __getitem__(self, key): - raise ValueError - self.assertRaises(ValueError, eval, "foo", {}, X()) - - def test_general_eval(self): - # Tests that general mappings can be used for the locals argument - - class M: - "Test mapping interface versus possible calls from eval()." - def __getitem__(self, key): - if key == 'a': - return 12 - raise KeyError - def keys(self): - return list('xyz') - - m = M() - g = globals() - self.assertEqual(eval('a', g, m), 12) - self.assertRaises(NameError, eval, 'b', g, m) - self.assertEqual(eval('dir()', g, m), list('xyz')) - self.assertEqual(eval('globals()', g, m), g) - self.assertEqual(eval('locals()', g, m), m) - self.assertRaises(TypeError, eval, 'a', m) - class A: - "Non-mapping" - pass - m = A() - self.assertRaises(TypeError, eval, 'a', g, m) - - # Verify that dict subclasses work as well - class D(dict): - def __getitem__(self, key): - if key == 'a': - return 12 - return dict.__getitem__(self, key) - def keys(self): - return list('xyz') - - d = D() - self.assertEqual(eval('a', g, d), 12) - self.assertRaises(NameError, eval, 'b', g, d) - self.assertEqual(eval('dir()', g, d), list('xyz')) - self.assertEqual(eval('globals()', g, d), g) - self.assertEqual(eval('locals()', g, d), d) - - # Verify locals stores (used by list comps) - eval('[locals() for i in (2,3)]', g, d) - eval('[locals() for i in (2,3)]', g, collections.UserDict()) - - class SpreadSheet: - "Sample application showing nested, calculated lookups." - _cells = {} - def __setitem__(self, key, formula): - self._cells[key] = formula - def __getitem__(self, key): - return eval(self._cells[key], globals(), self) - - ss = SpreadSheet() - ss['a1'] = '5' - ss['a2'] = 'a1*6' - ss['a3'] = 'a2*7' - self.assertEqual(ss['a3'], 210) - - # Verify that dir() catches a non-list returned by eval - # SF bug #1004669 - class C: - def __getitem__(self, item): - raise KeyError(item) - def keys(self): - return 1 # used to be 'a' but that's no longer an error - self.assertRaises(TypeError, eval, 'dir()', globals(), C()) - - def test_exec(self): - g = {} - exec('z = 1', g) - if '__builtins__' in g: - del g['__builtins__'] - self.assertEqual(g, {'z': 1}) - - exec('z = 1+1', g) - if '__builtins__' in g: - del g['__builtins__'] - self.assertEqual(g, {'z': 2}) - g = {} - l = {} - - with check_warnings(): - warnings.filterwarnings("ignore", "global statement", - module="") - exec('global a; a = 1; b = 2', g, l) - if '__builtins__' in g: - del g['__builtins__'] - if '__builtins__' in l: - del l['__builtins__'] - self.assertEqual((g, l), ({'a': 1}, {'b': 2})) - - def test_exec_globals(self): - code = compile("print('Hello World!')", "", "exec") - # no builtin function - self.assertRaisesRegex(NameError, "name 'print' is not defined", - exec, code, {'__builtins__': {}}) - # __builtins__ must be a mapping type - self.assertRaises(TypeError, - exec, code, {'__builtins__': 123}) - - # no __build_class__ function - code = compile("class A: pass", "", "exec") - self.assertRaisesRegex(NameError, "__build_class__ not found", - exec, code, {'__builtins__': {}}) - - class frozendict_error(Exception): - pass - - class frozendict(dict): - def __setitem__(self, key, value): - raise frozendict_error("frozendict is readonly") - - # read-only builtins - if isinstance(__builtins__, types.ModuleType): - frozen_builtins = frozendict(__builtins__.__dict__) - else: - frozen_builtins = frozendict(__builtins__) - code = compile("__builtins__['superglobal']=2; print(superglobal)", "test", "exec") - self.assertRaises(frozendict_error, - exec, code, {'__builtins__': frozen_builtins}) - - # read-only globals - namespace = frozendict({}) - code = compile("x=1", "test", "exec") - self.assertRaises(frozendict_error, - exec, code, namespace) - - def test_exec_redirected(self): - savestdout = sys.stdout - sys.stdout = None # Whatever that cannot flush() - try: - # Used to raise SystemError('error return without exception set') - exec('a') - except NameError: - pass - finally: - sys.stdout = savestdout - - def test_filter(self): - self.assertEqual(list(filter(lambda c: 'a' <= c <= 'z', 'Hello World')), list('elloorld')) - self.assertEqual(list(filter(None, [1, 'hello', [], [3], '', None, 9, 0])), [1, 'hello', [3], 9]) - self.assertEqual(list(filter(lambda x: x > 0, [1, -3, 9, 0, 2])), [1, 9, 2]) - self.assertEqual(list(filter(None, Squares(10))), [1, 4, 9, 16, 25, 36, 49, 64, 81]) - self.assertEqual(list(filter(lambda x: x%2, Squares(10))), [1, 9, 25, 49, 81]) - def identity(item): - return 1 - filter(identity, Squares(5)) - self.assertRaises(TypeError, filter) - class BadSeq(object): - def __getitem__(self, index): - if index<4: - return 42 - raise ValueError - self.assertRaises(ValueError, list, filter(lambda x: x, BadSeq())) - def badfunc(): - pass - self.assertRaises(TypeError, list, filter(badfunc, range(5))) - - # test bltinmodule.c::filtertuple() - self.assertEqual(list(filter(None, (1, 2))), [1, 2]) - self.assertEqual(list(filter(lambda x: x>=3, (1, 2, 3, 4))), [3, 4]) - self.assertRaises(TypeError, list, filter(42, (1, 2))) - - def test_filter_pickle(self): - for proto in range(pickle.HIGHEST_PROTOCOL + 1): - f1 = filter(filter_char, "abcdeabcde") - f2 = filter(filter_char, "abcdeabcde") - self.check_iter_pickle(f1, list(f2), proto) - - def test_getattr(self): - self.assertTrue(getattr(sys, 'stdout') is sys.stdout) - self.assertRaises(TypeError, getattr, sys, 1) - self.assertRaises(TypeError, getattr, sys, 1, "foo") - self.assertRaises(TypeError, getattr) - self.assertRaises(AttributeError, getattr, sys, chr(sys.maxunicode)) - # unicode surrogates are not encodable to the default encoding (utf8) - self.assertRaises(AttributeError, getattr, 1, "\uDAD1\uD51E") - - def test_hasattr(self): - self.assertTrue(hasattr(sys, 'stdout')) - self.assertRaises(TypeError, hasattr, sys, 1) - self.assertRaises(TypeError, hasattr) - self.assertEqual(False, hasattr(sys, chr(sys.maxunicode))) - - # Check that hasattr propagates all exceptions outside of - # AttributeError. - class A: - def __getattr__(self, what): - raise SystemExit - self.assertRaises(SystemExit, hasattr, A(), "b") - class B: - def __getattr__(self, what): - raise ValueError - self.assertRaises(ValueError, hasattr, B(), "b") - - def test_hash(self): - hash(None) - self.assertEqual(hash(1), hash(1)) - self.assertEqual(hash(1), hash(1.0)) - hash('spam') - self.assertEqual(hash('spam'), hash(b'spam')) - hash((0,1,2,3)) - def f(): pass - self.assertRaises(TypeError, hash, []) - self.assertRaises(TypeError, hash, {}) - # Bug 1536021: Allow hash to return long objects - class X: - def __hash__(self): - return 2**100 - self.assertEqual(type(hash(X())), int) - class Z(int): - def __hash__(self): - return self - self.assertEqual(hash(Z(42)), hash(42)) - - def test_hex(self): - self.assertEqual(hex(16), '0x10') - self.assertEqual(hex(-16), '-0x10') - self.assertRaises(TypeError, hex, {}) - - def test_id(self): - id(None) - id(1) - id(1.0) - id('spam') - id((0,1,2,3)) - id([0,1,2,3]) - id({'spam': 1, 'eggs': 2, 'ham': 3}) - - # Test input() later, alphabetized as if it were raw_input - - def test_iter(self): - self.assertRaises(TypeError, iter) - self.assertRaises(TypeError, iter, 42, 42) - lists = [("1", "2"), ["1", "2"], "12"] - for l in lists: - i = iter(l) - self.assertEqual(next(i), '1') - self.assertEqual(next(i), '2') - self.assertRaises(StopIteration, next, i) - - def test_isinstance(self): - class C: - pass - class D(C): - pass - class E: - pass - c = C() - d = D() - e = E() - self.assertTrue(isinstance(c, C)) - self.assertTrue(isinstance(d, C)) - self.assertTrue(not isinstance(e, C)) - self.assertTrue(not isinstance(c, D)) - self.assertTrue(not isinstance('foo', E)) - self.assertRaises(TypeError, isinstance, E, 'foo') - self.assertRaises(TypeError, isinstance) - - def test_issubclass(self): - class C: - pass - class D(C): - pass - class E: - pass - c = C() - d = D() - e = E() - self.assertTrue(issubclass(D, C)) - self.assertTrue(issubclass(C, C)) - self.assertTrue(not issubclass(C, D)) - self.assertRaises(TypeError, issubclass, 'foo', E) - self.assertRaises(TypeError, issubclass, E, 'foo') - self.assertRaises(TypeError, issubclass) - - def test_len(self): - self.assertEqual(len('123'), 3) - self.assertEqual(len(()), 0) - self.assertEqual(len((1, 2, 3, 4)), 4) - self.assertEqual(len([1, 2, 3, 4]), 4) - self.assertEqual(len({}), 0) - self.assertEqual(len({'a':1, 'b': 2}), 2) - class BadSeq: - def __len__(self): - raise ValueError - self.assertRaises(ValueError, len, BadSeq()) - class InvalidLen: - def __len__(self): - return None - self.assertRaises(TypeError, len, InvalidLen()) - class FloatLen: - def __len__(self): - return 4.5 - self.assertRaises(TypeError, len, FloatLen()) - class NegativeLen: - def __len__(self): - return -10 - self.assertRaises(ValueError, len, NegativeLen()) - class HugeLen: - def __len__(self): - return sys.maxsize + 1 - self.assertRaises(OverflowError, len, HugeLen()) - class HugeNegativeLen: - def __len__(self): - return -sys.maxsize-10 - self.assertRaises(ValueError, len, HugeNegativeLen()) - class NoLenMethod(object): pass - self.assertRaises(TypeError, len, NoLenMethod()) - - def test_map(self): - self.assertEqual( - list(map(lambda x: x*x, range(1,4))), - [1, 4, 9] - ) - try: - from math import sqrt - except ImportError: - def sqrt(x): - return pow(x, 0.5) - self.assertEqual( - list(map(lambda x: list(map(sqrt, x)), [[16, 4], [81, 9]])), - [[4.0, 2.0], [9.0, 3.0]] - ) - self.assertEqual( - list(map(lambda x, y: x+y, [1,3,2], [9,1,4])), - [10, 4, 6] - ) - - def plus(*v): - accu = 0 - for i in v: accu = accu + i - return accu - self.assertEqual( - list(map(plus, [1, 3, 7])), - [1, 3, 7] - ) - self.assertEqual( - list(map(plus, [1, 3, 7], [4, 9, 2])), - [1+4, 3+9, 7+2] - ) - self.assertEqual( - list(map(plus, [1, 3, 7], [4, 9, 2], [1, 1, 0])), - [1+4+1, 3+9+1, 7+2+0] - ) - self.assertEqual( - list(map(int, Squares(10))), - [0, 1, 4, 9, 16, 25, 36, 49, 64, 81] - ) - def Max(a, b): - if a is None: - return b - if b is None: - return a - return max(a, b) - self.assertEqual( - list(map(Max, Squares(3), Squares(2))), - [0, 1] - ) - self.assertRaises(TypeError, map) - self.assertRaises(TypeError, map, lambda x: x, 42) - class BadSeq: - def __iter__(self): - raise ValueError - yield None - self.assertRaises(ValueError, list, map(lambda x: x, BadSeq())) - def badfunc(x): - raise RuntimeError - self.assertRaises(RuntimeError, list, map(badfunc, range(5))) - - def test_map_pickle(self): - for proto in range(pickle.HIGHEST_PROTOCOL + 1): - m1 = map(map_char, "Is this the real life?") - m2 = map(map_char, "Is this the real life?") - self.check_iter_pickle(m1, list(m2), proto) - - def test_max(self): - self.assertEqual(max('123123'), '3') - self.assertEqual(max(1, 2, 3), 3) - self.assertEqual(max((1, 2, 3, 1, 2, 3)), 3) - self.assertEqual(max([1, 2, 3, 1, 2, 3]), 3) - - self.assertEqual(max(1, 2, 3.0), 3.0) - self.assertEqual(max(1, 2.0, 3), 3) - self.assertEqual(max(1.0, 2, 3), 3) - - self.assertRaises(TypeError, max) - self.assertRaises(TypeError, max, 42) - self.assertRaises(ValueError, max, ()) - class BadSeq: - def __getitem__(self, index): - raise ValueError - self.assertRaises(ValueError, max, BadSeq()) - - for stmt in ( - "max(key=int)", # no args - "max(default=None)", - "max(1, 2, default=None)", # require container for default - "max(default=None, key=int)", - "max(1, key=int)", # single arg not iterable - "max(1, 2, keystone=int)", # wrong keyword - "max(1, 2, key=int, abc=int)", # two many keywords - "max(1, 2, key=1)", # keyfunc is not callable - ): - try: - exec(stmt, globals()) - except TypeError: - pass - else: - self.fail(stmt) - - self.assertEqual(max((1,), key=neg), 1) # one elem iterable - self.assertEqual(max((1,2), key=neg), 1) # two elem iterable - self.assertEqual(max(1, 2, key=neg), 1) # two elems - - self.assertEqual(max((), default=None), None) # zero elem iterable - self.assertEqual(max((1,), default=None), 1) # one elem iterable - self.assertEqual(max((1,2), default=None), 2) # two elem iterable - - self.assertEqual(max((), default=1, key=neg), 1) - self.assertEqual(max((1, 2), default=3, key=neg), 1) - - self.assertEqual(max((1, 2), key=None), 2) - - data = [random.randrange(200) for i in range(100)] - keys = dict((elem, random.randrange(50)) for elem in data) - f = keys.__getitem__ - self.assertEqual(max(data, key=f), - sorted(reversed(data), key=f)[-1]) - - def test_min(self): - self.assertEqual(min('123123'), '1') - self.assertEqual(min(1, 2, 3), 1) - self.assertEqual(min((1, 2, 3, 1, 2, 3)), 1) - self.assertEqual(min([1, 2, 3, 1, 2, 3]), 1) - - self.assertEqual(min(1, 2, 3.0), 1) - self.assertEqual(min(1, 2.0, 3), 1) - self.assertEqual(min(1.0, 2, 3), 1.0) - - self.assertRaises(TypeError, min) - self.assertRaises(TypeError, min, 42) - self.assertRaises(ValueError, min, ()) - class BadSeq: - def __getitem__(self, index): - raise ValueError - self.assertRaises(ValueError, min, BadSeq()) - - for stmt in ( - "min(key=int)", # no args - "min(default=None)", - "min(1, 2, default=None)", # require container for default - "min(default=None, key=int)", - "min(1, key=int)", # single arg not iterable - "min(1, 2, keystone=int)", # wrong keyword - "min(1, 2, key=int, abc=int)", # two many keywords - "min(1, 2, key=1)", # keyfunc is not callable - ): - try: - exec(stmt, globals()) - except TypeError: - pass - else: - self.fail(stmt) - - self.assertEqual(min((1,), key=neg), 1) # one elem iterable - self.assertEqual(min((1,2), key=neg), 2) # two elem iterable - self.assertEqual(min(1, 2, key=neg), 2) # two elems - - self.assertEqual(min((), default=None), None) # zero elem iterable - self.assertEqual(min((1,), default=None), 1) # one elem iterable - self.assertEqual(min((1,2), default=None), 1) # two elem iterable - - self.assertEqual(min((), default=1, key=neg), 1) - self.assertEqual(min((1, 2), default=1, key=neg), 2) - - self.assertEqual(min((1, 2), key=None), 1) - - data = [random.randrange(200) for i in range(100)] - keys = dict((elem, random.randrange(50)) for elem in data) - f = keys.__getitem__ - self.assertEqual(min(data, key=f), - sorted(data, key=f)[0]) - - def test_next(self): - it = iter(range(2)) - self.assertEqual(next(it), 0) - self.assertEqual(next(it), 1) - self.assertRaises(StopIteration, next, it) - self.assertRaises(StopIteration, next, it) - self.assertEqual(next(it, 42), 42) - - class Iter(object): - def __iter__(self): - return self - def __next__(self): - raise StopIteration - - it = iter(Iter()) - self.assertEqual(next(it, 42), 42) - self.assertRaises(StopIteration, next, it) - - def gen(): - yield 1 - return - - it = gen() - self.assertEqual(next(it), 1) - self.assertRaises(StopIteration, next, it) - self.assertEqual(next(it, 42), 42) - - def test_oct(self): - self.assertEqual(oct(100), '0o144') - self.assertEqual(oct(-100), '-0o144') - self.assertRaises(TypeError, oct, ()) - - def write_testfile(self): - # NB the first 4 lines are also used to test input, below - fp = open(TESTFN, 'w') - self.addCleanup(unlink, TESTFN) - with fp: - fp.write('1+1\n') - fp.write('The quick brown fox jumps over the lazy dog') - fp.write('.\n') - fp.write('Dear John\n') - fp.write('XXX'*100) - fp.write('YYY'*100) - - def test_open(self): - self.write_testfile() - fp = open(TESTFN, 'r') - with fp: - self.assertEqual(fp.readline(4), '1+1\n') - self.assertEqual(fp.readline(), 'The quick brown fox jumps over the lazy dog.\n') - self.assertEqual(fp.readline(4), 'Dear') - self.assertEqual(fp.readline(100), ' John\n') - self.assertEqual(fp.read(300), 'XXX'*100) - self.assertEqual(fp.read(1000), 'YYY'*100) - - # embedded null bytes and characters - self.assertRaises(ValueError, open, 'a\x00b') - self.assertRaises(ValueError, open, b'a\x00b') - - @unittest.skipIf(sys.flags.utf8_mode, "utf-8 mode is enabled") - def test_open_default_encoding(self): - old_environ = dict(os.environ) - try: - # try to get a user preferred encoding different than the current - # locale encoding to check that open() uses the current locale - # encoding and not the user preferred encoding - for key in ('LC_ALL', 'LANG', 'LC_CTYPE'): - if key in os.environ: - del os.environ[key] - - self.write_testfile() - current_locale_encoding = locale.getpreferredencoding(False) - fp = open(TESTFN, 'w') - with fp: - self.assertEqual(fp.encoding, current_locale_encoding) - finally: - os.environ.clear() - os.environ.update(old_environ) - - def test_open_non_inheritable(self): - fileobj = open(__file__) - with fileobj: - self.assertFalse(os.get_inheritable(fileobj.fileno())) - - def test_ord(self): - self.assertEqual(ord(' '), 32) - self.assertEqual(ord('A'), 65) - self.assertEqual(ord('a'), 97) - self.assertEqual(ord('\x80'), 128) - self.assertEqual(ord('\xff'), 255) - - self.assertEqual(ord(b' '), 32) - self.assertEqual(ord(b'A'), 65) - self.assertEqual(ord(b'a'), 97) - self.assertEqual(ord(b'\x80'), 128) - self.assertEqual(ord(b'\xff'), 255) - - self.assertEqual(ord(chr(sys.maxunicode)), sys.maxunicode) - self.assertRaises(TypeError, ord, 42) - - self.assertEqual(ord(chr(0x10FFFF)), 0x10FFFF) - self.assertEqual(ord("\U0000FFFF"), 0x0000FFFF) - self.assertEqual(ord("\U00010000"), 0x00010000) - self.assertEqual(ord("\U00010001"), 0x00010001) - self.assertEqual(ord("\U000FFFFE"), 0x000FFFFE) - self.assertEqual(ord("\U000FFFFF"), 0x000FFFFF) - self.assertEqual(ord("\U00100000"), 0x00100000) - self.assertEqual(ord("\U00100001"), 0x00100001) - self.assertEqual(ord("\U0010FFFE"), 0x0010FFFE) - self.assertEqual(ord("\U0010FFFF"), 0x0010FFFF) - - def test_pow(self): - self.assertEqual(pow(0,0), 1) - self.assertEqual(pow(0,1), 0) - self.assertEqual(pow(1,0), 1) - self.assertEqual(pow(1,1), 1) - - self.assertEqual(pow(2,0), 1) - self.assertEqual(pow(2,10), 1024) - self.assertEqual(pow(2,20), 1024*1024) - self.assertEqual(pow(2,30), 1024*1024*1024) - - self.assertEqual(pow(-2,0), 1) - self.assertEqual(pow(-2,1), -2) - self.assertEqual(pow(-2,2), 4) - self.assertEqual(pow(-2,3), -8) - - self.assertAlmostEqual(pow(0.,0), 1.) - self.assertAlmostEqual(pow(0.,1), 0.) - self.assertAlmostEqual(pow(1.,0), 1.) - self.assertAlmostEqual(pow(1.,1), 1.) - - self.assertAlmostEqual(pow(2.,0), 1.) - self.assertAlmostEqual(pow(2.,10), 1024.) - self.assertAlmostEqual(pow(2.,20), 1024.*1024.) - self.assertAlmostEqual(pow(2.,30), 1024.*1024.*1024.) - - self.assertAlmostEqual(pow(-2.,0), 1.) - self.assertAlmostEqual(pow(-2.,1), -2.) - self.assertAlmostEqual(pow(-2.,2), 4.) - self.assertAlmostEqual(pow(-2.,3), -8.) - - for x in 2, 2.0: - for y in 10, 10.0: - for z in 1000, 1000.0: - if isinstance(x, float) or \ - isinstance(y, float) or \ - isinstance(z, float): - self.assertRaises(TypeError, pow, x, y, z) - else: - self.assertAlmostEqual(pow(x, y, z), 24.0) - - self.assertAlmostEqual(pow(-1, 0.5), 1j) - self.assertAlmostEqual(pow(-1, 1/3), 0.5 + 0.8660254037844386j) - - # See test_pow for additional tests for three-argument pow. - self.assertEqual(pow(-1, -2, 3), 1) - self.assertRaises(ValueError, pow, 1, 2, 0) - - self.assertRaises(TypeError, pow) - - # Test passing in arguments as keywords. - self.assertEqual(pow(0, exp=0), 1) - self.assertEqual(pow(base=2, exp=4), 16) - self.assertEqual(pow(base=5, exp=2, mod=14), 11) - twopow = partial(pow, base=2) - self.assertEqual(twopow(exp=5), 32) - fifth_power = partial(pow, exp=5) - self.assertEqual(fifth_power(2), 32) - mod10 = partial(pow, mod=10) - self.assertEqual(mod10(2, 6), 4) - self.assertEqual(mod10(exp=6, base=2), 4) - - def test_input(self): - self.write_testfile() - fp = open(TESTFN, 'r') - savestdin = sys.stdin - savestdout = sys.stdout # Eats the echo - try: - sys.stdin = fp - sys.stdout = BitBucket() - self.assertEqual(input(), "1+1") - self.assertEqual(input(), 'The quick brown fox jumps over the lazy dog.') - self.assertEqual(input('testing\n'), 'Dear John') - - # SF 1535165: don't segfault on closed stdin - # sys.stdout must be a regular file for triggering - sys.stdout = savestdout - sys.stdin.close() - self.assertRaises(ValueError, input) - - sys.stdout = BitBucket() - sys.stdin = io.StringIO("NULL\0") - self.assertRaises(TypeError, input, 42, 42) - sys.stdin = io.StringIO(" 'whitespace'") - self.assertEqual(input(), " 'whitespace'") - sys.stdin = io.StringIO() - self.assertRaises(EOFError, input) - - del sys.stdout - self.assertRaises(RuntimeError, input, 'prompt') - del sys.stdin - self.assertRaises(RuntimeError, input, 'prompt') - finally: - sys.stdin = savestdin - sys.stdout = savestdout - fp.close() - - # test_int(): see test_int.py for tests of built-in function int(). - - def test_repr(self): - self.assertEqual(repr(''), '\'\'') - self.assertEqual(repr(0), '0') - self.assertEqual(repr(()), '()') - self.assertEqual(repr([]), '[]') - self.assertEqual(repr({}), '{}') - a = [] - a.append(a) - self.assertEqual(repr(a), '[[...]]') - a = {} - a[0] = a - self.assertEqual(repr(a), '{0: {...}}') - - def test_round(self): - self.assertEqual(round(0.0), 0.0) - self.assertEqual(type(round(0.0)), int) - self.assertEqual(round(1.0), 1.0) - self.assertEqual(round(10.0), 10.0) - self.assertEqual(round(1000000000.0), 1000000000.0) - self.assertEqual(round(1e20), 1e20) - - self.assertEqual(round(-1.0), -1.0) - self.assertEqual(round(-10.0), -10.0) - self.assertEqual(round(-1000000000.0), -1000000000.0) - self.assertEqual(round(-1e20), -1e20) - - self.assertEqual(round(0.1), 0.0) - self.assertEqual(round(1.1), 1.0) - self.assertEqual(round(10.1), 10.0) - self.assertEqual(round(1000000000.1), 1000000000.0) - - self.assertEqual(round(-1.1), -1.0) - self.assertEqual(round(-10.1), -10.0) - self.assertEqual(round(-1000000000.1), -1000000000.0) - - self.assertEqual(round(0.9), 1.0) - self.assertEqual(round(9.9), 10.0) - self.assertEqual(round(999999999.9), 1000000000.0) - - self.assertEqual(round(-0.9), -1.0) - self.assertEqual(round(-9.9), -10.0) - self.assertEqual(round(-999999999.9), -1000000000.0) - - self.assertEqual(round(-8.0, -1), -10.0) - self.assertEqual(type(round(-8.0, -1)), float) - - self.assertEqual(type(round(-8.0, 0)), float) - self.assertEqual(type(round(-8.0, 1)), float) - - # Check even / odd rounding behaviour - self.assertEqual(round(5.5), 6) - self.assertEqual(round(6.5), 6) - self.assertEqual(round(-5.5), -6) - self.assertEqual(round(-6.5), -6) - - # Check behavior on ints - self.assertEqual(round(0), 0) - self.assertEqual(round(8), 8) - self.assertEqual(round(-8), -8) - self.assertEqual(type(round(0)), int) - self.assertEqual(type(round(-8, -1)), int) - self.assertEqual(type(round(-8, 0)), int) - self.assertEqual(type(round(-8, 1)), int) - - # test new kwargs - self.assertEqual(round(number=-8.0, ndigits=-1), -10.0) - - self.assertRaises(TypeError, round) - - # test generic rounding delegation for reals - class TestRound: - def __round__(self): - return 23 - - class TestNoRound: - pass - - self.assertEqual(round(TestRound()), 23) - - self.assertRaises(TypeError, round, 1, 2, 3) - self.assertRaises(TypeError, round, TestNoRound()) - - t = TestNoRound() - t.__round__ = lambda *args: args - self.assertRaises(TypeError, round, t) - self.assertRaises(TypeError, round, t, 0) - - # Some versions of glibc for alpha have a bug that affects - # float -> integer rounding (floor, ceil, rint, round) for - # values in the range [2**52, 2**53). See: - # - # http://sources.redhat.com/bugzilla/show_bug.cgi?id=5350 - # - # We skip this test on Linux/alpha if it would fail. - linux_alpha = (platform.system().startswith('Linux') and - platform.machine().startswith('alpha')) - system_round_bug = round(5e15+1) != 5e15+1 - @unittest.skipIf(linux_alpha and system_round_bug, - "test will fail; failure is probably due to a " - "buggy system round function") - def test_round_large(self): - # Issue #1869: integral floats should remain unchanged - self.assertEqual(round(5e15-1), 5e15-1) - self.assertEqual(round(5e15), 5e15) - self.assertEqual(round(5e15+1), 5e15+1) - self.assertEqual(round(5e15+2), 5e15+2) - self.assertEqual(round(5e15+3), 5e15+3) - - def test_bug_27936(self): - # Verify that ndigits=None means the same as passing in no argument - for x in [1234, - 1234.56, - decimal.Decimal('1234.56'), - fractions.Fraction(123456, 100)]: - self.assertEqual(round(x, None), round(x)) - self.assertEqual(type(round(x, None)), type(round(x))) - - def test_setattr(self): - setattr(sys, 'spam', 1) - self.assertEqual(sys.spam, 1) - self.assertRaises(TypeError, setattr, sys, 1, 'spam') - self.assertRaises(TypeError, setattr) - - # test_str(): see test_unicode.py and test_bytes.py for str() tests. - - def test_sum(self): - self.assertEqual(sum([]), 0) - self.assertEqual(sum(list(range(2,8))), 27) - self.assertEqual(sum(iter(list(range(2,8)))), 27) - self.assertEqual(sum(Squares(10)), 285) - self.assertEqual(sum(iter(Squares(10))), 285) - self.assertEqual(sum([[1], [2], [3]], []), [1, 2, 3]) - - self.assertEqual(sum(range(10), 1000), 1045) - self.assertEqual(sum(range(10), start=1000), 1045) - - self.assertRaises(TypeError, sum) - self.assertRaises(TypeError, sum, 42) - self.assertRaises(TypeError, sum, ['a', 'b', 'c']) - self.assertRaises(TypeError, sum, ['a', 'b', 'c'], '') - self.assertRaises(TypeError, sum, [b'a', b'c'], b'') - values = [bytearray(b'a'), bytearray(b'b')] - self.assertRaises(TypeError, sum, values, bytearray(b'')) - self.assertRaises(TypeError, sum, [[1], [2], [3]]) - self.assertRaises(TypeError, sum, [{2:3}]) - self.assertRaises(TypeError, sum, [{2:3}]*2, {2:3}) - - class BadSeq: - def __getitem__(self, index): - raise ValueError - self.assertRaises(ValueError, sum, BadSeq()) - - empty = [] - sum(([x] for x in range(10)), empty) - self.assertEqual(empty, []) - - def test_type(self): - self.assertEqual(type(''), type('123')) - self.assertNotEqual(type(''), type(())) - - # We don't want self in vars(), so these are static methods - - @staticmethod - def get_vars_f0(): - return vars() - - @staticmethod - def get_vars_f2(): - BuiltinTest.get_vars_f0() - a = 1 - b = 2 - return vars() - - class C_get_vars(object): - def getDict(self): - return {'a':2} - __dict__ = property(fget=getDict) - - def test_vars(self): - self.assertEqual(set(vars()), set(dir())) - self.assertEqual(set(vars(sys)), set(dir(sys))) - self.assertEqual(self.get_vars_f0(), {}) - self.assertEqual(self.get_vars_f2(), {'a': 1, 'b': 2}) - self.assertRaises(TypeError, vars, 42, 42) - self.assertRaises(TypeError, vars, 42) - self.assertEqual(vars(self.C_get_vars()), {'a':2}) - - def test_zip(self): - a = (1, 2, 3) - b = (4, 5, 6) - t = [(1, 4), (2, 5), (3, 6)] - self.assertEqual(list(zip(a, b)), t) - b = [4, 5, 6] - self.assertEqual(list(zip(a, b)), t) - b = (4, 5, 6, 7) - self.assertEqual(list(zip(a, b)), t) - class I: - def __getitem__(self, i): - if i < 0 or i > 2: raise IndexError - return i + 4 - self.assertEqual(list(zip(a, I())), t) - self.assertEqual(list(zip()), []) - self.assertEqual(list(zip(*[])), []) - self.assertRaises(TypeError, zip, None) - class G: - pass - self.assertRaises(TypeError, zip, a, G()) - self.assertRaises(RuntimeError, zip, a, TestFailingIter()) - - # Make sure zip doesn't try to allocate a billion elements for the - # result list when one of its arguments doesn't say how long it is. - # A MemoryError is the most likely failure mode. - class SequenceWithoutALength: - def __getitem__(self, i): - if i == 5: - raise IndexError - else: - return i - self.assertEqual( - list(zip(SequenceWithoutALength(), range(2**30))), - list(enumerate(range(5))) - ) - - class BadSeq: - def __getitem__(self, i): - if i == 5: - raise ValueError - else: - return i - self.assertRaises(ValueError, list, zip(BadSeq(), BadSeq())) - - def test_zip_pickle(self): - a = (1, 2, 3) - b = (4, 5, 6) - t = [(1, 4), (2, 5), (3, 6)] - for proto in range(pickle.HIGHEST_PROTOCOL + 1): - z1 = zip(a, b) - self.check_iter_pickle(z1, t, proto) - - def test_zip_bad_iterable(self): - exception = TypeError() - - class BadIterable: - def __iter__(self): - raise exception - - with self.assertRaises(TypeError) as cm: - zip(BadIterable()) - - self.assertIs(cm.exception, exception) - - @cpython_only - def test_zip_result_gc(self): - # bpo-42536: zip's tuple-reuse speed trick breaks the GC's assumptions - # about what can be untracked. Make sure we re-track result tuples - # whenever we reuse them. - it = zip([[]]) - gc.collect() - # That GC collection probably untracked the recycled internal result - # tuple, which is initialized to (None,). Make sure it's re-tracked when - # it's mutated and returned from __next__: - self.assertTrue(gc.is_tracked(next(it))) - - def test_format(self): - # Test the basic machinery of the format() builtin. Don't test - # the specifics of the various formatters - self.assertEqual(format(3, ''), '3') - - # Returns some classes to use for various tests. There's - # an old-style version, and a new-style version - def classes_new(): - class A(object): - def __init__(self, x): - self.x = x - def __format__(self, format_spec): - return str(self.x) + format_spec - class DerivedFromA(A): - pass - - class Simple(object): pass - class DerivedFromSimple(Simple): - def __init__(self, x): - self.x = x - def __format__(self, format_spec): - return str(self.x) + format_spec - class DerivedFromSimple2(DerivedFromSimple): pass - return A, DerivedFromA, DerivedFromSimple, DerivedFromSimple2 - - def class_test(A, DerivedFromA, DerivedFromSimple, DerivedFromSimple2): - self.assertEqual(format(A(3), 'spec'), '3spec') - self.assertEqual(format(DerivedFromA(4), 'spec'), '4spec') - self.assertEqual(format(DerivedFromSimple(5), 'abc'), '5abc') - self.assertEqual(format(DerivedFromSimple2(10), 'abcdef'), - '10abcdef') - - class_test(*classes_new()) - - def empty_format_spec(value): - # test that: - # format(x, '') == str(x) - # format(x) == str(x) - self.assertEqual(format(value, ""), str(value)) - self.assertEqual(format(value), str(value)) - - # for builtin types, format(x, "") == str(x) - empty_format_spec(17**13) - empty_format_spec(1.0) - empty_format_spec(3.1415e104) - empty_format_spec(-3.1415e104) - empty_format_spec(3.1415e-104) - empty_format_spec(-3.1415e-104) - empty_format_spec(object) - empty_format_spec(None) - - # TypeError because self.__format__ returns the wrong type - class BadFormatResult: - def __format__(self, format_spec): - return 1.0 - self.assertRaises(TypeError, format, BadFormatResult(), "") - - # TypeError because format_spec is not unicode or str - self.assertRaises(TypeError, format, object(), 4) - self.assertRaises(TypeError, format, object(), object()) - - # tests for object.__format__ really belong elsewhere, but - # there's no good place to put them - x = object().__format__('') - self.assertTrue(x.startswith(' the child exited - break - lines.append(line) - # Check the result was got and corresponds to the user's terminal input - if len(lines) != 2: - # Something went wrong, try to get at stderr - # Beware of Linux raising EIO when the slave is closed - child_output = bytearray() - while True: - try: - chunk = os.read(fd, 3000) - except OSError: # Assume EIO - break - if not chunk: - break - child_output.extend(chunk) - os.close(fd) - child_output = child_output.decode("ascii", "ignore") - self.fail("got %d lines in pipe but expected 2, child output was:\n%s" - % (len(lines), child_output)) - - # bpo-40155: Close the PTY before waiting for the child process - # completion, otherwise the child process hangs on AIX. - os.close(fd) - - # Wait until the child process completes - os.waitpid(pid, 0) - - return lines - - def check_input_tty(self, prompt, terminal_input, stdio_encoding=None): - if not sys.stdin.isatty() or not sys.stdout.isatty(): - self.skipTest("stdin and stdout must be ttys") - def child(wpipe): - # Check the error handlers are accounted for - if stdio_encoding: - sys.stdin = io.TextIOWrapper(sys.stdin.detach(), - encoding=stdio_encoding, - errors='surrogateescape') - sys.stdout = io.TextIOWrapper(sys.stdout.detach(), - encoding=stdio_encoding, - errors='replace') - print("tty =", sys.stdin.isatty() and sys.stdout.isatty(), file=wpipe) - print(ascii(input(prompt)), file=wpipe) - lines = self.run_child(child, terminal_input + b"\r\n") - # Check we did exercise the GNU readline path - self.assertIn(lines[0], {'tty = True', 'tty = False'}) - if lines[0] != 'tty = True': - self.skipTest("standard IO in should have been a tty") - input_result = eval(lines[1]) # ascii() -> eval() roundtrip - if stdio_encoding: - expected = terminal_input.decode(stdio_encoding, 'surrogateescape') - else: - expected = terminal_input.decode(sys.stdin.encoding) # what else? - self.assertEqual(input_result, expected) - - def test_input_tty(self): - # Test input() functionality when wired to a tty (the code path - # is different and invokes GNU readline if available). - self.check_input_tty("prompt", b"quux") - - def test_input_tty_non_ascii(self): - # Check stdin/stdout encoding is used when invoking GNU readline - self.check_input_tty("prompté", b"quux\xe9", "utf-8") - - def test_input_tty_non_ascii_unicode_errors(self): - # Check stdin/stdout error handler is used when invoking GNU readline - self.check_input_tty("prompté", b"quux\xe9", "ascii") - - def test_input_no_stdout_fileno(self): - # Issue #24402: If stdin is the original terminal but stdout.fileno() - # fails, do not use the original stdout file descriptor - def child(wpipe): - print("stdin.isatty():", sys.stdin.isatty(), file=wpipe) - sys.stdout = io.StringIO() # Does not support fileno() - input("prompt") - print("captured:", ascii(sys.stdout.getvalue()), file=wpipe) - lines = self.run_child(child, b"quux\r") - expected = ( - "stdin.isatty(): True", - "captured: 'prompt'", - ) - self.assertSequenceEqual(lines, expected) - - class TestSorted(unittest.TestCase): - - def test_basic(self): - data = list(range(100)) - copy = data[:] - random.shuffle(copy) - self.assertEqual(data, sorted(copy)) - self.assertNotEqual(data, copy) - - data.reverse() - random.shuffle(copy) - self.assertEqual(data, sorted(copy, key=lambda x: -x)) - self.assertNotEqual(data, copy) - random.shuffle(copy) - self.assertEqual(data, sorted(copy, reverse=1)) - self.assertNotEqual(data, copy) - - def test_bad_arguments(self): - # Issue #29327: The first argument is positional-only. - sorted([]) - with self.assertRaises(TypeError): - sorted(iterable=[]) - # Other arguments are keyword-only - sorted([], key=None) - with self.assertRaises(TypeError): - sorted([], None) - - def test_inputtypes(self): - s = 'abracadabra' - types = [list, tuple, str] - for T in types: - self.assertEqual(sorted(s), sorted(T(s))) - - s = ''.join(set(s)) # unique letters only - types = [str, set, frozenset, list, tuple, dict.fromkeys] - for T in types: - self.assertEqual(sorted(s), sorted(T(s))) - - def test_baddecorator(self): - data = 'The quick Brown fox Jumped over The lazy Dog'.split() - self.assertRaises(TypeError, sorted, data, None, lambda x,y: 0) - - - class ShutdownTest(unittest.TestCase): - - def test_cleanup(self): - # Issue #19255: builtins are still available at shutdown - code = """if 1: - import builtins - import sys - - class C: - def __del__(self): - print("before") - # Check that builtins still exist - len(()) - print("after") - - c = C() - # Make this module survive until builtins and sys are cleaned - builtins.here = sys.modules[__name__] - sys.here = sys.modules[__name__] - # Create a reference loop so that this module needs to go - # through a GC phase. - here = sys.modules[__name__] - """ - # Issue #20599: Force ASCII encoding to get a codec implemented in C, - # otherwise the codec may be unloaded before C.__del__() is called, and - # so print("before") fails because the codec cannot be used to encode - # "before" to sys.stdout.encoding. For example, on Windows, - # sys.stdout.encoding is the OEM code page and these code pages are - # implemented in Python - rc, out, err = assert_python_ok("-c", code, - PYTHONIOENCODING="ascii") - self.assertEqual(["before", "after"], out.decode().splitlines()) - - - class TestType(unittest.TestCase): - def test_new_type(self): - A = type('A', (), {}) - self.assertEqual(A.__name__, 'A') - self.assertEqual(A.__qualname__, 'A') - self.assertEqual(A.__module__, __name__) - self.assertEqual(A.__bases__, (object,)) - self.assertIs(A.__base__, object) - x = A() - self.assertIs(type(x), A) - self.assertIs(x.__class__, A) - - class B: - def ham(self): - return 'ham%d' % self - C = type('C', (B, int), {'spam': lambda self: 'spam%s' % self}) - self.assertEqual(C.__name__, 'C') - self.assertEqual(C.__qualname__, 'C') - self.assertEqual(C.__module__, __name__) - self.assertEqual(C.__bases__, (B, int)) - self.assertIs(C.__base__, int) - self.assertIn('spam', C.__dict__) - self.assertNotIn('ham', C.__dict__) - x = C(42) - self.assertEqual(x, 42) - self.assertIs(type(x), C) - self.assertIs(x.__class__, C) - self.assertEqual(x.ham(), 'ham42') - self.assertEqual(x.spam(), 'spam42') - self.assertEqual(x.to_bytes(2, 'little'), b'\x2a\x00') - - def test_type_nokwargs(self): - with self.assertRaises(TypeError): - type('a', (), {}, x=5) - with self.assertRaises(TypeError): - type('a', (), dict={}) - - def test_type_name(self): - for name in 'A', '\xc4', '\U0001f40d', 'B.A', '42', '': - with self.subTest(name=name): - A = type(name, (), {}) - self.assertEqual(A.__name__, name) - self.assertEqual(A.__qualname__, name) - self.assertEqual(A.__module__, __name__) - with self.assertRaises(ValueError): - type('A\x00B', (), {}) - with self.assertRaises(ValueError): - type('A\udcdcB', (), {}) - with self.assertRaises(TypeError): - type(b'A', (), {}) - - C = type('C', (), {}) - for name in 'A', '\xc4', '\U0001f40d', 'B.A', '42', '': - with self.subTest(name=name): - C.__name__ = name - self.assertEqual(C.__name__, name) - self.assertEqual(C.__qualname__, 'C') - self.assertEqual(C.__module__, __name__) - - A = type('C', (), {}) - with self.assertRaises(ValueError): - A.__name__ = 'A\x00B' - self.assertEqual(A.__name__, 'C') - with self.assertRaises(ValueError): - A.__name__ = 'A\udcdcB' - self.assertEqual(A.__name__, 'C') - with self.assertRaises(TypeError): - A.__name__ = b'A' - self.assertEqual(A.__name__, 'C') - - def test_type_qualname(self): - A = type('A', (), {'__qualname__': 'B.C'}) - self.assertEqual(A.__name__, 'A') - self.assertEqual(A.__qualname__, 'B.C') - self.assertEqual(A.__module__, __name__) - with self.assertRaises(TypeError): - type('A', (), {'__qualname__': b'B'}) - self.assertEqual(A.__qualname__, 'B.C') - - A.__qualname__ = 'D.E' - self.assertEqual(A.__name__, 'A') - self.assertEqual(A.__qualname__, 'D.E') - with self.assertRaises(TypeError): - A.__qualname__ = b'B' - self.assertEqual(A.__qualname__, 'D.E') - - def test_type_doc(self): - for doc in 'x', '\xc4', '\U0001f40d', 'x\x00y', b'x', 42, None: - A = type('A', (), {'__doc__': doc}) - self.assertEqual(A.__doc__, doc) - with self.assertRaises(UnicodeEncodeError): - type('A', (), {'__doc__': 'x\udcdcy'}) - - A = type('A', (), {}) - self.assertEqual(A.__doc__, None) - for doc in 'x', '\xc4', '\U0001f40d', 'x\x00y', 'x\udcdcy', b'x', 42, None: - A.__doc__ = doc - self.assertEqual(A.__doc__, doc) - - def test_bad_args(self): - with self.assertRaises(TypeError): - type() - with self.assertRaises(TypeError): - type('A', ()) - with self.assertRaises(TypeError): - type('A', (), {}, ()) - with self.assertRaises(TypeError): - type('A', (), dict={}) - with self.assertRaises(TypeError): - type('A', [], {}) - with self.assertRaises(TypeError): - type('A', (), types.MappingProxyType({})) - with self.assertRaises(TypeError): - type('A', (None,), {}) - with self.assertRaises(TypeError): - type('A', (bool,), {}) - with self.assertRaises(TypeError): - type('A', (int, str), {}) - - def test_bad_slots(self): - with self.assertRaises(TypeError): - type('A', (), {'__slots__': b'x'}) - with self.assertRaises(TypeError): - type('A', (int,), {'__slots__': 'x'}) - with self.assertRaises(TypeError): - type('A', (), {'__slots__': ''}) - with self.assertRaises(TypeError): - type('A', (), {'__slots__': '42'}) - with self.assertRaises(TypeError): - type('A', (), {'__slots__': 'x\x00y'}) - with self.assertRaises(ValueError): - type('A', (), {'__slots__': 'x', 'x': 0}) - with self.assertRaises(TypeError): - type('A', (), {'__slots__': ('__dict__', '__dict__')}) - with self.assertRaises(TypeError): - type('A', (), {'__slots__': ('__weakref__', '__weakref__')}) - - class B: - pass - with self.assertRaises(TypeError): - type('A', (B,), {'__slots__': '__dict__'}) - with self.assertRaises(TypeError): - type('A', (B,), {'__slots__': '__weakref__'}) - - def test_namespace_order(self): - # bpo-34320: namespace should preserve order - od = collections.OrderedDict([('a', 1), ('b', 2)]) - od.move_to_end('a') - expected = list(od.items()) - - C = type('C', (), od) - self.assertEqual(list(C.__dict__.items())[:2], [('b', 2), ('a', 1)]) - - - def load_tests(loader, tests, pattern): - from doctest import DocTestSuite - tests.addTest(DocTestSuite(builtins)) - return tests - - if __name__ == "__main__": - unittest.main() diff --git a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_bytes.yaml b/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_bytes.yaml deleted file mode 100644 index b9ae98666..000000000 --- a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_bytes.yaml +++ /dev/null @@ -1,1918 +0,0 @@ -python: | - """Unit tests for the bytes and bytearray types. - - XXX This is a mess. Common tests should be unified with string_tests.py (and - the latter should be modernized). - """ - - import array - import os - import re - import sys - import copy - import functools - import pickle - import tempfile - import unittest - - import test.support - import test.string_tests - import test.list_tests - from test.support import bigaddrspacetest, MAX_Py_ssize_t - - - if sys.flags.bytes_warning: - def check_bytes_warnings(func): - @functools.wraps(func) - def wrapper(*args, **kw): - with test.support.check_warnings(('', BytesWarning)): - return func(*args, **kw) - return wrapper - else: - # no-op - def check_bytes_warnings(func): - return func - - - class Indexable: - def __init__(self, value=0): - self.value = value - def __index__(self): - return self.value - - - class BaseBytesTest: - - def test_basics(self): - b = self.type2test() - self.assertEqual(type(b), self.type2test) - self.assertEqual(b.__class__, self.type2test) - - def test_copy(self): - a = self.type2test(b"abcd") - for copy_method in (copy.copy, copy.deepcopy): - b = copy_method(a) - self.assertEqual(a, b) - self.assertEqual(type(a), type(b)) - - def test_empty_sequence(self): - b = self.type2test() - self.assertEqual(len(b), 0) - self.assertRaises(IndexError, lambda: b[0]) - self.assertRaises(IndexError, lambda: b[1]) - self.assertRaises(IndexError, lambda: b[sys.maxsize]) - self.assertRaises(IndexError, lambda: b[sys.maxsize+1]) - self.assertRaises(IndexError, lambda: b[10**100]) - self.assertRaises(IndexError, lambda: b[-1]) - self.assertRaises(IndexError, lambda: b[-2]) - self.assertRaises(IndexError, lambda: b[-sys.maxsize]) - self.assertRaises(IndexError, lambda: b[-sys.maxsize-1]) - self.assertRaises(IndexError, lambda: b[-sys.maxsize-2]) - self.assertRaises(IndexError, lambda: b[-10**100]) - - def test_from_iterable(self): - b = self.type2test(range(256)) - self.assertEqual(len(b), 256) - self.assertEqual(list(b), list(range(256))) - - # Non-sequence iterable. - b = self.type2test({42}) - self.assertEqual(b, b"*") - b = self.type2test({43, 45}) - self.assertIn(tuple(b), {(43, 45), (45, 43)}) - - # Iterator that has a __length_hint__. - b = self.type2test(iter(range(256))) - self.assertEqual(len(b), 256) - self.assertEqual(list(b), list(range(256))) - - # Iterator that doesn't have a __length_hint__. - b = self.type2test(i for i in range(256) if i % 2) - self.assertEqual(len(b), 128) - self.assertEqual(list(b), list(range(256))[1::2]) - - # Sequence without __iter__. - class S: - def __getitem__(self, i): - return (1, 2, 3)[i] - b = self.type2test(S()) - self.assertEqual(b, b"\x01\x02\x03") - - def test_from_tuple(self): - # There is a special case for tuples. - b = self.type2test(tuple(range(256))) - self.assertEqual(len(b), 256) - self.assertEqual(list(b), list(range(256))) - b = self.type2test((1, 2, 3)) - self.assertEqual(b, b"\x01\x02\x03") - - def test_from_list(self): - # There is a special case for lists. - b = self.type2test(list(range(256))) - self.assertEqual(len(b), 256) - self.assertEqual(list(b), list(range(256))) - b = self.type2test([1, 2, 3]) - self.assertEqual(b, b"\x01\x02\x03") - - def test_from_mutating_list(self): - # Issue #34973: Crash in bytes constructor with mutating list. - class X: - def __index__(self): - a.clear() - return 42 - a = [X(), X()] - self.assertEqual(bytes(a), b'*') - - class Y: - def __index__(self): - if len(a) < 1000: - a.append(self) - return 42 - a = [Y()] - self.assertEqual(bytes(a), b'*' * 1000) # should not crash - - def test_from_index(self): - b = self.type2test([Indexable(), Indexable(1), Indexable(254), - Indexable(255)]) - self.assertEqual(list(b), [0, 1, 254, 255]) - self.assertRaises(ValueError, self.type2test, [Indexable(-1)]) - self.assertRaises(ValueError, self.type2test, [Indexable(256)]) - - def test_from_buffer(self): - a = self.type2test(array.array('B', [1, 2, 3])) - self.assertEqual(a, b"\x01\x02\x03") - a = self.type2test(b"\x01\x02\x03") - self.assertEqual(a, b"\x01\x02\x03") - - # Issues #29159 and #34974. - # Fallback when __index__ raises a TypeError - class B(bytes): - def __index__(self): - raise TypeError - - self.assertEqual(self.type2test(B(b"foobar")), b"foobar") - - def test_from_ssize(self): - self.assertEqual(self.type2test(0), b'') - self.assertEqual(self.type2test(1), b'\x00') - self.assertEqual(self.type2test(5), b'\x00\x00\x00\x00\x00') - self.assertRaises(ValueError, self.type2test, -1) - - self.assertEqual(self.type2test('0', 'ascii'), b'0') - self.assertEqual(self.type2test(b'0'), b'0') - self.assertRaises(OverflowError, self.type2test, sys.maxsize + 1) - - def test_constructor_type_errors(self): - self.assertRaises(TypeError, self.type2test, 0.0) - class C: - pass - self.assertRaises(TypeError, self.type2test, ["0"]) - self.assertRaises(TypeError, self.type2test, [0.0]) - self.assertRaises(TypeError, self.type2test, [None]) - self.assertRaises(TypeError, self.type2test, [C()]) - self.assertRaises(TypeError, self.type2test, encoding='ascii') - self.assertRaises(TypeError, self.type2test, errors='ignore') - self.assertRaises(TypeError, self.type2test, 0, 'ascii') - self.assertRaises(TypeError, self.type2test, b'', 'ascii') - self.assertRaises(TypeError, self.type2test, 0, errors='ignore') - self.assertRaises(TypeError, self.type2test, b'', errors='ignore') - self.assertRaises(TypeError, self.type2test, '') - self.assertRaises(TypeError, self.type2test, '', errors='ignore') - self.assertRaises(TypeError, self.type2test, '', b'ascii') - self.assertRaises(TypeError, self.type2test, '', 'ascii', b'ignore') - - def test_constructor_value_errors(self): - self.assertRaises(ValueError, self.type2test, [-1]) - self.assertRaises(ValueError, self.type2test, [-sys.maxsize]) - self.assertRaises(ValueError, self.type2test, [-sys.maxsize-1]) - self.assertRaises(ValueError, self.type2test, [-sys.maxsize-2]) - self.assertRaises(ValueError, self.type2test, [-10**100]) - self.assertRaises(ValueError, self.type2test, [256]) - self.assertRaises(ValueError, self.type2test, [257]) - self.assertRaises(ValueError, self.type2test, [sys.maxsize]) - self.assertRaises(ValueError, self.type2test, [sys.maxsize+1]) - self.assertRaises(ValueError, self.type2test, [10**100]) - - @bigaddrspacetest - def test_constructor_overflow(self): - size = MAX_Py_ssize_t - self.assertRaises((OverflowError, MemoryError), self.type2test, size) - try: - # Should either pass or raise an error (e.g. on debug builds with - # additional malloc() overhead), but shouldn't crash. - bytearray(size - 4) - except (OverflowError, MemoryError): - pass - - def test_constructor_exceptions(self): - # Issue #34974: bytes and bytearray constructors replace unexpected - # exceptions. - class BadInt: - def __index__(self): - 1/0 - self.assertRaises(ZeroDivisionError, self.type2test, BadInt()) - self.assertRaises(ZeroDivisionError, self.type2test, [BadInt()]) - - class BadIterable: - def __iter__(self): - 1/0 - self.assertRaises(ZeroDivisionError, self.type2test, BadIterable()) - - def test_compare(self): - b1 = self.type2test([1, 2, 3]) - b2 = self.type2test([1, 2, 3]) - b3 = self.type2test([1, 3]) - - self.assertEqual(b1, b2) - self.assertTrue(b2 != b3) - self.assertTrue(b1 <= b2) - self.assertTrue(b1 <= b3) - self.assertTrue(b1 < b3) - self.assertTrue(b1 >= b2) - self.assertTrue(b3 >= b2) - self.assertTrue(b3 > b2) - - self.assertFalse(b1 != b2) - self.assertFalse(b2 == b3) - self.assertFalse(b1 > b2) - self.assertFalse(b1 > b3) - self.assertFalse(b1 >= b3) - self.assertFalse(b1 < b2) - self.assertFalse(b3 < b2) - self.assertFalse(b3 <= b2) - - @check_bytes_warnings - def test_compare_to_str(self): - # Byte comparisons with unicode should always fail! - # Test this for all expected byte orders and Unicode character - # sizes. - self.assertEqual(self.type2test(b"\0a\0b\0c") == "abc", False) - self.assertEqual(self.type2test(b"\0\0\0a\0\0\0b\0\0\0c") == "abc", - False) - self.assertEqual(self.type2test(b"a\0b\0c\0") == "abc", False) - self.assertEqual(self.type2test(b"a\0\0\0b\0\0\0c\0\0\0") == "abc", - False) - self.assertEqual(self.type2test() == str(), False) - self.assertEqual(self.type2test() != str(), True) - - def test_reversed(self): - input = list(map(ord, "Hello")) - b = self.type2test(input) - output = list(reversed(b)) - input.reverse() - self.assertEqual(output, input) - - def test_getslice(self): - def by(s): - return self.type2test(map(ord, s)) - b = by("Hello, world") - - self.assertEqual(b[:5], by("Hello")) - self.assertEqual(b[1:5], by("ello")) - self.assertEqual(b[5:7], by(", ")) - self.assertEqual(b[7:], by("world")) - self.assertEqual(b[7:12], by("world")) - self.assertEqual(b[7:100], by("world")) - - self.assertEqual(b[:-7], by("Hello")) - self.assertEqual(b[-11:-7], by("ello")) - self.assertEqual(b[-7:-5], by(", ")) - self.assertEqual(b[-5:], by("world")) - self.assertEqual(b[-5:12], by("world")) - self.assertEqual(b[-5:100], by("world")) - self.assertEqual(b[-100:5], by("Hello")) - - def test_extended_getslice(self): - # Test extended slicing by comparing with list slicing. - L = list(range(255)) - b = self.type2test(L) - indices = (0, None, 1, 3, 19, 100, sys.maxsize, -1, -2, -31, -100) - for start in indices: - for stop in indices: - # Skip step 0 (invalid) - for step in indices[1:]: - self.assertEqual(b[start:stop:step], self.type2test(L[start:stop:step])) - - def test_encoding(self): - sample = "Hello world\n\u1234\u5678\u9abc" - for enc in ("utf-8", "utf-16"): - b = self.type2test(sample, enc) - self.assertEqual(b, self.type2test(sample.encode(enc))) - self.assertRaises(UnicodeEncodeError, self.type2test, sample, "latin-1") - b = self.type2test(sample, "latin-1", "ignore") - self.assertEqual(b, self.type2test(sample[:-3], "utf-8")) - - def test_decode(self): - sample = "Hello world\n\u1234\u5678\u9abc" - for enc in ("utf-8", "utf-16"): - b = self.type2test(sample, enc) - self.assertEqual(b.decode(enc), sample) - sample = "Hello world\n\x80\x81\xfe\xff" - b = self.type2test(sample, "latin-1") - self.assertRaises(UnicodeDecodeError, b.decode, "utf-8") - self.assertEqual(b.decode("utf-8", "ignore"), "Hello world\n") - self.assertEqual(b.decode(errors="ignore", encoding="utf-8"), - "Hello world\n") - # Default encoding is utf-8 - self.assertEqual(self.type2test(b'\xe2\x98\x83').decode(), '\u2603') - - def test_from_int(self): - b = self.type2test(0) - self.assertEqual(b, self.type2test()) - b = self.type2test(10) - self.assertEqual(b, self.type2test([0]*10)) - b = self.type2test(10000) - self.assertEqual(b, self.type2test([0]*10000)) - - def test_concat(self): - b1 = self.type2test(b"abc") - b2 = self.type2test(b"def") - self.assertEqual(b1 + b2, b"abcdef") - self.assertEqual(b1 + bytes(b"def"), b"abcdef") - self.assertEqual(bytes(b"def") + b1, b"defabc") - self.assertRaises(TypeError, lambda: b1 + "def") - self.assertRaises(TypeError, lambda: "abc" + b2) - - def test_repeat(self): - for b in b"abc", self.type2test(b"abc"): - self.assertEqual(b * 3, b"abcabcabc") - self.assertEqual(b * 0, b"") - self.assertEqual(b * -1, b"") - self.assertRaises(TypeError, lambda: b * 3.14) - self.assertRaises(TypeError, lambda: 3.14 * b) - # XXX Shouldn't bytes and bytearray agree on what to raise? - with self.assertRaises((OverflowError, MemoryError)): - c = b * sys.maxsize - with self.assertRaises((OverflowError, MemoryError)): - b *= sys.maxsize - - def test_repeat_1char(self): - self.assertEqual(self.type2test(b'x')*100, self.type2test([ord('x')]*100)) - - def test_contains(self): - b = self.type2test(b"abc") - self.assertIn(ord('a'), b) - self.assertIn(int(ord('a')), b) - self.assertNotIn(200, b) - self.assertRaises(ValueError, lambda: 300 in b) - self.assertRaises(ValueError, lambda: -1 in b) - self.assertRaises(ValueError, lambda: sys.maxsize+1 in b) - self.assertRaises(TypeError, lambda: None in b) - self.assertRaises(TypeError, lambda: float(ord('a')) in b) - self.assertRaises(TypeError, lambda: "a" in b) - for f in bytes, bytearray: - self.assertIn(f(b""), b) - self.assertIn(f(b"a"), b) - self.assertIn(f(b"b"), b) - self.assertIn(f(b"c"), b) - self.assertIn(f(b"ab"), b) - self.assertIn(f(b"bc"), b) - self.assertIn(f(b"abc"), b) - self.assertNotIn(f(b"ac"), b) - self.assertNotIn(f(b"d"), b) - self.assertNotIn(f(b"dab"), b) - self.assertNotIn(f(b"abd"), b) - - def test_fromhex(self): - self.assertRaises(TypeError, self.type2test.fromhex) - self.assertRaises(TypeError, self.type2test.fromhex, 1) - self.assertEqual(self.type2test.fromhex(''), self.type2test()) - b = bytearray([0x1a, 0x2b, 0x30]) - self.assertEqual(self.type2test.fromhex('1a2B30'), b) - self.assertEqual(self.type2test.fromhex(' 1A 2B 30 '), b) - - # check that ASCII whitespace is ignored - self.assertEqual(self.type2test.fromhex(' 1A\n2B\t30\v'), b) - for c in "\x09\x0A\x0B\x0C\x0D\x20": - self.assertEqual(self.type2test.fromhex(c), self.type2test()) - for c in "\x1C\x1D\x1E\x1F\x85\xa0\u2000\u2002\u2028": - self.assertRaises(ValueError, self.type2test.fromhex, c) - - self.assertEqual(self.type2test.fromhex('0000'), b'\0\0') - self.assertRaises(TypeError, self.type2test.fromhex, b'1B') - self.assertRaises(ValueError, self.type2test.fromhex, 'a') - self.assertRaises(ValueError, self.type2test.fromhex, 'rt') - self.assertRaises(ValueError, self.type2test.fromhex, '1a b cd') - self.assertRaises(ValueError, self.type2test.fromhex, '\x00') - self.assertRaises(ValueError, self.type2test.fromhex, '12 \x00 34') - - for data, pos in ( - # invalid first hexadecimal character - ('12 x4 56', 3), - # invalid second hexadecimal character - ('12 3x 56', 4), - # two invalid hexadecimal characters - ('12 xy 56', 3), - # test non-ASCII string - ('12 3\xff 56', 4), - ): - with self.assertRaises(ValueError) as cm: - self.type2test.fromhex(data) - self.assertIn('at position %s' % pos, str(cm.exception)) - - def test_hex(self): - self.assertRaises(TypeError, self.type2test.hex) - self.assertRaises(TypeError, self.type2test.hex, 1) - self.assertEqual(self.type2test(b"").hex(), "") - self.assertEqual(bytearray([0x1a, 0x2b, 0x30]).hex(), '1a2b30') - self.assertEqual(self.type2test(b"\x1a\x2b\x30").hex(), '1a2b30') - self.assertEqual(memoryview(b"\x1a\x2b\x30").hex(), '1a2b30') - - def test_hex_separator_basics(self): - three_bytes = self.type2test(b'\xb9\x01\xef') - self.assertEqual(three_bytes.hex(), 'b901ef') - with self.assertRaises(ValueError): - three_bytes.hex('') - with self.assertRaises(ValueError): - three_bytes.hex('xx') - self.assertEqual(three_bytes.hex(':', 0), 'b901ef') - with self.assertRaises(TypeError): - three_bytes.hex(None, 0) - with self.assertRaises(ValueError): - three_bytes.hex('\xff') - with self.assertRaises(ValueError): - three_bytes.hex(b'\xff') - with self.assertRaises(ValueError): - three_bytes.hex(b'\x80') - with self.assertRaises(ValueError): - three_bytes.hex(chr(0x100)) - self.assertEqual(three_bytes.hex(':', 0), 'b901ef') - self.assertEqual(three_bytes.hex(b'\x00'), 'b9\x0001\x00ef') - self.assertEqual(three_bytes.hex('\x00'), 'b9\x0001\x00ef') - self.assertEqual(three_bytes.hex(b'\x7f'), 'b9\x7f01\x7fef') - self.assertEqual(three_bytes.hex('\x7f'), 'b9\x7f01\x7fef') - self.assertEqual(three_bytes.hex(':', 3), 'b901ef') - self.assertEqual(three_bytes.hex(':', 4), 'b901ef') - self.assertEqual(three_bytes.hex(':', -4), 'b901ef') - self.assertEqual(three_bytes.hex(':'), 'b9:01:ef') - self.assertEqual(three_bytes.hex(b'$'), 'b9$01$ef') - self.assertEqual(three_bytes.hex(':', 1), 'b9:01:ef') - self.assertEqual(three_bytes.hex(':', -1), 'b9:01:ef') - self.assertEqual(three_bytes.hex(':', 2), 'b9:01ef') - self.assertEqual(three_bytes.hex(':', 1), 'b9:01:ef') - self.assertEqual(three_bytes.hex('*', -2), 'b901*ef') - - value = b'{s\005\000\000\000worldi\002\000\000\000s\005\000\000\000helloi\001\000\000\0000' - self.assertEqual(value.hex('.', 8), '7b7305000000776f.726c646902000000.730500000068656c.6c6f690100000030') - - def test_hex_separator_five_bytes(self): - five_bytes = self.type2test(range(90,95)) - self.assertEqual(five_bytes.hex(), '5a5b5c5d5e') - - def test_hex_separator_six_bytes(self): - six_bytes = self.type2test(x*3 for x in range(1, 7)) - self.assertEqual(six_bytes.hex(), '0306090c0f12') - self.assertEqual(six_bytes.hex('.', 1), '03.06.09.0c.0f.12') - self.assertEqual(six_bytes.hex(' ', 2), '0306 090c 0f12') - self.assertEqual(six_bytes.hex('-', 3), '030609-0c0f12') - self.assertEqual(six_bytes.hex(':', 4), '0306:090c0f12') - self.assertEqual(six_bytes.hex(':', 5), '03:06090c0f12') - self.assertEqual(six_bytes.hex(':', 6), '0306090c0f12') - self.assertEqual(six_bytes.hex(':', 95), '0306090c0f12') - self.assertEqual(six_bytes.hex('_', -3), '030609_0c0f12') - self.assertEqual(six_bytes.hex(':', -4), '0306090c:0f12') - self.assertEqual(six_bytes.hex(b'@', -5), '0306090c0f@12') - self.assertEqual(six_bytes.hex(':', -6), '0306090c0f12') - self.assertEqual(six_bytes.hex(' ', -95), '0306090c0f12') - - def test_join(self): - self.assertEqual(self.type2test(b"").join([]), b"") - self.assertEqual(self.type2test(b"").join([b""]), b"") - for lst in [[b"abc"], [b"a", b"bc"], [b"ab", b"c"], [b"a", b"b", b"c"]]: - lst = list(map(self.type2test, lst)) - self.assertEqual(self.type2test(b"").join(lst), b"abc") - self.assertEqual(self.type2test(b"").join(tuple(lst)), b"abc") - self.assertEqual(self.type2test(b"").join(iter(lst)), b"abc") - dot_join = self.type2test(b".:").join - self.assertEqual(dot_join([b"ab", b"cd"]), b"ab.:cd") - self.assertEqual(dot_join([memoryview(b"ab"), b"cd"]), b"ab.:cd") - self.assertEqual(dot_join([b"ab", memoryview(b"cd")]), b"ab.:cd") - self.assertEqual(dot_join([bytearray(b"ab"), b"cd"]), b"ab.:cd") - self.assertEqual(dot_join([b"ab", bytearray(b"cd")]), b"ab.:cd") - # Stress it with many items - seq = [b"abc"] * 1000 - expected = b"abc" + b".:abc" * 999 - self.assertEqual(dot_join(seq), expected) - self.assertRaises(TypeError, self.type2test(b" ").join, None) - # Error handling and cleanup when some item in the middle of the - # sequence has the wrong type. - with self.assertRaises(TypeError): - dot_join([bytearray(b"ab"), "cd", b"ef"]) - with self.assertRaises(TypeError): - dot_join([memoryview(b"ab"), "cd", b"ef"]) - - def test_count(self): - b = self.type2test(b'mississippi') - i = 105 - p = 112 - w = 119 - - self.assertEqual(b.count(b'i'), 4) - self.assertEqual(b.count(b'ss'), 2) - self.assertEqual(b.count(b'w'), 0) - - self.assertEqual(b.count(i), 4) - self.assertEqual(b.count(w), 0) - - self.assertEqual(b.count(b'i', 6), 2) - self.assertEqual(b.count(b'p', 6), 2) - self.assertEqual(b.count(b'i', 1, 3), 1) - self.assertEqual(b.count(b'p', 7, 9), 1) - - self.assertEqual(b.count(i, 6), 2) - self.assertEqual(b.count(p, 6), 2) - self.assertEqual(b.count(i, 1, 3), 1) - self.assertEqual(b.count(p, 7, 9), 1) - - def test_startswith(self): - b = self.type2test(b'hello') - self.assertFalse(self.type2test().startswith(b"anything")) - self.assertTrue(b.startswith(b"hello")) - self.assertTrue(b.startswith(b"hel")) - self.assertTrue(b.startswith(b"h")) - self.assertFalse(b.startswith(b"hellow")) - self.assertFalse(b.startswith(b"ha")) - with self.assertRaises(TypeError) as cm: - b.startswith([b'h']) - exc = str(cm.exception) - self.assertIn('bytes', exc) - self.assertIn('tuple', exc) - - def test_endswith(self): - b = self.type2test(b'hello') - self.assertFalse(bytearray().endswith(b"anything")) - self.assertTrue(b.endswith(b"hello")) - self.assertTrue(b.endswith(b"llo")) - self.assertTrue(b.endswith(b"o")) - self.assertFalse(b.endswith(b"whello")) - self.assertFalse(b.endswith(b"no")) - with self.assertRaises(TypeError) as cm: - b.endswith([b'o']) - exc = str(cm.exception) - self.assertIn('bytes', exc) - self.assertIn('tuple', exc) - - def test_find(self): - b = self.type2test(b'mississippi') - i = 105 - w = 119 - - self.assertEqual(b.find(b'ss'), 2) - self.assertEqual(b.find(b'w'), -1) - self.assertEqual(b.find(b'mississippian'), -1) - - self.assertEqual(b.find(i), 1) - self.assertEqual(b.find(w), -1) - - self.assertEqual(b.find(b'ss', 3), 5) - self.assertEqual(b.find(b'ss', 1, 7), 2) - self.assertEqual(b.find(b'ss', 1, 3), -1) - - self.assertEqual(b.find(i, 6), 7) - self.assertEqual(b.find(i, 1, 3), 1) - self.assertEqual(b.find(w, 1, 3), -1) - - for index in (-1, 256, sys.maxsize + 1): - self.assertRaisesRegex( - ValueError, r'byte must be in range\(0, 256\)', - b.find, index) - - def test_rfind(self): - b = self.type2test(b'mississippi') - i = 105 - w = 119 - - self.assertEqual(b.rfind(b'ss'), 5) - self.assertEqual(b.rfind(b'w'), -1) - self.assertEqual(b.rfind(b'mississippian'), -1) - - self.assertEqual(b.rfind(i), 10) - self.assertEqual(b.rfind(w), -1) - - self.assertEqual(b.rfind(b'ss', 3), 5) - self.assertEqual(b.rfind(b'ss', 0, 6), 2) - - self.assertEqual(b.rfind(i, 1, 3), 1) - self.assertEqual(b.rfind(i, 3, 9), 7) - self.assertEqual(b.rfind(w, 1, 3), -1) - - def test_index(self): - b = self.type2test(b'mississippi') - i = 105 - w = 119 - - self.assertEqual(b.index(b'ss'), 2) - self.assertRaises(ValueError, b.index, b'w') - self.assertRaises(ValueError, b.index, b'mississippian') - - self.assertEqual(b.index(i), 1) - self.assertRaises(ValueError, b.index, w) - - self.assertEqual(b.index(b'ss', 3), 5) - self.assertEqual(b.index(b'ss', 1, 7), 2) - self.assertRaises(ValueError, b.index, b'ss', 1, 3) - - self.assertEqual(b.index(i, 6), 7) - self.assertEqual(b.index(i, 1, 3), 1) - self.assertRaises(ValueError, b.index, w, 1, 3) - - def test_rindex(self): - b = self.type2test(b'mississippi') - i = 105 - w = 119 - - self.assertEqual(b.rindex(b'ss'), 5) - self.assertRaises(ValueError, b.rindex, b'w') - self.assertRaises(ValueError, b.rindex, b'mississippian') - - self.assertEqual(b.rindex(i), 10) - self.assertRaises(ValueError, b.rindex, w) - - self.assertEqual(b.rindex(b'ss', 3), 5) - self.assertEqual(b.rindex(b'ss', 0, 6), 2) - - self.assertEqual(b.rindex(i, 1, 3), 1) - self.assertEqual(b.rindex(i, 3, 9), 7) - self.assertRaises(ValueError, b.rindex, w, 1, 3) - - def test_mod(self): - b = self.type2test(b'hello, %b!') - orig = b - b = b % b'world' - self.assertEqual(b, b'hello, world!') - self.assertEqual(orig, b'hello, %b!') - self.assertFalse(b is orig) - b = self.type2test(b'%s / 100 = %d%%') - a = b % (b'seventy-nine', 79) - self.assertEqual(a, b'seventy-nine / 100 = 79%') - self.assertIs(type(a), self.type2test) - # issue 29714 - b = self.type2test(b'hello,\x00%b!') - b = b % b'world' - self.assertEqual(b, b'hello,\x00world!') - self.assertIs(type(b), self.type2test) - - def test_imod(self): - b = self.type2test(b'hello, %b!') - orig = b - b %= b'world' - self.assertEqual(b, b'hello, world!') - self.assertEqual(orig, b'hello, %b!') - self.assertFalse(b is orig) - b = self.type2test(b'%s / 100 = %d%%') - b %= (b'seventy-nine', 79) - self.assertEqual(b, b'seventy-nine / 100 = 79%') - self.assertIs(type(b), self.type2test) - # issue 29714 - b = self.type2test(b'hello,\x00%b!') - b %= b'world' - self.assertEqual(b, b'hello,\x00world!') - self.assertIs(type(b), self.type2test) - - def test_rmod(self): - with self.assertRaises(TypeError): - object() % self.type2test(b'abc') - self.assertIs(self.type2test(b'abc').__rmod__('%r'), NotImplemented) - - def test_replace(self): - b = self.type2test(b'mississippi') - self.assertEqual(b.replace(b'i', b'a'), b'massassappa') - self.assertEqual(b.replace(b'ss', b'x'), b'mixixippi') - - def test_replace_int_error(self): - self.assertRaises(TypeError, self.type2test(b'a b').replace, 32, b'') - - def test_split_string_error(self): - self.assertRaises(TypeError, self.type2test(b'a b').split, ' ') - self.assertRaises(TypeError, self.type2test(b'a b').rsplit, ' ') - - def test_split_int_error(self): - self.assertRaises(TypeError, self.type2test(b'a b').split, 32) - self.assertRaises(TypeError, self.type2test(b'a b').rsplit, 32) - - def test_split_unicodewhitespace(self): - for b in (b'a\x1Cb', b'a\x1Db', b'a\x1Eb', b'a\x1Fb'): - b = self.type2test(b) - self.assertEqual(b.split(), [b]) - b = self.type2test(b"\x09\x0A\x0B\x0C\x0D\x1C\x1D\x1E\x1F") - self.assertEqual(b.split(), [b'\x1c\x1d\x1e\x1f']) - - def test_rsplit_unicodewhitespace(self): - b = self.type2test(b"\x09\x0A\x0B\x0C\x0D\x1C\x1D\x1E\x1F") - self.assertEqual(b.rsplit(), [b'\x1c\x1d\x1e\x1f']) - - def test_partition(self): - b = self.type2test(b'mississippi') - self.assertEqual(b.partition(b'ss'), (b'mi', b'ss', b'issippi')) - self.assertEqual(b.partition(b'w'), (b'mississippi', b'', b'')) - - def test_rpartition(self): - b = self.type2test(b'mississippi') - self.assertEqual(b.rpartition(b'ss'), (b'missi', b'ss', b'ippi')) - self.assertEqual(b.rpartition(b'i'), (b'mississipp', b'i', b'')) - self.assertEqual(b.rpartition(b'w'), (b'', b'', b'mississippi')) - - def test_partition_string_error(self): - self.assertRaises(TypeError, self.type2test(b'a b').partition, ' ') - self.assertRaises(TypeError, self.type2test(b'a b').rpartition, ' ') - - def test_partition_int_error(self): - self.assertRaises(TypeError, self.type2test(b'a b').partition, 32) - self.assertRaises(TypeError, self.type2test(b'a b').rpartition, 32) - - def test_pickling(self): - for proto in range(pickle.HIGHEST_PROTOCOL + 1): - for b in b"", b"a", b"abc", b"\xffab\x80", b"\0\0\377\0\0": - b = self.type2test(b) - ps = pickle.dumps(b, proto) - q = pickle.loads(ps) - self.assertEqual(b, q) - - def test_iterator_pickling(self): - for proto in range(pickle.HIGHEST_PROTOCOL + 1): - for b in b"", b"a", b"abc", b"\xffab\x80", b"\0\0\377\0\0": - it = itorg = iter(self.type2test(b)) - data = list(self.type2test(b)) - d = pickle.dumps(it, proto) - it = pickle.loads(d) - self.assertEqual(type(itorg), type(it)) - self.assertEqual(list(it), data) - - it = pickle.loads(d) - if not b: - continue - next(it) - d = pickle.dumps(it, proto) - it = pickle.loads(d) - self.assertEqual(list(it), data[1:]) - - def test_strip_bytearray(self): - self.assertEqual(self.type2test(b'abc').strip(memoryview(b'ac')), b'b') - self.assertEqual(self.type2test(b'abc').lstrip(memoryview(b'ac')), b'bc') - self.assertEqual(self.type2test(b'abc').rstrip(memoryview(b'ac')), b'ab') - - def test_strip_string_error(self): - self.assertRaises(TypeError, self.type2test(b'abc').strip, 'ac') - self.assertRaises(TypeError, self.type2test(b'abc').lstrip, 'ac') - self.assertRaises(TypeError, self.type2test(b'abc').rstrip, 'ac') - - def test_strip_int_error(self): - self.assertRaises(TypeError, self.type2test(b' abc ').strip, 32) - self.assertRaises(TypeError, self.type2test(b' abc ').lstrip, 32) - self.assertRaises(TypeError, self.type2test(b' abc ').rstrip, 32) - - def test_center(self): - # Fill character can be either bytes or bytearray (issue 12380) - b = self.type2test(b'abc') - for fill_type in (bytes, bytearray): - self.assertEqual(b.center(7, fill_type(b'-')), - self.type2test(b'--abc--')) - - def test_ljust(self): - # Fill character can be either bytes or bytearray (issue 12380) - b = self.type2test(b'abc') - for fill_type in (bytes, bytearray): - self.assertEqual(b.ljust(7, fill_type(b'-')), - self.type2test(b'abc----')) - - def test_rjust(self): - # Fill character can be either bytes or bytearray (issue 12380) - b = self.type2test(b'abc') - for fill_type in (bytes, bytearray): - self.assertEqual(b.rjust(7, fill_type(b'-')), - self.type2test(b'----abc')) - - def test_xjust_int_error(self): - self.assertRaises(TypeError, self.type2test(b'abc').center, 7, 32) - self.assertRaises(TypeError, self.type2test(b'abc').ljust, 7, 32) - self.assertRaises(TypeError, self.type2test(b'abc').rjust, 7, 32) - - def test_ord(self): - b = self.type2test(b'\0A\x7f\x80\xff') - self.assertEqual([ord(b[i:i+1]) for i in range(len(b))], - [0, 65, 127, 128, 255]) - - def test_maketrans(self): - transtable = b'\000\001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037 !"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`xyzdefghijklmnopqrstuvwxyz{|}~\177\200\201\202\203\204\205\206\207\210\211\212\213\214\215\216\217\220\221\222\223\224\225\226\227\230\231\232\233\234\235\236\237\240\241\242\243\244\245\246\247\250\251\252\253\254\255\256\257\260\261\262\263\264\265\266\267\270\271\272\273\274\275\276\277\300\301\302\303\304\305\306\307\310\311\312\313\314\315\316\317\320\321\322\323\324\325\326\327\330\331\332\333\334\335\336\337\340\341\342\343\344\345\346\347\350\351\352\353\354\355\356\357\360\361\362\363\364\365\366\367\370\371\372\373\374\375\376\377' - self.assertEqual(self.type2test.maketrans(b'abc', b'xyz'), transtable) - transtable = b'\000\001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037 !"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\177\200\201\202\203\204\205\206\207\210\211\212\213\214\215\216\217\220\221\222\223\224\225\226\227\230\231\232\233\234\235\236\237\240\241\242\243\244\245\246\247\250\251\252\253\254\255\256\257\260\261\262\263\264\265\266\267\270\271\272\273\274\275\276\277\300\301\302\303\304\305\306\307\310\311\312\313\314\315\316\317\320\321\322\323\324\325\326\327\330\331\332\333\334\335\336\337\340\341\342\343\344\345\346\347\350\351\352\353\354\355\356\357\360\361\362\363\364\365\366\367\370\371\372\373\374xyz' - self.assertEqual(self.type2test.maketrans(b'\375\376\377', b'xyz'), transtable) - self.assertRaises(ValueError, self.type2test.maketrans, b'abc', b'xyzq') - self.assertRaises(TypeError, self.type2test.maketrans, 'abc', 'def') - - def test_none_arguments(self): - # issue 11828 - b = self.type2test(b'hello') - l = self.type2test(b'l') - h = self.type2test(b'h') - x = self.type2test(b'x') - o = self.type2test(b'o') - - self.assertEqual(2, b.find(l, None)) - self.assertEqual(3, b.find(l, -2, None)) - self.assertEqual(2, b.find(l, None, -2)) - self.assertEqual(0, b.find(h, None, None)) - - self.assertEqual(3, b.rfind(l, None)) - self.assertEqual(3, b.rfind(l, -2, None)) - self.assertEqual(2, b.rfind(l, None, -2)) - self.assertEqual(0, b.rfind(h, None, None)) - - self.assertEqual(2, b.index(l, None)) - self.assertEqual(3, b.index(l, -2, None)) - self.assertEqual(2, b.index(l, None, -2)) - self.assertEqual(0, b.index(h, None, None)) - - self.assertEqual(3, b.rindex(l, None)) - self.assertEqual(3, b.rindex(l, -2, None)) - self.assertEqual(2, b.rindex(l, None, -2)) - self.assertEqual(0, b.rindex(h, None, None)) - - self.assertEqual(2, b.count(l, None)) - self.assertEqual(1, b.count(l, -2, None)) - self.assertEqual(1, b.count(l, None, -2)) - self.assertEqual(0, b.count(x, None, None)) - - self.assertEqual(True, b.endswith(o, None)) - self.assertEqual(True, b.endswith(o, -2, None)) - self.assertEqual(True, b.endswith(l, None, -2)) - self.assertEqual(False, b.endswith(x, None, None)) - - self.assertEqual(True, b.startswith(h, None)) - self.assertEqual(True, b.startswith(l, -2, None)) - self.assertEqual(True, b.startswith(h, None, -2)) - self.assertEqual(False, b.startswith(x, None, None)) - - def test_integer_arguments_out_of_byte_range(self): - b = self.type2test(b'hello') - - for method in (b.count, b.find, b.index, b.rfind, b.rindex): - self.assertRaises(ValueError, method, -1) - self.assertRaises(ValueError, method, 256) - self.assertRaises(ValueError, method, 9999) - - def test_find_etc_raise_correct_error_messages(self): - # issue 11828 - b = self.type2test(b'hello') - x = self.type2test(b'x') - self.assertRaisesRegex(TypeError, r'\bfind\b', b.find, - x, None, None, None) - self.assertRaisesRegex(TypeError, r'\brfind\b', b.rfind, - x, None, None, None) - self.assertRaisesRegex(TypeError, r'\bindex\b', b.index, - x, None, None, None) - self.assertRaisesRegex(TypeError, r'\brindex\b', b.rindex, - x, None, None, None) - self.assertRaisesRegex(TypeError, r'\bcount\b', b.count, - x, None, None, None) - self.assertRaisesRegex(TypeError, r'\bstartswith\b', b.startswith, - x, None, None, None) - self.assertRaisesRegex(TypeError, r'\bendswith\b', b.endswith, - x, None, None, None) - - def test_free_after_iterating(self): - test.support.check_free_after_iterating(self, iter, self.type2test) - test.support.check_free_after_iterating(self, reversed, self.type2test) - - def test_translate(self): - b = self.type2test(b'hello') - rosetta = bytearray(range(256)) - rosetta[ord('o')] = ord('e') - - self.assertRaises(TypeError, b.translate) - self.assertRaises(TypeError, b.translate, None, None) - self.assertRaises(ValueError, b.translate, bytes(range(255))) - - c = b.translate(rosetta, b'hello') - self.assertEqual(b, b'hello') - self.assertIsInstance(c, self.type2test) - - c = b.translate(rosetta) - d = b.translate(rosetta, b'') - self.assertEqual(c, d) - self.assertEqual(c, b'helle') - - c = b.translate(rosetta, b'l') - self.assertEqual(c, b'hee') - c = b.translate(None, b'e') - self.assertEqual(c, b'hllo') - - # test delete as a keyword argument - c = b.translate(rosetta, delete=b'') - self.assertEqual(c, b'helle') - c = b.translate(rosetta, delete=b'l') - self.assertEqual(c, b'hee') - c = b.translate(None, delete=b'e') - self.assertEqual(c, b'hllo') - - - class BytesTest(BaseBytesTest, unittest.TestCase): - type2test = bytes - - def test_getitem_error(self): - b = b'python' - msg = "byte indices must be integers or slices" - with self.assertRaisesRegex(TypeError, msg): - b['a'] - - def test_buffer_is_readonly(self): - fd = os.open(__file__, os.O_RDONLY) - with open(fd, "rb", buffering=0) as f: - self.assertRaises(TypeError, f.readinto, b"") - - def test_custom(self): - class A: - def __bytes__(self): - return b'abc' - self.assertEqual(bytes(A()), b'abc') - class A: pass - self.assertRaises(TypeError, bytes, A()) - class A: - def __bytes__(self): - return None - self.assertRaises(TypeError, bytes, A()) - class A: - def __bytes__(self): - return b'a' - def __index__(self): - return 42 - self.assertEqual(bytes(A()), b'a') - # Issue #25766 - class A(str): - def __bytes__(self): - return b'abc' - self.assertEqual(bytes(A('\u20ac')), b'abc') - self.assertEqual(bytes(A('\u20ac'), 'iso8859-15'), b'\xa4') - # Issue #24731 - class A: - def __bytes__(self): - return OtherBytesSubclass(b'abc') - self.assertEqual(bytes(A()), b'abc') - self.assertIs(type(bytes(A())), OtherBytesSubclass) - self.assertEqual(BytesSubclass(A()), b'abc') - self.assertIs(type(BytesSubclass(A())), BytesSubclass) - - # Test PyBytes_FromFormat() - def test_from_format(self): - ctypes = test.support.import_module('ctypes') - _testcapi = test.support.import_module('_testcapi') - from ctypes import pythonapi, py_object - from ctypes import ( - c_int, c_uint, - c_long, c_ulong, - c_size_t, c_ssize_t, - c_char_p) - - PyBytes_FromFormat = pythonapi.PyBytes_FromFormat - PyBytes_FromFormat.argtypes = (c_char_p,) - PyBytes_FromFormat.restype = py_object - - # basic tests - self.assertEqual(PyBytes_FromFormat(b'format'), - b'format') - self.assertEqual(PyBytes_FromFormat(b'Hello %s !', b'world'), - b'Hello world !') - - # test formatters - self.assertEqual(PyBytes_FromFormat(b'c=%c', c_int(0)), - b'c=\0') - self.assertEqual(PyBytes_FromFormat(b'c=%c', c_int(ord('@'))), - b'c=@') - self.assertEqual(PyBytes_FromFormat(b'c=%c', c_int(255)), - b'c=\xff') - self.assertEqual(PyBytes_FromFormat(b'd=%d ld=%ld zd=%zd', - c_int(1), c_long(2), - c_size_t(3)), - b'd=1 ld=2 zd=3') - self.assertEqual(PyBytes_FromFormat(b'd=%d ld=%ld zd=%zd', - c_int(-1), c_long(-2), - c_size_t(-3)), - b'd=-1 ld=-2 zd=-3') - self.assertEqual(PyBytes_FromFormat(b'u=%u lu=%lu zu=%zu', - c_uint(123), c_ulong(456), - c_size_t(789)), - b'u=123 lu=456 zu=789') - self.assertEqual(PyBytes_FromFormat(b'i=%i', c_int(123)), - b'i=123') - self.assertEqual(PyBytes_FromFormat(b'i=%i', c_int(-123)), - b'i=-123') - self.assertEqual(PyBytes_FromFormat(b'x=%x', c_int(0xabc)), - b'x=abc') - - sizeof_ptr = ctypes.sizeof(c_char_p) - - if os.name == 'nt': - # Windows (MSCRT) - ptr_format = '0x%0{}X'.format(2 * sizeof_ptr) - def ptr_formatter(ptr): - return (ptr_format % ptr) - else: - # UNIX (glibc) - def ptr_formatter(ptr): - return '%#x' % ptr - - ptr = 0xabcdef - self.assertEqual(PyBytes_FromFormat(b'ptr=%p', c_char_p(ptr)), - ('ptr=' + ptr_formatter(ptr)).encode('ascii')) - self.assertEqual(PyBytes_FromFormat(b's=%s', c_char_p(b'cstr')), - b's=cstr') - - # test minimum and maximum integer values - size_max = c_size_t(-1).value - for formatstr, ctypes_type, value, py_formatter in ( - (b'%d', c_int, _testcapi.INT_MIN, str), - (b'%d', c_int, _testcapi.INT_MAX, str), - (b'%ld', c_long, _testcapi.LONG_MIN, str), - (b'%ld', c_long, _testcapi.LONG_MAX, str), - (b'%lu', c_ulong, _testcapi.ULONG_MAX, str), - (b'%zd', c_ssize_t, _testcapi.PY_SSIZE_T_MIN, str), - (b'%zd', c_ssize_t, _testcapi.PY_SSIZE_T_MAX, str), - (b'%zu', c_size_t, size_max, str), - (b'%p', c_char_p, size_max, ptr_formatter), - ): - self.assertEqual(PyBytes_FromFormat(formatstr, ctypes_type(value)), - py_formatter(value).encode('ascii')), - - # width and precision (width is currently ignored) - self.assertEqual(PyBytes_FromFormat(b'%5s', b'a'), - b'a') - self.assertEqual(PyBytes_FromFormat(b'%.3s', b'abcdef'), - b'abc') - - # '%%' formatter - self.assertEqual(PyBytes_FromFormat(b'%%'), - b'%') - self.assertEqual(PyBytes_FromFormat(b'[%%]'), - b'[%]') - self.assertEqual(PyBytes_FromFormat(b'%%%c', c_int(ord('_'))), - b'%_') - self.assertEqual(PyBytes_FromFormat(b'%%s'), - b'%s') - - # Invalid formats and partial formatting - self.assertEqual(PyBytes_FromFormat(b'%'), b'%') - self.assertEqual(PyBytes_FromFormat(b'x=%i y=%', c_int(2), c_int(3)), - b'x=2 y=%') - - # Issue #19969: %c must raise OverflowError for values - # not in the range [0; 255] - self.assertRaises(OverflowError, - PyBytes_FromFormat, b'%c', c_int(-1)) - self.assertRaises(OverflowError, - PyBytes_FromFormat, b'%c', c_int(256)) - - # Issue #33817: empty strings - self.assertEqual(PyBytes_FromFormat(b''), - b'') - self.assertEqual(PyBytes_FromFormat(b'%s', b''), - b'') - - def test_bytes_blocking(self): - class IterationBlocked(list): - __bytes__ = None - i = [0, 1, 2, 3] - self.assertEqual(bytes(i), b'\x00\x01\x02\x03') - self.assertRaises(TypeError, bytes, IterationBlocked(i)) - - # At least in CPython, because bytes.__new__ and the C API - # PyBytes_FromObject have different fallback rules, integer - # fallback is handled specially, so test separately. - class IntBlocked(int): - __bytes__ = None - self.assertEqual(bytes(3), b'\0\0\0') - self.assertRaises(TypeError, bytes, IntBlocked(3)) - - # While there is no separately-defined rule for handling bytes - # subclasses differently from other buffer-interface classes, - # an implementation may well special-case them (as CPython 2.x - # str did), so test them separately. - class BytesSubclassBlocked(bytes): - __bytes__ = None - self.assertEqual(bytes(b'ab'), b'ab') - self.assertRaises(TypeError, bytes, BytesSubclassBlocked(b'ab')) - - class BufferBlocked(bytearray): - __bytes__ = None - ba, bb = bytearray(b'ab'), BufferBlocked(b'ab') - self.assertEqual(bytes(ba), b'ab') - self.assertRaises(TypeError, bytes, bb) - - - class ByteArrayTest(BaseBytesTest, unittest.TestCase): - type2test = bytearray - - def test_getitem_error(self): - b = bytearray(b'python') - msg = "bytearray indices must be integers or slices" - with self.assertRaisesRegex(TypeError, msg): - b['a'] - - def test_setitem_error(self): - b = bytearray(b'python') - msg = "bytearray indices must be integers or slices" - with self.assertRaisesRegex(TypeError, msg): - b['a'] = "python" - - def test_nohash(self): - self.assertRaises(TypeError, hash, bytearray()) - - def test_bytearray_api(self): - short_sample = b"Hello world\n" - sample = short_sample + b"\0"*(20 - len(short_sample)) - tfn = tempfile.mktemp() - try: - # Prepare - with open(tfn, "wb") as f: - f.write(short_sample) - # Test readinto - with open(tfn, "rb") as f: - b = bytearray(20) - n = f.readinto(b) - self.assertEqual(n, len(short_sample)) - self.assertEqual(list(b), list(sample)) - # Test writing in binary mode - with open(tfn, "wb") as f: - f.write(b) - with open(tfn, "rb") as f: - self.assertEqual(f.read(), sample) - # Text mode is ambiguous; don't test - finally: - try: - os.remove(tfn) - except OSError: - pass - - def test_reverse(self): - b = bytearray(b'hello') - self.assertEqual(b.reverse(), None) - self.assertEqual(b, b'olleh') - b = bytearray(b'hello1') # test even number of items - b.reverse() - self.assertEqual(b, b'1olleh') - b = bytearray() - b.reverse() - self.assertFalse(b) - - def test_clear(self): - b = bytearray(b'python') - b.clear() - self.assertEqual(b, b'') - - b = bytearray(b'') - b.clear() - self.assertEqual(b, b'') - - b = bytearray(b'') - b.append(ord('r')) - b.clear() - b.append(ord('p')) - self.assertEqual(b, b'p') - - def test_copy(self): - b = bytearray(b'abc') - bb = b.copy() - self.assertEqual(bb, b'abc') - - b = bytearray(b'') - bb = b.copy() - self.assertEqual(bb, b'') - - # test that it's indeed a copy and not a reference - b = bytearray(b'abc') - bb = b.copy() - self.assertEqual(b, bb) - self.assertIsNot(b, bb) - bb.append(ord('d')) - self.assertEqual(bb, b'abcd') - self.assertEqual(b, b'abc') - - def test_regexps(self): - def by(s): - return bytearray(map(ord, s)) - b = by("Hello, world") - self.assertEqual(re.findall(br"\w+", b), [by("Hello"), by("world")]) - - def test_setitem(self): - b = bytearray([1, 2, 3]) - b[1] = 100 - self.assertEqual(b, bytearray([1, 100, 3])) - b[-1] = 200 - self.assertEqual(b, bytearray([1, 100, 200])) - b[0] = Indexable(10) - self.assertEqual(b, bytearray([10, 100, 200])) - try: - b[3] = 0 - self.fail("Didn't raise IndexError") - except IndexError: - pass - try: - b[-10] = 0 - self.fail("Didn't raise IndexError") - except IndexError: - pass - try: - b[0] = 256 - self.fail("Didn't raise ValueError") - except ValueError: - pass - try: - b[0] = Indexable(-1) - self.fail("Didn't raise ValueError") - except ValueError: - pass - try: - b[0] = None - self.fail("Didn't raise TypeError") - except TypeError: - pass - - def test_delitem(self): - b = bytearray(range(10)) - del b[0] - self.assertEqual(b, bytearray(range(1, 10))) - del b[-1] - self.assertEqual(b, bytearray(range(1, 9))) - del b[4] - self.assertEqual(b, bytearray([1, 2, 3, 4, 6, 7, 8])) - - def test_setslice(self): - b = bytearray(range(10)) - self.assertEqual(list(b), list(range(10))) - - b[0:5] = bytearray([1, 1, 1, 1, 1]) - self.assertEqual(b, bytearray([1, 1, 1, 1, 1, 5, 6, 7, 8, 9])) - - del b[0:-5] - self.assertEqual(b, bytearray([5, 6, 7, 8, 9])) - - b[0:0] = bytearray([0, 1, 2, 3, 4]) - self.assertEqual(b, bytearray(range(10))) - - b[-7:-3] = bytearray([100, 101]) - self.assertEqual(b, bytearray([0, 1, 2, 100, 101, 7, 8, 9])) - - b[3:5] = [3, 4, 5, 6] - self.assertEqual(b, bytearray(range(10))) - - b[3:0] = [42, 42, 42] - self.assertEqual(b, bytearray([0, 1, 2, 42, 42, 42, 3, 4, 5, 6, 7, 8, 9])) - - b[3:] = b'foo' - self.assertEqual(b, bytearray([0, 1, 2, 102, 111, 111])) - - b[:3] = memoryview(b'foo') - self.assertEqual(b, bytearray([102, 111, 111, 102, 111, 111])) - - b[3:4] = [] - self.assertEqual(b, bytearray([102, 111, 111, 111, 111])) - - for elem in [5, -5, 0, int(10e20), 'str', 2.3, - ['a', 'b'], [b'a', b'b'], [[]]]: - with self.assertRaises(TypeError): - b[3:4] = elem - - for elem in [[254, 255, 256], [-256, 9000]]: - with self.assertRaises(ValueError): - b[3:4] = elem - - def test_setslice_extend(self): - # Exercise the resizing logic (see issue #19087) - b = bytearray(range(100)) - self.assertEqual(list(b), list(range(100))) - del b[:10] - self.assertEqual(list(b), list(range(10, 100))) - b.extend(range(100, 110)) - self.assertEqual(list(b), list(range(10, 110))) - - def test_fifo_overrun(self): - # Test for issue #23985, a buffer overrun when implementing a FIFO - # Build Python in pydebug mode for best results. - b = bytearray(10) - b.pop() # Defeat expanding buffer off-by-one quirk - del b[:1] # Advance start pointer without reallocating - b += bytes(2) # Append exactly the number of deleted bytes - del b # Free memory buffer, allowing pydebug verification - - def test_del_expand(self): - # Reducing the size should not expand the buffer (issue #23985) - b = bytearray(10) - size = sys.getsizeof(b) - del b[:1] - self.assertLessEqual(sys.getsizeof(b), size) - - def test_extended_set_del_slice(self): - indices = (0, None, 1, 3, 19, 300, 1<<333, sys.maxsize, - -1, -2, -31, -300) - for start in indices: - for stop in indices: - # Skip invalid step 0 - for step in indices[1:]: - L = list(range(255)) - b = bytearray(L) - # Make sure we have a slice of exactly the right length, - # but with different data. - data = L[start:stop:step] - data.reverse() - L[start:stop:step] = data - b[start:stop:step] = data - self.assertEqual(b, bytearray(L)) - - del L[start:stop:step] - del b[start:stop:step] - self.assertEqual(b, bytearray(L)) - - def test_setslice_trap(self): - # This test verifies that we correctly handle assigning self - # to a slice of self (the old Lambert Meertens trap). - b = bytearray(range(256)) - b[8:] = b - self.assertEqual(b, bytearray(list(range(8)) + list(range(256)))) - - def test_iconcat(self): - b = bytearray(b"abc") - b1 = b - b += b"def" - self.assertEqual(b, b"abcdef") - self.assertEqual(b, b1) - self.assertIs(b, b1) - b += b"xyz" - self.assertEqual(b, b"abcdefxyz") - try: - b += "" - except TypeError: - pass - else: - self.fail("bytes += unicode didn't raise TypeError") - - def test_irepeat(self): - b = bytearray(b"abc") - b1 = b - b *= 3 - self.assertEqual(b, b"abcabcabc") - self.assertEqual(b, b1) - self.assertIs(b, b1) - - def test_irepeat_1char(self): - b = bytearray(b"x") - b1 = b - b *= 100 - self.assertEqual(b, b"x"*100) - self.assertEqual(b, b1) - self.assertIs(b, b1) - - def test_alloc(self): - b = bytearray() - alloc = b.__alloc__() - self.assertGreaterEqual(alloc, 0) - seq = [alloc] - for i in range(100): - b += b"x" - alloc = b.__alloc__() - self.assertGreater(alloc, len(b)) # including trailing null byte - if alloc not in seq: - seq.append(alloc) - - def test_init_alloc(self): - b = bytearray() - def g(): - for i in range(1, 100): - yield i - a = list(b) - self.assertEqual(a, list(range(1, len(a)+1))) - self.assertEqual(len(b), len(a)) - self.assertLessEqual(len(b), i) - alloc = b.__alloc__() - self.assertGreater(alloc, len(b)) # including trailing null byte - b.__init__(g()) - self.assertEqual(list(b), list(range(1, 100))) - self.assertEqual(len(b), 99) - alloc = b.__alloc__() - self.assertGreater(alloc, len(b)) - - def test_extend(self): - orig = b'hello' - a = bytearray(orig) - a.extend(a) - self.assertEqual(a, orig + orig) - self.assertEqual(a[5:], orig) - a = bytearray(b'') - # Test iterators that don't have a __length_hint__ - a.extend(map(int, orig * 25)) - a.extend(int(x) for x in orig * 25) - self.assertEqual(a, orig * 50) - self.assertEqual(a[-5:], orig) - a = bytearray(b'') - a.extend(iter(map(int, orig * 50))) - self.assertEqual(a, orig * 50) - self.assertEqual(a[-5:], orig) - a = bytearray(b'') - a.extend(list(map(int, orig * 50))) - self.assertEqual(a, orig * 50) - self.assertEqual(a[-5:], orig) - a = bytearray(b'') - self.assertRaises(ValueError, a.extend, [0, 1, 2, 256]) - self.assertRaises(ValueError, a.extend, [0, 1, 2, -1]) - self.assertEqual(len(a), 0) - a = bytearray(b'') - a.extend([Indexable(ord('a'))]) - self.assertEqual(a, b'a') - - def test_remove(self): - b = bytearray(b'hello') - b.remove(ord('l')) - self.assertEqual(b, b'helo') - b.remove(ord('l')) - self.assertEqual(b, b'heo') - self.assertRaises(ValueError, lambda: b.remove(ord('l'))) - self.assertRaises(ValueError, lambda: b.remove(400)) - self.assertRaises(TypeError, lambda: b.remove('e')) - # remove first and last - b.remove(ord('o')) - b.remove(ord('h')) - self.assertEqual(b, b'e') - self.assertRaises(TypeError, lambda: b.remove(b'e')) - b.remove(Indexable(ord('e'))) - self.assertEqual(b, b'') - - # test values outside of the ascii range: (0, 127) - c = bytearray([126, 127, 128, 129]) - c.remove(127) - self.assertEqual(c, bytes([126, 128, 129])) - c.remove(129) - self.assertEqual(c, bytes([126, 128])) - - def test_pop(self): - b = bytearray(b'world') - self.assertEqual(b.pop(), ord('d')) - self.assertEqual(b.pop(0), ord('w')) - self.assertEqual(b.pop(-2), ord('r')) - self.assertRaises(IndexError, lambda: b.pop(10)) - self.assertRaises(IndexError, lambda: bytearray().pop()) - # test for issue #6846 - self.assertEqual(bytearray(b'\xff').pop(), 0xff) - - def test_nosort(self): - self.assertRaises(AttributeError, lambda: bytearray().sort()) - - def test_append(self): - b = bytearray(b'hell') - b.append(ord('o')) - self.assertEqual(b, b'hello') - self.assertEqual(b.append(100), None) - b = bytearray() - b.append(ord('A')) - self.assertEqual(len(b), 1) - self.assertRaises(TypeError, lambda: b.append(b'o')) - b = bytearray() - b.append(Indexable(ord('A'))) - self.assertEqual(b, b'A') - - def test_insert(self): - b = bytearray(b'msssspp') - b.insert(1, ord('i')) - b.insert(4, ord('i')) - b.insert(-2, ord('i')) - b.insert(1000, ord('i')) - self.assertEqual(b, b'mississippi') - self.assertRaises(TypeError, lambda: b.insert(0, b'1')) - b = bytearray() - b.insert(0, Indexable(ord('A'))) - self.assertEqual(b, b'A') - - def test_copied(self): - # Issue 4348. Make sure that operations that don't mutate the array - # copy the bytes. - b = bytearray(b'abc') - self.assertIsNot(b, b.replace(b'abc', b'cde', 0)) - - t = bytearray([i for i in range(256)]) - x = bytearray(b'') - self.assertIsNot(x, x.translate(t)) - - def test_partition_bytearray_doesnt_share_nullstring(self): - a, b, c = bytearray(b"x").partition(b"y") - self.assertEqual(b, b"") - self.assertEqual(c, b"") - self.assertIsNot(b, c) - b += b"!" - self.assertEqual(c, b"") - a, b, c = bytearray(b"x").partition(b"y") - self.assertEqual(b, b"") - self.assertEqual(c, b"") - # Same for rpartition - b, c, a = bytearray(b"x").rpartition(b"y") - self.assertEqual(b, b"") - self.assertEqual(c, b"") - self.assertIsNot(b, c) - b += b"!" - self.assertEqual(c, b"") - c, b, a = bytearray(b"x").rpartition(b"y") - self.assertEqual(b, b"") - self.assertEqual(c, b"") - - def test_resize_forbidden(self): - # #4509: can't resize a bytearray when there are buffer exports, even - # if it wouldn't reallocate the underlying buffer. - # Furthermore, no destructive changes to the buffer may be applied - # before raising the error. - b = bytearray(range(10)) - v = memoryview(b) - def resize(n): - b[1:-1] = range(n + 1, 2*n - 1) - resize(10) - orig = b[:] - self.assertRaises(BufferError, resize, 11) - self.assertEqual(b, orig) - self.assertRaises(BufferError, resize, 9) - self.assertEqual(b, orig) - self.assertRaises(BufferError, resize, 0) - self.assertEqual(b, orig) - # Other operations implying resize - self.assertRaises(BufferError, b.pop, 0) - self.assertEqual(b, orig) - self.assertRaises(BufferError, b.remove, b[1]) - self.assertEqual(b, orig) - def delitem(): - del b[1] - self.assertRaises(BufferError, delitem) - self.assertEqual(b, orig) - # deleting a non-contiguous slice - def delslice(): - b[1:-1:2] = b"" - self.assertRaises(BufferError, delslice) - self.assertEqual(b, orig) - - @test.support.cpython_only - def test_obsolete_write_lock(self): - from _testcapi import getbuffer_with_null_view - self.assertRaises(BufferError, getbuffer_with_null_view, bytearray()) - - def test_iterator_pickling2(self): - orig = bytearray(b'abc') - data = list(b'qwerty') - for proto in range(pickle.HIGHEST_PROTOCOL + 1): - # initial iterator - itorig = iter(orig) - d = pickle.dumps((itorig, orig), proto) - it, b = pickle.loads(d) - b[:] = data - self.assertEqual(type(it), type(itorig)) - self.assertEqual(list(it), data) - - # running iterator - next(itorig) - d = pickle.dumps((itorig, orig), proto) - it, b = pickle.loads(d) - b[:] = data - self.assertEqual(type(it), type(itorig)) - self.assertEqual(list(it), data[1:]) - - # empty iterator - for i in range(1, len(orig)): - next(itorig) - d = pickle.dumps((itorig, orig), proto) - it, b = pickle.loads(d) - b[:] = data - self.assertEqual(type(it), type(itorig)) - self.assertEqual(list(it), data[len(orig):]) - - # exhausted iterator - self.assertRaises(StopIteration, next, itorig) - d = pickle.dumps((itorig, orig), proto) - it, b = pickle.loads(d) - b[:] = data - self.assertEqual(list(it), []) - - test_exhausted_iterator = test.list_tests.CommonTest.test_exhausted_iterator - - def test_iterator_length_hint(self): - # Issue 27443: __length_hint__ can return negative integer - ba = bytearray(b'ab') - it = iter(ba) - next(it) - ba.clear() - # Shouldn't raise an error - self.assertEqual(list(it), []) - - def test_repeat_after_setslice(self): - # bpo-42924: * used to copy from the wrong memory location - b = bytearray(b'abc') - b[:2] = b'x' - b1 = b * 1 - b3 = b * 3 - self.assertEqual(b1, b'xc') - self.assertEqual(b1, b) - self.assertEqual(b3, b'xcxcxc') - - - class AssortedBytesTest(unittest.TestCase): - # - # Test various combinations of bytes and bytearray - # - - @check_bytes_warnings - def test_repr_str(self): - for f in str, repr: - self.assertEqual(f(bytearray()), "bytearray(b'')") - self.assertEqual(f(bytearray([0])), "bytearray(b'\\x00')") - self.assertEqual(f(bytearray([0, 1, 254, 255])), - "bytearray(b'\\x00\\x01\\xfe\\xff')") - self.assertEqual(f(b"abc"), "b'abc'") - self.assertEqual(f(b"'"), '''b"'"''') # ''' - self.assertEqual(f(b"'\""), r"""b'\'"'""") # ' - - @check_bytes_warnings - def test_format(self): - for b in b'abc', bytearray(b'abc'): - self.assertEqual(format(b), str(b)) - self.assertEqual(format(b, ''), str(b)) - with self.assertRaisesRegex(TypeError, - r'\b%s\b' % re.escape(type(b).__name__)): - format(b, 's') - - def test_compare_bytes_to_bytearray(self): - self.assertEqual(b"abc" == bytes(b"abc"), True) - self.assertEqual(b"ab" != bytes(b"abc"), True) - self.assertEqual(b"ab" <= bytes(b"abc"), True) - self.assertEqual(b"ab" < bytes(b"abc"), True) - self.assertEqual(b"abc" >= bytes(b"ab"), True) - self.assertEqual(b"abc" > bytes(b"ab"), True) - - self.assertEqual(b"abc" != bytes(b"abc"), False) - self.assertEqual(b"ab" == bytes(b"abc"), False) - self.assertEqual(b"ab" > bytes(b"abc"), False) - self.assertEqual(b"ab" >= bytes(b"abc"), False) - self.assertEqual(b"abc" < bytes(b"ab"), False) - self.assertEqual(b"abc" <= bytes(b"ab"), False) - - self.assertEqual(bytes(b"abc") == b"abc", True) - self.assertEqual(bytes(b"ab") != b"abc", True) - self.assertEqual(bytes(b"ab") <= b"abc", True) - self.assertEqual(bytes(b"ab") < b"abc", True) - self.assertEqual(bytes(b"abc") >= b"ab", True) - self.assertEqual(bytes(b"abc") > b"ab", True) - - self.assertEqual(bytes(b"abc") != b"abc", False) - self.assertEqual(bytes(b"ab") == b"abc", False) - self.assertEqual(bytes(b"ab") > b"abc", False) - self.assertEqual(bytes(b"ab") >= b"abc", False) - self.assertEqual(bytes(b"abc") < b"ab", False) - self.assertEqual(bytes(b"abc") <= b"ab", False) - - @test.support.requires_docstrings - def test_doc(self): - self.assertIsNotNone(bytearray.__doc__) - self.assertTrue(bytearray.__doc__.startswith("bytearray("), bytearray.__doc__) - self.assertIsNotNone(bytes.__doc__) - self.assertTrue(bytes.__doc__.startswith("bytes("), bytes.__doc__) - - def test_from_bytearray(self): - sample = bytes(b"Hello world\n\x80\x81\xfe\xff") - buf = memoryview(sample) - b = bytearray(buf) - self.assertEqual(b, bytearray(sample)) - - @check_bytes_warnings - def test_to_str(self): - self.assertEqual(str(b''), "b''") - self.assertEqual(str(b'x'), "b'x'") - self.assertEqual(str(b'\x80'), "b'\\x80'") - self.assertEqual(str(bytearray(b'')), "bytearray(b'')") - self.assertEqual(str(bytearray(b'x')), "bytearray(b'x')") - self.assertEqual(str(bytearray(b'\x80')), "bytearray(b'\\x80')") - - def test_literal(self): - tests = [ - (b"Wonderful spam", "Wonderful spam"), - (br"Wonderful spam too", "Wonderful spam too"), - (b"\xaa\x00\000\200", "\xaa\x00\000\200"), - (br"\xaa\x00\000\200", r"\xaa\x00\000\200"), - ] - for b, s in tests: - self.assertEqual(b, bytearray(s, 'latin-1')) - for c in range(128, 256): - self.assertRaises(SyntaxError, eval, - 'b"%s"' % chr(c)) - - def test_split_bytearray(self): - self.assertEqual(b'a b'.split(memoryview(b' ')), [b'a', b'b']) - - def test_rsplit_bytearray(self): - self.assertEqual(b'a b'.rsplit(memoryview(b' ')), [b'a', b'b']) - - def test_return_self(self): - # bytearray.replace must always return a new bytearray - b = bytearray() - self.assertIsNot(b.replace(b'', b''), b) - - @unittest.skipUnless(sys.flags.bytes_warning, - "BytesWarning is needed for this test: use -bb option") - def test_compare(self): - def bytes_warning(): - return test.support.check_warnings(('', BytesWarning)) - with bytes_warning(): - b'' == '' - with bytes_warning(): - '' == b'' - with bytes_warning(): - b'' != '' - with bytes_warning(): - '' != b'' - with bytes_warning(): - bytearray(b'') == '' - with bytes_warning(): - '' == bytearray(b'') - with bytes_warning(): - bytearray(b'') != '' - with bytes_warning(): - '' != bytearray(b'') - with bytes_warning(): - b'\0' == 0 - with bytes_warning(): - 0 == b'\0' - with bytes_warning(): - b'\0' != 0 - with bytes_warning(): - 0 != b'\0' - - # Optimizations: - # __iter__? (optimization) - # __reversed__? (optimization) - - # XXX More string methods? (Those that don't use character properties) - - # There are tests in string_tests.py that are more - # comprehensive for things like partition, etc. - # Unfortunately they are all bundled with tests that - # are not appropriate for bytes - - # I've started porting some of those into bytearray_tests.py, we should port - # the rest that make sense (the code can be cleaned up to use modern - # unittest methods at the same time). - - class BytearrayPEP3137Test(unittest.TestCase): - def marshal(self, x): - return bytearray(x) - - def test_returns_new_copy(self): - val = self.marshal(b'1234') - # On immutable types these MAY return a reference to themselves - # but on mutable types like bytearray they MUST return a new copy. - for methname in ('zfill', 'rjust', 'ljust', 'center'): - method = getattr(val, methname) - newval = method(3) - self.assertEqual(val, newval) - self.assertIsNot(val, newval, - methname+' returned self on a mutable object') - for expr in ('val.split()[0]', 'val.rsplit()[0]', - 'val.partition(b".")[0]', 'val.rpartition(b".")[2]', - 'val.splitlines()[0]', 'val.replace(b"", b"")'): - newval = eval(expr) - self.assertEqual(val, newval) - self.assertIsNot(val, newval, - expr+' returned val on a mutable object') - sep = self.marshal(b'') - newval = sep.join([val]) - self.assertEqual(val, newval) - self.assertIsNot(val, newval) - - - class FixedStringTest(test.string_tests.BaseTest): - def fixtype(self, obj): - if isinstance(obj, str): - return self.type2test(obj.encode("utf-8")) - return super().fixtype(obj) - - contains_bytes = True - - class ByteArrayAsStringTest(FixedStringTest, unittest.TestCase): - type2test = bytearray - - class BytesAsStringTest(FixedStringTest, unittest.TestCase): - type2test = bytes - - - class SubclassTest: - - def test_basic(self): - self.assertTrue(issubclass(self.type2test, self.basetype)) - self.assertIsInstance(self.type2test(), self.basetype) - - a, b = b"abcd", b"efgh" - _a, _b = self.type2test(a), self.type2test(b) - - # test comparison operators with subclass instances - self.assertTrue(_a == _a) - self.assertTrue(_a != _b) - self.assertTrue(_a < _b) - self.assertTrue(_a <= _b) - self.assertTrue(_b >= _a) - self.assertTrue(_b > _a) - self.assertIsNot(_a, a) - - # test concat of subclass instances - self.assertEqual(a + b, _a + _b) - self.assertEqual(a + b, a + _b) - self.assertEqual(a + b, _a + b) - - # test repeat - self.assertTrue(a*5 == _a*5) - - def test_join(self): - # Make sure join returns a NEW object for single item sequences - # involving a subclass. - # Make sure that it is of the appropriate type. - s1 = self.type2test(b"abcd") - s2 = self.basetype().join([s1]) - self.assertIsNot(s1, s2) - self.assertIs(type(s2), self.basetype, type(s2)) - - # Test reverse, calling join on subclass - s3 = s1.join([b"abcd"]) - self.assertIs(type(s3), self.basetype) - - def test_pickle(self): - a = self.type2test(b"abcd") - a.x = 10 - a.y = self.type2test(b"efgh") - for proto in range(pickle.HIGHEST_PROTOCOL + 1): - b = pickle.loads(pickle.dumps(a, proto)) - self.assertNotEqual(id(a), id(b)) - self.assertEqual(a, b) - self.assertEqual(a.x, b.x) - self.assertEqual(a.y, b.y) - self.assertEqual(type(a), type(b)) - self.assertEqual(type(a.y), type(b.y)) - - def test_copy(self): - a = self.type2test(b"abcd") - a.x = 10 - a.y = self.type2test(b"efgh") - for copy_method in (copy.copy, copy.deepcopy): - b = copy_method(a) - self.assertNotEqual(id(a), id(b)) - self.assertEqual(a, b) - self.assertEqual(a.x, b.x) - self.assertEqual(a.y, b.y) - self.assertEqual(type(a), type(b)) - self.assertEqual(type(a.y), type(b.y)) - - def test_fromhex(self): - b = self.type2test.fromhex('1a2B30') - self.assertEqual(b, b'\x1a\x2b\x30') - self.assertIs(type(b), self.type2test) - - class B1(self.basetype): - def __new__(cls, value): - me = self.basetype.__new__(cls, value) - me.foo = 'bar' - return me - - b = B1.fromhex('1a2B30') - self.assertEqual(b, b'\x1a\x2b\x30') - self.assertIs(type(b), B1) - self.assertEqual(b.foo, 'bar') - - class B2(self.basetype): - def __init__(me, *args, **kwargs): - if self.basetype is not bytes: - self.basetype.__init__(me, *args, **kwargs) - me.foo = 'bar' - - b = B2.fromhex('1a2B30') - self.assertEqual(b, b'\x1a\x2b\x30') - self.assertIs(type(b), B2) - self.assertEqual(b.foo, 'bar') - - - class ByteArraySubclass(bytearray): - pass - - class BytesSubclass(bytes): - pass - - class OtherBytesSubclass(bytes): - pass - - class ByteArraySubclassTest(SubclassTest, unittest.TestCase): - basetype = bytearray - type2test = ByteArraySubclass - - def test_init_override(self): - class subclass(bytearray): - def __init__(me, newarg=1, *args, **kwargs): - bytearray.__init__(me, *args, **kwargs) - x = subclass(4, b"abcd") - x = subclass(4, source=b"abcd") - self.assertEqual(x, b"abcd") - x = subclass(newarg=4, source=b"abcd") - self.assertEqual(x, b"abcd") - - - class BytesSubclassTest(SubclassTest, unittest.TestCase): - basetype = bytes - type2test = BytesSubclass - - - if __name__ == "__main__": - unittest.main() diff --git a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_c_locale_coercion.yaml b/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_c_locale_coercion.yaml deleted file mode 100644 index 78a89d0d8..000000000 --- a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_c_locale_coercion.yaml +++ /dev/null @@ -1,435 +0,0 @@ -python: | - # Tests the attempted automatic coercion of the C locale to a UTF-8 locale - - import locale - import os - import subprocess - import sys - import sysconfig - import unittest - from collections import namedtuple - - from test import support - from test.support.script_helper import run_python_until_end - - - # Set the list of ways we expect to be able to ask for the "C" locale - EXPECTED_C_LOCALE_EQUIVALENTS = ["C", "invalid.ascii"] - - # Set our expectation for the default encoding used in the C locale - # for the filesystem encoding and the standard streams - EXPECTED_C_LOCALE_STREAM_ENCODING = "ascii" - EXPECTED_C_LOCALE_FS_ENCODING = "ascii" - - # Set our expectation for the default locale used when none is specified - EXPECT_COERCION_IN_DEFAULT_LOCALE = True - - TARGET_LOCALES = ["C.UTF-8", "C.utf8", "UTF-8"] - - # Apply some platform dependent overrides - if sys.platform.startswith("linux"): - if support.is_android: - # Android defaults to using UTF-8 for all system interfaces - EXPECTED_C_LOCALE_STREAM_ENCODING = "utf-8" - EXPECTED_C_LOCALE_FS_ENCODING = "utf-8" - else: - # Linux distros typically alias the POSIX locale directly to the C - # locale. - # TODO: Once https://bugs.python.org/issue30672 is addressed, we'll be - # able to check this case unconditionally - EXPECTED_C_LOCALE_EQUIVALENTS.append("POSIX") - elif sys.platform.startswith("aix"): - # AIX uses iso8859-1 in the C locale, other *nix platforms use ASCII - EXPECTED_C_LOCALE_STREAM_ENCODING = "iso8859-1" - EXPECTED_C_LOCALE_FS_ENCODING = "iso8859-1" - elif sys.platform == "darwin": - # FS encoding is UTF-8 on macOS - EXPECTED_C_LOCALE_FS_ENCODING = "utf-8" - elif sys.platform == "cygwin": - # Cygwin defaults to using C.UTF-8 - # TODO: Work out a robust dynamic test for this that doesn't rely on - # CPython's own locale handling machinery - EXPECT_COERCION_IN_DEFAULT_LOCALE = False - - # Note that the above expectations are still wrong in some cases, such as: - # * Windows when PYTHONLEGACYWINDOWSFSENCODING is set - # * Any platform other than AIX that uses latin-1 in the C locale - # * Any Linux distro where POSIX isn't a simple alias for the C locale - # * Any Linux distro where the default locale is something other than "C" - # - # Options for dealing with this: - # * Don't set the PY_COERCE_C_LOCALE preprocessor definition on - # such platforms (e.g. it isn't set on Windows) - # * Fix the test expectations to match the actual platform behaviour - - # In order to get the warning messages to match up as expected, the candidate - # order here must much the target locale order in Python/pylifecycle.c - _C_UTF8_LOCALES = ("C.UTF-8", "C.utf8", "UTF-8") - - # There's no reliable cross-platform way of checking locale alias - # lists, so the only way of knowing which of these locales will work - # is to try them with locale.setlocale(). We do that in a subprocess - # in setUpModule() below to avoid altering the locale of the test runner. - # - # If the relevant locale module attributes exist, and we're not on a platform - # where we expect it to always succeed, we also check that - # `locale.nl_langinfo(locale.CODESET)` works, as if it fails, the interpreter - # will skip locale coercion for that particular target locale - _check_nl_langinfo_CODESET = bool( - sys.platform not in ("darwin", "linux") and - hasattr(locale, "nl_langinfo") and - hasattr(locale, "CODESET") - ) - - def _set_locale_in_subprocess(locale_name): - cmd_fmt = "import locale; print(locale.setlocale(locale.LC_CTYPE, '{}'))" - if _check_nl_langinfo_CODESET: - # If there's no valid CODESET, we expect coercion to be skipped - cmd_fmt += "; import sys; sys.exit(not locale.nl_langinfo(locale.CODESET))" - cmd = cmd_fmt.format(locale_name) - result, py_cmd = run_python_until_end("-c", cmd, PYTHONCOERCECLOCALE='') - return result.rc == 0 - - - - _fields = "fsencoding stdin_info stdout_info stderr_info lang lc_ctype lc_all" - _EncodingDetails = namedtuple("EncodingDetails", _fields) - - class EncodingDetails(_EncodingDetails): - # XXX (ncoghlan): Using JSON for child state reporting may be less fragile - CHILD_PROCESS_SCRIPT = ";".join([ - "import sys, os", - "print(sys.getfilesystemencoding())", - "print(sys.stdin.encoding + ':' + sys.stdin.errors)", - "print(sys.stdout.encoding + ':' + sys.stdout.errors)", - "print(sys.stderr.encoding + ':' + sys.stderr.errors)", - "print(os.environ.get('LANG', 'not set'))", - "print(os.environ.get('LC_CTYPE', 'not set'))", - "print(os.environ.get('LC_ALL', 'not set'))", - ]) - - @classmethod - def get_expected_details(cls, coercion_expected, fs_encoding, stream_encoding, env_vars): - """Returns expected child process details for a given encoding""" - _stream = stream_encoding + ":{}" - # stdin and stdout should use surrogateescape either because the - # coercion triggered, or because the C locale was detected - stream_info = 2*[_stream.format("surrogateescape")] - # stderr should always use backslashreplace - stream_info.append(_stream.format("backslashreplace")) - expected_lang = env_vars.get("LANG", "not set") - if coercion_expected: - expected_lc_ctype = CLI_COERCION_TARGET - else: - expected_lc_ctype = env_vars.get("LC_CTYPE", "not set") - expected_lc_all = env_vars.get("LC_ALL", "not set") - env_info = expected_lang, expected_lc_ctype, expected_lc_all - return dict(cls(fs_encoding, *stream_info, *env_info)._asdict()) - - @classmethod - def get_child_details(cls, env_vars): - """Retrieves fsencoding and standard stream details from a child process - - Returns (encoding_details, stderr_lines): - - - encoding_details: EncodingDetails for eager decoding - - stderr_lines: result of calling splitlines() on the stderr output - - The child is run in isolated mode if the current interpreter supports - that. - """ - result, py_cmd = run_python_until_end( - "-X", "utf8=0", "-c", cls.CHILD_PROCESS_SCRIPT, - **env_vars - ) - if not result.rc == 0: - result.fail(py_cmd) - # All subprocess outputs in this test case should be pure ASCII - stdout_lines = result.out.decode("ascii").splitlines() - child_encoding_details = dict(cls(*stdout_lines)._asdict()) - stderr_lines = result.err.decode("ascii").rstrip().splitlines() - return child_encoding_details, stderr_lines - - - # Details of the shared library warning emitted at runtime - LEGACY_LOCALE_WARNING = ( - "Python runtime initialized with LC_CTYPE=C (a locale with default ASCII " - "encoding), which may cause Unicode compatibility problems. Using C.UTF-8, " - "C.utf8, or UTF-8 (if available) as alternative Unicode-compatible " - "locales is recommended." - ) - - # Details of the CLI locale coercion warning emitted at runtime - CLI_COERCION_WARNING_FMT = ( - "Python detected LC_CTYPE=C: LC_CTYPE coerced to {} (set another locale " - "or PYTHONCOERCECLOCALE=0 to disable this locale coercion behavior)." - ) - - - AVAILABLE_TARGETS = None - CLI_COERCION_TARGET = None - CLI_COERCION_WARNING = None - - def setUpModule(): - global AVAILABLE_TARGETS - global CLI_COERCION_TARGET - global CLI_COERCION_WARNING - - if AVAILABLE_TARGETS is not None: - # initialization already done - return - AVAILABLE_TARGETS = [] - - # Find the target locales available in the current system - for target_locale in _C_UTF8_LOCALES: - if _set_locale_in_subprocess(target_locale): - AVAILABLE_TARGETS.append(target_locale) - - if AVAILABLE_TARGETS: - # Coercion is expected to use the first available target locale - CLI_COERCION_TARGET = AVAILABLE_TARGETS[0] - CLI_COERCION_WARNING = CLI_COERCION_WARNING_FMT.format(CLI_COERCION_TARGET) - - if support.verbose: - print(f"AVAILABLE_TARGETS = {AVAILABLE_TARGETS!r}") - print(f"EXPECTED_C_LOCALE_EQUIVALENTS = {EXPECTED_C_LOCALE_EQUIVALENTS!r}") - print(f"EXPECTED_C_LOCALE_STREAM_ENCODING = {EXPECTED_C_LOCALE_STREAM_ENCODING!r}") - print(f"EXPECTED_C_LOCALE_FS_ENCODING = {EXPECTED_C_LOCALE_FS_ENCODING!r}") - print(f"EXPECT_COERCION_IN_DEFAULT_LOCALE = {EXPECT_COERCION_IN_DEFAULT_LOCALE!r}") - print(f"_C_UTF8_LOCALES = {_C_UTF8_LOCALES!r}") - print(f"_check_nl_langinfo_CODESET = {_check_nl_langinfo_CODESET!r}") - - - class _LocaleHandlingTestCase(unittest.TestCase): - # Base class to check expected locale handling behaviour - - def _check_child_encoding_details(self, - env_vars, - expected_fs_encoding, - expected_stream_encoding, - expected_warnings, - coercion_expected): - """Check the C locale handling for the given process environment - - Parameters: - expected_fs_encoding: expected sys.getfilesystemencoding() result - expected_stream_encoding: expected encoding for standard streams - expected_warning: stderr output to expect (if any) - """ - result = EncodingDetails.get_child_details(env_vars) - encoding_details, stderr_lines = result - expected_details = EncodingDetails.get_expected_details( - coercion_expected, - expected_fs_encoding, - expected_stream_encoding, - env_vars - ) - self.assertEqual(encoding_details, expected_details) - if expected_warnings is None: - expected_warnings = [] - self.assertEqual(stderr_lines, expected_warnings) - - - class LocaleConfigurationTests(_LocaleHandlingTestCase): - # Test explicit external configuration via the process environment - - @classmethod - def setUpClass(cls): - # This relies on setUpModule() having been run, so it can't be - # handled via the @unittest.skipUnless decorator - if not AVAILABLE_TARGETS: - raise unittest.SkipTest("No C-with-UTF-8 locale available") - - def test_external_target_locale_configuration(self): - - # Explicitly setting a target locale should give the same behaviour as - # is seen when implicitly coercing to that target locale - self.maxDiff = None - - expected_fs_encoding = "utf-8" - expected_stream_encoding = "utf-8" - - base_var_dict = { - "LANG": "", - "LC_CTYPE": "", - "LC_ALL": "", - "PYTHONCOERCECLOCALE": "", - } - for env_var in ("LANG", "LC_CTYPE"): - for locale_to_set in AVAILABLE_TARGETS: - # XXX (ncoghlan): LANG=UTF-8 doesn't appear to work as - # expected, so skip that combination for now - # See https://bugs.python.org/issue30672 for discussion - if env_var == "LANG" and locale_to_set == "UTF-8": - continue - - with self.subTest(env_var=env_var, - configured_locale=locale_to_set): - var_dict = base_var_dict.copy() - var_dict[env_var] = locale_to_set - self._check_child_encoding_details(var_dict, - expected_fs_encoding, - expected_stream_encoding, - expected_warnings=None, - coercion_expected=False) - - - - @support.cpython_only - @unittest.skipUnless(sysconfig.get_config_var("PY_COERCE_C_LOCALE"), - "C locale coercion disabled at build time") - class LocaleCoercionTests(_LocaleHandlingTestCase): - # Test implicit reconfiguration of the environment during CLI startup - - def _check_c_locale_coercion(self, - fs_encoding, stream_encoding, - coerce_c_locale, - expected_warnings=None, - coercion_expected=True, - **extra_vars): - """Check the C locale handling for various configurations - - Parameters: - fs_encoding: expected sys.getfilesystemencoding() result - stream_encoding: expected encoding for standard streams - coerce_c_locale: setting to use for PYTHONCOERCECLOCALE - None: don't set the variable at all - str: the value set in the child's environment - expected_warnings: expected warning lines on stderr - extra_vars: additional environment variables to set in subprocess - """ - self.maxDiff = None - - if not AVAILABLE_TARGETS: - # Locale coercion is disabled when there aren't any target locales - fs_encoding = EXPECTED_C_LOCALE_FS_ENCODING - stream_encoding = EXPECTED_C_LOCALE_STREAM_ENCODING - coercion_expected = False - if expected_warnings: - expected_warnings = [LEGACY_LOCALE_WARNING] - - base_var_dict = { - "LANG": "", - "LC_CTYPE": "", - "LC_ALL": "", - "PYTHONCOERCECLOCALE": "", - } - base_var_dict.update(extra_vars) - if coerce_c_locale is not None: - base_var_dict["PYTHONCOERCECLOCALE"] = coerce_c_locale - - # Check behaviour for the default locale - with self.subTest(default_locale=True, - PYTHONCOERCECLOCALE=coerce_c_locale): - if EXPECT_COERCION_IN_DEFAULT_LOCALE: - _expected_warnings = expected_warnings - _coercion_expected = coercion_expected - else: - _expected_warnings = None - _coercion_expected = False - # On Android CLI_COERCION_WARNING is not printed when all the - # locale environment variables are undefined or empty. When - # this code path is run with environ['LC_ALL'] == 'C', then - # LEGACY_LOCALE_WARNING is printed. - if (support.is_android and - _expected_warnings == [CLI_COERCION_WARNING]): - _expected_warnings = None - self._check_child_encoding_details(base_var_dict, - fs_encoding, - stream_encoding, - _expected_warnings, - _coercion_expected) - - # Check behaviour for explicitly configured locales - for locale_to_set in EXPECTED_C_LOCALE_EQUIVALENTS: - for env_var in ("LANG", "LC_CTYPE"): - with self.subTest(env_var=env_var, - nominal_locale=locale_to_set, - PYTHONCOERCECLOCALE=coerce_c_locale): - var_dict = base_var_dict.copy() - var_dict[env_var] = locale_to_set - # Check behaviour on successful coercion - self._check_child_encoding_details(var_dict, - fs_encoding, - stream_encoding, - expected_warnings, - coercion_expected) - - def test_PYTHONCOERCECLOCALE_not_set(self): - # This should coerce to the first available target locale by default - self._check_c_locale_coercion("utf-8", "utf-8", coerce_c_locale=None) - - def test_PYTHONCOERCECLOCALE_not_zero(self): - # *Any* string other than "0" is considered "set" for our purposes - # and hence should result in the locale coercion being enabled - for setting in ("", "1", "true", "false"): - self._check_c_locale_coercion("utf-8", "utf-8", coerce_c_locale=setting) - - def test_PYTHONCOERCECLOCALE_set_to_warn(self): - # PYTHONCOERCECLOCALE=warn enables runtime warnings for legacy locales - self._check_c_locale_coercion("utf-8", "utf-8", - coerce_c_locale="warn", - expected_warnings=[CLI_COERCION_WARNING]) - - - def test_PYTHONCOERCECLOCALE_set_to_zero(self): - # The setting "0" should result in the locale coercion being disabled - self._check_c_locale_coercion(EXPECTED_C_LOCALE_FS_ENCODING, - EXPECTED_C_LOCALE_STREAM_ENCODING, - coerce_c_locale="0", - coercion_expected=False) - # Setting LC_ALL=C shouldn't make any difference to the behaviour - self._check_c_locale_coercion(EXPECTED_C_LOCALE_FS_ENCODING, - EXPECTED_C_LOCALE_STREAM_ENCODING, - coerce_c_locale="0", - LC_ALL="C", - coercion_expected=False) - - def test_LC_ALL_set_to_C(self): - # Setting LC_ALL should render the locale coercion ineffective - self._check_c_locale_coercion(EXPECTED_C_LOCALE_FS_ENCODING, - EXPECTED_C_LOCALE_STREAM_ENCODING, - coerce_c_locale=None, - LC_ALL="C", - coercion_expected=False) - # And result in a warning about a lack of locale compatibility - self._check_c_locale_coercion(EXPECTED_C_LOCALE_FS_ENCODING, - EXPECTED_C_LOCALE_STREAM_ENCODING, - coerce_c_locale="warn", - LC_ALL="C", - expected_warnings=[LEGACY_LOCALE_WARNING], - coercion_expected=False) - - def test_PYTHONCOERCECLOCALE_set_to_one(self): - # skip the test if the LC_CTYPE locale is C or coerced - old_loc = locale.setlocale(locale.LC_CTYPE, None) - self.addCleanup(locale.setlocale, locale.LC_CTYPE, old_loc) - try: - loc = locale.setlocale(locale.LC_CTYPE, "") - except locale.Error as e: - self.skipTest(str(e)) - if loc == "C": - self.skipTest("test requires LC_CTYPE locale different than C") - if loc in TARGET_LOCALES : - self.skipTest("coerced LC_CTYPE locale: %s" % loc) - - # bpo-35336: PYTHONCOERCECLOCALE=1 must not coerce the LC_CTYPE locale - # if it's not equal to "C" - code = 'import locale; print(locale.setlocale(locale.LC_CTYPE, None))' - env = dict(os.environ, PYTHONCOERCECLOCALE='1') - cmd = subprocess.run([sys.executable, '-c', code], - stdout=subprocess.PIPE, - env=env, - text=True) - self.assertEqual(cmd.stdout.rstrip(), loc) - - - def test_main(): - support.run_unittest( - LocaleConfigurationTests, - LocaleCoercionTests - ) - support.reap_children() - - if __name__ == "__main__": - test_main() diff --git a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_calendar.yaml b/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_calendar.yaml deleted file mode 100644 index 0a739f9cf..000000000 --- a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_calendar.yaml +++ /dev/null @@ -1,965 +0,0 @@ -python: | - import calendar - import unittest - - from test import support - from test.support.script_helper import assert_python_ok, assert_python_failure - import time - import locale - import sys - import datetime - import os - - # From https://en.wikipedia.org/wiki/Leap_year_starting_on_Saturday - result_0_02_text = """\ - February 0 - Mo Tu We Th Fr Sa Su - 1 2 3 4 5 6 - 7 8 9 10 11 12 13 - 14 15 16 17 18 19 20 - 21 22 23 24 25 26 27 - 28 29 - """ - - result_0_text = """\ - 0 - - January February March - Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su - 1 2 1 2 3 4 5 6 1 2 3 4 5 - 3 4 5 6 7 8 9 7 8 9 10 11 12 13 6 7 8 9 10 11 12 - 10 11 12 13 14 15 16 14 15 16 17 18 19 20 13 14 15 16 17 18 19 - 17 18 19 20 21 22 23 21 22 23 24 25 26 27 20 21 22 23 24 25 26 - 24 25 26 27 28 29 30 28 29 27 28 29 30 31 - 31 - - April May June - Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su - 1 2 1 2 3 4 5 6 7 1 2 3 4 - 3 4 5 6 7 8 9 8 9 10 11 12 13 14 5 6 7 8 9 10 11 - 10 11 12 13 14 15 16 15 16 17 18 19 20 21 12 13 14 15 16 17 18 - 17 18 19 20 21 22 23 22 23 24 25 26 27 28 19 20 21 22 23 24 25 - 24 25 26 27 28 29 30 29 30 31 26 27 28 29 30 - - July August September - Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su - 1 2 1 2 3 4 5 6 1 2 3 - 3 4 5 6 7 8 9 7 8 9 10 11 12 13 4 5 6 7 8 9 10 - 10 11 12 13 14 15 16 14 15 16 17 18 19 20 11 12 13 14 15 16 17 - 17 18 19 20 21 22 23 21 22 23 24 25 26 27 18 19 20 21 22 23 24 - 24 25 26 27 28 29 30 28 29 30 31 25 26 27 28 29 30 - 31 - - October November December - Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su - 1 1 2 3 4 5 1 2 3 - 2 3 4 5 6 7 8 6 7 8 9 10 11 12 4 5 6 7 8 9 10 - 9 10 11 12 13 14 15 13 14 15 16 17 18 19 11 12 13 14 15 16 17 - 16 17 18 19 20 21 22 20 21 22 23 24 25 26 18 19 20 21 22 23 24 - 23 24 25 26 27 28 29 27 28 29 30 25 26 27 28 29 30 31 - 30 31 - """ - - result_2004_01_text = """\ - January 2004 - Mo Tu We Th Fr Sa Su - 1 2 3 4 - 5 6 7 8 9 10 11 - 12 13 14 15 16 17 18 - 19 20 21 22 23 24 25 - 26 27 28 29 30 31 - """ - - result_2004_text = """\ - 2004 - - January February March - Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su - 1 2 3 4 1 1 2 3 4 5 6 7 - 5 6 7 8 9 10 11 2 3 4 5 6 7 8 8 9 10 11 12 13 14 - 12 13 14 15 16 17 18 9 10 11 12 13 14 15 15 16 17 18 19 20 21 - 19 20 21 22 23 24 25 16 17 18 19 20 21 22 22 23 24 25 26 27 28 - 26 27 28 29 30 31 23 24 25 26 27 28 29 29 30 31 - - April May June - Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su - 1 2 3 4 1 2 1 2 3 4 5 6 - 5 6 7 8 9 10 11 3 4 5 6 7 8 9 7 8 9 10 11 12 13 - 12 13 14 15 16 17 18 10 11 12 13 14 15 16 14 15 16 17 18 19 20 - 19 20 21 22 23 24 25 17 18 19 20 21 22 23 21 22 23 24 25 26 27 - 26 27 28 29 30 24 25 26 27 28 29 30 28 29 30 - 31 - - July August September - Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su - 1 2 3 4 1 1 2 3 4 5 - 5 6 7 8 9 10 11 2 3 4 5 6 7 8 6 7 8 9 10 11 12 - 12 13 14 15 16 17 18 9 10 11 12 13 14 15 13 14 15 16 17 18 19 - 19 20 21 22 23 24 25 16 17 18 19 20 21 22 20 21 22 23 24 25 26 - 26 27 28 29 30 31 23 24 25 26 27 28 29 27 28 29 30 - 30 31 - - October November December - Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su - 1 2 3 1 2 3 4 5 6 7 1 2 3 4 5 - 4 5 6 7 8 9 10 8 9 10 11 12 13 14 6 7 8 9 10 11 12 - 11 12 13 14 15 16 17 15 16 17 18 19 20 21 13 14 15 16 17 18 19 - 18 19 20 21 22 23 24 22 23 24 25 26 27 28 20 21 22 23 24 25 26 - 25 26 27 28 29 30 31 29 30 27 28 29 30 31 - """ - - - default_format = dict(year="year", month="month", encoding="ascii") - - result_2004_html = """\ - - - - - - - Calendar for 2004 - - - -
2004
- - - - - - - -
January
MonTueWedThuFriSatSun
   1234
567891011
12131415161718
19202122232425
262728293031 
-
- - - - - - - -
February
MonTueWedThuFriSatSun
      1
2345678
9101112131415
16171819202122
23242526272829
-
- - - - - - - -
March
MonTueWedThuFriSatSun
1234567
891011121314
15161718192021
22232425262728
293031    
-
- - - - - - - -
April
MonTueWedThuFriSatSun
   1234
567891011
12131415161718
19202122232425
2627282930  
-
- - - - - - - - -
May
MonTueWedThuFriSatSun
     12
3456789
10111213141516
17181920212223
24252627282930
31      
-
- - - - - - - -
June
MonTueWedThuFriSatSun
 123456
78910111213
14151617181920
21222324252627
282930    
-
- - - - - - - -
July
MonTueWedThuFriSatSun
   1234
567891011
12131415161718
19202122232425
262728293031 
-
- - - - - - - - -
August
MonTueWedThuFriSatSun
      1
2345678
9101112131415
16171819202122
23242526272829
3031     
-
- - - - - - - -
September
MonTueWedThuFriSatSun
  12345
6789101112
13141516171819
20212223242526
27282930   
-
- - - - - - - -
October
MonTueWedThuFriSatSun
    123
45678910
11121314151617
18192021222324
25262728293031
-
- - - - - - - -
November
MonTueWedThuFriSatSun
1234567
891011121314
15161718192021
22232425262728
2930     
-
- - - - - - - -
December
MonTueWedThuFriSatSun
  12345
6789101112
13141516171819
20212223242526
2728293031  
-
- - """ - - result_2004_days = [ - [[[0, 0, 0, 1, 2, 3, 4], - [5, 6, 7, 8, 9, 10, 11], - [12, 13, 14, 15, 16, 17, 18], - [19, 20, 21, 22, 23, 24, 25], - [26, 27, 28, 29, 30, 31, 0]], - [[0, 0, 0, 0, 0, 0, 1], - [2, 3, 4, 5, 6, 7, 8], - [9, 10, 11, 12, 13, 14, 15], - [16, 17, 18, 19, 20, 21, 22], - [23, 24, 25, 26, 27, 28, 29]], - [[1, 2, 3, 4, 5, 6, 7], - [8, 9, 10, 11, 12, 13, 14], - [15, 16, 17, 18, 19, 20, 21], - [22, 23, 24, 25, 26, 27, 28], - [29, 30, 31, 0, 0, 0, 0]]], - [[[0, 0, 0, 1, 2, 3, 4], - [5, 6, 7, 8, 9, 10, 11], - [12, 13, 14, 15, 16, 17, 18], - [19, 20, 21, 22, 23, 24, 25], - [26, 27, 28, 29, 30, 0, 0]], - [[0, 0, 0, 0, 0, 1, 2], - [3, 4, 5, 6, 7, 8, 9], - [10, 11, 12, 13, 14, 15, 16], - [17, 18, 19, 20, 21, 22, 23], - [24, 25, 26, 27, 28, 29, 30], - [31, 0, 0, 0, 0, 0, 0]], - [[0, 1, 2, 3, 4, 5, 6], - [7, 8, 9, 10, 11, 12, 13], - [14, 15, 16, 17, 18, 19, 20], - [21, 22, 23, 24, 25, 26, 27], - [28, 29, 30, 0, 0, 0, 0]]], - [[[0, 0, 0, 1, 2, 3, 4], - [5, 6, 7, 8, 9, 10, 11], - [12, 13, 14, 15, 16, 17, 18], - [19, 20, 21, 22, 23, 24, 25], - [26, 27, 28, 29, 30, 31, 0]], - [[0, 0, 0, 0, 0, 0, 1], - [2, 3, 4, 5, 6, 7, 8], - [9, 10, 11, 12, 13, 14, 15], - [16, 17, 18, 19, 20, 21, 22], - [23, 24, 25, 26, 27, 28, 29], - [30, 31, 0, 0, 0, 0, 0]], - [[0, 0, 1, 2, 3, 4, 5], - [6, 7, 8, 9, 10, 11, 12], - [13, 14, 15, 16, 17, 18, 19], - [20, 21, 22, 23, 24, 25, 26], - [27, 28, 29, 30, 0, 0, 0]]], - [[[0, 0, 0, 0, 1, 2, 3], - [4, 5, 6, 7, 8, 9, 10], - [11, 12, 13, 14, 15, 16, 17], - [18, 19, 20, 21, 22, 23, 24], - [25, 26, 27, 28, 29, 30, 31]], - [[1, 2, 3, 4, 5, 6, 7], - [8, 9, 10, 11, 12, 13, 14], - [15, 16, 17, 18, 19, 20, 21], - [22, 23, 24, 25, 26, 27, 28], - [29, 30, 0, 0, 0, 0, 0]], - [[0, 0, 1, 2, 3, 4, 5], - [6, 7, 8, 9, 10, 11, 12], - [13, 14, 15, 16, 17, 18, 19], - [20, 21, 22, 23, 24, 25, 26], - [27, 28, 29, 30, 31, 0, 0]]] - ] - - result_2004_dates = \ - [[['12/29/03 12/30/03 12/31/03 01/01/04 01/02/04 01/03/04 01/04/04', - '01/05/04 01/06/04 01/07/04 01/08/04 01/09/04 01/10/04 01/11/04', - '01/12/04 01/13/04 01/14/04 01/15/04 01/16/04 01/17/04 01/18/04', - '01/19/04 01/20/04 01/21/04 01/22/04 01/23/04 01/24/04 01/25/04', - '01/26/04 01/27/04 01/28/04 01/29/04 01/30/04 01/31/04 02/01/04'], - ['01/26/04 01/27/04 01/28/04 01/29/04 01/30/04 01/31/04 02/01/04', - '02/02/04 02/03/04 02/04/04 02/05/04 02/06/04 02/07/04 02/08/04', - '02/09/04 02/10/04 02/11/04 02/12/04 02/13/04 02/14/04 02/15/04', - '02/16/04 02/17/04 02/18/04 02/19/04 02/20/04 02/21/04 02/22/04', - '02/23/04 02/24/04 02/25/04 02/26/04 02/27/04 02/28/04 02/29/04'], - ['03/01/04 03/02/04 03/03/04 03/04/04 03/05/04 03/06/04 03/07/04', - '03/08/04 03/09/04 03/10/04 03/11/04 03/12/04 03/13/04 03/14/04', - '03/15/04 03/16/04 03/17/04 03/18/04 03/19/04 03/20/04 03/21/04', - '03/22/04 03/23/04 03/24/04 03/25/04 03/26/04 03/27/04 03/28/04', - '03/29/04 03/30/04 03/31/04 04/01/04 04/02/04 04/03/04 04/04/04']], - [['03/29/04 03/30/04 03/31/04 04/01/04 04/02/04 04/03/04 04/04/04', - '04/05/04 04/06/04 04/07/04 04/08/04 04/09/04 04/10/04 04/11/04', - '04/12/04 04/13/04 04/14/04 04/15/04 04/16/04 04/17/04 04/18/04', - '04/19/04 04/20/04 04/21/04 04/22/04 04/23/04 04/24/04 04/25/04', - '04/26/04 04/27/04 04/28/04 04/29/04 04/30/04 05/01/04 05/02/04'], - ['04/26/04 04/27/04 04/28/04 04/29/04 04/30/04 05/01/04 05/02/04', - '05/03/04 05/04/04 05/05/04 05/06/04 05/07/04 05/08/04 05/09/04', - '05/10/04 05/11/04 05/12/04 05/13/04 05/14/04 05/15/04 05/16/04', - '05/17/04 05/18/04 05/19/04 05/20/04 05/21/04 05/22/04 05/23/04', - '05/24/04 05/25/04 05/26/04 05/27/04 05/28/04 05/29/04 05/30/04', - '05/31/04 06/01/04 06/02/04 06/03/04 06/04/04 06/05/04 06/06/04'], - ['05/31/04 06/01/04 06/02/04 06/03/04 06/04/04 06/05/04 06/06/04', - '06/07/04 06/08/04 06/09/04 06/10/04 06/11/04 06/12/04 06/13/04', - '06/14/04 06/15/04 06/16/04 06/17/04 06/18/04 06/19/04 06/20/04', - '06/21/04 06/22/04 06/23/04 06/24/04 06/25/04 06/26/04 06/27/04', - '06/28/04 06/29/04 06/30/04 07/01/04 07/02/04 07/03/04 07/04/04']], - [['06/28/04 06/29/04 06/30/04 07/01/04 07/02/04 07/03/04 07/04/04', - '07/05/04 07/06/04 07/07/04 07/08/04 07/09/04 07/10/04 07/11/04', - '07/12/04 07/13/04 07/14/04 07/15/04 07/16/04 07/17/04 07/18/04', - '07/19/04 07/20/04 07/21/04 07/22/04 07/23/04 07/24/04 07/25/04', - '07/26/04 07/27/04 07/28/04 07/29/04 07/30/04 07/31/04 08/01/04'], - ['07/26/04 07/27/04 07/28/04 07/29/04 07/30/04 07/31/04 08/01/04', - '08/02/04 08/03/04 08/04/04 08/05/04 08/06/04 08/07/04 08/08/04', - '08/09/04 08/10/04 08/11/04 08/12/04 08/13/04 08/14/04 08/15/04', - '08/16/04 08/17/04 08/18/04 08/19/04 08/20/04 08/21/04 08/22/04', - '08/23/04 08/24/04 08/25/04 08/26/04 08/27/04 08/28/04 08/29/04', - '08/30/04 08/31/04 09/01/04 09/02/04 09/03/04 09/04/04 09/05/04'], - ['08/30/04 08/31/04 09/01/04 09/02/04 09/03/04 09/04/04 09/05/04', - '09/06/04 09/07/04 09/08/04 09/09/04 09/10/04 09/11/04 09/12/04', - '09/13/04 09/14/04 09/15/04 09/16/04 09/17/04 09/18/04 09/19/04', - '09/20/04 09/21/04 09/22/04 09/23/04 09/24/04 09/25/04 09/26/04', - '09/27/04 09/28/04 09/29/04 09/30/04 10/01/04 10/02/04 10/03/04']], - [['09/27/04 09/28/04 09/29/04 09/30/04 10/01/04 10/02/04 10/03/04', - '10/04/04 10/05/04 10/06/04 10/07/04 10/08/04 10/09/04 10/10/04', - '10/11/04 10/12/04 10/13/04 10/14/04 10/15/04 10/16/04 10/17/04', - '10/18/04 10/19/04 10/20/04 10/21/04 10/22/04 10/23/04 10/24/04', - '10/25/04 10/26/04 10/27/04 10/28/04 10/29/04 10/30/04 10/31/04'], - ['11/01/04 11/02/04 11/03/04 11/04/04 11/05/04 11/06/04 11/07/04', - '11/08/04 11/09/04 11/10/04 11/11/04 11/12/04 11/13/04 11/14/04', - '11/15/04 11/16/04 11/17/04 11/18/04 11/19/04 11/20/04 11/21/04', - '11/22/04 11/23/04 11/24/04 11/25/04 11/26/04 11/27/04 11/28/04', - '11/29/04 11/30/04 12/01/04 12/02/04 12/03/04 12/04/04 12/05/04'], - ['11/29/04 11/30/04 12/01/04 12/02/04 12/03/04 12/04/04 12/05/04', - '12/06/04 12/07/04 12/08/04 12/09/04 12/10/04 12/11/04 12/12/04', - '12/13/04 12/14/04 12/15/04 12/16/04 12/17/04 12/18/04 12/19/04', - '12/20/04 12/21/04 12/22/04 12/23/04 12/24/04 12/25/04 12/26/04', - '12/27/04 12/28/04 12/29/04 12/30/04 12/31/04 01/01/05 01/02/05']]] - - - class OutputTestCase(unittest.TestCase): - def normalize_calendar(self, s): - # Filters out locale dependent strings - def neitherspacenordigit(c): - return not c.isspace() and not c.isdigit() - - lines = [] - for line in s.splitlines(keepends=False): - # Drop texts, as they are locale dependent - if line and not filter(neitherspacenordigit, line): - lines.append(line) - return lines - - def check_htmlcalendar_encoding(self, req, res): - cal = calendar.HTMLCalendar() - format_ = default_format.copy() - format_["encoding"] = req or 'utf-8' - output = cal.formatyearpage(2004, encoding=req) - self.assertEqual( - output, - result_2004_html.format(**format_).encode(res) - ) - - def test_output(self): - self.assertEqual( - self.normalize_calendar(calendar.calendar(2004)), - self.normalize_calendar(result_2004_text) - ) - self.assertEqual( - self.normalize_calendar(calendar.calendar(0)), - self.normalize_calendar(result_0_text) - ) - - def test_output_textcalendar(self): - self.assertEqual( - calendar.TextCalendar().formatyear(2004), - result_2004_text - ) - self.assertEqual( - calendar.TextCalendar().formatyear(0), - result_0_text - ) - - def test_output_htmlcalendar_encoding_ascii(self): - self.check_htmlcalendar_encoding('ascii', 'ascii') - - def test_output_htmlcalendar_encoding_utf8(self): - self.check_htmlcalendar_encoding('utf-8', 'utf-8') - - def test_output_htmlcalendar_encoding_default(self): - self.check_htmlcalendar_encoding(None, sys.getdefaultencoding()) - - def test_yeardatescalendar(self): - def shrink(cal): - return [[[' '.join('{:02d}/{:02d}/{}'.format( - d.month, d.day, str(d.year)[-2:]) for d in z) - for z in y] for y in x] for x in cal] - self.assertEqual( - shrink(calendar.Calendar().yeardatescalendar(2004)), - result_2004_dates - ) - - def test_yeardayscalendar(self): - self.assertEqual( - calendar.Calendar().yeardayscalendar(2004), - result_2004_days - ) - - def test_formatweekheader_short(self): - self.assertEqual( - calendar.TextCalendar().formatweekheader(2), - 'Mo Tu We Th Fr Sa Su' - ) - - def test_formatweekheader_long(self): - self.assertEqual( - calendar.TextCalendar().formatweekheader(9), - ' Monday Tuesday Wednesday Thursday ' - ' Friday Saturday Sunday ' - ) - - def test_formatmonth(self): - self.assertEqual( - calendar.TextCalendar().formatmonth(2004, 1), - result_2004_01_text - ) - self.assertEqual( - calendar.TextCalendar().formatmonth(0, 2), - result_0_02_text - ) - - def test_formatmonthname_with_year(self): - self.assertEqual( - calendar.HTMLCalendar().formatmonthname(2004, 1, withyear=True), - 'January 2004' - ) - - def test_formatmonthname_without_year(self): - self.assertEqual( - calendar.HTMLCalendar().formatmonthname(2004, 1, withyear=False), - 'January' - ) - - def test_prweek(self): - with support.captured_stdout() as out: - week = [(1,0), (2,1), (3,2), (4,3), (5,4), (6,5), (7,6)] - calendar.TextCalendar().prweek(week, 1) - self.assertEqual(out.getvalue(), " 1 2 3 4 5 6 7") - - def test_prmonth(self): - with support.captured_stdout() as out: - calendar.TextCalendar().prmonth(2004, 1) - self.assertEqual(out.getvalue(), result_2004_01_text) - - def test_pryear(self): - with support.captured_stdout() as out: - calendar.TextCalendar().pryear(2004) - self.assertEqual(out.getvalue(), result_2004_text) - - def test_format(self): - with support.captured_stdout() as out: - calendar.format(["1", "2", "3"], colwidth=3, spacing=1) - self.assertEqual(out.getvalue().strip(), "1 2 3") - - class CalendarTestCase(unittest.TestCase): - def test_isleap(self): - # Make sure that the return is right for a few years, and - # ensure that the return values are 1 or 0, not just true or - # false (see SF bug #485794). Specific additional tests may - # be appropriate; this tests a single "cycle". - self.assertEqual(calendar.isleap(2000), 1) - self.assertEqual(calendar.isleap(2001), 0) - self.assertEqual(calendar.isleap(2002), 0) - self.assertEqual(calendar.isleap(2003), 0) - - def test_setfirstweekday(self): - self.assertRaises(TypeError, calendar.setfirstweekday, 'flabber') - self.assertRaises(ValueError, calendar.setfirstweekday, -1) - self.assertRaises(ValueError, calendar.setfirstweekday, 200) - orig = calendar.firstweekday() - calendar.setfirstweekday(calendar.SUNDAY) - self.assertEqual(calendar.firstweekday(), calendar.SUNDAY) - calendar.setfirstweekday(calendar.MONDAY) - self.assertEqual(calendar.firstweekday(), calendar.MONDAY) - calendar.setfirstweekday(orig) - - def test_illegal_weekday_reported(self): - with self.assertRaisesRegex(calendar.IllegalWeekdayError, '123'): - calendar.setfirstweekday(123) - - def test_enumerate_weekdays(self): - self.assertRaises(IndexError, calendar.day_abbr.__getitem__, -10) - self.assertRaises(IndexError, calendar.day_name.__getitem__, 10) - self.assertEqual(len([d for d in calendar.day_abbr]), 7) - - def test_days(self): - for attr in "day_name", "day_abbr": - value = getattr(calendar, attr) - self.assertEqual(len(value), 7) - self.assertEqual(len(value[:]), 7) - # ensure they're all unique - self.assertEqual(len(set(value)), 7) - # verify it "acts like a sequence" in two forms of iteration - self.assertEqual(value[::-1], list(reversed(value))) - - def test_months(self): - for attr in "month_name", "month_abbr": - value = getattr(calendar, attr) - self.assertEqual(len(value), 13) - self.assertEqual(len(value[:]), 13) - self.assertEqual(value[0], "") - # ensure they're all unique - self.assertEqual(len(set(value)), 13) - # verify it "acts like a sequence" in two forms of iteration - self.assertEqual(value[::-1], list(reversed(value))) - - def test_locale_calendars(self): - # ensure that Locale{Text,HTML}Calendar resets the locale properly - # (it is still not thread-safe though) - old_october = calendar.TextCalendar().formatmonthname(2010, 10, 10) - try: - cal = calendar.LocaleTextCalendar(locale='') - local_weekday = cal.formatweekday(1, 10) - local_month = cal.formatmonthname(2010, 10, 10) - except locale.Error: - # cannot set the system default locale -- skip rest of test - raise unittest.SkipTest('cannot set the system default locale') - self.assertIsInstance(local_weekday, str) - self.assertIsInstance(local_month, str) - self.assertEqual(len(local_weekday), 10) - self.assertGreaterEqual(len(local_month), 10) - cal = calendar.LocaleHTMLCalendar(locale='') - local_weekday = cal.formatweekday(1) - local_month = cal.formatmonthname(2010, 10) - self.assertIsInstance(local_weekday, str) - self.assertIsInstance(local_month, str) - new_october = calendar.TextCalendar().formatmonthname(2010, 10, 10) - self.assertEqual(old_october, new_october) - - def test_itermonthdays3(self): - # ensure itermonthdays3 doesn't overflow after datetime.MAXYEAR - list(calendar.Calendar().itermonthdays3(datetime.MAXYEAR, 12)) - - def test_itermonthdays4(self): - cal = calendar.Calendar(firstweekday=3) - days = list(cal.itermonthdays4(2001, 2)) - self.assertEqual(days[0], (2001, 2, 1, 3)) - self.assertEqual(days[-1], (2001, 2, 28, 2)) - - def test_itermonthdays(self): - for firstweekday in range(7): - cal = calendar.Calendar(firstweekday) - # Test the extremes, see #28253 and #26650 - for y, m in [(1, 1), (9999, 12)]: - days = list(cal.itermonthdays(y, m)) - self.assertIn(len(days), (35, 42)) - # Test a short month - cal = calendar.Calendar(firstweekday=3) - days = list(cal.itermonthdays(2001, 2)) - self.assertEqual(days, list(range(1, 29))) - - def test_itermonthdays2(self): - for firstweekday in range(7): - cal = calendar.Calendar(firstweekday) - # Test the extremes, see #28253 and #26650 - for y, m in [(1, 1), (9999, 12)]: - days = list(cal.itermonthdays2(y, m)) - self.assertEqual(days[0][1], firstweekday) - self.assertEqual(days[-1][1], (firstweekday - 1) % 7) - - - class MonthCalendarTestCase(unittest.TestCase): - def setUp(self): - self.oldfirstweekday = calendar.firstweekday() - calendar.setfirstweekday(self.firstweekday) - - def tearDown(self): - calendar.setfirstweekday(self.oldfirstweekday) - - def check_weeks(self, year, month, weeks): - cal = calendar.monthcalendar(year, month) - self.assertEqual(len(cal), len(weeks)) - for i in range(len(weeks)): - self.assertEqual(weeks[i], sum(day != 0 for day in cal[i])) - - - class MondayTestCase(MonthCalendarTestCase): - firstweekday = calendar.MONDAY - - def test_february(self): - # A 28-day february starting on monday (7+7+7+7 days) - self.check_weeks(1999, 2, (7, 7, 7, 7)) - - # A 28-day february starting on tuesday (6+7+7+7+1 days) - self.check_weeks(2005, 2, (6, 7, 7, 7, 1)) - - # A 28-day february starting on sunday (1+7+7+7+6 days) - self.check_weeks(1987, 2, (1, 7, 7, 7, 6)) - - # A 29-day february starting on monday (7+7+7+7+1 days) - self.check_weeks(1988, 2, (7, 7, 7, 7, 1)) - - # A 29-day february starting on tuesday (6+7+7+7+2 days) - self.check_weeks(1972, 2, (6, 7, 7, 7, 2)) - - # A 29-day february starting on sunday (1+7+7+7+7 days) - self.check_weeks(2004, 2, (1, 7, 7, 7, 7)) - - def test_april(self): - # A 30-day april starting on monday (7+7+7+7+2 days) - self.check_weeks(1935, 4, (7, 7, 7, 7, 2)) - - # A 30-day april starting on tuesday (6+7+7+7+3 days) - self.check_weeks(1975, 4, (6, 7, 7, 7, 3)) - - # A 30-day april starting on sunday (1+7+7+7+7+1 days) - self.check_weeks(1945, 4, (1, 7, 7, 7, 7, 1)) - - # A 30-day april starting on saturday (2+7+7+7+7 days) - self.check_weeks(1995, 4, (2, 7, 7, 7, 7)) - - # A 30-day april starting on friday (3+7+7+7+6 days) - self.check_weeks(1994, 4, (3, 7, 7, 7, 6)) - - def test_december(self): - # A 31-day december starting on monday (7+7+7+7+3 days) - self.check_weeks(1980, 12, (7, 7, 7, 7, 3)) - - # A 31-day december starting on tuesday (6+7+7+7+4 days) - self.check_weeks(1987, 12, (6, 7, 7, 7, 4)) - - # A 31-day december starting on sunday (1+7+7+7+7+2 days) - self.check_weeks(1968, 12, (1, 7, 7, 7, 7, 2)) - - # A 31-day december starting on thursday (4+7+7+7+6 days) - self.check_weeks(1988, 12, (4, 7, 7, 7, 6)) - - # A 31-day december starting on friday (3+7+7+7+7 days) - self.check_weeks(2017, 12, (3, 7, 7, 7, 7)) - - # A 31-day december starting on saturday (2+7+7+7+7+1 days) - self.check_weeks(2068, 12, (2, 7, 7, 7, 7, 1)) - - - class SundayTestCase(MonthCalendarTestCase): - firstweekday = calendar.SUNDAY - - def test_february(self): - # A 28-day february starting on sunday (7+7+7+7 days) - self.check_weeks(2009, 2, (7, 7, 7, 7)) - - # A 28-day february starting on monday (6+7+7+7+1 days) - self.check_weeks(1999, 2, (6, 7, 7, 7, 1)) - - # A 28-day february starting on saturday (1+7+7+7+6 days) - self.check_weeks(1997, 2, (1, 7, 7, 7, 6)) - - # A 29-day february starting on sunday (7+7+7+7+1 days) - self.check_weeks(2004, 2, (7, 7, 7, 7, 1)) - - # A 29-day february starting on monday (6+7+7+7+2 days) - self.check_weeks(1960, 2, (6, 7, 7, 7, 2)) - - # A 29-day february starting on saturday (1+7+7+7+7 days) - self.check_weeks(1964, 2, (1, 7, 7, 7, 7)) - - def test_april(self): - # A 30-day april starting on sunday (7+7+7+7+2 days) - self.check_weeks(1923, 4, (7, 7, 7, 7, 2)) - - # A 30-day april starting on monday (6+7+7+7+3 days) - self.check_weeks(1918, 4, (6, 7, 7, 7, 3)) - - # A 30-day april starting on saturday (1+7+7+7+7+1 days) - self.check_weeks(1950, 4, (1, 7, 7, 7, 7, 1)) - - # A 30-day april starting on friday (2+7+7+7+7 days) - self.check_weeks(1960, 4, (2, 7, 7, 7, 7)) - - # A 30-day april starting on thursday (3+7+7+7+6 days) - self.check_weeks(1909, 4, (3, 7, 7, 7, 6)) - - def test_december(self): - # A 31-day december starting on sunday (7+7+7+7+3 days) - self.check_weeks(2080, 12, (7, 7, 7, 7, 3)) - - # A 31-day december starting on monday (6+7+7+7+4 days) - self.check_weeks(1941, 12, (6, 7, 7, 7, 4)) - - # A 31-day december starting on saturday (1+7+7+7+7+2 days) - self.check_weeks(1923, 12, (1, 7, 7, 7, 7, 2)) - - # A 31-day december starting on wednesday (4+7+7+7+6 days) - self.check_weeks(1948, 12, (4, 7, 7, 7, 6)) - - # A 31-day december starting on thursday (3+7+7+7+7 days) - self.check_weeks(1927, 12, (3, 7, 7, 7, 7)) - - # A 31-day december starting on friday (2+7+7+7+7+1 days) - self.check_weeks(1995, 12, (2, 7, 7, 7, 7, 1)) - - class TimegmTestCase(unittest.TestCase): - TIMESTAMPS = [0, 10, 100, 1000, 10000, 100000, 1000000, - 1234567890, 1262304000, 1275785153,] - def test_timegm(self): - for secs in self.TIMESTAMPS: - tuple = time.gmtime(secs) - self.assertEqual(secs, calendar.timegm(tuple)) - - class MonthRangeTestCase(unittest.TestCase): - def test_january(self): - # Tests valid lower boundary case. - self.assertEqual(calendar.monthrange(2004,1), (3,31)) - - def test_february_leap(self): - # Tests February during leap year. - self.assertEqual(calendar.monthrange(2004,2), (6,29)) - - def test_february_nonleap(self): - # Tests February in non-leap year. - self.assertEqual(calendar.monthrange(2010,2), (0,28)) - - def test_december(self): - # Tests valid upper boundary case. - self.assertEqual(calendar.monthrange(2004,12), (2,31)) - - def test_zeroth_month(self): - # Tests low invalid boundary case. - with self.assertRaises(calendar.IllegalMonthError): - calendar.monthrange(2004, 0) - - def test_thirteenth_month(self): - # Tests high invalid boundary case. - with self.assertRaises(calendar.IllegalMonthError): - calendar.monthrange(2004, 13) - - def test_illegal_month_reported(self): - with self.assertRaisesRegex(calendar.IllegalMonthError, '65'): - calendar.monthrange(2004, 65) - - class LeapdaysTestCase(unittest.TestCase): - def test_no_range(self): - # test when no range i.e. two identical years as args - self.assertEqual(calendar.leapdays(2010,2010), 0) - - def test_no_leapdays(self): - # test when no leap years in range - self.assertEqual(calendar.leapdays(2010,2011), 0) - - def test_no_leapdays_upper_boundary(self): - # test no leap years in range, when upper boundary is a leap year - self.assertEqual(calendar.leapdays(2010,2012), 0) - - def test_one_leapday_lower_boundary(self): - # test when one leap year in range, lower boundary is leap year - self.assertEqual(calendar.leapdays(2012,2013), 1) - - def test_several_leapyears_in_range(self): - self.assertEqual(calendar.leapdays(1997,2020), 5) - - - def conv(s): - return s.replace('\n', os.linesep).encode() - - class CommandLineTestCase(unittest.TestCase): - def run_ok(self, *args): - return assert_python_ok('-m', 'calendar', *args)[1] - - def assertFailure(self, *args): - rc, stdout, stderr = assert_python_failure('-m', 'calendar', *args) - self.assertIn(b'usage:', stderr) - self.assertEqual(rc, 2) - - def test_help(self): - stdout = self.run_ok('-h') - self.assertIn(b'usage:', stdout) - self.assertIn(b'calendar.py', stdout) - self.assertIn(b'--help', stdout) - - def test_illegal_arguments(self): - self.assertFailure('-z') - self.assertFailure('spam') - self.assertFailure('2004', 'spam') - self.assertFailure('-t', 'html', '2004', '1') - - def test_output_current_year(self): - stdout = self.run_ok() - year = datetime.datetime.now().year - self.assertIn((' %s' % year).encode(), stdout) - self.assertIn(b'January', stdout) - self.assertIn(b'Mo Tu We Th Fr Sa Su', stdout) - - def test_output_year(self): - stdout = self.run_ok('2004') - self.assertEqual(stdout, conv(result_2004_text)) - - def test_output_month(self): - stdout = self.run_ok('2004', '1') - self.assertEqual(stdout, conv(result_2004_01_text)) - - def test_option_encoding(self): - self.assertFailure('-e') - self.assertFailure('--encoding') - stdout = self.run_ok('--encoding', 'utf-16-le', '2004') - self.assertEqual(stdout, result_2004_text.encode('utf-16-le')) - - def test_option_locale(self): - self.assertFailure('-L') - self.assertFailure('--locale') - self.assertFailure('-L', 'en') - lang, enc = locale.getdefaultlocale() - lang = lang or 'C' - enc = enc or 'UTF-8' - try: - oldlocale = locale.getlocale(locale.LC_TIME) - try: - locale.setlocale(locale.LC_TIME, (lang, enc)) - finally: - locale.setlocale(locale.LC_TIME, oldlocale) - except (locale.Error, ValueError): - self.skipTest('cannot set the system default locale') - stdout = self.run_ok('--locale', lang, '--encoding', enc, '2004') - self.assertIn('2004'.encode(enc), stdout) - - def test_option_width(self): - self.assertFailure('-w') - self.assertFailure('--width') - self.assertFailure('-w', 'spam') - stdout = self.run_ok('--width', '3', '2004') - self.assertIn(b'Mon Tue Wed Thu Fri Sat Sun', stdout) - - def test_option_lines(self): - self.assertFailure('-l') - self.assertFailure('--lines') - self.assertFailure('-l', 'spam') - stdout = self.run_ok('--lines', '2', '2004') - self.assertIn(conv('December\n\nMo Tu We'), stdout) - - def test_option_spacing(self): - self.assertFailure('-s') - self.assertFailure('--spacing') - self.assertFailure('-s', 'spam') - stdout = self.run_ok('--spacing', '8', '2004') - self.assertIn(b'Su Mo', stdout) - - def test_option_months(self): - self.assertFailure('-m') - self.assertFailure('--month') - self.assertFailure('-m', 'spam') - stdout = self.run_ok('--months', '1', '2004') - self.assertIn(conv('\nMo Tu We Th Fr Sa Su\n'), stdout) - - def test_option_type(self): - self.assertFailure('-t') - self.assertFailure('--type') - self.assertFailure('-t', 'spam') - stdout = self.run_ok('--type', 'text', '2004') - self.assertEqual(stdout, conv(result_2004_text)) - stdout = self.run_ok('--type', 'html', '2004') - self.assertEqual(stdout[:6], b'Calendar for 2004', stdout) - - def test_html_output_current_year(self): - stdout = self.run_ok('--type', 'html') - year = datetime.datetime.now().year - self.assertIn(('Calendar for %s' % year).encode(), - stdout) - self.assertIn(b'January', - stdout) - - def test_html_output_year_encoding(self): - stdout = self.run_ok('-t', 'html', '--encoding', 'ascii', '2004') - self.assertEqual(stdout, - result_2004_html.format(**default_format).encode('ascii')) - - def test_html_output_year_css(self): - self.assertFailure('-t', 'html', '-c') - self.assertFailure('-t', 'html', '--css') - stdout = self.run_ok('-t', 'html', '--css', 'custom.css', '2004') - self.assertIn(b'', stdout) - - - class MiscTestCase(unittest.TestCase): - def test__all__(self): - blacklist = {'mdays', 'January', 'February', 'EPOCH', - 'MONDAY', 'TUESDAY', 'WEDNESDAY', 'THURSDAY', 'FRIDAY', - 'SATURDAY', 'SUNDAY', 'different_locale', 'c', - 'prweek', 'week', 'format', 'formatstring', 'main', - 'monthlen', 'prevmonth', 'nextmonth'} - support.check__all__(self, calendar, blacklist=blacklist) - - - class TestSubClassingCase(unittest.TestCase): - - def setUp(self): - - class CustomHTMLCal(calendar.HTMLCalendar): - cssclasses = [style + " text-nowrap" for style in - calendar.HTMLCalendar.cssclasses] - cssclasses_weekday_head = ["red", "blue", "green", "lilac", - "yellow", "orange", "pink"] - cssclass_month_head = "text-center month-head" - cssclass_month = "text-center month" - cssclass_year = "text-italic " - cssclass_year_head = "lead " - - self.cal = CustomHTMLCal() - - def test_formatmonthname(self): - self.assertIn('class="text-center month-head"', - self.cal.formatmonthname(2017, 5)) - - def test_formatmonth(self): - self.assertIn('class="text-center month"', - self.cal.formatmonth(2017, 5)) - - def test_formatweek(self): - weeks = self.cal.monthdays2calendar(2017, 5) - self.assertIn('class="wed text-nowrap"', self.cal.formatweek(weeks[0])) - - def test_formatweek_head(self): - header = self.cal.formatweekheader() - for color in self.cal.cssclasses_weekday_head: - self.assertIn('' % color, header) - - def test_format_year(self): - self.assertIn( - ('' % - self.cal.cssclass_year), self.cal.formatyear(2017)) - - def test_format_year_head(self): - self.assertIn('' % ( - 3, self.cal.cssclass_year_head, 2017), self.cal.formatyear(2017)) - - if __name__ == "__main__": - unittest.main() diff --git a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_call.yaml b/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_call.yaml deleted file mode 100644 index 249d6e37d..000000000 --- a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_call.yaml +++ /dev/null @@ -1,614 +0,0 @@ -python: | - import datetime - import unittest - from test.support import cpython_only - try: - import _testcapi - except ImportError: - _testcapi = None - import struct - import collections - import itertools - import gc - - - class FunctionCalls(unittest.TestCase): - - def test_kwargs_order(self): - # bpo-34320: **kwargs should preserve order of passed OrderedDict - od = collections.OrderedDict([('a', 1), ('b', 2)]) - od.move_to_end('a') - expected = list(od.items()) - - def fn(**kw): - return kw - - res = fn(**od) - self.assertIsInstance(res, dict) - self.assertEqual(list(res.items()), expected) - - - # The test cases here cover several paths through the function calling - # code. They depend on the METH_XXX flag that is used to define a C - # function, which can't be verified from Python. If the METH_XXX decl - # for a C function changes, these tests may not cover the right paths. - - class CFunctionCalls(unittest.TestCase): - - def test_varargs0(self): - self.assertRaises(TypeError, {}.__contains__) - - def test_varargs1(self): - {}.__contains__(0) - - def test_varargs2(self): - self.assertRaises(TypeError, {}.__contains__, 0, 1) - - def test_varargs0_ext(self): - try: - {}.__contains__(*()) - except TypeError: - pass - - def test_varargs1_ext(self): - {}.__contains__(*(0,)) - - def test_varargs2_ext(self): - try: - {}.__contains__(*(1, 2)) - except TypeError: - pass - else: - raise RuntimeError - - def test_varargs1_kw(self): - self.assertRaises(TypeError, {}.__contains__, x=2) - - def test_varargs2_kw(self): - self.assertRaises(TypeError, {}.__contains__, x=2, y=2) - - def test_oldargs0_0(self): - {}.keys() - - def test_oldargs0_1(self): - self.assertRaises(TypeError, {}.keys, 0) - - def test_oldargs0_2(self): - self.assertRaises(TypeError, {}.keys, 0, 1) - - def test_oldargs0_0_ext(self): - {}.keys(*()) - - def test_oldargs0_1_ext(self): - try: - {}.keys(*(0,)) - except TypeError: - pass - else: - raise RuntimeError - - def test_oldargs0_2_ext(self): - try: - {}.keys(*(1, 2)) - except TypeError: - pass - else: - raise RuntimeError - - def test_oldargs0_0_kw(self): - try: - {}.keys(x=2) - except TypeError: - pass - else: - raise RuntimeError - - def test_oldargs0_1_kw(self): - self.assertRaises(TypeError, {}.keys, x=2) - - def test_oldargs0_2_kw(self): - self.assertRaises(TypeError, {}.keys, x=2, y=2) - - def test_oldargs1_0(self): - self.assertRaises(TypeError, [].count) - - def test_oldargs1_1(self): - [].count(1) - - def test_oldargs1_2(self): - self.assertRaises(TypeError, [].count, 1, 2) - - def test_oldargs1_0_ext(self): - try: - [].count(*()) - except TypeError: - pass - else: - raise RuntimeError - - def test_oldargs1_1_ext(self): - [].count(*(1,)) - - def test_oldargs1_2_ext(self): - try: - [].count(*(1, 2)) - except TypeError: - pass - else: - raise RuntimeError - - def test_oldargs1_0_kw(self): - self.assertRaises(TypeError, [].count, x=2) - - def test_oldargs1_1_kw(self): - self.assertRaises(TypeError, [].count, {}, x=2) - - def test_oldargs1_2_kw(self): - self.assertRaises(TypeError, [].count, x=2, y=2) - - - @cpython_only - class CFunctionCallsErrorMessages(unittest.TestCase): - - def test_varargs0(self): - msg = r"__contains__\(\) takes exactly one argument \(0 given\)" - self.assertRaisesRegex(TypeError, msg, {}.__contains__) - - def test_varargs2(self): - msg = r"__contains__\(\) takes exactly one argument \(2 given\)" - self.assertRaisesRegex(TypeError, msg, {}.__contains__, 0, 1) - - def test_varargs3(self): - msg = r"^from_bytes\(\) takes exactly 2 positional arguments \(3 given\)" - self.assertRaisesRegex(TypeError, msg, int.from_bytes, b'a', 'little', False) - - def test_varargs1min(self): - msg = r"get expected at least 1 argument, got 0" - self.assertRaisesRegex(TypeError, msg, {}.get) - - msg = r"expected 1 argument, got 0" - self.assertRaisesRegex(TypeError, msg, {}.__delattr__) - - def test_varargs2min(self): - msg = r"getattr expected at least 2 arguments, got 0" - self.assertRaisesRegex(TypeError, msg, getattr) - - def test_varargs1max(self): - msg = r"input expected at most 1 argument, got 2" - self.assertRaisesRegex(TypeError, msg, input, 1, 2) - - def test_varargs2max(self): - msg = r"get expected at most 2 arguments, got 3" - self.assertRaisesRegex(TypeError, msg, {}.get, 1, 2, 3) - - def test_varargs1_kw(self): - msg = r"__contains__\(\) takes no keyword arguments" - self.assertRaisesRegex(TypeError, msg, {}.__contains__, x=2) - - def test_varargs2_kw(self): - msg = r"__contains__\(\) takes no keyword arguments" - self.assertRaisesRegex(TypeError, msg, {}.__contains__, x=2, y=2) - - def test_varargs3_kw(self): - msg = r"bool\(\) takes no keyword arguments" - self.assertRaisesRegex(TypeError, msg, bool, x=2) - - def test_varargs4_kw(self): - msg = r"^index\(\) takes no keyword arguments$" - self.assertRaisesRegex(TypeError, msg, [].index, x=2) - - def test_varargs5_kw(self): - msg = r"^hasattr\(\) takes no keyword arguments$" - self.assertRaisesRegex(TypeError, msg, hasattr, x=2) - - def test_varargs6_kw(self): - msg = r"^getattr\(\) takes no keyword arguments$" - self.assertRaisesRegex(TypeError, msg, getattr, x=2) - - def test_varargs7_kw(self): - msg = r"^next\(\) takes no keyword arguments$" - self.assertRaisesRegex(TypeError, msg, next, x=2) - - def test_varargs8_kw(self): - msg = r"^pack\(\) takes no keyword arguments$" - self.assertRaisesRegex(TypeError, msg, struct.pack, x=2) - - def test_varargs9_kw(self): - msg = r"^pack_into\(\) takes no keyword arguments$" - self.assertRaisesRegex(TypeError, msg, struct.pack_into, x=2) - - def test_varargs10_kw(self): - msg = r"^index\(\) takes no keyword arguments$" - self.assertRaisesRegex(TypeError, msg, collections.deque().index, x=2) - - def test_varargs11_kw(self): - msg = r"^pack\(\) takes no keyword arguments$" - self.assertRaisesRegex(TypeError, msg, struct.Struct.pack, struct.Struct(""), x=2) - - def test_varargs12_kw(self): - msg = r"^staticmethod\(\) takes no keyword arguments$" - self.assertRaisesRegex(TypeError, msg, staticmethod, func=id) - - def test_varargs13_kw(self): - msg = r"^classmethod\(\) takes no keyword arguments$" - self.assertRaisesRegex(TypeError, msg, classmethod, func=id) - - def test_varargs14_kw(self): - msg = r"^product\(\) takes at most 1 keyword argument \(2 given\)$" - self.assertRaisesRegex(TypeError, msg, - itertools.product, 0, repeat=1, foo=2) - - def test_varargs15_kw(self): - msg = r"^ImportError\(\) takes at most 2 keyword arguments \(3 given\)$" - self.assertRaisesRegex(TypeError, msg, - ImportError, 0, name=1, path=2, foo=3) - - def test_varargs16_kw(self): - msg = r"^min\(\) takes at most 2 keyword arguments \(3 given\)$" - self.assertRaisesRegex(TypeError, msg, - min, 0, default=1, key=2, foo=3) - - def test_varargs17_kw(self): - msg = r"^print\(\) takes at most 4 keyword arguments \(5 given\)$" - self.assertRaisesRegex(TypeError, msg, - print, 0, sep=1, end=2, file=3, flush=4, foo=5) - - def test_oldargs0_1(self): - msg = r"keys\(\) takes no arguments \(1 given\)" - self.assertRaisesRegex(TypeError, msg, {}.keys, 0) - - def test_oldargs0_2(self): - msg = r"keys\(\) takes no arguments \(2 given\)" - self.assertRaisesRegex(TypeError, msg, {}.keys, 0, 1) - - def test_oldargs0_1_kw(self): - msg = r"keys\(\) takes no keyword arguments" - self.assertRaisesRegex(TypeError, msg, {}.keys, x=2) - - def test_oldargs0_2_kw(self): - msg = r"keys\(\) takes no keyword arguments" - self.assertRaisesRegex(TypeError, msg, {}.keys, x=2, y=2) - - def test_oldargs1_0(self): - msg = r"count\(\) takes exactly one argument \(0 given\)" - self.assertRaisesRegex(TypeError, msg, [].count) - - def test_oldargs1_2(self): - msg = r"count\(\) takes exactly one argument \(2 given\)" - self.assertRaisesRegex(TypeError, msg, [].count, 1, 2) - - def test_oldargs1_0_kw(self): - msg = r"count\(\) takes no keyword arguments" - self.assertRaisesRegex(TypeError, msg, [].count, x=2) - - def test_oldargs1_1_kw(self): - msg = r"count\(\) takes no keyword arguments" - self.assertRaisesRegex(TypeError, msg, [].count, {}, x=2) - - def test_oldargs1_2_kw(self): - msg = r"count\(\) takes no keyword arguments" - self.assertRaisesRegex(TypeError, msg, [].count, x=2, y=2) - - - def pyfunc(arg1, arg2): - return [arg1, arg2] - - - def pyfunc_noarg(): - return "noarg" - - - class PythonClass: - def method(self, arg1, arg2): - return [arg1, arg2] - - def method_noarg(self): - return "noarg" - - @classmethod - def class_method(cls): - return "classmethod" - - @staticmethod - def static_method(): - return "staticmethod" - - - PYTHON_INSTANCE = PythonClass() - - - IGNORE_RESULT = object() - - - @cpython_only - class FastCallTests(unittest.TestCase): - # Test calls with positional arguments - CALLS_POSARGS = ( - # (func, args: tuple, result) - - # Python function with 2 arguments - (pyfunc, (1, 2), [1, 2]), - - # Python function without argument - (pyfunc_noarg, (), "noarg"), - - # Python class methods - (PythonClass.class_method, (), "classmethod"), - (PythonClass.static_method, (), "staticmethod"), - - # Python instance methods - (PYTHON_INSTANCE.method, (1, 2), [1, 2]), - (PYTHON_INSTANCE.method_noarg, (), "noarg"), - (PYTHON_INSTANCE.class_method, (), "classmethod"), - (PYTHON_INSTANCE.static_method, (), "staticmethod"), - - # C function: METH_NOARGS - (globals, (), IGNORE_RESULT), - - # C function: METH_O - (id, ("hello",), IGNORE_RESULT), - - # C function: METH_VARARGS - (dir, (1,), IGNORE_RESULT), - - # C function: METH_VARARGS | METH_KEYWORDS - (min, (5, 9), 5), - - # C function: METH_FASTCALL - (divmod, (1000, 33), (30, 10)), - - # C type static method: METH_FASTCALL | METH_CLASS - (int.from_bytes, (b'\x01\x00', 'little'), 1), - - # bpo-30524: Test that calling a C type static method with no argument - # doesn't crash (ignore the result): METH_FASTCALL | METH_CLASS - (datetime.datetime.now, (), IGNORE_RESULT), - ) - - # Test calls with positional and keyword arguments - CALLS_KWARGS = ( - # (func, args: tuple, kwargs: dict, result) - - # Python function with 2 arguments - (pyfunc, (1,), {'arg2': 2}, [1, 2]), - (pyfunc, (), {'arg1': 1, 'arg2': 2}, [1, 2]), - - # Python instance methods - (PYTHON_INSTANCE.method, (1,), {'arg2': 2}, [1, 2]), - (PYTHON_INSTANCE.method, (), {'arg1': 1, 'arg2': 2}, [1, 2]), - - # C function: METH_VARARGS | METH_KEYWORDS - (max, ([],), {'default': 9}, 9), - - # C type static method: METH_FASTCALL | METH_CLASS - (int.from_bytes, (b'\x01\x00',), {'byteorder': 'little'}, 1), - (int.from_bytes, (), {'bytes': b'\x01\x00', 'byteorder': 'little'}, 1), - ) - - def check_result(self, result, expected): - if expected is IGNORE_RESULT: - return - self.assertEqual(result, expected) - - def test_fastcall(self): - # Test _PyObject_FastCall() - - for func, args, expected in self.CALLS_POSARGS: - with self.subTest(func=func, args=args): - result = _testcapi.pyobject_fastcall(func, args) - self.check_result(result, expected) - - if not args: - # args=NULL, nargs=0 - result = _testcapi.pyobject_fastcall(func, None) - self.check_result(result, expected) - - def test_vectorcall_dict(self): - # Test _PyObject_FastCallDict() - - for func, args, expected in self.CALLS_POSARGS: - with self.subTest(func=func, args=args): - # kwargs=NULL - result = _testcapi.pyobject_fastcalldict(func, args, None) - self.check_result(result, expected) - - # kwargs={} - result = _testcapi.pyobject_fastcalldict(func, args, {}) - self.check_result(result, expected) - - if not args: - # args=NULL, nargs=0, kwargs=NULL - result = _testcapi.pyobject_fastcalldict(func, None, None) - self.check_result(result, expected) - - # args=NULL, nargs=0, kwargs={} - result = _testcapi.pyobject_fastcalldict(func, None, {}) - self.check_result(result, expected) - - for func, args, kwargs, expected in self.CALLS_KWARGS: - with self.subTest(func=func, args=args, kwargs=kwargs): - result = _testcapi.pyobject_fastcalldict(func, args, kwargs) - self.check_result(result, expected) - - def test_vectorcall(self): - # Test _PyObject_Vectorcall() - - for func, args, expected in self.CALLS_POSARGS: - with self.subTest(func=func, args=args): - # kwnames=NULL - result = _testcapi.pyobject_vectorcall(func, args, None) - self.check_result(result, expected) - - # kwnames=() - result = _testcapi.pyobject_vectorcall(func, args, ()) - self.check_result(result, expected) - - if not args: - # kwnames=NULL - result = _testcapi.pyobject_vectorcall(func, None, None) - self.check_result(result, expected) - - # kwnames=() - result = _testcapi.pyobject_vectorcall(func, None, ()) - self.check_result(result, expected) - - for func, args, kwargs, expected in self.CALLS_KWARGS: - with self.subTest(func=func, args=args, kwargs=kwargs): - kwnames = tuple(kwargs.keys()) - args = args + tuple(kwargs.values()) - result = _testcapi.pyobject_vectorcall(func, args, kwnames) - self.check_result(result, expected) - - def test_fastcall_clearing_dict(self): - # Test bpo-36907: the point of the test is just checking that this - # does not crash. - class IntWithDict: - __slots__ = ["kwargs"] - def __init__(self, **kwargs): - self.kwargs = kwargs - def __index__(self): - self.kwargs.clear() - gc.collect() - return 0 - x = IntWithDict(dont_inherit=IntWithDict()) - # We test the argument handling of "compile" here, the compilation - # itself is not relevant. When we pass flags=x below, x.__index__() is - # called, which changes the keywords dict. - compile("pass", "", "exec", x, **x.kwargs) - - - Py_TPFLAGS_HAVE_VECTORCALL = 1 << 11 - Py_TPFLAGS_METHOD_DESCRIPTOR = 1 << 17 - - - def testfunction(self): - """some doc""" - return self - - - def testfunction_kw(self, *, kw): - """some doc""" - return self - - - class TestPEP590(unittest.TestCase): - - def test_method_descriptor_flag(self): - import functools - cached = functools.lru_cache(1)(testfunction) - - self.assertFalse(type(repr).__flags__ & Py_TPFLAGS_METHOD_DESCRIPTOR) - self.assertTrue(type(list.append).__flags__ & Py_TPFLAGS_METHOD_DESCRIPTOR) - self.assertTrue(type(list.__add__).__flags__ & Py_TPFLAGS_METHOD_DESCRIPTOR) - self.assertTrue(type(testfunction).__flags__ & Py_TPFLAGS_METHOD_DESCRIPTOR) - self.assertTrue(type(cached).__flags__ & Py_TPFLAGS_METHOD_DESCRIPTOR) - - self.assertTrue(_testcapi.MethodDescriptorBase.__flags__ & Py_TPFLAGS_METHOD_DESCRIPTOR) - self.assertTrue(_testcapi.MethodDescriptorDerived.__flags__ & Py_TPFLAGS_METHOD_DESCRIPTOR) - self.assertFalse(_testcapi.MethodDescriptorNopGet.__flags__ & Py_TPFLAGS_METHOD_DESCRIPTOR) - - # Heap type should not inherit Py_TPFLAGS_METHOD_DESCRIPTOR - class MethodDescriptorHeap(_testcapi.MethodDescriptorBase): - pass - self.assertFalse(MethodDescriptorHeap.__flags__ & Py_TPFLAGS_METHOD_DESCRIPTOR) - - def test_vectorcall_flag(self): - self.assertTrue(_testcapi.MethodDescriptorBase.__flags__ & Py_TPFLAGS_HAVE_VECTORCALL) - self.assertTrue(_testcapi.MethodDescriptorDerived.__flags__ & Py_TPFLAGS_HAVE_VECTORCALL) - self.assertFalse(_testcapi.MethodDescriptorNopGet.__flags__ & Py_TPFLAGS_HAVE_VECTORCALL) - self.assertTrue(_testcapi.MethodDescriptor2.__flags__ & Py_TPFLAGS_HAVE_VECTORCALL) - - # Heap type should not inherit Py_TPFLAGS_HAVE_VECTORCALL - class MethodDescriptorHeap(_testcapi.MethodDescriptorBase): - pass - self.assertFalse(MethodDescriptorHeap.__flags__ & Py_TPFLAGS_HAVE_VECTORCALL) - - def test_vectorcall_override(self): - # Check that tp_call can correctly override vectorcall. - # MethodDescriptorNopGet implements tp_call but it inherits from - # MethodDescriptorBase, which implements vectorcall. Since - # MethodDescriptorNopGet returns the args tuple when called, we check - # additionally that no new tuple is created for this call. - args = tuple(range(5)) - f = _testcapi.MethodDescriptorNopGet() - self.assertIs(f(*args), args) - - def test_vectorcall(self): - # Test a bunch of different ways to call objects: - # 1. vectorcall using PyVectorcall_Call() - # (only for objects that support vectorcall directly) - # 2. normal call - # 3. vectorcall using _PyObject_Vectorcall() - # 4. call as bound method - # 5. call using functools.partial - - # A list of (function, args, kwargs, result) calls to test - calls = [(len, (range(42),), {}, 42), - (list.append, ([], 0), {}, None), - ([].append, (0,), {}, None), - (sum, ([36],), {"start":6}, 42), - (testfunction, (42,), {}, 42), - (testfunction_kw, (42,), {"kw":None}, 42), - (_testcapi.MethodDescriptorBase(), (0,), {}, True), - (_testcapi.MethodDescriptorDerived(), (0,), {}, True), - (_testcapi.MethodDescriptor2(), (0,), {}, False)] - - from _testcapi import pyobject_vectorcall, pyvectorcall_call - from types import MethodType - from functools import partial - - def vectorcall(func, args, kwargs): - args = *args, *kwargs.values() - kwnames = tuple(kwargs) - return pyobject_vectorcall(func, args, kwnames) - - for (func, args, kwargs, expected) in calls: - with self.subTest(str(func)): - if not kwargs: - self.assertEqual(expected, pyvectorcall_call(func, args)) - self.assertEqual(expected, pyvectorcall_call(func, args, kwargs)) - - # Add derived classes (which do not support vectorcall directly, - # but do support all other ways of calling). - - class MethodDescriptorHeap(_testcapi.MethodDescriptorBase): - pass - - class MethodDescriptorOverridden(_testcapi.MethodDescriptorBase): - def __call__(self, n): - return 'new' - - class SuperBase: - def __call__(self, *args): - return super().__call__(*args) - - class MethodDescriptorSuper(SuperBase, _testcapi.MethodDescriptorBase): - def __call__(self, *args): - return super().__call__(*args) - - calls += [ - (dict.update, ({},), {"key":True}, None), - ({}.update, ({},), {"key":True}, None), - (MethodDescriptorHeap(), (0,), {}, True), - (MethodDescriptorOverridden(), (0,), {}, 'new'), - (MethodDescriptorSuper(), (0,), {}, True), - ] - - for (func, args, kwargs, expected) in calls: - with self.subTest(str(func)): - args1 = args[1:] - meth = MethodType(func, args[0]) - wrapped = partial(func) - if not kwargs: - self.assertEqual(expected, func(*args)) - self.assertEqual(expected, pyobject_vectorcall(func, args, None)) - self.assertEqual(expected, meth(*args1)) - self.assertEqual(expected, wrapped(*args)) - self.assertEqual(expected, func(*args, **kwargs)) - self.assertEqual(expected, vectorcall(func, args, kwargs)) - self.assertEqual(expected, meth(*args1, **kwargs)) - self.assertEqual(expected, wrapped(*args, **kwargs)) - - - if __name__ == "__main__": - unittest.main() diff --git a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_capi.yaml b/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_capi.yaml deleted file mode 100644 index 1440dd9ad..000000000 --- a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_capi.yaml +++ /dev/null @@ -1,769 +0,0 @@ -python: | - # Run the _testcapi module tests (tests for the Python/C API): by defn, - # these are all functions _testcapi exports whose name begins with 'test_'. - - from collections import OrderedDict - import os - import pickle - import random - import re - import subprocess - import sys - import textwrap - import threading - import time - import unittest - from test import support - from test.support import MISSING_C_DOCSTRINGS - from test.support.script_helper import assert_python_failure, assert_python_ok - try: - import _posixsubprocess - except ImportError: - _posixsubprocess = None - - # Skip this test if the _testcapi module isn't available. - _testcapi = support.import_module('_testcapi') - - # Were we compiled --with-pydebug or with #define Py_DEBUG? - Py_DEBUG = hasattr(sys, 'gettotalrefcount') - - - def testfunction(self): - """some doc""" - return self - - - class InstanceMethod: - id = _testcapi.instancemethod(id) - testfunction = _testcapi.instancemethod(testfunction) - - class CAPITest(unittest.TestCase): - - def test_instancemethod(self): - inst = InstanceMethod() - self.assertEqual(id(inst), inst.id()) - self.assertTrue(inst.testfunction() is inst) - self.assertEqual(inst.testfunction.__doc__, testfunction.__doc__) - self.assertEqual(InstanceMethod.testfunction.__doc__, testfunction.__doc__) - - InstanceMethod.testfunction.attribute = "test" - self.assertEqual(testfunction.attribute, "test") - self.assertRaises(AttributeError, setattr, inst.testfunction, "attribute", "test") - - def test_no_FatalError_infinite_loop(self): - with support.SuppressCrashReport(): - p = subprocess.Popen([sys.executable, "-c", - 'import _testcapi;' - '_testcapi.crash_no_current_thread()'], - stdout=subprocess.PIPE, - stderr=subprocess.PIPE) - (out, err) = p.communicate() - self.assertEqual(out, b'') - # This used to cause an infinite loop. - self.assertTrue(err.rstrip().startswith( - b'Fatal Python error:' - b' PyThreadState_Get: no current thread')) - - def test_memoryview_from_NULL_pointer(self): - self.assertRaises(ValueError, _testcapi.make_memoryview_from_NULL_pointer) - - def test_exc_info(self): - raised_exception = ValueError("5") - new_exc = TypeError("TEST") - try: - raise raised_exception - except ValueError as e: - tb = e.__traceback__ - orig_sys_exc_info = sys.exc_info() - orig_exc_info = _testcapi.set_exc_info(new_exc.__class__, new_exc, None) - new_sys_exc_info = sys.exc_info() - new_exc_info = _testcapi.set_exc_info(*orig_exc_info) - reset_sys_exc_info = sys.exc_info() - - self.assertEqual(orig_exc_info[1], e) - - self.assertSequenceEqual(orig_exc_info, (raised_exception.__class__, raised_exception, tb)) - self.assertSequenceEqual(orig_sys_exc_info, orig_exc_info) - self.assertSequenceEqual(reset_sys_exc_info, orig_exc_info) - self.assertSequenceEqual(new_exc_info, (new_exc.__class__, new_exc, None)) - self.assertSequenceEqual(new_sys_exc_info, new_exc_info) - else: - self.assertTrue(False) - - @unittest.skipUnless(_posixsubprocess, '_posixsubprocess required for this test.') - def test_seq_bytes_to_charp_array(self): - # Issue #15732: crash in _PySequence_BytesToCharpArray() - class Z(object): - def __len__(self): - return 1 - self.assertRaises(TypeError, _posixsubprocess.fork_exec, - 1,Z(),3,(1, 2),5,6,7,8,9,10,11,12,13,14,15,16,17) - # Issue #15736: overflow in _PySequence_BytesToCharpArray() - class Z(object): - def __len__(self): - return sys.maxsize - def __getitem__(self, i): - return b'x' - self.assertRaises(MemoryError, _posixsubprocess.fork_exec, - 1,Z(),3,(1, 2),5,6,7,8,9,10,11,12,13,14,15,16,17) - - @unittest.skipUnless(_posixsubprocess, '_posixsubprocess required for this test.') - def test_subprocess_fork_exec(self): - class Z(object): - def __len__(self): - return 1 - - # Issue #15738: crash in subprocess_fork_exec() - self.assertRaises(TypeError, _posixsubprocess.fork_exec, - Z(),[b'1'],3,(1, 2),5,6,7,8,9,10,11,12,13,14,15,16,17) - - @unittest.skipIf(MISSING_C_DOCSTRINGS, - "Signature information for builtins requires docstrings") - def test_docstring_signature_parsing(self): - - self.assertEqual(_testcapi.no_docstring.__doc__, None) - self.assertEqual(_testcapi.no_docstring.__text_signature__, None) - - self.assertEqual(_testcapi.docstring_empty.__doc__, None) - self.assertEqual(_testcapi.docstring_empty.__text_signature__, None) - - self.assertEqual(_testcapi.docstring_no_signature.__doc__, - "This docstring has no signature.") - self.assertEqual(_testcapi.docstring_no_signature.__text_signature__, None) - - self.assertEqual(_testcapi.docstring_with_invalid_signature.__doc__, - "docstring_with_invalid_signature($module, /, boo)\n" - "\n" - "This docstring has an invalid signature." - ) - self.assertEqual(_testcapi.docstring_with_invalid_signature.__text_signature__, None) - - self.assertEqual(_testcapi.docstring_with_invalid_signature2.__doc__, - "docstring_with_invalid_signature2($module, /, boo)\n" - "\n" - "--\n" - "\n" - "This docstring also has an invalid signature." - ) - self.assertEqual(_testcapi.docstring_with_invalid_signature2.__text_signature__, None) - - self.assertEqual(_testcapi.docstring_with_signature.__doc__, - "This docstring has a valid signature.") - self.assertEqual(_testcapi.docstring_with_signature.__text_signature__, "($module, /, sig)") - - self.assertEqual(_testcapi.docstring_with_signature_but_no_doc.__doc__, None) - self.assertEqual(_testcapi.docstring_with_signature_but_no_doc.__text_signature__, - "($module, /, sig)") - - self.assertEqual(_testcapi.docstring_with_signature_and_extra_newlines.__doc__, - "\nThis docstring has a valid signature and some extra newlines.") - self.assertEqual(_testcapi.docstring_with_signature_and_extra_newlines.__text_signature__, - "($module, /, parameter)") - - def test_c_type_with_matrix_multiplication(self): - M = _testcapi.matmulType - m1 = M() - m2 = M() - self.assertEqual(m1 @ m2, ("matmul", m1, m2)) - self.assertEqual(m1 @ 42, ("matmul", m1, 42)) - self.assertEqual(42 @ m1, ("matmul", 42, m1)) - o = m1 - o @= m2 - self.assertEqual(o, ("imatmul", m1, m2)) - o = m1 - o @= 42 - self.assertEqual(o, ("imatmul", m1, 42)) - o = 42 - o @= m1 - self.assertEqual(o, ("matmul", 42, m1)) - - def test_c_type_with_ipow(self): - # When the __ipow__ method of a type was implemented in C, using the - # modulo param would cause segfaults. - o = _testcapi.ipowType() - self.assertEqual(o.__ipow__(1), (1, None)) - self.assertEqual(o.__ipow__(2, 2), (2, 2)) - - def test_return_null_without_error(self): - # Issue #23571: A function must not return NULL without setting an - # error - if Py_DEBUG: - code = textwrap.dedent(""" - import _testcapi - from test import support - - with support.SuppressCrashReport(): - _testcapi.return_null_without_error() - """) - rc, out, err = assert_python_failure('-c', code) - self.assertRegex(err.replace(b'\r', b''), - br'Fatal Python error: a function returned NULL ' - br'without setting an error\n' - br'Python runtime state: initialized\n' - br'SystemError: returned NULL ' - br'without setting an error\n' - br'\n' - br'Current thread.*:\n' - br' File .*", line 6 in ') - else: - with self.assertRaises(SystemError) as cm: - _testcapi.return_null_without_error() - self.assertRegex(str(cm.exception), - 'return_null_without_error.* ' - 'returned NULL without setting an error') - - def test_return_result_with_error(self): - # Issue #23571: A function must not return a result with an error set - if Py_DEBUG: - code = textwrap.dedent(""" - import _testcapi - from test import support - - with support.SuppressCrashReport(): - _testcapi.return_result_with_error() - """) - rc, out, err = assert_python_failure('-c', code) - self.assertRegex(err.replace(b'\r', b''), - br'Fatal Python error: a function returned a ' - br'result with an error set\n' - br'Python runtime state: initialized\n' - br'ValueError\n' - br'\n' - br'The above exception was the direct cause ' - br'of the following exception:\n' - br'\n' - br'SystemError: ' - br'returned a result with an error set\n' - br'\n' - br'Current thread.*:\n' - br' File .*, line 6 in ') - else: - with self.assertRaises(SystemError) as cm: - _testcapi.return_result_with_error() - self.assertRegex(str(cm.exception), - 'return_result_with_error.* ' - 'returned a result with an error set') - - def test_buildvalue_N(self): - _testcapi.test_buildvalue_N() - - def test_set_nomemory(self): - code = """if 1: - import _testcapi - - class C(): pass - - # The first loop tests both functions and that remove_mem_hooks() - # can be called twice in a row. The second loop checks a call to - # set_nomemory() after a call to remove_mem_hooks(). The third - # loop checks the start and stop arguments of set_nomemory(). - for outer_cnt in range(1, 4): - start = 10 * outer_cnt - for j in range(100): - if j == 0: - if outer_cnt != 3: - _testcapi.set_nomemory(start) - else: - _testcapi.set_nomemory(start, start + 1) - try: - C() - except MemoryError as e: - if outer_cnt != 3: - _testcapi.remove_mem_hooks() - print('MemoryError', outer_cnt, j) - _testcapi.remove_mem_hooks() - break - """ - rc, out, err = assert_python_ok('-c', code) - self.assertIn(b'MemoryError 1 10', out) - self.assertIn(b'MemoryError 2 20', out) - self.assertIn(b'MemoryError 3 30', out) - - def test_mapping_keys_values_items(self): - class Mapping1(dict): - def keys(self): - return list(super().keys()) - def values(self): - return list(super().values()) - def items(self): - return list(super().items()) - class Mapping2(dict): - def keys(self): - return tuple(super().keys()) - def values(self): - return tuple(super().values()) - def items(self): - return tuple(super().items()) - dict_obj = {'foo': 1, 'bar': 2, 'spam': 3} - - for mapping in [{}, OrderedDict(), Mapping1(), Mapping2(), - dict_obj, OrderedDict(dict_obj), - Mapping1(dict_obj), Mapping2(dict_obj)]: - self.assertListEqual(_testcapi.get_mapping_keys(mapping), - list(mapping.keys())) - self.assertListEqual(_testcapi.get_mapping_values(mapping), - list(mapping.values())) - self.assertListEqual(_testcapi.get_mapping_items(mapping), - list(mapping.items())) - - def test_mapping_keys_values_items_bad_arg(self): - self.assertRaises(AttributeError, _testcapi.get_mapping_keys, None) - self.assertRaises(AttributeError, _testcapi.get_mapping_values, None) - self.assertRaises(AttributeError, _testcapi.get_mapping_items, None) - - class BadMapping: - def keys(self): - return None - def values(self): - return None - def items(self): - return None - bad_mapping = BadMapping() - self.assertRaises(TypeError, _testcapi.get_mapping_keys, bad_mapping) - self.assertRaises(TypeError, _testcapi.get_mapping_values, bad_mapping) - self.assertRaises(TypeError, _testcapi.get_mapping_items, bad_mapping) - - @unittest.skipUnless(hasattr(_testcapi, 'negative_refcount'), - 'need _testcapi.negative_refcount') - def test_negative_refcount(self): - # bpo-35059: Check that Py_DECREF() reports the correct filename - # when calling _Py_NegativeRefcount() to abort Python. - code = textwrap.dedent(""" - import _testcapi - from test import support - - with support.SuppressCrashReport(): - _testcapi.negative_refcount() - """) - rc, out, err = assert_python_failure('-c', code) - self.assertRegex(err, - br'_testcapimodule\.c:[0-9]+: ' - br'_Py_NegativeRefcount: Assertion failed: ' - br'object has negative ref count') - - def test_trashcan_subclass(self): - # bpo-35983: Check that the trashcan mechanism for "list" is NOT - # activated when its tp_dealloc is being called by a subclass - from _testcapi import MyList - L = None - for i in range(1000): - L = MyList((L,)) - - @support.requires_resource('cpu') - def test_trashcan_python_class1(self): - self.do_test_trashcan_python_class(list) - - @support.requires_resource('cpu') - def test_trashcan_python_class2(self): - from _testcapi import MyList - self.do_test_trashcan_python_class(MyList) - - def do_test_trashcan_python_class(self, base): - # Check that the trashcan mechanism works properly for a Python - # subclass of a class using the trashcan (this specific test assumes - # that the base class "base" behaves like list) - class PyList(base): - # Count the number of PyList instances to verify that there is - # no memory leak - num = 0 - def __init__(self, *args): - __class__.num += 1 - super().__init__(*args) - def __del__(self): - __class__.num -= 1 - - for parity in (0, 1): - L = None - # We need in the order of 2**20 iterations here such that a - # typical 8MB stack would overflow without the trashcan. - for i in range(2**20): - L = PyList((L,)) - L.attr = i - if parity: - # Add one additional nesting layer - L = (L,) - self.assertGreater(PyList.num, 0) - del L - self.assertEqual(PyList.num, 0) - - def test_subclass_of_heap_gc_ctype_with_tpdealloc_decrefs_once(self): - class HeapGcCTypeSubclass(_testcapi.HeapGcCType): - def __init__(self): - self.value2 = 20 - super().__init__() - - subclass_instance = HeapGcCTypeSubclass() - type_refcnt = sys.getrefcount(HeapGcCTypeSubclass) - - # Test that subclass instance was fully created - self.assertEqual(subclass_instance.value, 10) - self.assertEqual(subclass_instance.value2, 20) - - # Test that the type reference count is only decremented once - del subclass_instance - self.assertEqual(type_refcnt - 1, sys.getrefcount(HeapGcCTypeSubclass)) - - def test_subclass_of_heap_gc_ctype_with_del_modifying_dunder_class_only_decrefs_once(self): - class A(_testcapi.HeapGcCType): - def __init__(self): - self.value2 = 20 - super().__init__() - - class B(A): - def __init__(self): - super().__init__() - - def __del__(self): - self.__class__ = A - A.refcnt_in_del = sys.getrefcount(A) - B.refcnt_in_del = sys.getrefcount(B) - - subclass_instance = B() - type_refcnt = sys.getrefcount(B) - new_type_refcnt = sys.getrefcount(A) - - # Test that subclass instance was fully created - self.assertEqual(subclass_instance.value, 10) - self.assertEqual(subclass_instance.value2, 20) - - del subclass_instance - - # Test that setting __class__ modified the reference counts of the types - self.assertEqual(type_refcnt - 1, B.refcnt_in_del) - self.assertEqual(new_type_refcnt + 1, A.refcnt_in_del) - - # Test that the original type already has decreased its refcnt - self.assertEqual(type_refcnt - 1, sys.getrefcount(B)) - - # Test that subtype_dealloc decref the newly assigned __class__ only once - self.assertEqual(new_type_refcnt, sys.getrefcount(A)) - - def test_c_subclass_of_heap_ctype_with_tpdealloc_decrefs_once(self): - subclass_instance = _testcapi.HeapCTypeSubclass() - type_refcnt = sys.getrefcount(_testcapi.HeapCTypeSubclass) - - # Test that subclass instance was fully created - self.assertEqual(subclass_instance.value, 10) - self.assertEqual(subclass_instance.value2, 20) - - # Test that the type reference count is only decremented once - del subclass_instance - self.assertEqual(type_refcnt - 1, sys.getrefcount(_testcapi.HeapCTypeSubclass)) - - def test_c_subclass_of_heap_ctype_with_del_modifying_dunder_class_only_decrefs_once(self): - subclass_instance = _testcapi.HeapCTypeSubclassWithFinalizer() - type_refcnt = sys.getrefcount(_testcapi.HeapCTypeSubclassWithFinalizer) - new_type_refcnt = sys.getrefcount(_testcapi.HeapCTypeSubclass) - - # Test that subclass instance was fully created - self.assertEqual(subclass_instance.value, 10) - self.assertEqual(subclass_instance.value2, 20) - - # The tp_finalize slot will set __class__ to HeapCTypeSubclass - del subclass_instance - - # Test that setting __class__ modified the reference counts of the types - self.assertEqual(type_refcnt - 1, _testcapi.HeapCTypeSubclassWithFinalizer.refcnt_in_del) - self.assertEqual(new_type_refcnt + 1, _testcapi.HeapCTypeSubclass.refcnt_in_del) - - # Test that the original type already has decreased its refcnt - self.assertEqual(type_refcnt - 1, sys.getrefcount(_testcapi.HeapCTypeSubclassWithFinalizer)) - - # Test that subtype_dealloc decref the newly assigned __class__ only once - self.assertEqual(new_type_refcnt, sys.getrefcount(_testcapi.HeapCTypeSubclass)) - - def test_heaptype_with_setattro(self): - obj = _testcapi.HeapCTypeSetattr() - self.assertEqual(obj.pvalue, 10) - obj.value = 12 - self.assertEqual(obj.pvalue, 12) - del obj.value - self.assertEqual(obj.pvalue, 0) - - def test_pynumber_tobase(self): - from _testcapi import pynumber_tobase - self.assertEqual(pynumber_tobase(123, 2), '0b1111011') - self.assertEqual(pynumber_tobase(123, 8), '0o173') - self.assertEqual(pynumber_tobase(123, 10), '123') - self.assertEqual(pynumber_tobase(123, 16), '0x7b') - self.assertEqual(pynumber_tobase(-123, 2), '-0b1111011') - self.assertEqual(pynumber_tobase(-123, 8), '-0o173') - self.assertEqual(pynumber_tobase(-123, 10), '-123') - self.assertEqual(pynumber_tobase(-123, 16), '-0x7b') - self.assertRaises(TypeError, pynumber_tobase, 123.0, 10) - self.assertRaises(TypeError, pynumber_tobase, '123', 10) - self.assertRaises(SystemError, pynumber_tobase, 123, 0) - - - class TestPendingCalls(unittest.TestCase): - - def pendingcalls_submit(self, l, n): - def callback(): - #this function can be interrupted by thread switching so let's - #use an atomic operation - l.append(None) - - for i in range(n): - time.sleep(random.random()*0.02) #0.01 secs on average - #try submitting callback until successful. - #rely on regular interrupt to flush queue if we are - #unsuccessful. - while True: - if _testcapi._pending_threadfunc(callback): - break; - - def pendingcalls_wait(self, l, n, context = None): - #now, stick around until l[0] has grown to 10 - count = 0; - while len(l) != n: - #this busy loop is where we expect to be interrupted to - #run our callbacks. Note that callbacks are only run on the - #main thread - if False and support.verbose: - print("(%i)"%(len(l),),) - for i in range(1000): - a = i*i - if context and not context.event.is_set(): - continue - count += 1 - self.assertTrue(count < 10000, - "timeout waiting for %i callbacks, got %i"%(n, len(l))) - if False and support.verbose: - print("(%i)"%(len(l),)) - - def test_pendingcalls_threaded(self): - - #do every callback on a separate thread - n = 32 #total callbacks - threads = [] - class foo(object):pass - context = foo() - context.l = [] - context.n = 2 #submits per thread - context.nThreads = n // context.n - context.nFinished = 0 - context.lock = threading.Lock() - context.event = threading.Event() - - threads = [threading.Thread(target=self.pendingcalls_thread, - args=(context,)) - for i in range(context.nThreads)] - with support.start_threads(threads): - self.pendingcalls_wait(context.l, n, context) - - def pendingcalls_thread(self, context): - try: - self.pendingcalls_submit(context.l, context.n) - finally: - with context.lock: - context.nFinished += 1 - nFinished = context.nFinished - if False and support.verbose: - print("finished threads: ", nFinished) - if nFinished == context.nThreads: - context.event.set() - - def test_pendingcalls_non_threaded(self): - #again, just using the main thread, likely they will all be dispatched at - #once. It is ok to ask for too many, because we loop until we find a slot. - #the loop can be interrupted to dispatch. - #there are only 32 dispatch slots, so we go for twice that! - l = [] - n = 64 - self.pendingcalls_submit(l, n) - self.pendingcalls_wait(l, n) - - - class SubinterpreterTest(unittest.TestCase): - - def test_subinterps(self): - import builtins - r, w = os.pipe() - code = """if 1: - import sys, builtins, pickle - with open({:d}, "wb") as f: - pickle.dump(id(sys.modules), f) - pickle.dump(id(builtins), f) - """.format(w) - with open(r, "rb") as f: - ret = support.run_in_subinterp(code) - self.assertEqual(ret, 0) - self.assertNotEqual(pickle.load(f), id(sys.modules)) - self.assertNotEqual(pickle.load(f), id(builtins)) - - def test_subinterps_recent_language_features(self): - r, w = os.pipe() - code = """if 1: - import pickle - with open({:d}, "wb") as f: - - def noop(x): return x - - a = (b := f'1{{2}}3') + noop('x') # Py 3.8 (:=) / 3.6 (f'') - - async def foo(arg): return await arg # Py 3.5 - - pickle.dump(dict(a=a, b=b), f) - """.format(w) - - with open(r, "rb") as f: - ret = support.run_in_subinterp(code) - self.assertEqual(ret, 0) - self.assertEqual(pickle.load(f), {'a': '123x', 'b': '123'}) - - def test_mutate_exception(self): - """ - Exceptions saved in global module state get shared between - individual module instances. This test checks whether or not - a change in one interpreter's module gets reflected into the - other ones. - """ - import binascii - - support.run_in_subinterp("import binascii; binascii.Error.foobar = 'foobar'") - - self.assertFalse(hasattr(binascii.Error, "foobar")) - - - class TestThreadState(unittest.TestCase): - - @support.reap_threads - def test_thread_state(self): - # some extra thread-state tests driven via _testcapi - def target(): - idents = [] - - def callback(): - idents.append(threading.get_ident()) - - _testcapi._test_thread_state(callback) - a = b = callback - time.sleep(1) - # Check our main thread is in the list exactly 3 times. - self.assertEqual(idents.count(threading.get_ident()), 3, - "Couldn't find main thread correctly in the list") - - target() - t = threading.Thread(target=target) - t.start() - t.join() - - - class Test_testcapi(unittest.TestCase): - locals().update((name, getattr(_testcapi, name)) - for name in dir(_testcapi) - if name.startswith('test_') and not name.endswith('_code')) - - - class PyMemDebugTests(unittest.TestCase): - PYTHONMALLOC = 'debug' - # '0x04c06e0' or '04C06E0' - PTR_REGEX = r'(?:0x)?[0-9a-fA-F]+' - - def check(self, code): - with support.SuppressCrashReport(): - out = assert_python_failure('-c', code, - PYTHONMALLOC=self.PYTHONMALLOC) - stderr = out.err - return stderr.decode('ascii', 'replace') - - def test_buffer_overflow(self): - out = self.check('import _testcapi; _testcapi.pymem_buffer_overflow()') - regex = (r"Debug memory block at address p={ptr}: API 'm'\n" - r" 16 bytes originally requested\n" - r" The [0-9] pad bytes at p-[0-9] are FORBIDDENBYTE, as expected.\n" - r" The [0-9] pad bytes at tail={ptr} are not all FORBIDDENBYTE \(0x[0-9a-f]{{2}}\):\n" - r" at tail\+0: 0x78 \*\*\* OUCH\n" - r" at tail\+1: 0xfd\n" - r" at tail\+2: 0xfd\n" - r" .*\n" - r"( The block was made by call #[0-9]+ to debug malloc/realloc.\n)?" - r" Data at p: cd cd cd .*\n" - r"\n" - r"Enable tracemalloc to get the memory block allocation traceback\n" - r"\n" - r"Fatal Python error: bad trailing pad byte") - regex = regex.format(ptr=self.PTR_REGEX) - regex = re.compile(regex, flags=re.DOTALL) - self.assertRegex(out, regex) - - def test_api_misuse(self): - out = self.check('import _testcapi; _testcapi.pymem_api_misuse()') - regex = (r"Debug memory block at address p={ptr}: API 'm'\n" - r" 16 bytes originally requested\n" - r" The [0-9] pad bytes at p-[0-9] are FORBIDDENBYTE, as expected.\n" - r" The [0-9] pad bytes at tail={ptr} are FORBIDDENBYTE, as expected.\n" - r"( The block was made by call #[0-9]+ to debug malloc/realloc.\n)?" - r" Data at p: cd cd cd .*\n" - r"\n" - r"Enable tracemalloc to get the memory block allocation traceback\n" - r"\n" - r"Fatal Python error: bad ID: Allocated using API 'm', verified using API 'r'\n") - regex = regex.format(ptr=self.PTR_REGEX) - self.assertRegex(out, regex) - - def check_malloc_without_gil(self, code): - out = self.check(code) - expected = ('Fatal Python error: Python memory allocator called ' - 'without holding the GIL') - self.assertIn(expected, out) - - def test_pymem_malloc_without_gil(self): - # Debug hooks must raise an error if PyMem_Malloc() is called - # without holding the GIL - code = 'import _testcapi; _testcapi.pymem_malloc_without_gil()' - self.check_malloc_without_gil(code) - - def test_pyobject_malloc_without_gil(self): - # Debug hooks must raise an error if PyObject_Malloc() is called - # without holding the GIL - code = 'import _testcapi; _testcapi.pyobject_malloc_without_gil()' - self.check_malloc_without_gil(code) - - def check_pyobject_is_freed(self, func_name): - code = textwrap.dedent(f''' - import gc, os, sys, _testcapi - # Disable the GC to avoid crash on GC collection - gc.disable() - try: - _testcapi.{func_name}() - # Exit immediately to avoid a crash while deallocating - # the invalid object - os._exit(0) - except _testcapi.error: - os._exit(1) - ''') - assert_python_ok('-c', code, PYTHONMALLOC=self.PYTHONMALLOC) - - def test_pyobject_null_is_freed(self): - self.check_pyobject_is_freed('check_pyobject_null_is_freed') - - def test_pyobject_uninitialized_is_freed(self): - self.check_pyobject_is_freed('check_pyobject_uninitialized_is_freed') - - def test_pyobject_forbidden_bytes_is_freed(self): - self.check_pyobject_is_freed('check_pyobject_forbidden_bytes_is_freed') - - def test_pyobject_freed_is_freed(self): - self.check_pyobject_is_freed('check_pyobject_freed_is_freed') - - - class PyMemMallocDebugTests(PyMemDebugTests): - PYTHONMALLOC = 'malloc_debug' - - - @unittest.skipUnless(support.with_pymalloc(), 'need pymalloc') - class PyMemPymallocDebugTests(PyMemDebugTests): - PYTHONMALLOC = 'pymalloc_debug' - - - @unittest.skipUnless(Py_DEBUG, 'need Py_DEBUG') - class PyMemDefaultTests(PyMemDebugTests): - # test default allocator of Python compiled in debug mode - PYTHONMALLOC = '' - - - if __name__ == "__main__": - unittest.main() diff --git a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_cgi.yaml b/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_cgi.yaml deleted file mode 100644 index 041c6ab65..000000000 --- a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_cgi.yaml +++ /dev/null @@ -1,637 +0,0 @@ -python: | - import cgi - import os - import sys - import tempfile - import unittest - from collections import namedtuple - from io import StringIO, BytesIO - from test import support - - class HackedSysModule: - # The regression test will have real values in sys.argv, which - # will completely confuse the test of the cgi module - argv = [] - stdin = sys.stdin - - cgi.sys = HackedSysModule() - - class ComparableException: - def __init__(self, err): - self.err = err - - def __str__(self): - return str(self.err) - - def __eq__(self, anExc): - if not isinstance(anExc, Exception): - return NotImplemented - return (self.err.__class__ == anExc.__class__ and - self.err.args == anExc.args) - - def __getattr__(self, attr): - return getattr(self.err, attr) - - def do_test(buf, method): - env = {} - if method == "GET": - fp = None - env['REQUEST_METHOD'] = 'GET' - env['QUERY_STRING'] = buf - elif method == "POST": - fp = BytesIO(buf.encode('latin-1')) # FieldStorage expects bytes - env['REQUEST_METHOD'] = 'POST' - env['CONTENT_TYPE'] = 'application/x-www-form-urlencoded' - env['CONTENT_LENGTH'] = str(len(buf)) - else: - raise ValueError("unknown method: %s" % method) - try: - return cgi.parse(fp, env, strict_parsing=1) - except Exception as err: - return ComparableException(err) - - parse_strict_test_cases = [ - ("", ValueError("bad query field: ''")), - ("&", ValueError("bad query field: ''")), - ("&&", ValueError("bad query field: ''")), - # Should the next few really be valid? - ("=", {}), - ("=&=", {}), - # This rest seem to make sense - ("=a", {'': ['a']}), - ("&=a", ValueError("bad query field: ''")), - ("=a&", ValueError("bad query field: ''")), - ("=&a", ValueError("bad query field: 'a'")), - ("b=a", {'b': ['a']}), - ("b+=a", {'b ': ['a']}), - ("a=b=a", {'a': ['b=a']}), - ("a=+b=a", {'a': [' b=a']}), - ("&b=a", ValueError("bad query field: ''")), - ("b&=a", ValueError("bad query field: 'b'")), - ("a=a+b&b=b+c", {'a': ['a b'], 'b': ['b c']}), - ("a=a+b&a=b+a", {'a': ['a b', 'b a']}), - ("x=1&y=2.0&z=2-3.%2b0", {'x': ['1'], 'y': ['2.0'], 'z': ['2-3.+0']}), - ("Hbc5161168c542333633315dee1182227:key_store_seqid=400006&cuyer=r&view=bustomer&order_id=0bb2e248638833d48cb7fed300000f1b&expire=964546263&lobale=en-US&kid=130003.300038&ss=env", - {'Hbc5161168c542333633315dee1182227:key_store_seqid': ['400006'], - 'cuyer': ['r'], - 'expire': ['964546263'], - 'kid': ['130003.300038'], - 'lobale': ['en-US'], - 'order_id': ['0bb2e248638833d48cb7fed300000f1b'], - 'ss': ['env'], - 'view': ['bustomer'], - }), - - ("group_id=5470&set=custom&_assigned_to=31392&_status=1&_category=100&SUBMIT=Browse", - {'SUBMIT': ['Browse'], - '_assigned_to': ['31392'], - '_category': ['100'], - '_status': ['1'], - 'group_id': ['5470'], - 'set': ['custom'], - }) - ] - - def norm(seq): - return sorted(seq, key=repr) - - def first_elts(list): - return [p[0] for p in list] - - def first_second_elts(list): - return [(p[0], p[1][0]) for p in list] - - def gen_result(data, environ): - encoding = 'latin-1' - fake_stdin = BytesIO(data.encode(encoding)) - fake_stdin.seek(0) - form = cgi.FieldStorage(fp=fake_stdin, environ=environ, encoding=encoding) - - result = {} - for k, v in dict(form).items(): - result[k] = isinstance(v, list) and form.getlist(k) or v.value - - return result - - class CgiTests(unittest.TestCase): - - def test_parse_multipart(self): - fp = BytesIO(POSTDATA.encode('latin1')) - env = {'boundary': BOUNDARY.encode('latin1'), - 'CONTENT-LENGTH': '558'} - result = cgi.parse_multipart(fp, env) - expected = {'submit': [' Add '], 'id': ['1234'], - 'file': [b'Testing 123.\n'], 'title': ['']} - self.assertEqual(result, expected) - - def test_parse_multipart_without_content_length(self): - POSTDATA = '''--JfISa01 - Content-Disposition: form-data; name="submit-name" - - just a string - - --JfISa01-- - ''' - fp = BytesIO(POSTDATA.encode('latin1')) - env = {'boundary': 'JfISa01'.encode('latin1')} - result = cgi.parse_multipart(fp, env) - expected = {'submit-name': ['just a string\n']} - self.assertEqual(result, expected) - - def test_parse_multipart_invalid_encoding(self): - BOUNDARY = "JfISa01" - POSTDATA = """--JfISa01 - Content-Disposition: form-data; name="submit-name" - Content-Length: 3 - - \u2603 - --JfISa01""" - fp = BytesIO(POSTDATA.encode('utf8')) - env = {'boundary': BOUNDARY.encode('latin1'), - 'CONTENT-LENGTH': str(len(POSTDATA.encode('utf8')))} - result = cgi.parse_multipart(fp, env, encoding="ascii", - errors="surrogateescape") - expected = {'submit-name': ["\udce2\udc98\udc83"]} - self.assertEqual(result, expected) - self.assertEqual("\u2603".encode('utf8'), - result["submit-name"][0].encode('utf8', 'surrogateescape')) - - def test_fieldstorage_properties(self): - fs = cgi.FieldStorage() - self.assertFalse(fs) - self.assertIn("FieldStorage", repr(fs)) - self.assertEqual(list(fs), list(fs.keys())) - fs.list.append(namedtuple('MockFieldStorage', 'name')('fieldvalue')) - self.assertTrue(fs) - - def test_fieldstorage_invalid(self): - self.assertRaises(TypeError, cgi.FieldStorage, "not-a-file-obj", - environ={"REQUEST_METHOD":"PUT"}) - self.assertRaises(TypeError, cgi.FieldStorage, "foo", "bar") - fs = cgi.FieldStorage(headers={'content-type':'text/plain'}) - self.assertRaises(TypeError, bool, fs) - - def test_strict(self): - for orig, expect in parse_strict_test_cases: - # Test basic parsing - d = do_test(orig, "GET") - self.assertEqual(d, expect, "Error parsing %s method GET" % repr(orig)) - d = do_test(orig, "POST") - self.assertEqual(d, expect, "Error parsing %s method POST" % repr(orig)) - - env = {'QUERY_STRING': orig} - fs = cgi.FieldStorage(environ=env) - if isinstance(expect, dict): - # test dict interface - self.assertEqual(len(expect), len(fs)) - self.assertCountEqual(expect.keys(), fs.keys()) - ##self.assertEqual(norm(expect.values()), norm(fs.values())) - ##self.assertEqual(norm(expect.items()), norm(fs.items())) - self.assertEqual(fs.getvalue("nonexistent field", "default"), "default") - # test individual fields - for key in expect.keys(): - expect_val = expect[key] - self.assertIn(key, fs) - if len(expect_val) > 1: - self.assertEqual(fs.getvalue(key), expect_val) - else: - self.assertEqual(fs.getvalue(key), expect_val[0]) - - def test_separator(self): - parse_semicolon = [ - ("x=1;y=2.0", {'x': ['1'], 'y': ['2.0']}), - ("x=1;y=2.0;z=2-3.%2b0", {'x': ['1'], 'y': ['2.0'], 'z': ['2-3.+0']}), - (";", ValueError("bad query field: ''")), - (";;", ValueError("bad query field: ''")), - ("=;a", ValueError("bad query field: 'a'")), - (";b=a", ValueError("bad query field: ''")), - ("b;=a", ValueError("bad query field: 'b'")), - ("a=a+b;b=b+c", {'a': ['a b'], 'b': ['b c']}), - ("a=a+b;a=b+a", {'a': ['a b', 'b a']}), - ] - for orig, expect in parse_semicolon: - env = {'QUERY_STRING': orig} - fs = cgi.FieldStorage(separator=';', environ=env) - if isinstance(expect, dict): - for key in expect.keys(): - expect_val = expect[key] - self.assertIn(key, fs) - if len(expect_val) > 1: - self.assertEqual(fs.getvalue(key), expect_val) - else: - self.assertEqual(fs.getvalue(key), expect_val[0]) - - def test_log(self): - cgi.log("Testing") - - cgi.logfp = StringIO() - cgi.initlog("%s", "Testing initlog 1") - cgi.log("%s", "Testing log 2") - self.assertEqual(cgi.logfp.getvalue(), "Testing initlog 1\nTesting log 2\n") - if os.path.exists(os.devnull): - cgi.logfp = None - cgi.logfile = os.devnull - cgi.initlog("%s", "Testing log 3") - self.addCleanup(cgi.closelog) - cgi.log("Testing log 4") - - def test_fieldstorage_readline(self): - # FieldStorage uses readline, which has the capacity to read all - # contents of the input file into memory; we use readline's size argument - # to prevent that for files that do not contain any newlines in - # non-GET/HEAD requests - class TestReadlineFile: - def __init__(self, file): - self.file = file - self.numcalls = 0 - - def readline(self, size=None): - self.numcalls += 1 - if size: - return self.file.readline(size) - else: - return self.file.readline() - - def __getattr__(self, name): - file = self.__dict__['file'] - a = getattr(file, name) - if not isinstance(a, int): - setattr(self, name, a) - return a - - f = TestReadlineFile(tempfile.TemporaryFile("wb+")) - self.addCleanup(f.close) - f.write(b'x' * 256 * 1024) - f.seek(0) - env = {'REQUEST_METHOD':'PUT'} - fs = cgi.FieldStorage(fp=f, environ=env) - self.addCleanup(fs.file.close) - # if we're not chunking properly, readline is only called twice - # (by read_binary); if we are chunking properly, it will be called 5 times - # as long as the chunksize is 1 << 16. - self.assertGreater(f.numcalls, 2) - f.close() - - def test_fieldstorage_multipart(self): - #Test basic FieldStorage multipart parsing - env = { - 'REQUEST_METHOD': 'POST', - 'CONTENT_TYPE': 'multipart/form-data; boundary={}'.format(BOUNDARY), - 'CONTENT_LENGTH': '558'} - fp = BytesIO(POSTDATA.encode('latin-1')) - fs = cgi.FieldStorage(fp, environ=env, encoding="latin-1") - self.assertEqual(len(fs.list), 4) - expect = [{'name':'id', 'filename':None, 'value':'1234'}, - {'name':'title', 'filename':None, 'value':''}, - {'name':'file', 'filename':'test.txt', 'value':b'Testing 123.\n'}, - {'name':'submit', 'filename':None, 'value':' Add '}] - for x in range(len(fs.list)): - for k, exp in expect[x].items(): - got = getattr(fs.list[x], k) - self.assertEqual(got, exp) - - def test_fieldstorage_multipart_leading_whitespace(self): - env = { - 'REQUEST_METHOD': 'POST', - 'CONTENT_TYPE': 'multipart/form-data; boundary={}'.format(BOUNDARY), - 'CONTENT_LENGTH': '560'} - # Add some leading whitespace to our post data that will cause the - # first line to not be the innerboundary. - fp = BytesIO(b"\r\n" + POSTDATA.encode('latin-1')) - fs = cgi.FieldStorage(fp, environ=env, encoding="latin-1") - self.assertEqual(len(fs.list), 4) - expect = [{'name':'id', 'filename':None, 'value':'1234'}, - {'name':'title', 'filename':None, 'value':''}, - {'name':'file', 'filename':'test.txt', 'value':b'Testing 123.\n'}, - {'name':'submit', 'filename':None, 'value':' Add '}] - for x in range(len(fs.list)): - for k, exp in expect[x].items(): - got = getattr(fs.list[x], k) - self.assertEqual(got, exp) - - def test_fieldstorage_multipart_non_ascii(self): - #Test basic FieldStorage multipart parsing - env = {'REQUEST_METHOD':'POST', - 'CONTENT_TYPE': 'multipart/form-data; boundary={}'.format(BOUNDARY), - 'CONTENT_LENGTH':'558'} - for encoding in ['iso-8859-1','utf-8']: - fp = BytesIO(POSTDATA_NON_ASCII.encode(encoding)) - fs = cgi.FieldStorage(fp, environ=env,encoding=encoding) - self.assertEqual(len(fs.list), 1) - expect = [{'name':'id', 'filename':None, 'value':'\xe7\xf1\x80'}] - for x in range(len(fs.list)): - for k, exp in expect[x].items(): - got = getattr(fs.list[x], k) - self.assertEqual(got, exp) - - def test_fieldstorage_multipart_maxline(self): - # Issue #18167 - maxline = 1 << 16 - self.maxDiff = None - def check(content): - data = """---123 - Content-Disposition: form-data; name="upload"; filename="fake.txt" - Content-Type: text/plain - - %s - ---123-- - """.replace('\n', '\r\n') % content - environ = { - 'CONTENT_LENGTH': str(len(data)), - 'CONTENT_TYPE': 'multipart/form-data; boundary=-123', - 'REQUEST_METHOD': 'POST', - } - self.assertEqual(gen_result(data, environ), - {'upload': content.encode('latin1')}) - check('x' * (maxline - 1)) - check('x' * (maxline - 1) + '\r') - check('x' * (maxline - 1) + '\r' + 'y' * (maxline - 1)) - - def test_fieldstorage_multipart_w3c(self): - # Test basic FieldStorage multipart parsing (W3C sample) - env = { - 'REQUEST_METHOD': 'POST', - 'CONTENT_TYPE': 'multipart/form-data; boundary={}'.format(BOUNDARY_W3), - 'CONTENT_LENGTH': str(len(POSTDATA_W3))} - fp = BytesIO(POSTDATA_W3.encode('latin-1')) - fs = cgi.FieldStorage(fp, environ=env, encoding="latin-1") - self.assertEqual(len(fs.list), 2) - self.assertEqual(fs.list[0].name, 'submit-name') - self.assertEqual(fs.list[0].value, 'Larry') - self.assertEqual(fs.list[1].name, 'files') - files = fs.list[1].value - self.assertEqual(len(files), 2) - expect = [{'name': None, 'filename': 'file1.txt', 'value': b'... contents of file1.txt ...'}, - {'name': None, 'filename': 'file2.gif', 'value': b'...contents of file2.gif...'}] - for x in range(len(files)): - for k, exp in expect[x].items(): - got = getattr(files[x], k) - self.assertEqual(got, exp) - - def test_fieldstorage_part_content_length(self): - BOUNDARY = "JfISa01" - POSTDATA = """--JfISa01 - Content-Disposition: form-data; name="submit-name" - Content-Length: 5 - - Larry - --JfISa01""" - env = { - 'REQUEST_METHOD': 'POST', - 'CONTENT_TYPE': 'multipart/form-data; boundary={}'.format(BOUNDARY), - 'CONTENT_LENGTH': str(len(POSTDATA))} - fp = BytesIO(POSTDATA.encode('latin-1')) - fs = cgi.FieldStorage(fp, environ=env, encoding="latin-1") - self.assertEqual(len(fs.list), 1) - self.assertEqual(fs.list[0].name, 'submit-name') - self.assertEqual(fs.list[0].value, 'Larry') - - def test_field_storage_multipart_no_content_length(self): - fp = BytesIO(b"""--MyBoundary - Content-Disposition: form-data; name="my-arg"; filename="foo" - - Test - - --MyBoundary-- - """) - env = { - "REQUEST_METHOD": "POST", - "CONTENT_TYPE": "multipart/form-data; boundary=MyBoundary", - "wsgi.input": fp, - } - fields = cgi.FieldStorage(fp, environ=env) - - self.assertEqual(len(fields["my-arg"].file.read()), 5) - - def test_fieldstorage_as_context_manager(self): - fp = BytesIO(b'x' * 10) - env = {'REQUEST_METHOD': 'PUT'} - with cgi.FieldStorage(fp=fp, environ=env) as fs: - content = fs.file.read() - self.assertFalse(fs.file.closed) - self.assertTrue(fs.file.closed) - self.assertEqual(content, 'x' * 10) - with self.assertRaisesRegex(ValueError, 'I/O operation on closed file'): - fs.file.read() - - _qs_result = { - 'key1': 'value1', - 'key2': ['value2x', 'value2y'], - 'key3': 'value3', - 'key4': 'value4' - } - def testQSAndUrlEncode(self): - data = "key2=value2x&key3=value3&key4=value4" - environ = { - 'CONTENT_LENGTH': str(len(data)), - 'CONTENT_TYPE': 'application/x-www-form-urlencoded', - 'QUERY_STRING': 'key1=value1&key2=value2y', - 'REQUEST_METHOD': 'POST', - } - v = gen_result(data, environ) - self.assertEqual(self._qs_result, v) - - def test_max_num_fields(self): - # For application/x-www-form-urlencoded - data = '&'.join(['a=a']*11) - environ = { - 'CONTENT_LENGTH': str(len(data)), - 'CONTENT_TYPE': 'application/x-www-form-urlencoded', - 'REQUEST_METHOD': 'POST', - } - - with self.assertRaises(ValueError): - cgi.FieldStorage( - fp=BytesIO(data.encode()), - environ=environ, - max_num_fields=10, - ) - - # For multipart/form-data - data = """---123 - Content-Disposition: form-data; name="a" - - 3 - ---123 - Content-Type: application/x-www-form-urlencoded - - a=4 - ---123 - Content-Type: application/x-www-form-urlencoded - - a=5 - ---123-- - """ - environ = { - 'CONTENT_LENGTH': str(len(data)), - 'CONTENT_TYPE': 'multipart/form-data; boundary=-123', - 'QUERY_STRING': 'a=1&a=2', - 'REQUEST_METHOD': 'POST', - } - - # 2 GET entities - # 1 top level POST entities - # 1 entity within the second POST entity - # 1 entity within the third POST entity - with self.assertRaises(ValueError): - cgi.FieldStorage( - fp=BytesIO(data.encode()), - environ=environ, - max_num_fields=4, - ) - cgi.FieldStorage( - fp=BytesIO(data.encode()), - environ=environ, - max_num_fields=5, - ) - - def testQSAndFormData(self): - data = """---123 - Content-Disposition: form-data; name="key2" - - value2y - ---123 - Content-Disposition: form-data; name="key3" - - value3 - ---123 - Content-Disposition: form-data; name="key4" - - value4 - ---123-- - """ - environ = { - 'CONTENT_LENGTH': str(len(data)), - 'CONTENT_TYPE': 'multipart/form-data; boundary=-123', - 'QUERY_STRING': 'key1=value1&key2=value2x', - 'REQUEST_METHOD': 'POST', - } - v = gen_result(data, environ) - self.assertEqual(self._qs_result, v) - - def testQSAndFormDataFile(self): - data = """---123 - Content-Disposition: form-data; name="key2" - - value2y - ---123 - Content-Disposition: form-data; name="key3" - - value3 - ---123 - Content-Disposition: form-data; name="key4" - - value4 - ---123 - Content-Disposition: form-data; name="upload"; filename="fake.txt" - Content-Type: text/plain - - this is the content of the fake file - - ---123-- - """ - environ = { - 'CONTENT_LENGTH': str(len(data)), - 'CONTENT_TYPE': 'multipart/form-data; boundary=-123', - 'QUERY_STRING': 'key1=value1&key2=value2x', - 'REQUEST_METHOD': 'POST', - } - result = self._qs_result.copy() - result.update({ - 'upload': b'this is the content of the fake file\n' - }) - v = gen_result(data, environ) - self.assertEqual(result, v) - - def test_parse_header(self): - self.assertEqual( - cgi.parse_header("text/plain"), - ("text/plain", {})) - self.assertEqual( - cgi.parse_header("text/vnd.just.made.this.up ; "), - ("text/vnd.just.made.this.up", {})) - self.assertEqual( - cgi.parse_header("text/plain;charset=us-ascii"), - ("text/plain", {"charset": "us-ascii"})) - self.assertEqual( - cgi.parse_header('text/plain ; charset="us-ascii"'), - ("text/plain", {"charset": "us-ascii"})) - self.assertEqual( - cgi.parse_header('text/plain ; charset="us-ascii"; another=opt'), - ("text/plain", {"charset": "us-ascii", "another": "opt"})) - self.assertEqual( - cgi.parse_header('attachment; filename="silly.txt"'), - ("attachment", {"filename": "silly.txt"})) - self.assertEqual( - cgi.parse_header('attachment; filename="strange;name"'), - ("attachment", {"filename": "strange;name"})) - self.assertEqual( - cgi.parse_header('attachment; filename="strange;name";size=123;'), - ("attachment", {"filename": "strange;name", "size": "123"})) - self.assertEqual( - cgi.parse_header('form-data; name="files"; filename="fo\\"o;bar"'), - ("form-data", {"name": "files", "filename": 'fo"o;bar'})) - - def test_all(self): - blacklist = {"logfile", "logfp", "initlog", "dolog", "nolog", - "closelog", "log", "maxlen", "valid_boundary"} - support.check__all__(self, cgi, blacklist=blacklist) - - - BOUNDARY = "---------------------------721837373350705526688164684" - - POSTDATA = """-----------------------------721837373350705526688164684 - Content-Disposition: form-data; name="id" - - 1234 - -----------------------------721837373350705526688164684 - Content-Disposition: form-data; name="title" - - - -----------------------------721837373350705526688164684 - Content-Disposition: form-data; name="file"; filename="test.txt" - Content-Type: text/plain - - Testing 123. - - -----------------------------721837373350705526688164684 - Content-Disposition: form-data; name="submit" - - Add\x20 - -----------------------------721837373350705526688164684-- - """ - - POSTDATA_NON_ASCII = """-----------------------------721837373350705526688164684 - Content-Disposition: form-data; name="id" - - \xe7\xf1\x80 - -----------------------------721837373350705526688164684 - """ - - # http://www.w3.org/TR/html401/interact/forms.html#h-17.13.4 - BOUNDARY_W3 = "AaB03x" - POSTDATA_W3 = """--AaB03x - Content-Disposition: form-data; name="submit-name" - - Larry - --AaB03x - Content-Disposition: form-data; name="files" - Content-Type: multipart/mixed; boundary=BbC04y - - --BbC04y - Content-Disposition: file; filename="file1.txt" - Content-Type: text/plain - - ... contents of file1.txt ... - --BbC04y - Content-Disposition: file; filename="file2.gif" - Content-Type: image/gif - Content-Transfer-Encoding: binary - - ...contents of file2.gif... - --BbC04y-- - --AaB03x-- - """ - - if __name__ == '__main__': - unittest.main() diff --git a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_cgitb.yaml b/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_cgitb.yaml deleted file mode 100644 index 532b6c0f2..000000000 --- a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_cgitb.yaml +++ /dev/null @@ -1,69 +0,0 @@ -python: | - from test.support import temp_dir - from test.support.script_helper import assert_python_failure - import unittest - import sys - import cgitb - - class TestCgitb(unittest.TestCase): - - def test_fonts(self): - text = "Hello Robbie!" - self.assertEqual(cgitb.small(text), "{}".format(text)) - self.assertEqual(cgitb.strong(text), "{}".format(text)) - self.assertEqual(cgitb.grey(text), - '{}'.format(text)) - - def test_blanks(self): - self.assertEqual(cgitb.small(""), "") - self.assertEqual(cgitb.strong(""), "") - self.assertEqual(cgitb.grey(""), "") - - def test_html(self): - try: - raise ValueError("Hello World") - except ValueError as err: - # If the html was templated we could do a bit more here. - # At least check that we get details on what we just raised. - html = cgitb.html(sys.exc_info()) - self.assertIn("ValueError", html) - self.assertIn(str(err), html) - - def test_text(self): - try: - raise ValueError("Hello World") - except ValueError as err: - text = cgitb.text(sys.exc_info()) - self.assertIn("ValueError", text) - self.assertIn("Hello World", text) - - def test_syshook_no_logdir_default_format(self): - with temp_dir() as tracedir: - rc, out, err = assert_python_failure( - '-c', - ('import cgitb; cgitb.enable(logdir=%s); ' - 'raise ValueError("Hello World")') % repr(tracedir)) - out = out.decode(sys.getfilesystemencoding()) - self.assertIn("ValueError", out) - self.assertIn("Hello World", out) - self.assertIn("<module>", out) - # By default we emit HTML markup. - self.assertIn('

', out) - self.assertIn('

', out) - - def test_syshook_no_logdir_text_format(self): - # Issue 12890: we were emitting the

tag in text mode. - with temp_dir() as tracedir: - rc, out, err = assert_python_failure( - '-c', - ('import cgitb; cgitb.enable(format="text", logdir=%s); ' - 'raise ValueError("Hello World")') % repr(tracedir)) - out = out.decode(sys.getfilesystemencoding()) - self.assertIn("ValueError", out) - self.assertIn("Hello World", out) - self.assertNotIn('

', out) - self.assertNotIn('

', out) - - - if __name__ == "__main__": - unittest.main() diff --git a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_charmapcodec.yaml b/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_charmapcodec.yaml deleted file mode 100644 index 5228fa345..000000000 --- a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_charmapcodec.yaml +++ /dev/null @@ -1,54 +0,0 @@ -python: | - """ Python character mapping codec test - - This uses the test codec in testcodec.py and thus also tests the - encodings package lookup scheme. - - Written by Marc-Andre Lemburg (mal@lemburg.com). - - (c) Copyright 2000 Guido van Rossum. - - """#" - - import unittest - - import codecs - - # Register a search function which knows about our codec - def codec_search_function(encoding): - if encoding == 'testcodec': - from test import testcodec - return tuple(testcodec.getregentry()) - return None - - codecs.register(codec_search_function) - - # test codec's name (see test/testcodec.py) - codecname = 'testcodec' - - class CharmapCodecTest(unittest.TestCase): - def test_constructorx(self): - self.assertEqual(str(b'abc', codecname), 'abc') - self.assertEqual(str(b'xdef', codecname), 'abcdef') - self.assertEqual(str(b'defx', codecname), 'defabc') - self.assertEqual(str(b'dxf', codecname), 'dabcf') - self.assertEqual(str(b'dxfx', codecname), 'dabcfabc') - - def test_encodex(self): - self.assertEqual('abc'.encode(codecname), b'abc') - self.assertEqual('xdef'.encode(codecname), b'abcdef') - self.assertEqual('defx'.encode(codecname), b'defabc') - self.assertEqual('dxf'.encode(codecname), b'dabcf') - self.assertEqual('dxfx'.encode(codecname), b'dabcfabc') - - def test_constructory(self): - self.assertEqual(str(b'ydef', codecname), 'def') - self.assertEqual(str(b'defy', codecname), 'def') - self.assertEqual(str(b'dyf', codecname), 'df') - self.assertEqual(str(b'dyfy', codecname), 'df') - - def test_maptoundefined(self): - self.assertRaises(UnicodeError, str, b'abc\001', codecname) - - if __name__ == "__main__": - unittest.main() diff --git a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_class.yaml b/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_class.yaml deleted file mode 100644 index ce440772e..000000000 --- a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_class.yaml +++ /dev/null @@ -1,671 +0,0 @@ -python: | - "Test the functionality of Python classes implementing operators." - - import unittest - - - testmeths = [ - - # Binary operations - "add", - "radd", - "sub", - "rsub", - "mul", - "rmul", - "matmul", - "rmatmul", - "truediv", - "rtruediv", - "floordiv", - "rfloordiv", - "mod", - "rmod", - "divmod", - "rdivmod", - "pow", - "rpow", - "rshift", - "rrshift", - "lshift", - "rlshift", - "and", - "rand", - "or", - "ror", - "xor", - "rxor", - - # List/dict operations - "contains", - "getitem", - "setitem", - "delitem", - - # Unary operations - "neg", - "pos", - "abs", - - # generic operations - "init", - ] - - # These need to return something other than None - # "hash", - # "str", - # "repr", - # "int", - # "float", - - # These are separate because they can influence the test of other methods. - # "getattr", - # "setattr", - # "delattr", - - callLst = [] - def trackCall(f): - def track(*args, **kwargs): - callLst.append((f.__name__, args)) - return f(*args, **kwargs) - return track - - statictests = """ - @trackCall - def __hash__(self, *args): - return hash(id(self)) - - @trackCall - def __str__(self, *args): - return "AllTests" - - @trackCall - def __repr__(self, *args): - return "AllTests" - - @trackCall - def __int__(self, *args): - return 1 - - @trackCall - def __index__(self, *args): - return 1 - - @trackCall - def __float__(self, *args): - return 1.0 - - @trackCall - def __eq__(self, *args): - return True - - @trackCall - def __ne__(self, *args): - return False - - @trackCall - def __lt__(self, *args): - return False - - @trackCall - def __le__(self, *args): - return True - - @trackCall - def __gt__(self, *args): - return False - - @trackCall - def __ge__(self, *args): - return True - """ - - # Synthesize all the other AllTests methods from the names in testmeths. - - method_template = """\ - @trackCall - def __%s__(self, *args): - pass - """ - - d = {} - exec(statictests, globals(), d) - for method in testmeths: - exec(method_template % method, globals(), d) - AllTests = type("AllTests", (object,), d) - del d, statictests, method, method_template - - class ClassTests(unittest.TestCase): - def setUp(self): - callLst[:] = [] - - def assertCallStack(self, expected_calls): - actualCallList = callLst[:] # need to copy because the comparison below will add - # additional calls to callLst - if expected_calls != actualCallList: - self.fail("Expected call list:\n %s\ndoes not match actual call list\n %s" % - (expected_calls, actualCallList)) - - def testInit(self): - foo = AllTests() - self.assertCallStack([("__init__", (foo,))]) - - def testBinaryOps(self): - testme = AllTests() - # Binary operations - - callLst[:] = [] - testme + 1 - self.assertCallStack([("__add__", (testme, 1))]) - - callLst[:] = [] - 1 + testme - self.assertCallStack([("__radd__", (testme, 1))]) - - callLst[:] = [] - testme - 1 - self.assertCallStack([("__sub__", (testme, 1))]) - - callLst[:] = [] - 1 - testme - self.assertCallStack([("__rsub__", (testme, 1))]) - - callLst[:] = [] - testme * 1 - self.assertCallStack([("__mul__", (testme, 1))]) - - callLst[:] = [] - 1 * testme - self.assertCallStack([("__rmul__", (testme, 1))]) - - callLst[:] = [] - testme @ 1 - self.assertCallStack([("__matmul__", (testme, 1))]) - - callLst[:] = [] - 1 @ testme - self.assertCallStack([("__rmatmul__", (testme, 1))]) - - callLst[:] = [] - testme / 1 - self.assertCallStack([("__truediv__", (testme, 1))]) - - - callLst[:] = [] - 1 / testme - self.assertCallStack([("__rtruediv__", (testme, 1))]) - - callLst[:] = [] - testme // 1 - self.assertCallStack([("__floordiv__", (testme, 1))]) - - - callLst[:] = [] - 1 // testme - self.assertCallStack([("__rfloordiv__", (testme, 1))]) - - callLst[:] = [] - testme % 1 - self.assertCallStack([("__mod__", (testme, 1))]) - - callLst[:] = [] - 1 % testme - self.assertCallStack([("__rmod__", (testme, 1))]) - - - callLst[:] = [] - divmod(testme,1) - self.assertCallStack([("__divmod__", (testme, 1))]) - - callLst[:] = [] - divmod(1, testme) - self.assertCallStack([("__rdivmod__", (testme, 1))]) - - callLst[:] = [] - testme ** 1 - self.assertCallStack([("__pow__", (testme, 1))]) - - callLst[:] = [] - 1 ** testme - self.assertCallStack([("__rpow__", (testme, 1))]) - - callLst[:] = [] - testme >> 1 - self.assertCallStack([("__rshift__", (testme, 1))]) - - callLst[:] = [] - 1 >> testme - self.assertCallStack([("__rrshift__", (testme, 1))]) - - callLst[:] = [] - testme << 1 - self.assertCallStack([("__lshift__", (testme, 1))]) - - callLst[:] = [] - 1 << testme - self.assertCallStack([("__rlshift__", (testme, 1))]) - - callLst[:] = [] - testme & 1 - self.assertCallStack([("__and__", (testme, 1))]) - - callLst[:] = [] - 1 & testme - self.assertCallStack([("__rand__", (testme, 1))]) - - callLst[:] = [] - testme | 1 - self.assertCallStack([("__or__", (testme, 1))]) - - callLst[:] = [] - 1 | testme - self.assertCallStack([("__ror__", (testme, 1))]) - - callLst[:] = [] - testme ^ 1 - self.assertCallStack([("__xor__", (testme, 1))]) - - callLst[:] = [] - 1 ^ testme - self.assertCallStack([("__rxor__", (testme, 1))]) - - def testListAndDictOps(self): - testme = AllTests() - - # List/dict operations - - class Empty: pass - - try: - 1 in Empty() - self.fail('failed, should have raised TypeError') - except TypeError: - pass - - callLst[:] = [] - 1 in testme - self.assertCallStack([('__contains__', (testme, 1))]) - - callLst[:] = [] - testme[1] - self.assertCallStack([('__getitem__', (testme, 1))]) - - callLst[:] = [] - testme[1] = 1 - self.assertCallStack([('__setitem__', (testme, 1, 1))]) - - callLst[:] = [] - del testme[1] - self.assertCallStack([('__delitem__', (testme, 1))]) - - callLst[:] = [] - testme[:42] - self.assertCallStack([('__getitem__', (testme, slice(None, 42)))]) - - callLst[:] = [] - testme[:42] = "The Answer" - self.assertCallStack([('__setitem__', (testme, slice(None, 42), - "The Answer"))]) - - callLst[:] = [] - del testme[:42] - self.assertCallStack([('__delitem__', (testme, slice(None, 42)))]) - - callLst[:] = [] - testme[2:1024:10] - self.assertCallStack([('__getitem__', (testme, slice(2, 1024, 10)))]) - - callLst[:] = [] - testme[2:1024:10] = "A lot" - self.assertCallStack([('__setitem__', (testme, slice(2, 1024, 10), - "A lot"))]) - callLst[:] = [] - del testme[2:1024:10] - self.assertCallStack([('__delitem__', (testme, slice(2, 1024, 10)))]) - - callLst[:] = [] - testme[:42, ..., :24:, 24, 100] - self.assertCallStack([('__getitem__', (testme, (slice(None, 42, None), - Ellipsis, - slice(None, 24, None), - 24, 100)))]) - callLst[:] = [] - testme[:42, ..., :24:, 24, 100] = "Strange" - self.assertCallStack([('__setitem__', (testme, (slice(None, 42, None), - Ellipsis, - slice(None, 24, None), - 24, 100), "Strange"))]) - callLst[:] = [] - del testme[:42, ..., :24:, 24, 100] - self.assertCallStack([('__delitem__', (testme, (slice(None, 42, None), - Ellipsis, - slice(None, 24, None), - 24, 100)))]) - - def testUnaryOps(self): - testme = AllTests() - - callLst[:] = [] - -testme - self.assertCallStack([('__neg__', (testme,))]) - callLst[:] = [] - +testme - self.assertCallStack([('__pos__', (testme,))]) - callLst[:] = [] - abs(testme) - self.assertCallStack([('__abs__', (testme,))]) - callLst[:] = [] - int(testme) - self.assertCallStack([('__int__', (testme,))]) - callLst[:] = [] - float(testme) - self.assertCallStack([('__float__', (testme,))]) - callLst[:] = [] - oct(testme) - self.assertCallStack([('__index__', (testme,))]) - callLst[:] = [] - hex(testme) - self.assertCallStack([('__index__', (testme,))]) - - - def testMisc(self): - testme = AllTests() - - callLst[:] = [] - hash(testme) - self.assertCallStack([('__hash__', (testme,))]) - - callLst[:] = [] - repr(testme) - self.assertCallStack([('__repr__', (testme,))]) - - callLst[:] = [] - str(testme) - self.assertCallStack([('__str__', (testme,))]) - - callLst[:] = [] - testme == 1 - self.assertCallStack([('__eq__', (testme, 1))]) - - callLst[:] = [] - testme < 1 - self.assertCallStack([('__lt__', (testme, 1))]) - - callLst[:] = [] - testme > 1 - self.assertCallStack([('__gt__', (testme, 1))]) - - callLst[:] = [] - testme != 1 - self.assertCallStack([('__ne__', (testme, 1))]) - - callLst[:] = [] - 1 == testme - self.assertCallStack([('__eq__', (1, testme))]) - - callLst[:] = [] - 1 < testme - self.assertCallStack([('__gt__', (1, testme))]) - - callLst[:] = [] - 1 > testme - self.assertCallStack([('__lt__', (1, testme))]) - - callLst[:] = [] - 1 != testme - self.assertCallStack([('__ne__', (1, testme))]) - - - def testGetSetAndDel(self): - # Interfering tests - class ExtraTests(AllTests): - @trackCall - def __getattr__(self, *args): - return "SomeVal" - - @trackCall - def __setattr__(self, *args): - pass - - @trackCall - def __delattr__(self, *args): - pass - - testme = ExtraTests() - - callLst[:] = [] - testme.spam - self.assertCallStack([('__getattr__', (testme, "spam"))]) - - callLst[:] = [] - testme.eggs = "spam, spam, spam and ham" - self.assertCallStack([('__setattr__', (testme, "eggs", - "spam, spam, spam and ham"))]) - - callLst[:] = [] - del testme.cardinal - self.assertCallStack([('__delattr__', (testme, "cardinal"))]) - - def testDel(self): - x = [] - - class DelTest: - def __del__(self): - x.append("crab people, crab people") - testme = DelTest() - del testme - import gc - gc.collect() - self.assertEqual(["crab people, crab people"], x) - - def testBadTypeReturned(self): - # return values of some method are type-checked - class BadTypeClass: - def __int__(self): - return None - __float__ = __int__ - __complex__ = __int__ - __str__ = __int__ - __repr__ = __int__ - __bytes__ = __int__ - __bool__ = __int__ - __index__ = __int__ - def index(x): - return [][x] - - for f in [float, complex, str, repr, bytes, bin, oct, hex, bool, index]: - self.assertRaises(TypeError, f, BadTypeClass()) - - def testHashStuff(self): - # Test correct errors from hash() on objects with comparisons but - # no __hash__ - - class C0: - pass - - hash(C0()) # This should work; the next two should raise TypeError - - class C2: - def __eq__(self, other): return 1 - - self.assertRaises(TypeError, hash, C2()) - - - def testSFBug532646(self): - # Test for SF bug 532646 - - class A: - pass - A.__call__ = A() - a = A() - - try: - a() # This should not segfault - except RecursionError: - pass - else: - self.fail("Failed to raise RecursionError") - - def testForExceptionsRaisedInInstanceGetattr2(self): - # Tests for exceptions raised in instance_getattr2(). - - def booh(self): - raise AttributeError("booh") - - class A: - a = property(booh) - try: - A().a # Raised AttributeError: A instance has no attribute 'a' - except AttributeError as x: - if str(x) != "booh": - self.fail("attribute error for A().a got masked: %s" % x) - - class E: - __eq__ = property(booh) - E() == E() # In debug mode, caused a C-level assert() to fail - - class I: - __init__ = property(booh) - try: - # In debug mode, printed XXX undetected error and - # raises AttributeError - I() - except AttributeError as x: - pass - else: - self.fail("attribute error for I.__init__ got masked") - - def assertNotOrderable(self, a, b): - with self.assertRaises(TypeError): - a < b - with self.assertRaises(TypeError): - a > b - with self.assertRaises(TypeError): - a <= b - with self.assertRaises(TypeError): - a >= b - - def testHashComparisonOfMethods(self): - # Test comparison and hash of methods - class A: - def __init__(self, x): - self.x = x - def f(self): - pass - def g(self): - pass - def __eq__(self, other): - return True - def __hash__(self): - raise TypeError - class B(A): - pass - - a1 = A(1) - a2 = A(1) - self.assertTrue(a1.f == a1.f) - self.assertFalse(a1.f != a1.f) - self.assertFalse(a1.f == a2.f) - self.assertTrue(a1.f != a2.f) - self.assertFalse(a1.f == a1.g) - self.assertTrue(a1.f != a1.g) - self.assertNotOrderable(a1.f, a1.f) - self.assertEqual(hash(a1.f), hash(a1.f)) - - self.assertFalse(A.f == a1.f) - self.assertTrue(A.f != a1.f) - self.assertFalse(A.f == A.g) - self.assertTrue(A.f != A.g) - self.assertTrue(B.f == A.f) - self.assertFalse(B.f != A.f) - self.assertNotOrderable(A.f, A.f) - self.assertEqual(hash(B.f), hash(A.f)) - - # the following triggers a SystemError in 2.4 - a = A(hash(A.f)^(-1)) - hash(a.f) - - def testSetattrWrapperNameIntern(self): - # Issue #25794: __setattr__ should intern the attribute name - class A: - pass - - def add(self, other): - return 'summa' - - name = str(b'__add__', 'ascii') # shouldn't be optimized - self.assertIsNot(name, '__add__') # not interned - type.__setattr__(A, name, add) - self.assertEqual(A() + 1, 'summa') - - name2 = str(b'__add__', 'ascii') - self.assertIsNot(name2, '__add__') - self.assertIsNot(name2, name) - type.__delattr__(A, name2) - with self.assertRaises(TypeError): - A() + 1 - - def testSetattrNonStringName(self): - class A: - pass - - with self.assertRaises(TypeError): - type.__setattr__(A, b'x', None) - - def testConstructorErrorMessages(self): - # bpo-31506: Improves the error message logic for object_new & object_init - - # Class without any method overrides - class C: - pass - - error_msg = r'C.__init__\(\) takes exactly one argument \(the instance to initialize\)' - - with self.assertRaisesRegex(TypeError, r'C\(\) takes no arguments'): - C(42) - - with self.assertRaisesRegex(TypeError, r'C\(\) takes no arguments'): - C.__new__(C, 42) - - with self.assertRaisesRegex(TypeError, error_msg): - C().__init__(42) - - with self.assertRaisesRegex(TypeError, r'C\(\) takes no arguments'): - object.__new__(C, 42) - - with self.assertRaisesRegex(TypeError, error_msg): - object.__init__(C(), 42) - - # Class with both `__init__` & `__new__` method overridden - class D: - def __new__(cls, *args, **kwargs): - super().__new__(cls, *args, **kwargs) - def __init__(self, *args, **kwargs): - super().__init__(*args, **kwargs) - - error_msg = r'object.__new__\(\) takes exactly one argument \(the type to instantiate\)' - - with self.assertRaisesRegex(TypeError, error_msg): - D(42) - - with self.assertRaisesRegex(TypeError, error_msg): - D.__new__(D, 42) - - with self.assertRaisesRegex(TypeError, error_msg): - object.__new__(D, 42) - - # Class that only overrides __init__ - class E: - def __init__(self, *args, **kwargs): - super().__init__(*args, **kwargs) - - error_msg = r'object.__init__\(\) takes exactly one argument \(the instance to initialize\)' - - with self.assertRaisesRegex(TypeError, error_msg): - E().__init__(42) - - with self.assertRaisesRegex(TypeError, error_msg): - object.__init__(E(), 42) - - if __name__ == '__main__': - unittest.main() diff --git a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_clinic.yaml b/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_clinic.yaml deleted file mode 100644 index 6e448ed0e..000000000 --- a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_clinic.yaml +++ /dev/null @@ -1,831 +0,0 @@ -python: | - # Argument Clinic - # Copyright 2012-2013 by Larry Hastings. - # Licensed to the PSF under a contributor agreement. - - from test import support - from unittest import TestCase - import collections - import inspect - import os.path - import sys - import unittest - - - clinic_path = os.path.join(os.path.dirname(__file__), '..', '..', 'Tools', 'clinic') - clinic_path = os.path.normpath(clinic_path) - if not os.path.exists(clinic_path): - raise unittest.SkipTest(f'{clinic_path!r} path does not exist') - sys.path.append(clinic_path) - try: - import clinic - from clinic import DSLParser - finally: - del sys.path[-1] - - - class FakeConverter: - def __init__(self, name, args): - self.name = name - self.args = args - - - class FakeConverterFactory: - def __init__(self, name): - self.name = name - - def __call__(self, name, default, **kwargs): - return FakeConverter(self.name, kwargs) - - - class FakeConvertersDict: - def __init__(self): - self.used_converters = {} - - def get(self, name, default): - return self.used_converters.setdefault(name, FakeConverterFactory(name)) - - c = clinic.Clinic(language='C', filename = "file") - - class FakeClinic: - def __init__(self): - self.converters = FakeConvertersDict() - self.legacy_converters = FakeConvertersDict() - self.language = clinic.CLanguage(None) - self.filename = None - self.destination_buffers = {} - self.block_parser = clinic.BlockParser('', self.language) - self.modules = collections.OrderedDict() - self.classes = collections.OrderedDict() - clinic.clinic = self - self.name = "FakeClinic" - self.line_prefix = self.line_suffix = '' - self.destinations = {} - self.add_destination("block", "buffer") - self.add_destination("file", "buffer") - self.add_destination("suppress", "suppress") - d = self.destinations.get - self.field_destinations = collections.OrderedDict(( - ('docstring_prototype', d('suppress')), - ('docstring_definition', d('block')), - ('methoddef_define', d('block')), - ('impl_prototype', d('block')), - ('parser_prototype', d('suppress')), - ('parser_definition', d('block')), - ('impl_definition', d('block')), - )) - - def get_destination(self, name): - d = self.destinations.get(name) - if not d: - sys.exit("Destination does not exist: " + repr(name)) - return d - - def add_destination(self, name, type, *args): - if name in self.destinations: - sys.exit("Destination already exists: " + repr(name)) - self.destinations[name] = clinic.Destination(name, type, self, *args) - - def is_directive(self, name): - return name == "module" - - def directive(self, name, args): - self.called_directives[name] = args - - _module_and_class = clinic.Clinic._module_and_class - - class ClinicWholeFileTest(TestCase): - def test_eol(self): - # regression test: - # clinic's block parser didn't recognize - # the "end line" for the block if it - # didn't end in "\n" (as in, the last) - # byte of the file was '/'. - # so it would spit out an end line for you. - # and since you really already had one, - # the last line of the block got corrupted. - c = clinic.Clinic(clinic.CLanguage(None), filename="file") - raw = "/*[clinic]\nfoo\n[clinic]*/" - cooked = c.parse(raw).splitlines() - end_line = cooked[2].rstrip() - # this test is redundant, it's just here explicitly to catch - # the regression test so we don't forget what it looked like - self.assertNotEqual(end_line, "[clinic]*/[clinic]*/") - self.assertEqual(end_line, "[clinic]*/") - - - - class ClinicGroupPermuterTest(TestCase): - def _test(self, l, m, r, output): - computed = clinic.permute_optional_groups(l, m, r) - self.assertEqual(output, computed) - - def test_range(self): - self._test([['start']], ['stop'], [['step']], - ( - ('stop',), - ('start', 'stop',), - ('start', 'stop', 'step',), - )) - - def test_add_window(self): - self._test([['x', 'y']], ['ch'], [['attr']], - ( - ('ch',), - ('ch', 'attr'), - ('x', 'y', 'ch',), - ('x', 'y', 'ch', 'attr'), - )) - - def test_ludicrous(self): - self._test([['a1', 'a2', 'a3'], ['b1', 'b2']], ['c1'], [['d1', 'd2'], ['e1', 'e2', 'e3']], - ( - ('c1',), - ('b1', 'b2', 'c1'), - ('b1', 'b2', 'c1', 'd1', 'd2'), - ('a1', 'a2', 'a3', 'b1', 'b2', 'c1'), - ('a1', 'a2', 'a3', 'b1', 'b2', 'c1', 'd1', 'd2'), - ('a1', 'a2', 'a3', 'b1', 'b2', 'c1', 'd1', 'd2', 'e1', 'e2', 'e3'), - )) - - def test_right_only(self): - self._test([], [], [['a'],['b'],['c']], - ( - (), - ('a',), - ('a', 'b'), - ('a', 'b', 'c') - )) - - def test_have_left_options_but_required_is_empty(self): - def fn(): - clinic.permute_optional_groups(['a'], [], []) - self.assertRaises(AssertionError, fn) - - - class ClinicLinearFormatTest(TestCase): - def _test(self, input, output, **kwargs): - computed = clinic.linear_format(input, **kwargs) - self.assertEqual(output, computed) - - def test_empty_strings(self): - self._test('', '') - - def test_solo_newline(self): - self._test('\n', '\n') - - def test_no_substitution(self): - self._test(""" - abc - """, """ - abc - """) - - def test_empty_substitution(self): - self._test(""" - abc - {name} - def - """, """ - abc - def - """, name='') - - def test_single_line_substitution(self): - self._test(""" - abc - {name} - def - """, """ - abc - GARGLE - def - """, name='GARGLE') - - def test_multiline_substitution(self): - self._test(""" - abc - {name} - def - """, """ - abc - bingle - bungle - - def - """, name='bingle\nbungle\n') - - class InertParser: - def __init__(self, clinic): - pass - - def parse(self, block): - pass - - class CopyParser: - def __init__(self, clinic): - pass - - def parse(self, block): - block.output = block.input - - - class ClinicBlockParserTest(TestCase): - def _test(self, input, output): - language = clinic.CLanguage(None) - - blocks = list(clinic.BlockParser(input, language)) - writer = clinic.BlockPrinter(language) - for block in blocks: - writer.print_block(block) - output = writer.f.getvalue() - assert output == input, "output != input!\n\noutput " + repr(output) + "\n\n input " + repr(input) - - def round_trip(self, input): - return self._test(input, input) - - def test_round_trip_1(self): - self.round_trip(""" - verbatim text here - lah dee dah - """) - def test_round_trip_2(self): - self.round_trip(""" - verbatim text here - lah dee dah - /*[inert] - abc - [inert]*/ - def - /*[inert checksum: 7b18d017f89f61cf17d47f92749ea6930a3f1deb]*/ - xyz - """) - - def _test_clinic(self, input, output): - language = clinic.CLanguage(None) - c = clinic.Clinic(language, filename="file") - c.parsers['inert'] = InertParser(c) - c.parsers['copy'] = CopyParser(c) - computed = c.parse(input) - self.assertEqual(output, computed) - - def test_clinic_1(self): - self._test_clinic(""" - verbatim text here - lah dee dah - /*[copy input] - def - [copy start generated code]*/ - abc - /*[copy end generated code: output=03cfd743661f0797 input=7b18d017f89f61cf]*/ - xyz - """, """ - verbatim text here - lah dee dah - /*[copy input] - def - [copy start generated code]*/ - def - /*[copy end generated code: output=7b18d017f89f61cf input=7b18d017f89f61cf]*/ - xyz - """) - - - class ClinicParserTest(TestCase): - def test_trivial(self): - parser = DSLParser(FakeClinic()) - block = clinic.Block("module os\nos.access") - parser.parse(block) - module, function = block.signatures - self.assertEqual("access", function.name) - self.assertEqual("os", module.name) - - def test_ignore_line(self): - block = self.parse("#\nmodule os\nos.access") - module, function = block.signatures - self.assertEqual("access", function.name) - self.assertEqual("os", module.name) - - def test_param(self): - function = self.parse_function("module os\nos.access\n path: int") - self.assertEqual("access", function.name) - self.assertEqual(2, len(function.parameters)) - p = function.parameters['path'] - self.assertEqual('path', p.name) - self.assertIsInstance(p.converter, clinic.int_converter) - - def test_param_default(self): - function = self.parse_function("module os\nos.access\n follow_symlinks: bool = True") - p = function.parameters['follow_symlinks'] - self.assertEqual(True, p.default) - - def test_param_with_continuations(self): - function = self.parse_function("module os\nos.access\n follow_symlinks: \\\n bool \\\n =\\\n True") - p = function.parameters['follow_symlinks'] - self.assertEqual(True, p.default) - - def test_param_default_expression(self): - function = self.parse_function("module os\nos.access\n follow_symlinks: int(c_default='MAXSIZE') = sys.maxsize") - p = function.parameters['follow_symlinks'] - self.assertEqual(sys.maxsize, p.default) - self.assertEqual("MAXSIZE", p.converter.c_default) - - s = self.parse_function_should_fail("module os\nos.access\n follow_symlinks: int = sys.maxsize") - self.assertEqual(s, "Error on line 0:\nWhen you specify a named constant ('sys.maxsize') as your default value,\nyou MUST specify a valid c_default.\n") - - def test_param_no_docstring(self): - function = self.parse_function(""" - module os - os.access - follow_symlinks: bool = True - something_else: str = ''""") - p = function.parameters['follow_symlinks'] - self.assertEqual(3, len(function.parameters)) - self.assertIsInstance(function.parameters['something_else'].converter, clinic.str_converter) - - def test_param_default_parameters_out_of_order(self): - s = self.parse_function_should_fail(""" - module os - os.access - follow_symlinks: bool = True - something_else: str""") - self.assertEqual(s, """Error on line 0: - Can't have a parameter without a default ('something_else') - after a parameter with a default! - """) - - def disabled_test_converter_arguments(self): - function = self.parse_function("module os\nos.access\n path: path_t(allow_fd=1)") - p = function.parameters['path'] - self.assertEqual(1, p.converter.args['allow_fd']) - - def test_function_docstring(self): - function = self.parse_function(""" - module os - os.stat as os_stat_fn - - path: str - Path to be examined - - Perform a stat system call on the given path.""") - self.assertEqual(""" - stat($module, /, path) - -- - - Perform a stat system call on the given path. - - path - Path to be examined - """.strip(), function.docstring) - - def test_explicit_parameters_in_docstring(self): - function = self.parse_function(""" - module foo - foo.bar - x: int - Documentation for x. - y: int - - This is the documentation for foo. - - Okay, we're done here. - """) - self.assertEqual(""" - bar($module, /, x, y) - -- - - This is the documentation for foo. - - x - Documentation for x. - - Okay, we're done here. - """.strip(), function.docstring) - - def test_parser_regression_special_character_in_parameter_column_of_docstring_first_line(self): - function = self.parse_function(""" - module os - os.stat - path: str - This/used to break Clinic! - """) - self.assertEqual("stat($module, /, path)\n--\n\nThis/used to break Clinic!", function.docstring) - - def test_c_name(self): - function = self.parse_function("module os\nos.stat as os_stat_fn") - self.assertEqual("os_stat_fn", function.c_basename) - - def test_return_converter(self): - function = self.parse_function("module os\nos.stat -> int") - self.assertIsInstance(function.return_converter, clinic.int_return_converter) - - def test_star(self): - function = self.parse_function("module os\nos.access\n *\n follow_symlinks: bool = True") - p = function.parameters['follow_symlinks'] - self.assertEqual(inspect.Parameter.KEYWORD_ONLY, p.kind) - self.assertEqual(0, p.group) - - def test_group(self): - function = self.parse_function("module window\nwindow.border\n [\n ls : int\n ]\n /\n") - p = function.parameters['ls'] - self.assertEqual(1, p.group) - - def test_left_group(self): - function = self.parse_function(""" - module curses - curses.addch - [ - y: int - Y-coordinate. - x: int - X-coordinate. - ] - ch: char - Character to add. - [ - attr: long - Attributes for the character. - ] - / - """) - for name, group in ( - ('y', -1), ('x', -1), - ('ch', 0), - ('attr', 1), - ): - p = function.parameters[name] - self.assertEqual(p.group, group) - self.assertEqual(p.kind, inspect.Parameter.POSITIONAL_ONLY) - self.assertEqual(function.docstring.strip(), """ - addch([y, x,] ch, [attr]) - - - y - Y-coordinate. - x - X-coordinate. - ch - Character to add. - attr - Attributes for the character. - """.strip()) - - def test_nested_groups(self): - function = self.parse_function(""" - module curses - curses.imaginary - [ - [ - y1: int - Y-coordinate. - y2: int - Y-coordinate. - ] - x1: int - X-coordinate. - x2: int - X-coordinate. - ] - ch: char - Character to add. - [ - attr1: long - Attributes for the character. - attr2: long - Attributes for the character. - attr3: long - Attributes for the character. - [ - attr4: long - Attributes for the character. - attr5: long - Attributes for the character. - attr6: long - Attributes for the character. - ] - ] - / - """) - for name, group in ( - ('y1', -2), ('y2', -2), - ('x1', -1), ('x2', -1), - ('ch', 0), - ('attr1', 1), ('attr2', 1), ('attr3', 1), - ('attr4', 2), ('attr5', 2), ('attr6', 2), - ): - p = function.parameters[name] - self.assertEqual(p.group, group) - self.assertEqual(p.kind, inspect.Parameter.POSITIONAL_ONLY) - - self.assertEqual(function.docstring.strip(), """ - imaginary([[y1, y2,] x1, x2,] ch, [attr1, attr2, attr3, [attr4, attr5, - attr6]]) - - - y1 - Y-coordinate. - y2 - Y-coordinate. - x1 - X-coordinate. - x2 - X-coordinate. - ch - Character to add. - attr1 - Attributes for the character. - attr2 - Attributes for the character. - attr3 - Attributes for the character. - attr4 - Attributes for the character. - attr5 - Attributes for the character. - attr6 - Attributes for the character. - """.strip()) - - def parse_function_should_fail(self, s): - with support.captured_stdout() as stdout: - with self.assertRaises(SystemExit): - self.parse_function(s) - return stdout.getvalue() - - def test_disallowed_grouping__two_top_groups_on_left(self): - s = self.parse_function_should_fail(""" - module foo - foo.two_top_groups_on_left - [ - group1 : int - ] - [ - group2 : int - ] - param: int - """) - self.assertEqual(s, - ('Error on line 0:\n' - 'Function two_top_groups_on_left has an unsupported group configuration. (Unexpected state 2.b)\n')) - - def test_disallowed_grouping__two_top_groups_on_right(self): - self.parse_function_should_fail(""" - module foo - foo.two_top_groups_on_right - param: int - [ - group1 : int - ] - [ - group2 : int - ] - """) - - def test_disallowed_grouping__parameter_after_group_on_right(self): - self.parse_function_should_fail(""" - module foo - foo.parameter_after_group_on_right - param: int - [ - [ - group1 : int - ] - group2 : int - ] - """) - - def test_disallowed_grouping__group_after_parameter_on_left(self): - self.parse_function_should_fail(""" - module foo - foo.group_after_parameter_on_left - [ - group2 : int - [ - group1 : int - ] - ] - param: int - """) - - def test_disallowed_grouping__empty_group_on_left(self): - self.parse_function_should_fail(""" - module foo - foo.empty_group - [ - [ - ] - group2 : int - ] - param: int - """) - - def test_disallowed_grouping__empty_group_on_right(self): - self.parse_function_should_fail(""" - module foo - foo.empty_group - param: int - [ - [ - ] - group2 : int - ] - """) - - def test_no_parameters(self): - function = self.parse_function(""" - module foo - foo.bar - - Docstring - - """) - self.assertEqual("bar($module, /)\n--\n\nDocstring", function.docstring) - self.assertEqual(1, len(function.parameters)) # self! - - def test_init_with_no_parameters(self): - function = self.parse_function(""" - module foo - class foo.Bar "unused" "notneeded" - foo.Bar.__init__ - - Docstring - - """, signatures_in_block=3, function_index=2) - # self is not in the signature - self.assertEqual("Bar()\n--\n\nDocstring", function.docstring) - # but it *is* a parameter - self.assertEqual(1, len(function.parameters)) - - def test_illegal_module_line(self): - self.parse_function_should_fail(""" - module foo - foo.bar => int - / - """) - - def test_illegal_c_basename(self): - self.parse_function_should_fail(""" - module foo - foo.bar as 935 - / - """) - - def test_single_star(self): - self.parse_function_should_fail(""" - module foo - foo.bar - * - * - """) - - def test_parameters_required_after_star_without_initial_parameters_or_docstring(self): - self.parse_function_should_fail(""" - module foo - foo.bar - * - """) - - def test_parameters_required_after_star_without_initial_parameters_with_docstring(self): - self.parse_function_should_fail(""" - module foo - foo.bar - * - Docstring here. - """) - - def test_parameters_required_after_star_with_initial_parameters_without_docstring(self): - self.parse_function_should_fail(""" - module foo - foo.bar - this: int - * - """) - - def test_parameters_required_after_star_with_initial_parameters_and_docstring(self): - self.parse_function_should_fail(""" - module foo - foo.bar - this: int - * - Docstring. - """) - - def test_single_slash(self): - self.parse_function_should_fail(""" - module foo - foo.bar - / - / - """) - - def test_mix_star_and_slash(self): - self.parse_function_should_fail(""" - module foo - foo.bar - x: int - y: int - * - z: int - / - """) - - def test_parameters_not_permitted_after_slash_for_now(self): - self.parse_function_should_fail(""" - module foo - foo.bar - / - x: int - """) - - def test_function_not_at_column_0(self): - function = self.parse_function(""" - module foo - foo.bar - x: int - Nested docstring here, goeth. - * - y: str - Not at column 0! - """) - self.assertEqual(""" - bar($module, /, x, *, y) - -- - - Not at column 0! - - x - Nested docstring here, goeth. - """.strip(), function.docstring) - - def test_directive(self): - c = FakeClinic() - parser = DSLParser(c) - parser.flag = False - parser.directives['setflag'] = lambda : setattr(parser, 'flag', True) - block = clinic.Block("setflag") - parser.parse(block) - self.assertTrue(parser.flag) - - def test_legacy_converters(self): - block = self.parse('module os\nos.access\n path: "s"') - module, function = block.signatures - self.assertIsInstance((function.parameters['path']).converter, clinic.str_converter) - - def parse(self, text): - c = FakeClinic() - parser = DSLParser(c) - block = clinic.Block(text) - parser.parse(block) - return block - - def parse_function(self, text, signatures_in_block=2, function_index=1): - block = self.parse(text) - s = block.signatures - self.assertEqual(len(s), signatures_in_block) - assert isinstance(s[0], clinic.Module) - assert isinstance(s[function_index], clinic.Function) - return s[function_index] - - def test_scaffolding(self): - # test repr on special values - self.assertEqual(repr(clinic.unspecified), '') - self.assertEqual(repr(clinic.NULL), '') - - # test that fail fails - with support.captured_stdout() as stdout: - with self.assertRaises(SystemExit): - clinic.fail('The igloos are melting!', filename='clown.txt', line_number=69) - self.assertEqual(stdout.getvalue(), 'Error in file "clown.txt" on line 69:\nThe igloos are melting!\n') - - - class ClinicExternalTest(TestCase): - maxDiff = None - - def test_external(self): - # bpo-42398: Test that the destination file is left unchanged if the - # content does not change. Moreover, check also that the file - # modification time does not change in this case. - source = support.findfile('clinic.test') - with open(source, 'r', encoding='utf-8') as f: - orig_contents = f.read() - - with support.temp_dir() as tmp_dir: - testfile = os.path.join(tmp_dir, 'clinic.test.c') - with open(testfile, 'w', encoding='utf-8') as f: - f.write(orig_contents) - old_mtime_ns = os.stat(testfile).st_mtime_ns - - clinic.parse_file(testfile) - - with open(testfile, 'r', encoding='utf-8') as f: - new_contents = f.read() - new_mtime_ns = os.stat(testfile).st_mtime_ns - - self.assertEqual(new_contents, orig_contents) - # Don't change the file modification time - # if the content does not change - self.assertEqual(new_mtime_ns, old_mtime_ns) - - - if __name__ == "__main__": - unittest.main() diff --git a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_cmath.yaml b/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_cmath.yaml deleted file mode 100644 index 431a0d033..000000000 --- a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_cmath.yaml +++ /dev/null @@ -1,641 +0,0 @@ -python: | - from test.support import requires_IEEE_754, cpython_only - from test.test_math import parse_testfile, test_file - import test.test_math as test_math - import unittest - import cmath, math - from cmath import phase, polar, rect, pi - import platform - import sys - - - INF = float('inf') - NAN = float('nan') - - complex_zeros = [complex(x, y) for x in [0.0, -0.0] for y in [0.0, -0.0]] - complex_infinities = [complex(x, y) for x, y in [ - (INF, 0.0), # 1st quadrant - (INF, 2.3), - (INF, INF), - (2.3, INF), - (0.0, INF), - (-0.0, INF), # 2nd quadrant - (-2.3, INF), - (-INF, INF), - (-INF, 2.3), - (-INF, 0.0), - (-INF, -0.0), # 3rd quadrant - (-INF, -2.3), - (-INF, -INF), - (-2.3, -INF), - (-0.0, -INF), - (0.0, -INF), # 4th quadrant - (2.3, -INF), - (INF, -INF), - (INF, -2.3), - (INF, -0.0) - ]] - complex_nans = [complex(x, y) for x, y in [ - (NAN, -INF), - (NAN, -2.3), - (NAN, -0.0), - (NAN, 0.0), - (NAN, 2.3), - (NAN, INF), - (-INF, NAN), - (-2.3, NAN), - (-0.0, NAN), - (0.0, NAN), - (2.3, NAN), - (INF, NAN) - ]] - - class CMathTests(unittest.TestCase): - # list of all functions in cmath - test_functions = [getattr(cmath, fname) for fname in [ - 'acos', 'acosh', 'asin', 'asinh', 'atan', 'atanh', - 'cos', 'cosh', 'exp', 'log', 'log10', 'sin', 'sinh', - 'sqrt', 'tan', 'tanh']] - # test first and second arguments independently for 2-argument log - test_functions.append(lambda x : cmath.log(x, 1729. + 0j)) - test_functions.append(lambda x : cmath.log(14.-27j, x)) - - def setUp(self): - self.test_values = open(test_file) - - def tearDown(self): - self.test_values.close() - - def assertFloatIdentical(self, x, y): - """Fail unless floats x and y are identical, in the sense that: - (1) both x and y are nans, or - (2) both x and y are infinities, with the same sign, or - (3) both x and y are zeros, with the same sign, or - (4) x and y are both finite and nonzero, and x == y - - """ - msg = 'floats {!r} and {!r} are not identical' - - if math.isnan(x) or math.isnan(y): - if math.isnan(x) and math.isnan(y): - return - elif x == y: - if x != 0.0: - return - # both zero; check that signs match - elif math.copysign(1.0, x) == math.copysign(1.0, y): - return - else: - msg += ': zeros have different signs' - self.fail(msg.format(x, y)) - - def assertComplexIdentical(self, x, y): - """Fail unless complex numbers x and y have equal values and signs. - - In particular, if x and y both have real (or imaginary) part - zero, but the zeros have different signs, this test will fail. - - """ - self.assertFloatIdentical(x.real, y.real) - self.assertFloatIdentical(x.imag, y.imag) - - def rAssertAlmostEqual(self, a, b, rel_err = 2e-15, abs_err = 5e-323, - msg=None): - """Fail if the two floating-point numbers are not almost equal. - - Determine whether floating-point values a and b are equal to within - a (small) rounding error. The default values for rel_err and - abs_err are chosen to be suitable for platforms where a float is - represented by an IEEE 754 double. They allow an error of between - 9 and 19 ulps. - """ - - # special values testing - if math.isnan(a): - if math.isnan(b): - return - self.fail(msg or '{!r} should be nan'.format(b)) - - if math.isinf(a): - if a == b: - return - self.fail(msg or 'finite result where infinity expected: ' - 'expected {!r}, got {!r}'.format(a, b)) - - # if both a and b are zero, check whether they have the same sign - # (in theory there are examples where it would be legitimate for a - # and b to have opposite signs; in practice these hardly ever - # occur). - if not a and not b: - if math.copysign(1., a) != math.copysign(1., b): - self.fail(msg or 'zero has wrong sign: expected {!r}, ' - 'got {!r}'.format(a, b)) - - # if a-b overflows, or b is infinite, return False. Again, in - # theory there are examples where a is within a few ulps of the - # max representable float, and then b could legitimately be - # infinite. In practice these examples are rare. - try: - absolute_error = abs(b-a) - except OverflowError: - pass - else: - # test passes if either the absolute error or the relative - # error is sufficiently small. The defaults amount to an - # error of between 9 ulps and 19 ulps on an IEEE-754 compliant - # machine. - if absolute_error <= max(abs_err, rel_err * abs(a)): - return - self.fail(msg or - '{!r} and {!r} are not sufficiently close'.format(a, b)) - - def test_constants(self): - e_expected = 2.71828182845904523536 - pi_expected = 3.14159265358979323846 - self.assertAlmostEqual(cmath.pi, pi_expected, places=9, - msg="cmath.pi is {}; should be {}".format(cmath.pi, pi_expected)) - self.assertAlmostEqual(cmath.e, e_expected, places=9, - msg="cmath.e is {}; should be {}".format(cmath.e, e_expected)) - - def test_infinity_and_nan_constants(self): - self.assertEqual(cmath.inf.real, math.inf) - self.assertEqual(cmath.inf.imag, 0.0) - self.assertEqual(cmath.infj.real, 0.0) - self.assertEqual(cmath.infj.imag, math.inf) - - self.assertTrue(math.isnan(cmath.nan.real)) - self.assertEqual(cmath.nan.imag, 0.0) - self.assertEqual(cmath.nanj.real, 0.0) - self.assertTrue(math.isnan(cmath.nanj.imag)) - - # Check consistency with reprs. - self.assertEqual(repr(cmath.inf), "inf") - self.assertEqual(repr(cmath.infj), "infj") - self.assertEqual(repr(cmath.nan), "nan") - self.assertEqual(repr(cmath.nanj), "nanj") - - def test_user_object(self): - # Test automatic calling of __complex__ and __float__ by cmath - # functions - - # some random values to use as test values; we avoid values - # for which any of the functions in cmath is undefined - # (i.e. 0., 1., -1., 1j, -1j) or would cause overflow - cx_arg = 4.419414439 + 1.497100113j - flt_arg = -6.131677725 - - # a variety of non-complex numbers, used to check that - # non-complex return values from __complex__ give an error - non_complexes = ["not complex", 1, 5, 2., None, - object(), NotImplemented] - - # Now we introduce a variety of classes whose instances might - # end up being passed to the cmath functions - - # usual case: new-style class implementing __complex__ - class MyComplex(object): - def __init__(self, value): - self.value = value - def __complex__(self): - return self.value - - # old-style class implementing __complex__ - class MyComplexOS: - def __init__(self, value): - self.value = value - def __complex__(self): - return self.value - - # classes for which __complex__ raises an exception - class SomeException(Exception): - pass - class MyComplexException(object): - def __complex__(self): - raise SomeException - class MyComplexExceptionOS: - def __complex__(self): - raise SomeException - - # some classes not providing __float__ or __complex__ - class NeitherComplexNorFloat(object): - pass - class NeitherComplexNorFloatOS: - pass - class Index: - def __int__(self): return 2 - def __index__(self): return 2 - class MyInt: - def __int__(self): return 2 - - # other possible combinations of __float__ and __complex__ - # that should work - class FloatAndComplex(object): - def __float__(self): - return flt_arg - def __complex__(self): - return cx_arg - class FloatAndComplexOS: - def __float__(self): - return flt_arg - def __complex__(self): - return cx_arg - class JustFloat(object): - def __float__(self): - return flt_arg - class JustFloatOS: - def __float__(self): - return flt_arg - - for f in self.test_functions: - # usual usage - self.assertEqual(f(MyComplex(cx_arg)), f(cx_arg)) - self.assertEqual(f(MyComplexOS(cx_arg)), f(cx_arg)) - # other combinations of __float__ and __complex__ - self.assertEqual(f(FloatAndComplex()), f(cx_arg)) - self.assertEqual(f(FloatAndComplexOS()), f(cx_arg)) - self.assertEqual(f(JustFloat()), f(flt_arg)) - self.assertEqual(f(JustFloatOS()), f(flt_arg)) - self.assertEqual(f(Index()), f(int(Index()))) - # TypeError should be raised for classes not providing - # either __complex__ or __float__, even if they provide - # __int__ or __index__. An old-style class - # currently raises AttributeError instead of a TypeError; - # this could be considered a bug. - self.assertRaises(TypeError, f, NeitherComplexNorFloat()) - self.assertRaises(TypeError, f, MyInt()) - self.assertRaises(Exception, f, NeitherComplexNorFloatOS()) - # non-complex return value from __complex__ -> TypeError - for bad_complex in non_complexes: - self.assertRaises(TypeError, f, MyComplex(bad_complex)) - self.assertRaises(TypeError, f, MyComplexOS(bad_complex)) - # exceptions in __complex__ should be propagated correctly - self.assertRaises(SomeException, f, MyComplexException()) - self.assertRaises(SomeException, f, MyComplexExceptionOS()) - - def test_input_type(self): - # ints should be acceptable inputs to all cmath - # functions, by virtue of providing a __float__ method - for f in self.test_functions: - for arg in [2, 2.]: - self.assertEqual(f(arg), f(arg.__float__())) - - # but strings should give a TypeError - for f in self.test_functions: - for arg in ["a", "long_string", "0", "1j", ""]: - self.assertRaises(TypeError, f, arg) - - def test_cmath_matches_math(self): - # check that corresponding cmath and math functions are equal - # for floats in the appropriate range - - # test_values in (0, 1) - test_values = [0.01, 0.1, 0.2, 0.5, 0.9, 0.99] - - # test_values for functions defined on [-1., 1.] - unit_interval = test_values + [-x for x in test_values] + \ - [0., 1., -1.] - - # test_values for log, log10, sqrt - positive = test_values + [1.] + [1./x for x in test_values] - nonnegative = [0.] + positive - - # test_values for functions defined on the whole real line - real_line = [0.] + positive + [-x for x in positive] - - test_functions = { - 'acos' : unit_interval, - 'asin' : unit_interval, - 'atan' : real_line, - 'cos' : real_line, - 'cosh' : real_line, - 'exp' : real_line, - 'log' : positive, - 'log10' : positive, - 'sin' : real_line, - 'sinh' : real_line, - 'sqrt' : nonnegative, - 'tan' : real_line, - 'tanh' : real_line} - - for fn, values in test_functions.items(): - float_fn = getattr(math, fn) - complex_fn = getattr(cmath, fn) - for v in values: - z = complex_fn(v) - self.rAssertAlmostEqual(float_fn(v), z.real) - self.assertEqual(0., z.imag) - - # test two-argument version of log with various bases - for base in [0.5, 2., 10.]: - for v in positive: - z = cmath.log(v, base) - self.rAssertAlmostEqual(math.log(v, base), z.real) - self.assertEqual(0., z.imag) - - @requires_IEEE_754 - def test_specific_values(self): - # Some tests need to be skipped on ancient OS X versions. - # See issue #27953. - SKIP_ON_TIGER = {'tan0064'} - - osx_version = None - if sys.platform == 'darwin': - version_txt = platform.mac_ver()[0] - try: - osx_version = tuple(map(int, version_txt.split('.'))) - except ValueError: - pass - - def rect_complex(z): - """Wrapped version of rect that accepts a complex number instead of - two float arguments.""" - return cmath.rect(z.real, z.imag) - - def polar_complex(z): - """Wrapped version of polar that returns a complex number instead of - two floats.""" - return complex(*polar(z)) - - for id, fn, ar, ai, er, ei, flags in parse_testfile(test_file): - arg = complex(ar, ai) - expected = complex(er, ei) - - # Skip certain tests on OS X 10.4. - if osx_version is not None and osx_version < (10, 5): - if id in SKIP_ON_TIGER: - continue - - if fn == 'rect': - function = rect_complex - elif fn == 'polar': - function = polar_complex - else: - function = getattr(cmath, fn) - if 'divide-by-zero' in flags or 'invalid' in flags: - try: - actual = function(arg) - except ValueError: - continue - else: - self.fail('ValueError not raised in test ' - '{}: {}(complex({!r}, {!r}))'.format(id, fn, ar, ai)) - - if 'overflow' in flags: - try: - actual = function(arg) - except OverflowError: - continue - else: - self.fail('OverflowError not raised in test ' - '{}: {}(complex({!r}, {!r}))'.format(id, fn, ar, ai)) - - actual = function(arg) - - if 'ignore-real-sign' in flags: - actual = complex(abs(actual.real), actual.imag) - expected = complex(abs(expected.real), expected.imag) - if 'ignore-imag-sign' in flags: - actual = complex(actual.real, abs(actual.imag)) - expected = complex(expected.real, abs(expected.imag)) - - # for the real part of the log function, we allow an - # absolute error of up to 2e-15. - if fn in ('log', 'log10'): - real_abs_err = 2e-15 - else: - real_abs_err = 5e-323 - - error_message = ( - '{}: {}(complex({!r}, {!r}))\n' - 'Expected: complex({!r}, {!r})\n' - 'Received: complex({!r}, {!r})\n' - 'Received value insufficiently close to expected value.' - ).format(id, fn, ar, ai, - expected.real, expected.imag, - actual.real, actual.imag) - self.rAssertAlmostEqual(expected.real, actual.real, - abs_err=real_abs_err, - msg=error_message) - self.rAssertAlmostEqual(expected.imag, actual.imag, - msg=error_message) - - def check_polar(self, func): - def check(arg, expected): - got = func(arg) - for e, g in zip(expected, got): - self.rAssertAlmostEqual(e, g) - check(0, (0., 0.)) - check(1, (1., 0.)) - check(-1, (1., pi)) - check(1j, (1., pi / 2)) - check(-3j, (3., -pi / 2)) - inf = float('inf') - check(complex(inf, 0), (inf, 0.)) - check(complex(-inf, 0), (inf, pi)) - check(complex(3, inf), (inf, pi / 2)) - check(complex(5, -inf), (inf, -pi / 2)) - check(complex(inf, inf), (inf, pi / 4)) - check(complex(inf, -inf), (inf, -pi / 4)) - check(complex(-inf, inf), (inf, 3 * pi / 4)) - check(complex(-inf, -inf), (inf, -3 * pi / 4)) - nan = float('nan') - check(complex(nan, 0), (nan, nan)) - check(complex(0, nan), (nan, nan)) - check(complex(nan, nan), (nan, nan)) - check(complex(inf, nan), (inf, nan)) - check(complex(-inf, nan), (inf, nan)) - check(complex(nan, inf), (inf, nan)) - check(complex(nan, -inf), (inf, nan)) - - def test_polar(self): - self.check_polar(polar) - - @cpython_only - def test_polar_errno(self): - # Issue #24489: check a previously set C errno doesn't disturb polar() - from _testcapi import set_errno - def polar_with_errno_set(z): - set_errno(11) - try: - return polar(z) - finally: - set_errno(0) - self.check_polar(polar_with_errno_set) - - def test_phase(self): - self.assertAlmostEqual(phase(0), 0.) - self.assertAlmostEqual(phase(1.), 0.) - self.assertAlmostEqual(phase(-1.), pi) - self.assertAlmostEqual(phase(-1.+1E-300j), pi) - self.assertAlmostEqual(phase(-1.-1E-300j), -pi) - self.assertAlmostEqual(phase(1j), pi/2) - self.assertAlmostEqual(phase(-1j), -pi/2) - - # zeros - self.assertEqual(phase(complex(0.0, 0.0)), 0.0) - self.assertEqual(phase(complex(0.0, -0.0)), -0.0) - self.assertEqual(phase(complex(-0.0, 0.0)), pi) - self.assertEqual(phase(complex(-0.0, -0.0)), -pi) - - # infinities - self.assertAlmostEqual(phase(complex(-INF, -0.0)), -pi) - self.assertAlmostEqual(phase(complex(-INF, -2.3)), -pi) - self.assertAlmostEqual(phase(complex(-INF, -INF)), -0.75*pi) - self.assertAlmostEqual(phase(complex(-2.3, -INF)), -pi/2) - self.assertAlmostEqual(phase(complex(-0.0, -INF)), -pi/2) - self.assertAlmostEqual(phase(complex(0.0, -INF)), -pi/2) - self.assertAlmostEqual(phase(complex(2.3, -INF)), -pi/2) - self.assertAlmostEqual(phase(complex(INF, -INF)), -pi/4) - self.assertEqual(phase(complex(INF, -2.3)), -0.0) - self.assertEqual(phase(complex(INF, -0.0)), -0.0) - self.assertEqual(phase(complex(INF, 0.0)), 0.0) - self.assertEqual(phase(complex(INF, 2.3)), 0.0) - self.assertAlmostEqual(phase(complex(INF, INF)), pi/4) - self.assertAlmostEqual(phase(complex(2.3, INF)), pi/2) - self.assertAlmostEqual(phase(complex(0.0, INF)), pi/2) - self.assertAlmostEqual(phase(complex(-0.0, INF)), pi/2) - self.assertAlmostEqual(phase(complex(-2.3, INF)), pi/2) - self.assertAlmostEqual(phase(complex(-INF, INF)), 0.75*pi) - self.assertAlmostEqual(phase(complex(-INF, 2.3)), pi) - self.assertAlmostEqual(phase(complex(-INF, 0.0)), pi) - - # real or imaginary part NaN - for z in complex_nans: - self.assertTrue(math.isnan(phase(z))) - - def test_abs(self): - # zeros - for z in complex_zeros: - self.assertEqual(abs(z), 0.0) - - # infinities - for z in complex_infinities: - self.assertEqual(abs(z), INF) - - # real or imaginary part NaN - self.assertEqual(abs(complex(NAN, -INF)), INF) - self.assertTrue(math.isnan(abs(complex(NAN, -2.3)))) - self.assertTrue(math.isnan(abs(complex(NAN, -0.0)))) - self.assertTrue(math.isnan(abs(complex(NAN, 0.0)))) - self.assertTrue(math.isnan(abs(complex(NAN, 2.3)))) - self.assertEqual(abs(complex(NAN, INF)), INF) - self.assertEqual(abs(complex(-INF, NAN)), INF) - self.assertTrue(math.isnan(abs(complex(-2.3, NAN)))) - self.assertTrue(math.isnan(abs(complex(-0.0, NAN)))) - self.assertTrue(math.isnan(abs(complex(0.0, NAN)))) - self.assertTrue(math.isnan(abs(complex(2.3, NAN)))) - self.assertEqual(abs(complex(INF, NAN)), INF) - self.assertTrue(math.isnan(abs(complex(NAN, NAN)))) - - - @requires_IEEE_754 - def test_abs_overflows(self): - # result overflows - self.assertRaises(OverflowError, abs, complex(1.4e308, 1.4e308)) - - def assertCEqual(self, a, b): - eps = 1E-7 - if abs(a.real - b[0]) > eps or abs(a.imag - b[1]) > eps: - self.fail((a ,b)) - - def test_rect(self): - self.assertCEqual(rect(0, 0), (0, 0)) - self.assertCEqual(rect(1, 0), (1., 0)) - self.assertCEqual(rect(1, -pi), (-1., 0)) - self.assertCEqual(rect(1, pi/2), (0, 1.)) - self.assertCEqual(rect(1, -pi/2), (0, -1.)) - - def test_isfinite(self): - real_vals = [float('-inf'), -2.3, -0.0, - 0.0, 2.3, float('inf'), float('nan')] - for x in real_vals: - for y in real_vals: - z = complex(x, y) - self.assertEqual(cmath.isfinite(z), - math.isfinite(x) and math.isfinite(y)) - - def test_isnan(self): - self.assertFalse(cmath.isnan(1)) - self.assertFalse(cmath.isnan(1j)) - self.assertFalse(cmath.isnan(INF)) - self.assertTrue(cmath.isnan(NAN)) - self.assertTrue(cmath.isnan(complex(NAN, 0))) - self.assertTrue(cmath.isnan(complex(0, NAN))) - self.assertTrue(cmath.isnan(complex(NAN, NAN))) - self.assertTrue(cmath.isnan(complex(NAN, INF))) - self.assertTrue(cmath.isnan(complex(INF, NAN))) - - def test_isinf(self): - self.assertFalse(cmath.isinf(1)) - self.assertFalse(cmath.isinf(1j)) - self.assertFalse(cmath.isinf(NAN)) - self.assertTrue(cmath.isinf(INF)) - self.assertTrue(cmath.isinf(complex(INF, 0))) - self.assertTrue(cmath.isinf(complex(0, INF))) - self.assertTrue(cmath.isinf(complex(INF, INF))) - self.assertTrue(cmath.isinf(complex(NAN, INF))) - self.assertTrue(cmath.isinf(complex(INF, NAN))) - - @requires_IEEE_754 - def testTanhSign(self): - for z in complex_zeros: - self.assertComplexIdentical(cmath.tanh(z), z) - - # The algorithm used for atan and atanh makes use of the system - # log1p function; If that system function doesn't respect the sign - # of zero, then atan and atanh will also have difficulties with - # the sign of complex zeros. - @requires_IEEE_754 - def testAtanSign(self): - for z in complex_zeros: - self.assertComplexIdentical(cmath.atan(z), z) - - @requires_IEEE_754 - def testAtanhSign(self): - for z in complex_zeros: - self.assertComplexIdentical(cmath.atanh(z), z) - - - class IsCloseTests(test_math.IsCloseTests): - isclose = cmath.isclose - - def test_reject_complex_tolerances(self): - with self.assertRaises(TypeError): - self.isclose(1j, 1j, rel_tol=1j) - - with self.assertRaises(TypeError): - self.isclose(1j, 1j, abs_tol=1j) - - with self.assertRaises(TypeError): - self.isclose(1j, 1j, rel_tol=1j, abs_tol=1j) - - def test_complex_values(self): - # test complex values that are close to within 12 decimal places - complex_examples = [(1.0+1.0j, 1.000000000001+1.0j), - (1.0+1.0j, 1.0+1.000000000001j), - (-1.0+1.0j, -1.000000000001+1.0j), - (1.0-1.0j, 1.0-0.999999999999j), - ] - - self.assertAllClose(complex_examples, rel_tol=1e-12) - self.assertAllNotClose(complex_examples, rel_tol=1e-13) - - def test_complex_near_zero(self): - # test values near zero that are near to within three decimal places - near_zero_examples = [(0.001j, 0), - (0.001, 0), - (0.001+0.001j, 0), - (-0.001+0.001j, 0), - (0.001-0.001j, 0), - (-0.001-0.001j, 0), - ] - - self.assertAllClose(near_zero_examples, abs_tol=1.5e-03) - self.assertAllNotClose(near_zero_examples, abs_tol=0.5e-03) - - self.assertIsClose(0.001-0.001j, 0.001+0.001j, abs_tol=2e-03) - self.assertIsNotClose(0.001-0.001j, 0.001+0.001j, abs_tol=1e-03) - - - if __name__ == "__main__": - unittest.main() diff --git a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_cmd.yaml b/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_cmd.yaml deleted file mode 100644 index 763f2963b..000000000 --- a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_cmd.yaml +++ /dev/null @@ -1,243 +0,0 @@ -python: | - """ - Test script for the 'cmd' module - Original by Michael Schneider - """ - - - import cmd - import sys - import unittest - import io - from test import support - - class samplecmdclass(cmd.Cmd): - """ - Instance the sampleclass: - >>> mycmd = samplecmdclass() - - Test for the function parseline(): - >>> mycmd.parseline("") - (None, None, '') - >>> mycmd.parseline("?") - ('help', '', 'help ') - >>> mycmd.parseline("?help") - ('help', 'help', 'help help') - >>> mycmd.parseline("!") - ('shell', '', 'shell ') - >>> mycmd.parseline("!command") - ('shell', 'command', 'shell command') - >>> mycmd.parseline("func") - ('func', '', 'func') - >>> mycmd.parseline("func arg1") - ('func', 'arg1', 'func arg1') - - - Test for the function onecmd(): - >>> mycmd.onecmd("") - >>> mycmd.onecmd("add 4 5") - 9 - >>> mycmd.onecmd("") - 9 - >>> mycmd.onecmd("test") - *** Unknown syntax: test - - Test for the function emptyline(): - >>> mycmd.emptyline() - *** Unknown syntax: test - - Test for the function default(): - >>> mycmd.default("default") - *** Unknown syntax: default - - Test for the function completedefault(): - >>> mycmd.completedefault() - This is the completedefault method - >>> mycmd.completenames("a") - ['add'] - - Test for the function completenames(): - >>> mycmd.completenames("12") - [] - >>> mycmd.completenames("help") - ['help'] - - Test for the function complete_help(): - >>> mycmd.complete_help("a") - ['add'] - >>> mycmd.complete_help("he") - ['help'] - >>> mycmd.complete_help("12") - [] - >>> sorted(mycmd.complete_help("")) - ['add', 'exit', 'help', 'shell'] - - Test for the function do_help(): - >>> mycmd.do_help("testet") - *** No help on testet - >>> mycmd.do_help("add") - help text for add - >>> mycmd.onecmd("help add") - help text for add - >>> mycmd.do_help("") - - Documented commands (type help ): - ======================================== - add help - - Undocumented commands: - ====================== - exit shell - - - Test for the function print_topics(): - >>> mycmd.print_topics("header", ["command1", "command2"], 2 ,10) - header - ====== - command1 - command2 - - - Test for the function columnize(): - >>> mycmd.columnize([str(i) for i in range(20)]) - 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 - >>> mycmd.columnize([str(i) for i in range(20)], 10) - 0 7 14 - 1 8 15 - 2 9 16 - 3 10 17 - 4 11 18 - 5 12 19 - 6 13 - - This is an interactive test, put some commands in the cmdqueue attribute - and let it execute - This test includes the preloop(), postloop(), default(), emptyline(), - parseline(), do_help() functions - >>> mycmd.use_rawinput=0 - >>> mycmd.cmdqueue=["", "add", "add 4 5", "help", "help add","exit"] - >>> mycmd.cmdloop() - Hello from preloop - help text for add - *** invalid number of arguments - 9 - - Documented commands (type help ): - ======================================== - add help - - Undocumented commands: - ====================== - exit shell - - help text for add - Hello from postloop - """ - - def preloop(self): - print("Hello from preloop") - - def postloop(self): - print("Hello from postloop") - - def completedefault(self, *ignored): - print("This is the completedefault method") - - def complete_command(self): - print("complete command") - - def do_shell(self, s): - pass - - def do_add(self, s): - l = s.split() - if len(l) != 2: - print("*** invalid number of arguments") - return - try: - l = [int(i) for i in l] - except ValueError: - print("*** arguments should be numbers") - return - print(l[0]+l[1]) - - def help_add(self): - print("help text for add") - return - - def do_exit(self, arg): - return True - - - class TestAlternateInput(unittest.TestCase): - - class simplecmd(cmd.Cmd): - - def do_print(self, args): - print(args, file=self.stdout) - - def do_EOF(self, args): - return True - - - class simplecmd2(simplecmd): - - def do_EOF(self, args): - print('*** Unknown syntax: EOF', file=self.stdout) - return True - - - def test_file_with_missing_final_nl(self): - input = io.StringIO("print test\nprint test2") - output = io.StringIO() - cmd = self.simplecmd(stdin=input, stdout=output) - cmd.use_rawinput = False - cmd.cmdloop() - self.assertMultiLineEqual(output.getvalue(), - ("(Cmd) test\n" - "(Cmd) test2\n" - "(Cmd) ")) - - - def test_input_reset_at_EOF(self): - input = io.StringIO("print test\nprint test2") - output = io.StringIO() - cmd = self.simplecmd2(stdin=input, stdout=output) - cmd.use_rawinput = False - cmd.cmdloop() - self.assertMultiLineEqual(output.getvalue(), - ("(Cmd) test\n" - "(Cmd) test2\n" - "(Cmd) *** Unknown syntax: EOF\n")) - input = io.StringIO("print \n\n") - output = io.StringIO() - cmd.stdin = input - cmd.stdout = output - cmd.cmdloop() - self.assertMultiLineEqual(output.getvalue(), - ("(Cmd) \n" - "(Cmd) \n" - "(Cmd) *** Unknown syntax: EOF\n")) - - - def test_main(verbose=None): - from test import test_cmd - support.run_doctest(test_cmd, verbose) - support.run_unittest(TestAlternateInput) - - def test_coverage(coverdir): - trace = support.import_module('trace') - tracer=trace.Trace(ignoredirs=[sys.base_prefix, sys.base_exec_prefix,], - trace=0, count=1) - tracer.run('import importlib; importlib.reload(cmd); test_main()') - r=tracer.results() - print("Writing coverage results...") - r.write_results(show_missing=True, summary=True, coverdir=coverdir) - - if __name__ == "__main__": - if "-c" in sys.argv: - test_coverage('/tmp/cmd.cover') - elif "-i" in sys.argv: - samplecmdclass().cmdloop() - else: - test_main() diff --git a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_code.yaml b/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_code.yaml deleted file mode 100644 index 75cfeed3f..000000000 --- a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_code.yaml +++ /dev/null @@ -1,484 +0,0 @@ -python: | - """This module includes tests of the code object representation. - - >>> def f(x): - ... def g(y): - ... return x + y - ... return g - ... - - >>> dump(f.__code__) - name: f - argcount: 1 - posonlyargcount: 0 - kwonlyargcount: 0 - names: () - varnames: ('x', 'g') - cellvars: ('x',) - freevars: () - nlocals: 2 - flags: 3 - consts: ('None', '', "'f..g'") - - >>> dump(f(4).__code__) - name: g - argcount: 1 - posonlyargcount: 0 - kwonlyargcount: 0 - names: () - varnames: ('y',) - cellvars: () - freevars: ('x',) - nlocals: 1 - flags: 19 - consts: ('None',) - - >>> def h(x, y): - ... a = x + y - ... b = x - y - ... c = a * b - ... return c - ... - - >>> dump(h.__code__) - name: h - argcount: 2 - posonlyargcount: 0 - kwonlyargcount: 0 - names: () - varnames: ('x', 'y', 'a', 'b', 'c') - cellvars: () - freevars: () - nlocals: 5 - flags: 67 - consts: ('None',) - - >>> def attrs(obj): - ... print(obj.attr1) - ... print(obj.attr2) - ... print(obj.attr3) - - >>> dump(attrs.__code__) - name: attrs - argcount: 1 - posonlyargcount: 0 - kwonlyargcount: 0 - names: ('print', 'attr1', 'attr2', 'attr3') - varnames: ('obj',) - cellvars: () - freevars: () - nlocals: 1 - flags: 67 - consts: ('None',) - - >>> def optimize_away(): - ... 'doc string' - ... 'not a docstring' - ... 53 - ... 0x53 - - >>> dump(optimize_away.__code__) - name: optimize_away - argcount: 0 - posonlyargcount: 0 - kwonlyargcount: 0 - names: () - varnames: () - cellvars: () - freevars: () - nlocals: 0 - flags: 67 - consts: ("'doc string'", 'None') - - >>> def keywordonly_args(a,b,*,k1): - ... return a,b,k1 - ... - - >>> dump(keywordonly_args.__code__) - name: keywordonly_args - argcount: 2 - posonlyargcount: 0 - kwonlyargcount: 1 - names: () - varnames: ('a', 'b', 'k1') - cellvars: () - freevars: () - nlocals: 3 - flags: 67 - consts: ('None',) - - >>> def posonly_args(a,b,/,c): - ... return a,b,c - ... - - >>> dump(posonly_args.__code__) - name: posonly_args - argcount: 3 - posonlyargcount: 2 - kwonlyargcount: 0 - names: () - varnames: ('a', 'b', 'c') - cellvars: () - freevars: () - nlocals: 3 - flags: 67 - consts: ('None',) - - """ - - import inspect - import sys - import threading - import unittest - import weakref - import opcode - try: - import ctypes - except ImportError: - ctypes = None - from test.support import (run_doctest, run_unittest, cpython_only, - check_impl_detail) - - - def consts(t): - """Yield a doctest-safe sequence of object reprs.""" - for elt in t: - r = repr(elt) - if r.startswith("" % elt.co_name - else: - yield r - - def dump(co): - """Print out a text representation of a code object.""" - for attr in ["name", "argcount", "posonlyargcount", - "kwonlyargcount", "names", "varnames", - "cellvars", "freevars", "nlocals", "flags"]: - print("%s: %s" % (attr, getattr(co, "co_" + attr))) - print("consts:", tuple(consts(co.co_consts))) - - # Needed for test_closure_injection below - # Defined at global scope to avoid implicitly closing over __class__ - def external_getitem(self, i): - return f"Foreign getitem: {super().__getitem__(i)}" - - class CodeTest(unittest.TestCase): - - @cpython_only - def test_newempty(self): - import _testcapi - co = _testcapi.code_newempty("filename", "funcname", 15) - self.assertEqual(co.co_filename, "filename") - self.assertEqual(co.co_name, "funcname") - self.assertEqual(co.co_firstlineno, 15) - - @cpython_only - def test_closure_injection(self): - # From https://bugs.python.org/issue32176 - from types import FunctionType - - def create_closure(__class__): - return (lambda: __class__).__closure__ - - def new_code(c): - '''A new code object with a __class__ cell added to freevars''' - return c.replace(co_freevars=c.co_freevars + ('__class__',)) - - def add_foreign_method(cls, name, f): - code = new_code(f.__code__) - assert not f.__closure__ - closure = create_closure(cls) - defaults = f.__defaults__ - setattr(cls, name, FunctionType(code, globals(), name, defaults, closure)) - - class List(list): - pass - - add_foreign_method(List, "__getitem__", external_getitem) - - # Ensure the closure injection actually worked - function = List.__getitem__ - class_ref = function.__closure__[0].cell_contents - self.assertIs(class_ref, List) - - # Ensure the code correctly indicates it accesses a free variable - self.assertFalse(function.__code__.co_flags & inspect.CO_NOFREE, - hex(function.__code__.co_flags)) - - # Ensure the zero-arg super() call in the injected method works - obj = List([1, 2, 3]) - self.assertEqual(obj[0], "Foreign getitem: 1") - - def test_constructor(self): - def func(): pass - co = func.__code__ - CodeType = type(co) - - # test code constructor - return CodeType(co.co_argcount, - co.co_posonlyargcount, - co.co_kwonlyargcount, - co.co_nlocals, - co.co_stacksize, - co.co_flags, - co.co_code, - co.co_consts, - co.co_names, - co.co_varnames, - co.co_filename, - co.co_name, - co.co_firstlineno, - co.co_lnotab, - co.co_freevars, - co.co_cellvars) - - def test_replace(self): - def func(): - x = 1 - return x - code = func.__code__ - - # different co_name, co_varnames, co_consts - def func2(): - y = 2 - return y - code2 = func.__code__ - - for attr, value in ( - ("co_argcount", 0), - ("co_posonlyargcount", 0), - ("co_kwonlyargcount", 0), - ("co_nlocals", 0), - ("co_stacksize", 0), - ("co_flags", code.co_flags | inspect.CO_COROUTINE), - ("co_firstlineno", 100), - ("co_code", code2.co_code), - ("co_consts", code2.co_consts), - ("co_names", ("myname",)), - ("co_varnames", code2.co_varnames), - ("co_freevars", ("freevar",)), - ("co_cellvars", ("cellvar",)), - ("co_filename", "newfilename"), - ("co_name", "newname"), - ("co_lnotab", code2.co_lnotab), - ): - with self.subTest(attr=attr, value=value): - new_code = code.replace(**{attr: value}) - self.assertEqual(getattr(new_code, attr), value) - - - def isinterned(s): - return s is sys.intern(('_' + s + '_')[1:-1]) - - class CodeConstsTest(unittest.TestCase): - - def find_const(self, consts, value): - for v in consts: - if v == value: - return v - self.assertIn(value, consts) # raises an exception - self.fail('Should never be reached') - - def assertIsInterned(self, s): - if not isinterned(s): - self.fail('String %r is not interned' % (s,)) - - def assertIsNotInterned(self, s): - if isinterned(s): - self.fail('String %r is interned' % (s,)) - - @cpython_only - def test_interned_string(self): - co = compile('res = "str_value"', '?', 'exec') - v = self.find_const(co.co_consts, 'str_value') - self.assertIsInterned(v) - - @cpython_only - def test_interned_string_in_tuple(self): - co = compile('res = ("str_value",)', '?', 'exec') - v = self.find_const(co.co_consts, ('str_value',)) - self.assertIsInterned(v[0]) - - @cpython_only - def test_interned_string_in_frozenset(self): - co = compile('res = a in {"str_value"}', '?', 'exec') - v = self.find_const(co.co_consts, frozenset(('str_value',))) - self.assertIsInterned(tuple(v)[0]) - - @cpython_only - def test_interned_string_default(self): - def f(a='str_value'): - return a - self.assertIsInterned(f()) - - @cpython_only - def test_interned_string_with_null(self): - co = compile(r'res = "str\0value!"', '?', 'exec') - v = self.find_const(co.co_consts, 'str\0value!') - self.assertIsNotInterned(v) - - - class CodeWeakRefTest(unittest.TestCase): - - def test_basic(self): - # Create a code object in a clean environment so that we know we have - # the only reference to it left. - namespace = {} - exec("def f(): pass", globals(), namespace) - f = namespace["f"] - del namespace - - self.called = False - def callback(code): - self.called = True - - # f is now the last reference to the function, and through it, the code - # object. While we hold it, check that we can create a weakref and - # deref it. Then delete it, and check that the callback gets called and - # the reference dies. - coderef = weakref.ref(f.__code__, callback) - self.assertTrue(bool(coderef())) - del f - self.assertFalse(bool(coderef())) - self.assertTrue(self.called) - - - if check_impl_detail(cpython=True) and ctypes is not None: - py = ctypes.pythonapi - freefunc = ctypes.CFUNCTYPE(None,ctypes.c_voidp) - - RequestCodeExtraIndex = py._PyEval_RequestCodeExtraIndex - RequestCodeExtraIndex.argtypes = (freefunc,) - RequestCodeExtraIndex.restype = ctypes.c_ssize_t - - SetExtra = py._PyCode_SetExtra - SetExtra.argtypes = (ctypes.py_object, ctypes.c_ssize_t, ctypes.c_voidp) - SetExtra.restype = ctypes.c_int - - GetExtra = py._PyCode_GetExtra - GetExtra.argtypes = (ctypes.py_object, ctypes.c_ssize_t, - ctypes.POINTER(ctypes.c_voidp)) - GetExtra.restype = ctypes.c_int - - LAST_FREED = None - def myfree(ptr): - global LAST_FREED - LAST_FREED = ptr - - FREE_FUNC = freefunc(myfree) - FREE_INDEX = RequestCodeExtraIndex(FREE_FUNC) - - class CoExtra(unittest.TestCase): - def get_func(self): - # Defining a function causes the containing function to have a - # reference to the code object. We need the code objects to go - # away, so we eval a lambda. - return eval('lambda:42') - - def test_get_non_code(self): - f = self.get_func() - - self.assertRaises(SystemError, SetExtra, 42, FREE_INDEX, - ctypes.c_voidp(100)) - self.assertRaises(SystemError, GetExtra, 42, FREE_INDEX, - ctypes.c_voidp(100)) - - def test_bad_index(self): - f = self.get_func() - self.assertRaises(SystemError, SetExtra, f.__code__, - FREE_INDEX+100, ctypes.c_voidp(100)) - self.assertEqual(GetExtra(f.__code__, FREE_INDEX+100, - ctypes.c_voidp(100)), 0) - - def test_free_called(self): - # Verify that the provided free function gets invoked - # when the code object is cleaned up. - f = self.get_func() - - SetExtra(f.__code__, FREE_INDEX, ctypes.c_voidp(100)) - del f - self.assertEqual(LAST_FREED, 100) - - def test_get_set(self): - # Test basic get/set round tripping. - f = self.get_func() - - extra = ctypes.c_voidp() - - SetExtra(f.__code__, FREE_INDEX, ctypes.c_voidp(200)) - # reset should free... - SetExtra(f.__code__, FREE_INDEX, ctypes.c_voidp(300)) - self.assertEqual(LAST_FREED, 200) - - extra = ctypes.c_voidp() - GetExtra(f.__code__, FREE_INDEX, extra) - self.assertEqual(extra.value, 300) - del f - - def test_free_different_thread(self): - # Freeing a code object on a different thread then - # where the co_extra was set should be safe. - f = self.get_func() - class ThreadTest(threading.Thread): - def __init__(self, f, test): - super().__init__() - self.f = f - self.test = test - def run(self): - del self.f - self.test.assertEqual(LAST_FREED, 500) - - SetExtra(f.__code__, FREE_INDEX, ctypes.c_voidp(500)) - tt = ThreadTest(f, self) - del f - tt.start() - tt.join() - self.assertEqual(LAST_FREED, 500) - - @cpython_only - def test_clean_stack_on_return(self): - - def f(x): - return x - - code = f.__code__ - ct = type(f.__code__) - - # Insert an extra LOAD_FAST, this duplicates the value of - # 'x' in the stack, leaking it if the frame is not properly - # cleaned up upon exit. - - bytecode = list(code.co_code) - bytecode.insert(-2, opcode.opmap['LOAD_FAST']) - bytecode.insert(-2, 0) - - c = ct(code.co_argcount, code.co_posonlyargcount, - code.co_kwonlyargcount, code.co_nlocals, code.co_stacksize+1, - code.co_flags, bytes(bytecode), - code.co_consts, code.co_names, code.co_varnames, - code.co_filename, code.co_name, code.co_firstlineno, - code.co_lnotab, code.co_freevars, code.co_cellvars) - new_function = type(f)(c, f.__globals__, 'nf', f.__defaults__, f.__closure__) - - class Var: - pass - the_object = Var() - var = weakref.ref(the_object) - - new_function(the_object) - - # Check if the_object is leaked - del the_object - assert var() is None - - - def test_main(verbose=None): - from test import test_code - run_doctest(test_code, verbose) - tests = [CodeTest, CodeConstsTest, CodeWeakRefTest] - if check_impl_detail(cpython=True) and ctypes is not None: - tests.append(CoExtra) - run_unittest(*tests) - - if __name__ == "__main__": - test_main() diff --git a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_code_module.yaml b/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_code_module.yaml deleted file mode 100644 index aa426ae27..000000000 --- a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_code_module.yaml +++ /dev/null @@ -1,155 +0,0 @@ -python: | - "Test InteractiveConsole and InteractiveInterpreter from code module" - import sys - import unittest - from textwrap import dedent - from contextlib import ExitStack - from unittest import mock - from test import support - - code = support.import_module('code') - - - class TestInteractiveConsole(unittest.TestCase): - - def setUp(self): - self.console = code.InteractiveConsole() - self.mock_sys() - - def mock_sys(self): - "Mock system environment for InteractiveConsole" - # use exit stack to match patch context managers to addCleanup - stack = ExitStack() - self.addCleanup(stack.close) - self.infunc = stack.enter_context(mock.patch('code.input', - create=True)) - self.stdout = stack.enter_context(mock.patch('code.sys.stdout')) - self.stderr = stack.enter_context(mock.patch('code.sys.stderr')) - prepatch = mock.patch('code.sys', wraps=code.sys, spec=code.sys) - self.sysmod = stack.enter_context(prepatch) - if sys.excepthook is sys.__excepthook__: - self.sysmod.excepthook = self.sysmod.__excepthook__ - del self.sysmod.ps1 - del self.sysmod.ps2 - - def test_ps1(self): - self.infunc.side_effect = EOFError('Finished') - self.console.interact() - self.assertEqual(self.sysmod.ps1, '>>> ') - self.sysmod.ps1 = 'custom1> ' - self.console.interact() - self.assertEqual(self.sysmod.ps1, 'custom1> ') - - def test_ps2(self): - self.infunc.side_effect = EOFError('Finished') - self.console.interact() - self.assertEqual(self.sysmod.ps2, '... ') - self.sysmod.ps1 = 'custom2> ' - self.console.interact() - self.assertEqual(self.sysmod.ps1, 'custom2> ') - - def test_console_stderr(self): - self.infunc.side_effect = ["'antioch'", "", EOFError('Finished')] - self.console.interact() - for call in list(self.stdout.method_calls): - if 'antioch' in ''.join(call[1]): - break - else: - raise AssertionError("no console stdout") - - def test_syntax_error(self): - self.infunc.side_effect = ["undefined", EOFError('Finished')] - self.console.interact() - for call in self.stderr.method_calls: - if 'NameError' in ''.join(call[1]): - break - else: - raise AssertionError("No syntax error from console") - - def test_sysexcepthook(self): - self.infunc.side_effect = ["raise ValueError('')", - EOFError('Finished')] - hook = mock.Mock() - self.sysmod.excepthook = hook - self.console.interact() - self.assertTrue(hook.called) - - def test_banner(self): - # with banner - self.infunc.side_effect = EOFError('Finished') - self.console.interact(banner='Foo') - self.assertEqual(len(self.stderr.method_calls), 3) - banner_call = self.stderr.method_calls[0] - self.assertEqual(banner_call, ['write', ('Foo\n',), {}]) - - # no banner - self.stderr.reset_mock() - self.infunc.side_effect = EOFError('Finished') - self.console.interact(banner='') - self.assertEqual(len(self.stderr.method_calls), 2) - - def test_exit_msg(self): - # default exit message - self.infunc.side_effect = EOFError('Finished') - self.console.interact(banner='') - self.assertEqual(len(self.stderr.method_calls), 2) - err_msg = self.stderr.method_calls[1] - expected = 'now exiting InteractiveConsole...\n' - self.assertEqual(err_msg, ['write', (expected,), {}]) - - # no exit message - self.stderr.reset_mock() - self.infunc.side_effect = EOFError('Finished') - self.console.interact(banner='', exitmsg='') - self.assertEqual(len(self.stderr.method_calls), 1) - - # custom exit message - self.stderr.reset_mock() - message = ( - 'bye! \N{GREEK SMALL LETTER ZETA}\N{CYRILLIC SMALL LETTER ZHE}' - ) - self.infunc.side_effect = EOFError('Finished') - self.console.interact(banner='', exitmsg=message) - self.assertEqual(len(self.stderr.method_calls), 2) - err_msg = self.stderr.method_calls[1] - expected = message + '\n' - self.assertEqual(err_msg, ['write', (expected,), {}]) - - - def test_cause_tb(self): - self.infunc.side_effect = ["raise ValueError('') from AttributeError", - EOFError('Finished')] - self.console.interact() - output = ''.join(''.join(call[1]) for call in self.stderr.method_calls) - expected = dedent(""" - AttributeError - - The above exception was the direct cause of the following exception: - - Traceback (most recent call last): - File "", line 1, in - ValueError - """) - self.assertIn(expected, output) - - def test_context_tb(self): - self.infunc.side_effect = ["try: ham\nexcept: eggs\n", - EOFError('Finished')] - self.console.interact() - output = ''.join(''.join(call[1]) for call in self.stderr.method_calls) - expected = dedent(""" - Traceback (most recent call last): - File "", line 1, in - NameError: name 'ham' is not defined - - During handling of the above exception, another exception occurred: - - Traceback (most recent call last): - File "", line 2, in - NameError: name 'eggs' is not defined - """) - self.assertIn(expected, output) - - - if __name__ == "__main__": - unittest.main() diff --git a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_codeccallbacks.yaml b/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_codeccallbacks.yaml deleted file mode 100644 index 4aa284c52..000000000 --- a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_codeccallbacks.yaml +++ /dev/null @@ -1,1082 +0,0 @@ -python: | - import codecs - import html.entities - import sys - import unicodedata - import unittest - - - class PosReturn: - # this can be used for configurable callbacks - - def __init__(self): - self.pos = 0 - - def handle(self, exc): - oldpos = self.pos - realpos = oldpos - if realpos<0: - realpos = len(exc.object) + realpos - # if we don't advance this time, terminate on the next call - # otherwise we'd get an endless loop - if realpos <= exc.start: - self.pos = len(exc.object) - return ("", oldpos) - - # A UnicodeEncodeError object with a bad start attribute - class BadStartUnicodeEncodeError(UnicodeEncodeError): - def __init__(self): - UnicodeEncodeError.__init__(self, "ascii", "", 0, 1, "bad") - self.start = [] - - # A UnicodeEncodeError object with a bad object attribute - class BadObjectUnicodeEncodeError(UnicodeEncodeError): - def __init__(self): - UnicodeEncodeError.__init__(self, "ascii", "", 0, 1, "bad") - self.object = [] - - # A UnicodeDecodeError object without an end attribute - class NoEndUnicodeDecodeError(UnicodeDecodeError): - def __init__(self): - UnicodeDecodeError.__init__(self, "ascii", bytearray(b""), 0, 1, "bad") - del self.end - - # A UnicodeDecodeError object with a bad object attribute - class BadObjectUnicodeDecodeError(UnicodeDecodeError): - def __init__(self): - UnicodeDecodeError.__init__(self, "ascii", bytearray(b""), 0, 1, "bad") - self.object = [] - - # A UnicodeTranslateError object without a start attribute - class NoStartUnicodeTranslateError(UnicodeTranslateError): - def __init__(self): - UnicodeTranslateError.__init__(self, "", 0, 1, "bad") - del self.start - - # A UnicodeTranslateError object without an end attribute - class NoEndUnicodeTranslateError(UnicodeTranslateError): - def __init__(self): - UnicodeTranslateError.__init__(self, "", 0, 1, "bad") - del self.end - - # A UnicodeTranslateError object without an object attribute - class NoObjectUnicodeTranslateError(UnicodeTranslateError): - def __init__(self): - UnicodeTranslateError.__init__(self, "", 0, 1, "bad") - del self.object - - class CodecCallbackTest(unittest.TestCase): - - def test_xmlcharrefreplace(self): - # replace unencodable characters which numeric character entities. - # For ascii, latin-1 and charmaps this is completely implemented - # in C and should be reasonably fast. - s = "\u30b9\u30d1\u30e2 \xe4nd eggs" - self.assertEqual( - s.encode("ascii", "xmlcharrefreplace"), - b"スパモ änd eggs" - ) - self.assertEqual( - s.encode("latin-1", "xmlcharrefreplace"), - b"スパモ \xe4nd eggs" - ) - - def test_xmlcharnamereplace(self): - # This time use a named character entity for unencodable - # characters, if one is available. - - def xmlcharnamereplace(exc): - if not isinstance(exc, UnicodeEncodeError): - raise TypeError("don't know how to handle %r" % exc) - l = [] - for c in exc.object[exc.start:exc.end]: - try: - l.append("&%s;" % html.entities.codepoint2name[ord(c)]) - except KeyError: - l.append("&#%d;" % ord(c)) - return ("".join(l), exc.end) - - codecs.register_error( - "test.xmlcharnamereplace", xmlcharnamereplace) - - sin = "\xab\u211c\xbb = \u2329\u1234\u20ac\u232a" - sout = b"«ℜ» = ⟨ሴ€⟩" - self.assertEqual(sin.encode("ascii", "test.xmlcharnamereplace"), sout) - sout = b"\xabℜ\xbb = ⟨ሴ€⟩" - self.assertEqual(sin.encode("latin-1", "test.xmlcharnamereplace"), sout) - sout = b"\xabℜ\xbb = ⟨ሴ\xa4⟩" - self.assertEqual(sin.encode("iso-8859-15", "test.xmlcharnamereplace"), sout) - - def test_uninamereplace(self): - # We're using the names from the unicode database this time, - # and we're doing "syntax highlighting" here, i.e. we include - # the replaced text in ANSI escape sequences. For this it is - # useful that the error handler is not called for every single - # unencodable character, but for a complete sequence of - # unencodable characters, otherwise we would output many - # unnecessary escape sequences. - - def uninamereplace(exc): - if not isinstance(exc, UnicodeEncodeError): - raise TypeError("don't know how to handle %r" % exc) - l = [] - for c in exc.object[exc.start:exc.end]: - l.append(unicodedata.name(c, "0x%x" % ord(c))) - return ("\033[1m%s\033[0m" % ", ".join(l), exc.end) - - codecs.register_error( - "test.uninamereplace", uninamereplace) - - sin = "\xac\u1234\u20ac\u8000" - sout = b"\033[1mNOT SIGN, ETHIOPIC SYLLABLE SEE, EURO SIGN, CJK UNIFIED IDEOGRAPH-8000\033[0m" - self.assertEqual(sin.encode("ascii", "test.uninamereplace"), sout) - - sout = b"\xac\033[1mETHIOPIC SYLLABLE SEE, EURO SIGN, CJK UNIFIED IDEOGRAPH-8000\033[0m" - self.assertEqual(sin.encode("latin-1", "test.uninamereplace"), sout) - - sout = b"\xac\033[1mETHIOPIC SYLLABLE SEE\033[0m\xa4\033[1mCJK UNIFIED IDEOGRAPH-8000\033[0m" - self.assertEqual(sin.encode("iso-8859-15", "test.uninamereplace"), sout) - - def test_backslashescape(self): - # Does the same as the "unicode-escape" encoding, but with different - # base encodings. - sin = "a\xac\u1234\u20ac\u8000\U0010ffff" - sout = b"a\\xac\\u1234\\u20ac\\u8000\\U0010ffff" - self.assertEqual(sin.encode("ascii", "backslashreplace"), sout) - - sout = b"a\xac\\u1234\\u20ac\\u8000\\U0010ffff" - self.assertEqual(sin.encode("latin-1", "backslashreplace"), sout) - - sout = b"a\xac\\u1234\xa4\\u8000\\U0010ffff" - self.assertEqual(sin.encode("iso-8859-15", "backslashreplace"), sout) - - def test_nameescape(self): - # Does the same as backslashescape, but prefers ``\N{...}`` escape - # sequences. - sin = "a\xac\u1234\u20ac\u8000\U0010ffff" - sout = (b'a\\N{NOT SIGN}\\N{ETHIOPIC SYLLABLE SEE}\\N{EURO SIGN}' - b'\\N{CJK UNIFIED IDEOGRAPH-8000}\\U0010ffff') - self.assertEqual(sin.encode("ascii", "namereplace"), sout) - - sout = (b'a\xac\\N{ETHIOPIC SYLLABLE SEE}\\N{EURO SIGN}' - b'\\N{CJK UNIFIED IDEOGRAPH-8000}\\U0010ffff') - self.assertEqual(sin.encode("latin-1", "namereplace"), sout) - - sout = (b'a\xac\\N{ETHIOPIC SYLLABLE SEE}\xa4' - b'\\N{CJK UNIFIED IDEOGRAPH-8000}\\U0010ffff') - self.assertEqual(sin.encode("iso-8859-15", "namereplace"), sout) - - def test_decoding_callbacks(self): - # This is a test for a decoding callback handler - # that allows the decoding of the invalid sequence - # "\xc0\x80" and returns "\x00" instead of raising an error. - # All other illegal sequences will be handled strictly. - def relaxedutf8(exc): - if not isinstance(exc, UnicodeDecodeError): - raise TypeError("don't know how to handle %r" % exc) - if exc.object[exc.start:exc.start+2] == b"\xc0\x80": - return ("\x00", exc.start+2) # retry after two bytes - else: - raise exc - - codecs.register_error("test.relaxedutf8", relaxedutf8) - - # all the "\xc0\x80" will be decoded to "\x00" - sin = b"a\x00b\xc0\x80c\xc3\xbc\xc0\x80\xc0\x80" - sout = "a\x00b\x00c\xfc\x00\x00" - self.assertEqual(sin.decode("utf-8", "test.relaxedutf8"), sout) - - # "\xc0\x81" is not valid and a UnicodeDecodeError will be raised - sin = b"\xc0\x80\xc0\x81" - self.assertRaises(UnicodeDecodeError, sin.decode, - "utf-8", "test.relaxedutf8") - - def test_charmapencode(self): - # For charmap encodings the replacement string will be - # mapped through the encoding again. This means, that - # to be able to use e.g. the "replace" handler, the - # charmap has to have a mapping for "?". - charmap = dict((ord(c), bytes(2*c.upper(), 'ascii')) for c in "abcdefgh") - sin = "abc" - sout = b"AABBCC" - self.assertEqual(codecs.charmap_encode(sin, "strict", charmap)[0], sout) - - sin = "abcA" - self.assertRaises(UnicodeError, codecs.charmap_encode, sin, "strict", charmap) - - charmap[ord("?")] = b"XYZ" - sin = "abcDEF" - sout = b"AABBCCXYZXYZXYZ" - self.assertEqual(codecs.charmap_encode(sin, "replace", charmap)[0], sout) - - charmap[ord("?")] = "XYZ" # wrong type in mapping - self.assertRaises(TypeError, codecs.charmap_encode, sin, "replace", charmap) - - def test_callbacks(self): - def handler1(exc): - r = range(exc.start, exc.end) - if isinstance(exc, UnicodeEncodeError): - l = ["<%d>" % ord(exc.object[pos]) for pos in r] - elif isinstance(exc, UnicodeDecodeError): - l = ["<%d>" % exc.object[pos] for pos in r] - else: - raise TypeError("don't know how to handle %r" % exc) - return ("[%s]" % "".join(l), exc.end) - - codecs.register_error("test.handler1", handler1) - - def handler2(exc): - if not isinstance(exc, UnicodeDecodeError): - raise TypeError("don't know how to handle %r" % exc) - l = ["<%d>" % exc.object[pos] for pos in range(exc.start, exc.end)] - return ("[%s]" % "".join(l), exc.end+1) # skip one character - - codecs.register_error("test.handler2", handler2) - - s = b"\x00\x81\x7f\x80\xff" - - self.assertEqual( - s.decode("ascii", "test.handler1"), - "\x00[<129>]\x7f[<128>][<255>]" - ) - self.assertEqual( - s.decode("ascii", "test.handler2"), - "\x00[<129>][<128>]" - ) - - self.assertEqual( - b"\\u3042\\u3xxx".decode("unicode-escape", "test.handler1"), - "\u3042[<92><117><51>]xxx" - ) - - self.assertEqual( - b"\\u3042\\u3xx".decode("unicode-escape", "test.handler1"), - "\u3042[<92><117><51>]xx" - ) - - self.assertEqual( - codecs.charmap_decode(b"abc", "test.handler1", {ord("a"): "z"})[0], - "z[<98>][<99>]" - ) - - self.assertEqual( - "g\xfc\xdfrk".encode("ascii", "test.handler1"), - b"g[<252><223>]rk" - ) - - self.assertEqual( - "g\xfc\xdf".encode("ascii", "test.handler1"), - b"g[<252><223>]" - ) - - def test_longstrings(self): - # test long strings to check for memory overflow problems - errors = [ "strict", "ignore", "replace", "xmlcharrefreplace", - "backslashreplace", "namereplace"] - # register the handlers under different names, - # to prevent the codec from recognizing the name - for err in errors: - codecs.register_error("test." + err, codecs.lookup_error(err)) - l = 1000 - errors += [ "test." + err for err in errors ] - for uni in [ s*l for s in ("x", "\u3042", "a\xe4") ]: - for enc in ("ascii", "latin-1", "iso-8859-1", "iso-8859-15", - "utf-8", "utf-7", "utf-16", "utf-32"): - for err in errors: - try: - uni.encode(enc, err) - except UnicodeError: - pass - - def check_exceptionobjectargs(self, exctype, args, msg): - # Test UnicodeError subclasses: construction, attribute assignment and __str__ conversion - # check with one missing argument - self.assertRaises(TypeError, exctype, *args[:-1]) - # check with one argument too much - self.assertRaises(TypeError, exctype, *(args + ["too much"])) - # check with one argument of the wrong type - wrongargs = [ "spam", b"eggs", b"spam", 42, 1.0, None ] - for i in range(len(args)): - for wrongarg in wrongargs: - if type(wrongarg) is type(args[i]): - continue - # build argument array - callargs = [] - for j in range(len(args)): - if i==j: - callargs.append(wrongarg) - else: - callargs.append(args[i]) - self.assertRaises(TypeError, exctype, *callargs) - - # check with the correct number and type of arguments - exc = exctype(*args) - self.assertEqual(str(exc), msg) - - def test_unicodeencodeerror(self): - self.check_exceptionobjectargs( - UnicodeEncodeError, - ["ascii", "g\xfcrk", 1, 2, "ouch"], - "'ascii' codec can't encode character '\\xfc' in position 1: ouch" - ) - self.check_exceptionobjectargs( - UnicodeEncodeError, - ["ascii", "g\xfcrk", 1, 4, "ouch"], - "'ascii' codec can't encode characters in position 1-3: ouch" - ) - self.check_exceptionobjectargs( - UnicodeEncodeError, - ["ascii", "\xfcx", 0, 1, "ouch"], - "'ascii' codec can't encode character '\\xfc' in position 0: ouch" - ) - self.check_exceptionobjectargs( - UnicodeEncodeError, - ["ascii", "\u0100x", 0, 1, "ouch"], - "'ascii' codec can't encode character '\\u0100' in position 0: ouch" - ) - self.check_exceptionobjectargs( - UnicodeEncodeError, - ["ascii", "\uffffx", 0, 1, "ouch"], - "'ascii' codec can't encode character '\\uffff' in position 0: ouch" - ) - self.check_exceptionobjectargs( - UnicodeEncodeError, - ["ascii", "\U00010000x", 0, 1, "ouch"], - "'ascii' codec can't encode character '\\U00010000' in position 0: ouch" - ) - - def test_unicodedecodeerror(self): - self.check_exceptionobjectargs( - UnicodeDecodeError, - ["ascii", bytearray(b"g\xfcrk"), 1, 2, "ouch"], - "'ascii' codec can't decode byte 0xfc in position 1: ouch" - ) - self.check_exceptionobjectargs( - UnicodeDecodeError, - ["ascii", bytearray(b"g\xfcrk"), 1, 3, "ouch"], - "'ascii' codec can't decode bytes in position 1-2: ouch" - ) - - def test_unicodetranslateerror(self): - self.check_exceptionobjectargs( - UnicodeTranslateError, - ["g\xfcrk", 1, 2, "ouch"], - "can't translate character '\\xfc' in position 1: ouch" - ) - self.check_exceptionobjectargs( - UnicodeTranslateError, - ["g\u0100rk", 1, 2, "ouch"], - "can't translate character '\\u0100' in position 1: ouch" - ) - self.check_exceptionobjectargs( - UnicodeTranslateError, - ["g\uffffrk", 1, 2, "ouch"], - "can't translate character '\\uffff' in position 1: ouch" - ) - self.check_exceptionobjectargs( - UnicodeTranslateError, - ["g\U00010000rk", 1, 2, "ouch"], - "can't translate character '\\U00010000' in position 1: ouch" - ) - self.check_exceptionobjectargs( - UnicodeTranslateError, - ["g\xfcrk", 1, 3, "ouch"], - "can't translate characters in position 1-2: ouch" - ) - - def test_badandgoodstrictexceptions(self): - # "strict" complains about a non-exception passed in - self.assertRaises( - TypeError, - codecs.strict_errors, - 42 - ) - # "strict" complains about the wrong exception type - self.assertRaises( - Exception, - codecs.strict_errors, - Exception("ouch") - ) - - # If the correct exception is passed in, "strict" raises it - self.assertRaises( - UnicodeEncodeError, - codecs.strict_errors, - UnicodeEncodeError("ascii", "\u3042", 0, 1, "ouch") - ) - self.assertRaises( - UnicodeDecodeError, - codecs.strict_errors, - UnicodeDecodeError("ascii", bytearray(b"\xff"), 0, 1, "ouch") - ) - self.assertRaises( - UnicodeTranslateError, - codecs.strict_errors, - UnicodeTranslateError("\u3042", 0, 1, "ouch") - ) - - def test_badandgoodignoreexceptions(self): - # "ignore" complains about a non-exception passed in - self.assertRaises( - TypeError, - codecs.ignore_errors, - 42 - ) - # "ignore" complains about the wrong exception type - self.assertRaises( - TypeError, - codecs.ignore_errors, - UnicodeError("ouch") - ) - # If the correct exception is passed in, "ignore" returns an empty replacement - self.assertEqual( - codecs.ignore_errors( - UnicodeEncodeError("ascii", "a\u3042b", 1, 2, "ouch")), - ("", 2) - ) - self.assertEqual( - codecs.ignore_errors( - UnicodeDecodeError("ascii", bytearray(b"a\xffb"), 1, 2, "ouch")), - ("", 2) - ) - self.assertEqual( - codecs.ignore_errors( - UnicodeTranslateError("a\u3042b", 1, 2, "ouch")), - ("", 2) - ) - - def test_badandgoodreplaceexceptions(self): - # "replace" complains about a non-exception passed in - self.assertRaises( - TypeError, - codecs.replace_errors, - 42 - ) - # "replace" complains about the wrong exception type - self.assertRaises( - TypeError, - codecs.replace_errors, - UnicodeError("ouch") - ) - self.assertRaises( - TypeError, - codecs.replace_errors, - BadObjectUnicodeEncodeError() - ) - self.assertRaises( - TypeError, - codecs.replace_errors, - BadObjectUnicodeDecodeError() - ) - # With the correct exception, "replace" returns an "?" or "\ufffd" replacement - self.assertEqual( - codecs.replace_errors( - UnicodeEncodeError("ascii", "a\u3042b", 1, 2, "ouch")), - ("?", 2) - ) - self.assertEqual( - codecs.replace_errors( - UnicodeDecodeError("ascii", bytearray(b"a\xffb"), 1, 2, "ouch")), - ("\ufffd", 2) - ) - self.assertEqual( - codecs.replace_errors( - UnicodeTranslateError("a\u3042b", 1, 2, "ouch")), - ("\ufffd", 2) - ) - - def test_badandgoodxmlcharrefreplaceexceptions(self): - # "xmlcharrefreplace" complains about a non-exception passed in - self.assertRaises( - TypeError, - codecs.xmlcharrefreplace_errors, - 42 - ) - # "xmlcharrefreplace" complains about the wrong exception types - self.assertRaises( - TypeError, - codecs.xmlcharrefreplace_errors, - UnicodeError("ouch") - ) - # "xmlcharrefreplace" can only be used for encoding - self.assertRaises( - TypeError, - codecs.xmlcharrefreplace_errors, - UnicodeDecodeError("ascii", bytearray(b"\xff"), 0, 1, "ouch") - ) - self.assertRaises( - TypeError, - codecs.xmlcharrefreplace_errors, - UnicodeTranslateError("\u3042", 0, 1, "ouch") - ) - # Use the correct exception - cs = (0, 1, 9, 10, 99, 100, 999, 1000, 9999, 10000, 99999, 100000, - 999999, 1000000) - cs += (0xd800, 0xdfff) - s = "".join(chr(c) for c in cs) - self.assertEqual( - codecs.xmlcharrefreplace_errors( - UnicodeEncodeError("ascii", "a" + s + "b", - 1, 1 + len(s), "ouch") - ), - ("".join("&#%d;" % c for c in cs), 1 + len(s)) - ) - - def test_badandgoodbackslashreplaceexceptions(self): - # "backslashreplace" complains about a non-exception passed in - self.assertRaises( - TypeError, - codecs.backslashreplace_errors, - 42 - ) - # "backslashreplace" complains about the wrong exception types - self.assertRaises( - TypeError, - codecs.backslashreplace_errors, - UnicodeError("ouch") - ) - # Use the correct exception - tests = [ - ("\u3042", "\\u3042"), - ("\n", "\\x0a"), - ("a", "\\x61"), - ("\x00", "\\x00"), - ("\xff", "\\xff"), - ("\u0100", "\\u0100"), - ("\uffff", "\\uffff"), - ("\U00010000", "\\U00010000"), - ("\U0010ffff", "\\U0010ffff"), - # Lone surrogates - ("\ud800", "\\ud800"), - ("\udfff", "\\udfff"), - ("\ud800\udfff", "\\ud800\\udfff"), - ] - for s, r in tests: - with self.subTest(str=s): - self.assertEqual( - codecs.backslashreplace_errors( - UnicodeEncodeError("ascii", "a" + s + "b", - 1, 1 + len(s), "ouch")), - (r, 1 + len(s)) - ) - self.assertEqual( - codecs.backslashreplace_errors( - UnicodeTranslateError("a" + s + "b", - 1, 1 + len(s), "ouch")), - (r, 1 + len(s)) - ) - tests = [ - (b"a", "\\x61"), - (b"\n", "\\x0a"), - (b"\x00", "\\x00"), - (b"\xff", "\\xff"), - ] - for b, r in tests: - with self.subTest(bytes=b): - self.assertEqual( - codecs.backslashreplace_errors( - UnicodeDecodeError("ascii", bytearray(b"a" + b + b"b"), - 1, 2, "ouch")), - (r, 2) - ) - - def test_badandgoodnamereplaceexceptions(self): - # "namereplace" complains about a non-exception passed in - self.assertRaises( - TypeError, - codecs.namereplace_errors, - 42 - ) - # "namereplace" complains about the wrong exception types - self.assertRaises( - TypeError, - codecs.namereplace_errors, - UnicodeError("ouch") - ) - # "namereplace" can only be used for encoding - self.assertRaises( - TypeError, - codecs.namereplace_errors, - UnicodeDecodeError("ascii", bytearray(b"\xff"), 0, 1, "ouch") - ) - self.assertRaises( - TypeError, - codecs.namereplace_errors, - UnicodeTranslateError("\u3042", 0, 1, "ouch") - ) - # Use the correct exception - tests = [ - ("\u3042", "\\N{HIRAGANA LETTER A}"), - ("\x00", "\\x00"), - ("\ufbf9", "\\N{ARABIC LIGATURE UIGHUR KIRGHIZ YEH WITH " - "HAMZA ABOVE WITH ALEF MAKSURA ISOLATED FORM}"), - ("\U000e007f", "\\N{CANCEL TAG}"), - ("\U0010ffff", "\\U0010ffff"), - # Lone surrogates - ("\ud800", "\\ud800"), - ("\udfff", "\\udfff"), - ("\ud800\udfff", "\\ud800\\udfff"), - ] - for s, r in tests: - with self.subTest(str=s): - self.assertEqual( - codecs.namereplace_errors( - UnicodeEncodeError("ascii", "a" + s + "b", - 1, 1 + len(s), "ouch")), - (r, 1 + len(s)) - ) - - def test_badandgoodsurrogateescapeexceptions(self): - surrogateescape_errors = codecs.lookup_error('surrogateescape') - # "surrogateescape" complains about a non-exception passed in - self.assertRaises( - TypeError, - surrogateescape_errors, - 42 - ) - # "surrogateescape" complains about the wrong exception types - self.assertRaises( - TypeError, - surrogateescape_errors, - UnicodeError("ouch") - ) - # "surrogateescape" can not be used for translating - self.assertRaises( - TypeError, - surrogateescape_errors, - UnicodeTranslateError("\udc80", 0, 1, "ouch") - ) - # Use the correct exception - for s in ("a", "\udc7f", "\udd00"): - with self.subTest(str=s): - self.assertRaises( - UnicodeEncodeError, - surrogateescape_errors, - UnicodeEncodeError("ascii", s, 0, 1, "ouch") - ) - self.assertEqual( - surrogateescape_errors( - UnicodeEncodeError("ascii", "a\udc80b", 1, 2, "ouch")), - (b"\x80", 2) - ) - self.assertRaises( - UnicodeDecodeError, - surrogateescape_errors, - UnicodeDecodeError("ascii", bytearray(b"a"), 0, 1, "ouch") - ) - self.assertEqual( - surrogateescape_errors( - UnicodeDecodeError("ascii", bytearray(b"a\x80b"), 1, 2, "ouch")), - ("\udc80", 2) - ) - - def test_badandgoodsurrogatepassexceptions(self): - surrogatepass_errors = codecs.lookup_error('surrogatepass') - # "surrogatepass" complains about a non-exception passed in - self.assertRaises( - TypeError, - surrogatepass_errors, - 42 - ) - # "surrogatepass" complains about the wrong exception types - self.assertRaises( - TypeError, - surrogatepass_errors, - UnicodeError("ouch") - ) - # "surrogatepass" can not be used for translating - self.assertRaises( - TypeError, - surrogatepass_errors, - UnicodeTranslateError("\ud800", 0, 1, "ouch") - ) - # Use the correct exception - for enc in ("utf-8", "utf-16le", "utf-16be", "utf-32le", "utf-32be"): - with self.subTest(encoding=enc): - self.assertRaises( - UnicodeEncodeError, - surrogatepass_errors, - UnicodeEncodeError(enc, "a", 0, 1, "ouch") - ) - self.assertRaises( - UnicodeDecodeError, - surrogatepass_errors, - UnicodeDecodeError(enc, "a".encode(enc), 0, 1, "ouch") - ) - for s in ("\ud800", "\udfff", "\ud800\udfff"): - with self.subTest(str=s): - self.assertRaises( - UnicodeEncodeError, - surrogatepass_errors, - UnicodeEncodeError("ascii", s, 0, len(s), "ouch") - ) - tests = [ - ("utf-8", "\ud800", b'\xed\xa0\x80', 3), - ("utf-16le", "\ud800", b'\x00\xd8', 2), - ("utf-16be", "\ud800", b'\xd8\x00', 2), - ("utf-32le", "\ud800", b'\x00\xd8\x00\x00', 4), - ("utf-32be", "\ud800", b'\x00\x00\xd8\x00', 4), - ("utf-8", "\udfff", b'\xed\xbf\xbf', 3), - ("utf-16le", "\udfff", b'\xff\xdf', 2), - ("utf-16be", "\udfff", b'\xdf\xff', 2), - ("utf-32le", "\udfff", b'\xff\xdf\x00\x00', 4), - ("utf-32be", "\udfff", b'\x00\x00\xdf\xff', 4), - ("utf-8", "\ud800\udfff", b'\xed\xa0\x80\xed\xbf\xbf', 3), - ("utf-16le", "\ud800\udfff", b'\x00\xd8\xff\xdf', 2), - ("utf-16be", "\ud800\udfff", b'\xd8\x00\xdf\xff', 2), - ("utf-32le", "\ud800\udfff", b'\x00\xd8\x00\x00\xff\xdf\x00\x00', 4), - ("utf-32be", "\ud800\udfff", b'\x00\x00\xd8\x00\x00\x00\xdf\xff', 4), - ] - for enc, s, b, n in tests: - with self.subTest(encoding=enc, str=s, bytes=b): - self.assertEqual( - surrogatepass_errors( - UnicodeEncodeError(enc, "a" + s + "b", - 1, 1 + len(s), "ouch")), - (b, 1 + len(s)) - ) - self.assertEqual( - surrogatepass_errors( - UnicodeDecodeError(enc, bytearray(b"a" + b[:n] + b"b"), - 1, 1 + n, "ouch")), - (s[:1], 1 + n) - ) - - def test_badhandlerresults(self): - results = ( 42, "foo", (1,2,3), ("foo", 1, 3), ("foo", None), ("foo",), ("foo", 1, 3), ("foo", None), ("foo",) ) - encs = ("ascii", "latin-1", "iso-8859-1", "iso-8859-15") - - for res in results: - codecs.register_error("test.badhandler", lambda x: res) - for enc in encs: - self.assertRaises( - TypeError, - "\u3042".encode, - enc, - "test.badhandler" - ) - for (enc, bytes) in ( - ("ascii", b"\xff"), - ("utf-8", b"\xff"), - ("utf-7", b"+x-"), - ): - self.assertRaises( - TypeError, - bytes.decode, - enc, - "test.badhandler" - ) - - def test_lookup(self): - self.assertEqual(codecs.strict_errors, codecs.lookup_error("strict")) - self.assertEqual(codecs.ignore_errors, codecs.lookup_error("ignore")) - self.assertEqual(codecs.strict_errors, codecs.lookup_error("strict")) - self.assertEqual( - codecs.xmlcharrefreplace_errors, - codecs.lookup_error("xmlcharrefreplace") - ) - self.assertEqual( - codecs.backslashreplace_errors, - codecs.lookup_error("backslashreplace") - ) - self.assertEqual( - codecs.namereplace_errors, - codecs.lookup_error("namereplace") - ) - - def test_unencodablereplacement(self): - def unencrepl(exc): - if isinstance(exc, UnicodeEncodeError): - return ("\u4242", exc.end) - else: - raise TypeError("don't know how to handle %r" % exc) - codecs.register_error("test.unencreplhandler", unencrepl) - for enc in ("ascii", "iso-8859-1", "iso-8859-15"): - self.assertRaises( - UnicodeEncodeError, - "\u4242".encode, - enc, - "test.unencreplhandler" - ) - - def test_badregistercall(self): - # enhance coverage of: - # Modules/_codecsmodule.c::register_error() - # Python/codecs.c::PyCodec_RegisterError() - self.assertRaises(TypeError, codecs.register_error, 42) - self.assertRaises(TypeError, codecs.register_error, "test.dummy", 42) - - def test_badlookupcall(self): - # enhance coverage of: - # Modules/_codecsmodule.c::lookup_error() - self.assertRaises(TypeError, codecs.lookup_error) - - def test_unknownhandler(self): - # enhance coverage of: - # Modules/_codecsmodule.c::lookup_error() - self.assertRaises(LookupError, codecs.lookup_error, "test.unknown") - - def test_xmlcharrefvalues(self): - # enhance coverage of: - # Python/codecs.c::PyCodec_XMLCharRefReplaceErrors() - # and inline implementations - v = (1, 5, 10, 50, 100, 500, 1000, 5000, 10000, 50000, 100000, - 500000, 1000000) - s = "".join([chr(x) for x in v]) - codecs.register_error("test.xmlcharrefreplace", codecs.xmlcharrefreplace_errors) - for enc in ("ascii", "iso-8859-15"): - for err in ("xmlcharrefreplace", "test.xmlcharrefreplace"): - s.encode(enc, err) - - def test_decodehelper(self): - # enhance coverage of: - # Objects/unicodeobject.c::unicode_decode_call_errorhandler() - # and callers - self.assertRaises(LookupError, b"\xff".decode, "ascii", "test.unknown") - - def baddecodereturn1(exc): - return 42 - codecs.register_error("test.baddecodereturn1", baddecodereturn1) - self.assertRaises(TypeError, b"\xff".decode, "ascii", "test.baddecodereturn1") - self.assertRaises(TypeError, b"\\".decode, "unicode-escape", "test.baddecodereturn1") - self.assertRaises(TypeError, b"\\x0".decode, "unicode-escape", "test.baddecodereturn1") - self.assertRaises(TypeError, b"\\x0y".decode, "unicode-escape", "test.baddecodereturn1") - self.assertRaises(TypeError, b"\\Uffffeeee".decode, "unicode-escape", "test.baddecodereturn1") - self.assertRaises(TypeError, b"\\uyyyy".decode, "raw-unicode-escape", "test.baddecodereturn1") - - def baddecodereturn2(exc): - return ("?", None) - codecs.register_error("test.baddecodereturn2", baddecodereturn2) - self.assertRaises(TypeError, b"\xff".decode, "ascii", "test.baddecodereturn2") - - handler = PosReturn() - codecs.register_error("test.posreturn", handler.handle) - - # Valid negative position - handler.pos = -1 - self.assertEqual(b"\xff0".decode("ascii", "test.posreturn"), "0") - - # Valid negative position - handler.pos = -2 - self.assertEqual(b"\xff0".decode("ascii", "test.posreturn"), "") - - # Negative position out of bounds - handler.pos = -3 - self.assertRaises(IndexError, b"\xff0".decode, "ascii", "test.posreturn") - - # Valid positive position - handler.pos = 1 - self.assertEqual(b"\xff0".decode("ascii", "test.posreturn"), "0") - - # Largest valid positive position (one beyond end of input) - handler.pos = 2 - self.assertEqual(b"\xff0".decode("ascii", "test.posreturn"), "") - - # Invalid positive position - handler.pos = 3 - self.assertRaises(IndexError, b"\xff0".decode, "ascii", "test.posreturn") - - # Restart at the "0" - handler.pos = 6 - self.assertEqual(b"\\uyyyy0".decode("raw-unicode-escape", "test.posreturn"), "0") - - class D(dict): - def __getitem__(self, key): - raise ValueError - self.assertRaises(UnicodeError, codecs.charmap_decode, b"\xff", "strict", {0xff: None}) - self.assertRaises(ValueError, codecs.charmap_decode, b"\xff", "strict", D()) - self.assertRaises(TypeError, codecs.charmap_decode, b"\xff", "strict", {0xff: sys.maxunicode+1}) - - def test_encodehelper(self): - # enhance coverage of: - # Objects/unicodeobject.c::unicode_encode_call_errorhandler() - # and callers - self.assertRaises(LookupError, "\xff".encode, "ascii", "test.unknown") - - def badencodereturn1(exc): - return 42 - codecs.register_error("test.badencodereturn1", badencodereturn1) - self.assertRaises(TypeError, "\xff".encode, "ascii", "test.badencodereturn1") - - def badencodereturn2(exc): - return ("?", None) - codecs.register_error("test.badencodereturn2", badencodereturn2) - self.assertRaises(TypeError, "\xff".encode, "ascii", "test.badencodereturn2") - - handler = PosReturn() - codecs.register_error("test.posreturn", handler.handle) - - # Valid negative position - handler.pos = -1 - self.assertEqual("\xff0".encode("ascii", "test.posreturn"), b"0") - - # Valid negative position - handler.pos = -2 - self.assertEqual("\xff0".encode("ascii", "test.posreturn"), b"") - - # Negative position out of bounds - handler.pos = -3 - self.assertRaises(IndexError, "\xff0".encode, "ascii", "test.posreturn") - - # Valid positive position - handler.pos = 1 - self.assertEqual("\xff0".encode("ascii", "test.posreturn"), b"0") - - # Largest valid positive position (one beyond end of input - handler.pos = 2 - self.assertEqual("\xff0".encode("ascii", "test.posreturn"), b"") - - # Invalid positive position - handler.pos = 3 - self.assertRaises(IndexError, "\xff0".encode, "ascii", "test.posreturn") - - handler.pos = 0 - - class D(dict): - def __getitem__(self, key): - raise ValueError - for err in ("strict", "replace", "xmlcharrefreplace", - "backslashreplace", "namereplace", "test.posreturn"): - self.assertRaises(UnicodeError, codecs.charmap_encode, "\xff", err, {0xff: None}) - self.assertRaises(ValueError, codecs.charmap_encode, "\xff", err, D()) - self.assertRaises(TypeError, codecs.charmap_encode, "\xff", err, {0xff: 300}) - - def test_translatehelper(self): - # enhance coverage of: - # Objects/unicodeobject.c::unicode_encode_call_errorhandler() - # and callers - # (Unfortunately the errors argument is not directly accessible - # from Python, so we can't test that much) - class D(dict): - def __getitem__(self, key): - raise ValueError - #self.assertRaises(ValueError, "\xff".translate, D()) - self.assertRaises(ValueError, "\xff".translate, {0xff: sys.maxunicode+1}) - self.assertRaises(TypeError, "\xff".translate, {0xff: ()}) - - def test_bug828737(self): - charmap = { - ord("&"): "&", - ord("<"): "<", - ord(">"): ">", - ord('"'): """, - } - - for n in (1, 10, 100, 1000): - text = 'abcghi'*n - text.translate(charmap) - - def test_mutatingdecodehandler(self): - baddata = [ - ("ascii", b"\xff"), - ("utf-7", b"++"), - ("utf-8", b"\xff"), - ("utf-16", b"\xff"), - ("utf-32", b"\xff"), - ("unicode-escape", b"\\u123g"), - ("raw-unicode-escape", b"\\u123g"), - ] - - def replacing(exc): - if isinstance(exc, UnicodeDecodeError): - exc.object = 42 - return ("\u4242", 0) - else: - raise TypeError("don't know how to handle %r" % exc) - codecs.register_error("test.replacing", replacing) - - for (encoding, data) in baddata: - with self.assertRaises(TypeError): - data.decode(encoding, "test.replacing") - - def mutating(exc): - if isinstance(exc, UnicodeDecodeError): - exc.object = b"" - return ("\u4242", 0) - else: - raise TypeError("don't know how to handle %r" % exc) - codecs.register_error("test.mutating", mutating) - # If the decoder doesn't pick up the modified input the following - # will lead to an endless loop - for (encoding, data) in baddata: - self.assertEqual(data.decode(encoding, "test.mutating"), "\u4242") - - # issue32583 - def test_crashing_decode_handler(self): - # better generating one more character to fill the extra space slot - # so in debug build it can steadily fail - def forward_shorter_than_end(exc): - if isinstance(exc, UnicodeDecodeError): - # size one character, 0 < forward < exc.end - return ('\ufffd', exc.start+1) - else: - raise TypeError("don't know how to handle %r" % exc) - codecs.register_error( - "test.forward_shorter_than_end", forward_shorter_than_end) - - self.assertEqual( - b'\xd8\xd8\xd8\xd8\xd8\x00\x00\x00'.decode( - 'utf-16-le', 'test.forward_shorter_than_end'), - '\ufffd\ufffd\ufffd\ufffd\xd8\x00' - ) - self.assertEqual( - b'\xd8\xd8\xd8\xd8\x00\xd8\x00\x00'.decode( - 'utf-16-be', 'test.forward_shorter_than_end'), - '\ufffd\ufffd\ufffd\ufffd\xd8\x00' - ) - self.assertEqual( - b'\x11\x11\x11\x11\x11\x00\x00\x00\x00\x00\x00'.decode( - 'utf-32-le', 'test.forward_shorter_than_end'), - '\ufffd\ufffd\ufffd\u1111\x00' - ) - self.assertEqual( - b'\x11\x11\x11\x00\x00\x11\x11\x00\x00\x00\x00'.decode( - 'utf-32-be', 'test.forward_shorter_than_end'), - '\ufffd\ufffd\ufffd\u1111\x00' - ) - - def replace_with_long(exc): - if isinstance(exc, UnicodeDecodeError): - exc.object = b"\x00" * 8 - return ('\ufffd', exc.start) - else: - raise TypeError("don't know how to handle %r" % exc) - codecs.register_error("test.replace_with_long", replace_with_long) - - self.assertEqual( - b'\x00'.decode('utf-16', 'test.replace_with_long'), - '\ufffd\x00\x00\x00\x00' - ) - self.assertEqual( - b'\x00'.decode('utf-32', 'test.replace_with_long'), - '\ufffd\x00\x00' - ) - - - def test_fake_error_class(self): - handlers = [ - codecs.strict_errors, - codecs.ignore_errors, - codecs.replace_errors, - codecs.backslashreplace_errors, - codecs.namereplace_errors, - codecs.xmlcharrefreplace_errors, - codecs.lookup_error('surrogateescape'), - codecs.lookup_error('surrogatepass'), - ] - for cls in UnicodeEncodeError, UnicodeDecodeError, UnicodeTranslateError: - class FakeUnicodeError(str): - __class__ = cls - for handler in handlers: - with self.subTest(handler=handler, error_class=cls): - self.assertRaises(TypeError, handler, FakeUnicodeError()) - class FakeUnicodeError(Exception): - __class__ = cls - for handler in handlers: - with self.subTest(handler=handler, error_class=cls): - with self.assertRaises((TypeError, FakeUnicodeError)): - handler(FakeUnicodeError()) - - - if __name__ == "__main__": - unittest.main() diff --git a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_codecencodings_cn.yaml b/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_codecencodings_cn.yaml deleted file mode 100644 index 6142cd371..000000000 --- a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_codecencodings_cn.yaml +++ /dev/null @@ -1,97 +0,0 @@ -python: | - # - # test_codecencodings_cn.py - # Codec encoding tests for PRC encodings. - # - - from test import multibytecodec_support - import unittest - - class Test_GB2312(multibytecodec_support.TestBase, unittest.TestCase): - encoding = 'gb2312' - tstring = multibytecodec_support.load_teststring('gb2312') - codectests = ( - # invalid bytes - (b"abc\x81\x81\xc1\xc4", "strict", None), - (b"abc\xc8", "strict", None), - (b"abc\x81\x81\xc1\xc4", "replace", "abc\ufffd\ufffd\u804a"), - (b"abc\x81\x81\xc1\xc4\xc8", "replace", "abc\ufffd\ufffd\u804a\ufffd"), - (b"abc\x81\x81\xc1\xc4", "ignore", "abc\u804a"), - (b"\xc1\x64", "strict", None), - ) - - class Test_GBK(multibytecodec_support.TestBase, unittest.TestCase): - encoding = 'gbk' - tstring = multibytecodec_support.load_teststring('gbk') - codectests = ( - # invalid bytes - (b"abc\x80\x80\xc1\xc4", "strict", None), - (b"abc\xc8", "strict", None), - (b"abc\x80\x80\xc1\xc4", "replace", "abc\ufffd\ufffd\u804a"), - (b"abc\x80\x80\xc1\xc4\xc8", "replace", "abc\ufffd\ufffd\u804a\ufffd"), - (b"abc\x80\x80\xc1\xc4", "ignore", "abc\u804a"), - (b"\x83\x34\x83\x31", "strict", None), - ("\u30fb", "strict", None), - ) - - class Test_GB18030(multibytecodec_support.TestBase, unittest.TestCase): - encoding = 'gb18030' - tstring = multibytecodec_support.load_teststring('gb18030') - codectests = ( - # invalid bytes - (b"abc\x80\x80\xc1\xc4", "strict", None), - (b"abc\xc8", "strict", None), - (b"abc\x80\x80\xc1\xc4", "replace", "abc\ufffd\ufffd\u804a"), - (b"abc\x80\x80\xc1\xc4\xc8", "replace", "abc\ufffd\ufffd\u804a\ufffd"), - (b"abc\x80\x80\xc1\xc4", "ignore", "abc\u804a"), - (b"abc\x84\x39\x84\x39\xc1\xc4", "replace", "abc\ufffd9\ufffd9\u804a"), - ("\u30fb", "strict", b"\x819\xa79"), - (b"abc\x84\x32\x80\x80def", "replace", 'abc\ufffd2\ufffd\ufffddef'), - (b"abc\x81\x30\x81\x30def", "strict", 'abc\x80def'), - (b"abc\x86\x30\x81\x30def", "replace", 'abc\ufffd0\ufffd0def'), - # issue29990 - (b"\xff\x30\x81\x30", "strict", None), - (b"\x81\x30\xff\x30", "strict", None), - (b"abc\x81\x39\xff\x39\xc1\xc4", "replace", "abc\ufffd\x39\ufffd\x39\u804a"), - (b"abc\xab\x36\xff\x30def", "replace", 'abc\ufffd\x36\ufffd\x30def'), - (b"abc\xbf\x38\xff\x32\xc1\xc4", "ignore", "abc\x38\x32\u804a"), - ) - has_iso10646 = True - - class Test_HZ(multibytecodec_support.TestBase, unittest.TestCase): - encoding = 'hz' - tstring = multibytecodec_support.load_teststring('hz') - codectests = ( - # test '~\n' (3 lines) - (b'This sentence is in ASCII.\n' - b'The next sentence is in GB.~{<:Ky2;S{#,~}~\n' - b'~{NpJ)l6HK!#~}Bye.\n', - 'strict', - 'This sentence is in ASCII.\n' - 'The next sentence is in GB.' - '\u5df1\u6240\u4e0d\u6b32\uff0c\u52ff\u65bd\u65bc\u4eba\u3002' - 'Bye.\n'), - # test '~\n' (4 lines) - (b'This sentence is in ASCII.\n' - b'The next sentence is in GB.~\n' - b'~{<:Ky2;S{#,NpJ)l6HK!#~}~\n' - b'Bye.\n', - 'strict', - 'This sentence is in ASCII.\n' - 'The next sentence is in GB.' - '\u5df1\u6240\u4e0d\u6b32\uff0c\u52ff\u65bd\u65bc\u4eba\u3002' - 'Bye.\n'), - # invalid bytes - (b'ab~cd', 'replace', 'ab\uFFFDcd'), - (b'ab\xffcd', 'replace', 'ab\uFFFDcd'), - (b'ab~{\x81\x81\x41\x44~}cd', 'replace', 'ab\uFFFD\uFFFD\u804Acd'), - (b'ab~{\x41\x44~}cd', 'replace', 'ab\u804Acd'), - (b"ab~{\x79\x79\x41\x44~}cd", "replace", "ab\ufffd\ufffd\u804acd"), - # issue 30003 - ('ab~cd', 'strict', b'ab~~cd'), # escape ~ - (b'~{Dc~~:C~}', 'strict', None), # ~~ only in ASCII mode - (b'~{Dc~\n:C~}', 'strict', None), # ~\n only in ASCII mode - ) - - if __name__ == "__main__": - unittest.main() diff --git a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_codecencodings_hk.yaml b/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_codecencodings_hk.yaml deleted file mode 100644 index c8a03f5d4..000000000 --- a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_codecencodings_hk.yaml +++ /dev/null @@ -1,23 +0,0 @@ -python: | - # - # test_codecencodings_hk.py - # Codec encoding tests for HongKong encodings. - # - - from test import multibytecodec_support - import unittest - - class Test_Big5HKSCS(multibytecodec_support.TestBase, unittest.TestCase): - encoding = 'big5hkscs' - tstring = multibytecodec_support.load_teststring('big5hkscs') - codectests = ( - # invalid bytes - (b"abc\x80\x80\xc1\xc4", "strict", None), - (b"abc\xc8", "strict", None), - (b"abc\x80\x80\xc1\xc4", "replace", "abc\ufffd\ufffd\u8b10"), - (b"abc\x80\x80\xc1\xc4\xc8", "replace", "abc\ufffd\ufffd\u8b10\ufffd"), - (b"abc\x80\x80\xc1\xc4", "ignore", "abc\u8b10"), - ) - - if __name__ == "__main__": - unittest.main() diff --git a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_codecencodings_iso2022.yaml b/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_codecencodings_iso2022.yaml deleted file mode 100644 index 97ffb5b71..000000000 --- a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_codecencodings_iso2022.yaml +++ /dev/null @@ -1,42 +0,0 @@ -python: | - # Codec encoding tests for ISO 2022 encodings. - - from test import multibytecodec_support - import unittest - - COMMON_CODEC_TESTS = ( - # invalid bytes - (b'ab\xFFcd', 'replace', 'ab\uFFFDcd'), - (b'ab\x1Bdef', 'replace', 'ab\x1Bdef'), - (b'ab\x1B$def', 'replace', 'ab\uFFFD'), - ) - - class Test_ISO2022_JP(multibytecodec_support.TestBase, unittest.TestCase): - encoding = 'iso2022_jp' - tstring = multibytecodec_support.load_teststring('iso2022_jp') - codectests = COMMON_CODEC_TESTS + ( - (b'ab\x1BNdef', 'replace', 'ab\x1BNdef'), - ) - - class Test_ISO2022_JP2(multibytecodec_support.TestBase, unittest.TestCase): - encoding = 'iso2022_jp_2' - tstring = multibytecodec_support.load_teststring('iso2022_jp') - codectests = COMMON_CODEC_TESTS + ( - (b'ab\x1BNdef', 'replace', 'abdef'), - ) - - class Test_ISO2022_KR(multibytecodec_support.TestBase, unittest.TestCase): - encoding = 'iso2022_kr' - tstring = multibytecodec_support.load_teststring('iso2022_kr') - codectests = COMMON_CODEC_TESTS + ( - (b'ab\x1BNdef', 'replace', 'ab\x1BNdef'), - ) - - # iso2022_kr.txt cannot be used to test "chunk coding": the escape - # sequence is only written on the first line - @unittest.skip('iso2022_kr.txt cannot be used to test "chunk coding"') - def test_chunkcoding(self): - pass - - if __name__ == "__main__": - unittest.main() diff --git a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_codecencodings_jp.yaml b/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_codecencodings_jp.yaml deleted file mode 100644 index ce914b91b..000000000 --- a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_codecencodings_jp.yaml +++ /dev/null @@ -1,127 +0,0 @@ -python: | - # - # test_codecencodings_jp.py - # Codec encoding tests for Japanese encodings. - # - - from test import multibytecodec_support - import unittest - - class Test_CP932(multibytecodec_support.TestBase, unittest.TestCase): - encoding = 'cp932' - tstring = multibytecodec_support.load_teststring('shift_jis') - codectests = ( - # invalid bytes - (b"abc\x81\x00\x81\x00\x82\x84", "strict", None), - (b"abc\xf8", "strict", None), - (b"abc\x81\x00\x82\x84", "replace", "abc\ufffd\x00\uff44"), - (b"abc\x81\x00\x82\x84\x88", "replace", "abc\ufffd\x00\uff44\ufffd"), - (b"abc\x81\x00\x82\x84", "ignore", "abc\x00\uff44"), - (b"ab\xEBxy", "replace", "ab\uFFFDxy"), - (b"ab\xF0\x39xy", "replace", "ab\uFFFD9xy"), - (b"ab\xEA\xF0xy", "replace", 'ab\ufffd\ue038y'), - # sjis vs cp932 - (b"\\\x7e", "replace", "\\\x7e"), - (b"\x81\x5f\x81\x61\x81\x7c", "replace", "\uff3c\u2225\uff0d"), - ) - - euc_commontests = ( - # invalid bytes - (b"abc\x80\x80\xc1\xc4", "strict", None), - (b"abc\x80\x80\xc1\xc4", "replace", "abc\ufffd\ufffd\u7956"), - (b"abc\x80\x80\xc1\xc4\xc8", "replace", "abc\ufffd\ufffd\u7956\ufffd"), - (b"abc\x80\x80\xc1\xc4", "ignore", "abc\u7956"), - (b"abc\xc8", "strict", None), - (b"abc\x8f\x83\x83", "replace", "abc\ufffd\ufffd\ufffd"), - (b"\x82\xFCxy", "replace", "\ufffd\ufffdxy"), - (b"\xc1\x64", "strict", None), - (b"\xa1\xc0", "strict", "\uff3c"), - (b"\xa1\xc0\\", "strict", "\uff3c\\"), - (b"\x8eXY", "replace", "\ufffdXY"), - ) - - class Test_EUC_JIS_2004(multibytecodec_support.TestBase, - unittest.TestCase): - encoding = 'euc_jis_2004' - tstring = multibytecodec_support.load_teststring('euc_jisx0213') - codectests = euc_commontests - xmlcharnametest = ( - "\xab\u211c\xbb = \u2329\u1234\u232a", - b"\xa9\xa8ℜ\xa9\xb2 = ⟨ሴ⟩" - ) - - class Test_EUC_JISX0213(multibytecodec_support.TestBase, - unittest.TestCase): - encoding = 'euc_jisx0213' - tstring = multibytecodec_support.load_teststring('euc_jisx0213') - codectests = euc_commontests - xmlcharnametest = ( - "\xab\u211c\xbb = \u2329\u1234\u232a", - b"\xa9\xa8ℜ\xa9\xb2 = ⟨ሴ⟩" - ) - - class Test_EUC_JP_COMPAT(multibytecodec_support.TestBase, - unittest.TestCase): - encoding = 'euc_jp' - tstring = multibytecodec_support.load_teststring('euc_jp') - codectests = euc_commontests + ( - ("\xa5", "strict", b"\x5c"), - ("\u203e", "strict", b"\x7e"), - ) - - shiftjis_commonenctests = ( - (b"abc\x80\x80\x82\x84", "strict", None), - (b"abc\xf8", "strict", None), - (b"abc\x80\x80\x82\x84def", "ignore", "abc\uff44def"), - ) - - class Test_SJIS_COMPAT(multibytecodec_support.TestBase, unittest.TestCase): - encoding = 'shift_jis' - tstring = multibytecodec_support.load_teststring('shift_jis') - codectests = shiftjis_commonenctests + ( - (b"abc\x80\x80\x82\x84", "replace", "abc\ufffd\ufffd\uff44"), - (b"abc\x80\x80\x82\x84\x88", "replace", "abc\ufffd\ufffd\uff44\ufffd"), - - (b"\\\x7e", "strict", "\\\x7e"), - (b"\x81\x5f\x81\x61\x81\x7c", "strict", "\uff3c\u2016\u2212"), - (b"abc\x81\x39", "replace", "abc\ufffd9"), - (b"abc\xEA\xFC", "replace", "abc\ufffd\ufffd"), - (b"abc\xFF\x58", "replace", "abc\ufffdX"), - ) - - class Test_SJIS_2004(multibytecodec_support.TestBase, unittest.TestCase): - encoding = 'shift_jis_2004' - tstring = multibytecodec_support.load_teststring('shift_jis') - codectests = shiftjis_commonenctests + ( - (b"\\\x7e", "strict", "\xa5\u203e"), - (b"\x81\x5f\x81\x61\x81\x7c", "strict", "\\\u2016\u2212"), - (b"abc\xEA\xFC", "strict", "abc\u64bf"), - (b"\x81\x39xy", "replace", "\ufffd9xy"), - (b"\xFF\x58xy", "replace", "\ufffdXxy"), - (b"\x80\x80\x82\x84xy", "replace", "\ufffd\ufffd\uff44xy"), - (b"\x80\x80\x82\x84\x88xy", "replace", "\ufffd\ufffd\uff44\u5864y"), - (b"\xFC\xFBxy", "replace", '\ufffd\u95b4y'), - ) - xmlcharnametest = ( - "\xab\u211c\xbb = \u2329\u1234\u232a", - b"\x85Gℜ\x85Q = ⟨ሴ⟩" - ) - - class Test_SJISX0213(multibytecodec_support.TestBase, unittest.TestCase): - encoding = 'shift_jisx0213' - tstring = multibytecodec_support.load_teststring('shift_jisx0213') - codectests = shiftjis_commonenctests + ( - (b"abc\x80\x80\x82\x84", "replace", "abc\ufffd\ufffd\uff44"), - (b"abc\x80\x80\x82\x84\x88", "replace", "abc\ufffd\ufffd\uff44\ufffd"), - - # sjis vs cp932 - (b"\\\x7e", "replace", "\xa5\u203e"), - (b"\x81\x5f\x81\x61\x81\x7c", "replace", "\x5c\u2016\u2212"), - ) - xmlcharnametest = ( - "\xab\u211c\xbb = \u2329\u1234\u232a", - b"\x85Gℜ\x85Q = ⟨ሴ⟩" - ) - - if __name__ == "__main__": - unittest.main() diff --git a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_codecencodings_kr.yaml b/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_codecencodings_kr.yaml deleted file mode 100644 index 42e65a2c2..000000000 --- a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_codecencodings_kr.yaml +++ /dev/null @@ -1,70 +0,0 @@ -python: | - # - # test_codecencodings_kr.py - # Codec encoding tests for ROK encodings. - # - - from test import multibytecodec_support - import unittest - - class Test_CP949(multibytecodec_support.TestBase, unittest.TestCase): - encoding = 'cp949' - tstring = multibytecodec_support.load_teststring('cp949') - codectests = ( - # invalid bytes - (b"abc\x80\x80\xc1\xc4", "strict", None), - (b"abc\xc8", "strict", None), - (b"abc\x80\x80\xc1\xc4", "replace", "abc\ufffd\ufffd\uc894"), - (b"abc\x80\x80\xc1\xc4\xc8", "replace", "abc\ufffd\ufffd\uc894\ufffd"), - (b"abc\x80\x80\xc1\xc4", "ignore", "abc\uc894"), - ) - - class Test_EUCKR(multibytecodec_support.TestBase, unittest.TestCase): - encoding = 'euc_kr' - tstring = multibytecodec_support.load_teststring('euc_kr') - codectests = ( - # invalid bytes - (b"abc\x80\x80\xc1\xc4", "strict", None), - (b"abc\xc8", "strict", None), - (b"abc\x80\x80\xc1\xc4", "replace", 'abc\ufffd\ufffd\uc894'), - (b"abc\x80\x80\xc1\xc4\xc8", "replace", "abc\ufffd\ufffd\uc894\ufffd"), - (b"abc\x80\x80\xc1\xc4", "ignore", "abc\uc894"), - - # composed make-up sequence errors - (b"\xa4\xd4", "strict", None), - (b"\xa4\xd4\xa4", "strict", None), - (b"\xa4\xd4\xa4\xb6", "strict", None), - (b"\xa4\xd4\xa4\xb6\xa4", "strict", None), - (b"\xa4\xd4\xa4\xb6\xa4\xd0", "strict", None), - (b"\xa4\xd4\xa4\xb6\xa4\xd0\xa4", "strict", None), - (b"\xa4\xd4\xa4\xb6\xa4\xd0\xa4\xd4", "strict", "\uc4d4"), - (b"\xa4\xd4\xa4\xb6\xa4\xd0\xa4\xd4x", "strict", "\uc4d4x"), - (b"a\xa4\xd4\xa4\xb6\xa4", "replace", 'a\ufffd'), - (b"\xa4\xd4\xa3\xb6\xa4\xd0\xa4\xd4", "strict", None), - (b"\xa4\xd4\xa4\xb6\xa3\xd0\xa4\xd4", "strict", None), - (b"\xa4\xd4\xa4\xb6\xa4\xd0\xa3\xd4", "strict", None), - (b"\xa4\xd4\xa4\xff\xa4\xd0\xa4\xd4", "replace", '\ufffd\u6e21\ufffd\u3160\ufffd'), - (b"\xa4\xd4\xa4\xb6\xa4\xff\xa4\xd4", "replace", '\ufffd\u6e21\ub544\ufffd\ufffd'), - (b"\xa4\xd4\xa4\xb6\xa4\xd0\xa4\xff", "replace", '\ufffd\u6e21\ub544\u572d\ufffd'), - (b"\xa4\xd4\xff\xa4\xd4\xa4\xb6\xa4\xd0\xa4\xd4", "replace", '\ufffd\ufffd\ufffd\uc4d4'), - (b"\xc1\xc4", "strict", "\uc894"), - ) - - class Test_JOHAB(multibytecodec_support.TestBase, unittest.TestCase): - encoding = 'johab' - tstring = multibytecodec_support.load_teststring('johab') - codectests = ( - # invalid bytes - (b"abc\x80\x80\xc1\xc4", "strict", None), - (b"abc\xc8", "strict", None), - (b"abc\x80\x80\xc1\xc4", "replace", "abc\ufffd\ufffd\ucd27"), - (b"abc\x80\x80\xc1\xc4\xc8", "replace", "abc\ufffd\ufffd\ucd27\ufffd"), - (b"abc\x80\x80\xc1\xc4", "ignore", "abc\ucd27"), - (b"\xD8abc", "replace", "\uFFFDabc"), - (b"\xD8\xFFabc", "replace", "\uFFFD\uFFFDabc"), - (b"\x84bxy", "replace", "\uFFFDbxy"), - (b"\x8CBxy", "replace", "\uFFFDBxy"), - ) - - if __name__ == "__main__": - unittest.main() diff --git a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_codecencodings_tw.yaml b/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_codecencodings_tw.yaml deleted file mode 100644 index e4b7a86d0..000000000 --- a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_codecencodings_tw.yaml +++ /dev/null @@ -1,23 +0,0 @@ -python: | - # - # test_codecencodings_tw.py - # Codec encoding tests for ROC encodings. - # - - from test import multibytecodec_support - import unittest - - class Test_Big5(multibytecodec_support.TestBase, unittest.TestCase): - encoding = 'big5' - tstring = multibytecodec_support.load_teststring('big5') - codectests = ( - # invalid bytes - (b"abc\x80\x80\xc1\xc4", "strict", None), - (b"abc\xc8", "strict", None), - (b"abc\x80\x80\xc1\xc4", "replace", "abc\ufffd\ufffd\u8b10"), - (b"abc\x80\x80\xc1\xc4\xc8", "replace", "abc\ufffd\ufffd\u8b10\ufffd"), - (b"abc\x80\x80\xc1\xc4", "ignore", "abc\u8b10"), - ) - - if __name__ == "__main__": - unittest.main() diff --git a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_codecmaps_cn.yaml b/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_codecmaps_cn.yaml deleted file mode 100644 index 1b2cd975c..000000000 --- a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_codecmaps_cn.yaml +++ /dev/null @@ -1,27 +0,0 @@ -python: | - # - # test_codecmaps_cn.py - # Codec mapping tests for PRC encodings - # - - from test import multibytecodec_support - import unittest - - class TestGB2312Map(multibytecodec_support.TestBase_Mapping, - unittest.TestCase): - encoding = 'gb2312' - mapfileurl = 'http://www.pythontest.net/unicode/EUC-CN.TXT' - - class TestGBKMap(multibytecodec_support.TestBase_Mapping, - unittest.TestCase): - encoding = 'gbk' - mapfileurl = 'http://www.pythontest.net/unicode/CP936.TXT' - - class TestGB18030Map(multibytecodec_support.TestBase_Mapping, - unittest.TestCase): - encoding = 'gb18030' - mapfileurl = 'http://www.pythontest.net/unicode/gb-18030-2000.xml' - - - if __name__ == "__main__": - unittest.main() diff --git a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_codecmaps_hk.yaml b/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_codecmaps_hk.yaml deleted file mode 100644 index 143b5393d..000000000 --- a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_codecmaps_hk.yaml +++ /dev/null @@ -1,16 +0,0 @@ -python: | - # - # test_codecmaps_hk.py - # Codec mapping tests for HongKong encodings - # - - from test import multibytecodec_support - import unittest - - class TestBig5HKSCSMap(multibytecodec_support.TestBase_Mapping, - unittest.TestCase): - encoding = 'big5hkscs' - mapfileurl = 'http://www.pythontest.net/unicode/BIG5HKSCS-2004.TXT' - - if __name__ == "__main__": - unittest.main() diff --git a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_codecmaps_jp.yaml b/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_codecmaps_jp.yaml deleted file mode 100644 index 943ecda27..000000000 --- a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_codecmaps_jp.yaml +++ /dev/null @@ -1,61 +0,0 @@ -python: | - # - # test_codecmaps_jp.py - # Codec mapping tests for Japanese encodings - # - - from test import multibytecodec_support - import unittest - - class TestCP932Map(multibytecodec_support.TestBase_Mapping, - unittest.TestCase): - encoding = 'cp932' - mapfileurl = 'http://www.pythontest.net/unicode/CP932.TXT' - supmaps = [ - (b'\x80', '\u0080'), - (b'\xa0', '\uf8f0'), - (b'\xfd', '\uf8f1'), - (b'\xfe', '\uf8f2'), - (b'\xff', '\uf8f3'), - ] - for i in range(0xa1, 0xe0): - supmaps.append((bytes([i]), chr(i+0xfec0))) - - - class TestEUCJPCOMPATMap(multibytecodec_support.TestBase_Mapping, - unittest.TestCase): - encoding = 'euc_jp' - mapfilename = 'EUC-JP.TXT' - mapfileurl = 'http://www.pythontest.net/unicode/EUC-JP.TXT' - - - class TestSJISCOMPATMap(multibytecodec_support.TestBase_Mapping, - unittest.TestCase): - encoding = 'shift_jis' - mapfilename = 'SHIFTJIS.TXT' - mapfileurl = 'http://www.pythontest.net/unicode/SHIFTJIS.TXT' - pass_enctest = [ - (b'\x81_', '\\'), - ] - pass_dectest = [ - (b'\\', '\xa5'), - (b'~', '\u203e'), - (b'\x81_', '\\'), - ] - - class TestEUCJISX0213Map(multibytecodec_support.TestBase_Mapping, - unittest.TestCase): - encoding = 'euc_jisx0213' - mapfilename = 'EUC-JISX0213.TXT' - mapfileurl = 'http://www.pythontest.net/unicode/EUC-JISX0213.TXT' - - - class TestSJISX0213Map(multibytecodec_support.TestBase_Mapping, - unittest.TestCase): - encoding = 'shift_jisx0213' - mapfilename = 'SHIFT_JISX0213.TXT' - mapfileurl = 'http://www.pythontest.net/unicode/SHIFT_JISX0213.TXT' - - - if __name__ == "__main__": - unittest.main() diff --git a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_codecmaps_kr.yaml b/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_codecmaps_kr.yaml deleted file mode 100644 index d7e09cfaa..000000000 --- a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_codecmaps_kr.yaml +++ /dev/null @@ -1,38 +0,0 @@ -python: | - # - # test_codecmaps_kr.py - # Codec mapping tests for ROK encodings - # - - from test import multibytecodec_support - import unittest - - class TestCP949Map(multibytecodec_support.TestBase_Mapping, - unittest.TestCase): - encoding = 'cp949' - mapfileurl = 'http://www.pythontest.net/unicode/CP949.TXT' - - - class TestEUCKRMap(multibytecodec_support.TestBase_Mapping, - unittest.TestCase): - encoding = 'euc_kr' - mapfileurl = 'http://www.pythontest.net/unicode/EUC-KR.TXT' - - # A4D4 HANGUL FILLER indicates the begin of 8-bytes make-up sequence. - pass_enctest = [(b'\xa4\xd4', '\u3164')] - pass_dectest = [(b'\xa4\xd4', '\u3164')] - - - class TestJOHABMap(multibytecodec_support.TestBase_Mapping, - unittest.TestCase): - encoding = 'johab' - mapfileurl = 'http://www.pythontest.net/unicode/JOHAB.TXT' - # KS X 1001 standard assigned 0x5c as WON SIGN. - # But the early 90s is the only era that used johab widely, - # most software implements it as REVERSE SOLIDUS. - # So, we ignore the standard here. - pass_enctest = [(b'\\', '\u20a9')] - pass_dectest = [(b'\\', '\u20a9')] - - if __name__ == "__main__": - unittest.main() diff --git a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_codecmaps_tw.yaml b/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_codecmaps_tw.yaml deleted file mode 100644 index 07c98e299..000000000 --- a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_codecmaps_tw.yaml +++ /dev/null @@ -1,28 +0,0 @@ -python: | - # - # test_codecmaps_tw.py - # Codec mapping tests for ROC encodings - # - - from test import multibytecodec_support - import unittest - - class TestBIG5Map(multibytecodec_support.TestBase_Mapping, - unittest.TestCase): - encoding = 'big5' - mapfileurl = 'http://www.pythontest.net/unicode/BIG5.TXT' - - class TestCP950Map(multibytecodec_support.TestBase_Mapping, - unittest.TestCase): - encoding = 'cp950' - mapfileurl = 'http://www.pythontest.net/unicode/CP950.TXT' - pass_enctest = [ - (b'\xa2\xcc', '\u5341'), - (b'\xa2\xce', '\u5345'), - ] - codectests = ( - (b"\xFFxy", "replace", "\ufffdxy"), - ) - - if __name__ == "__main__": - unittest.main() diff --git a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_codecs.yaml b/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_codecs.yaml deleted file mode 100644 index 4a2cf07dd..000000000 --- a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_codecs.yaml +++ /dev/null @@ -1,3418 +0,0 @@ -python: | - import codecs - import contextlib - import io - import locale - import sys - import unittest - import encodings - from unittest import mock - - from test import support - - try: - import _testcapi - except ImportError as exc: - _testcapi = None - - try: - import ctypes - except ImportError: - ctypes = None - SIZEOF_WCHAR_T = -1 - else: - SIZEOF_WCHAR_T = ctypes.sizeof(ctypes.c_wchar) - - def coding_checker(self, coder): - def check(input, expect): - self.assertEqual(coder(input), (expect, len(input))) - return check - - # On small versions of Windows like Windows IoT or Windows Nano Server not all codepages are present - def is_code_page_present(cp): - from ctypes import POINTER, WINFUNCTYPE, WinDLL - from ctypes.wintypes import BOOL, UINT, BYTE, WCHAR, UINT, DWORD - - MAX_LEADBYTES = 12 # 5 ranges, 2 bytes ea., 0 term. - MAX_DEFAULTCHAR = 2 # single or double byte - MAX_PATH = 260 - class CPINFOEXW(ctypes.Structure): - _fields_ = [("MaxCharSize", UINT), - ("DefaultChar", BYTE*MAX_DEFAULTCHAR), - ("LeadByte", BYTE*MAX_LEADBYTES), - ("UnicodeDefaultChar", WCHAR), - ("CodePage", UINT), - ("CodePageName", WCHAR*MAX_PATH)] - - prototype = WINFUNCTYPE(BOOL, UINT, DWORD, POINTER(CPINFOEXW)) - GetCPInfoEx = prototype(("GetCPInfoExW", WinDLL("kernel32"))) - info = CPINFOEXW() - return GetCPInfoEx(cp, 0, info) - - class Queue(object): - """ - queue: write bytes at one end, read bytes from the other end - """ - def __init__(self, buffer): - self._buffer = buffer - - def write(self, chars): - self._buffer += chars - - def read(self, size=-1): - if size<0: - s = self._buffer - self._buffer = self._buffer[:0] # make empty - return s - else: - s = self._buffer[:size] - self._buffer = self._buffer[size:] - return s - - - class MixInCheckStateHandling: - def check_state_handling_decode(self, encoding, u, s): - for i in range(len(s)+1): - d = codecs.getincrementaldecoder(encoding)() - part1 = d.decode(s[:i]) - state = d.getstate() - self.assertIsInstance(state[1], int) - # Check that the condition stated in the documentation for - # IncrementalDecoder.getstate() holds - if not state[1]: - # reset decoder to the default state without anything buffered - d.setstate((state[0][:0], 0)) - # Feeding the previous input may not produce any output - self.assertTrue(not d.decode(state[0])) - # The decoder must return to the same state - self.assertEqual(state, d.getstate()) - # Create a new decoder and set it to the state - # we extracted from the old one - d = codecs.getincrementaldecoder(encoding)() - d.setstate(state) - part2 = d.decode(s[i:], True) - self.assertEqual(u, part1+part2) - - def check_state_handling_encode(self, encoding, u, s): - for i in range(len(u)+1): - d = codecs.getincrementalencoder(encoding)() - part1 = d.encode(u[:i]) - state = d.getstate() - d = codecs.getincrementalencoder(encoding)() - d.setstate(state) - part2 = d.encode(u[i:], True) - self.assertEqual(s, part1+part2) - - - class ReadTest(MixInCheckStateHandling): - def check_partial(self, input, partialresults): - # get a StreamReader for the encoding and feed the bytestring version - # of input to the reader byte by byte. Read everything available from - # the StreamReader and check that the results equal the appropriate - # entries from partialresults. - q = Queue(b"") - r = codecs.getreader(self.encoding)(q) - result = "" - for (c, partialresult) in zip(input.encode(self.encoding), partialresults): - q.write(bytes([c])) - result += r.read() - self.assertEqual(result, partialresult) - # check that there's nothing left in the buffers - self.assertEqual(r.read(), "") - self.assertEqual(r.bytebuffer, b"") - - # do the check again, this time using an incremental decoder - d = codecs.getincrementaldecoder(self.encoding)() - result = "" - for (c, partialresult) in zip(input.encode(self.encoding), partialresults): - result += d.decode(bytes([c])) - self.assertEqual(result, partialresult) - # check that there's nothing left in the buffers - self.assertEqual(d.decode(b"", True), "") - self.assertEqual(d.buffer, b"") - - # Check whether the reset method works properly - d.reset() - result = "" - for (c, partialresult) in zip(input.encode(self.encoding), partialresults): - result += d.decode(bytes([c])) - self.assertEqual(result, partialresult) - # check that there's nothing left in the buffers - self.assertEqual(d.decode(b"", True), "") - self.assertEqual(d.buffer, b"") - - # check iterdecode() - encoded = input.encode(self.encoding) - self.assertEqual( - input, - "".join(codecs.iterdecode([bytes([c]) for c in encoded], self.encoding)) - ) - - def test_readline(self): - def getreader(input): - stream = io.BytesIO(input.encode(self.encoding)) - return codecs.getreader(self.encoding)(stream) - - def readalllines(input, keepends=True, size=None): - reader = getreader(input) - lines = [] - while True: - line = reader.readline(size=size, keepends=keepends) - if not line: - break - lines.append(line) - return "|".join(lines) - - s = "foo\nbar\r\nbaz\rspam\u2028eggs" - sexpected = "foo\n|bar\r\n|baz\r|spam\u2028|eggs" - sexpectednoends = "foo|bar|baz|spam|eggs" - self.assertEqual(readalllines(s, True), sexpected) - self.assertEqual(readalllines(s, False), sexpectednoends) - self.assertEqual(readalllines(s, True, 10), sexpected) - self.assertEqual(readalllines(s, False, 10), sexpectednoends) - - lineends = ("\n", "\r\n", "\r", "\u2028") - # Test long lines (multiple calls to read() in readline()) - vw = [] - vwo = [] - for (i, lineend) in enumerate(lineends): - vw.append((i*200+200)*"\u3042" + lineend) - vwo.append((i*200+200)*"\u3042") - self.assertEqual(readalllines("".join(vw), True), "|".join(vw)) - self.assertEqual(readalllines("".join(vw), False), "|".join(vwo)) - - # Test lines where the first read might end with \r, so the - # reader has to look ahead whether this is a lone \r or a \r\n - for size in range(80): - for lineend in lineends: - s = 10*(size*"a" + lineend + "xxx\n") - reader = getreader(s) - for i in range(10): - self.assertEqual( - reader.readline(keepends=True), - size*"a" + lineend, - ) - self.assertEqual( - reader.readline(keepends=True), - "xxx\n", - ) - reader = getreader(s) - for i in range(10): - self.assertEqual( - reader.readline(keepends=False), - size*"a", - ) - self.assertEqual( - reader.readline(keepends=False), - "xxx", - ) - - def test_mixed_readline_and_read(self): - lines = ["Humpty Dumpty sat on a wall,\n", - "Humpty Dumpty had a great fall.\r\n", - "All the king's horses and all the king's men\r", - "Couldn't put Humpty together again."] - data = ''.join(lines) - def getreader(): - stream = io.BytesIO(data.encode(self.encoding)) - return codecs.getreader(self.encoding)(stream) - - # Issue #8260: Test readline() followed by read() - f = getreader() - self.assertEqual(f.readline(), lines[0]) - self.assertEqual(f.read(), ''.join(lines[1:])) - self.assertEqual(f.read(), '') - - # Issue #32110: Test readline() followed by read(n) - f = getreader() - self.assertEqual(f.readline(), lines[0]) - self.assertEqual(f.read(1), lines[1][0]) - self.assertEqual(f.read(0), '') - self.assertEqual(f.read(100), data[len(lines[0]) + 1:][:100]) - - # Issue #16636: Test readline() followed by readlines() - f = getreader() - self.assertEqual(f.readline(), lines[0]) - self.assertEqual(f.readlines(), lines[1:]) - self.assertEqual(f.read(), '') - - # Test read(n) followed by read() - f = getreader() - self.assertEqual(f.read(size=40, chars=5), data[:5]) - self.assertEqual(f.read(), data[5:]) - self.assertEqual(f.read(), '') - - # Issue #32110: Test read(n) followed by read(n) - f = getreader() - self.assertEqual(f.read(size=40, chars=5), data[:5]) - self.assertEqual(f.read(1), data[5]) - self.assertEqual(f.read(0), '') - self.assertEqual(f.read(100), data[6:106]) - - # Issue #12446: Test read(n) followed by readlines() - f = getreader() - self.assertEqual(f.read(size=40, chars=5), data[:5]) - self.assertEqual(f.readlines(), [lines[0][5:]] + lines[1:]) - self.assertEqual(f.read(), '') - - def test_bug1175396(self): - s = [ - '<%!--===================================================\r\n', - ' BLOG index page: show recent articles,\r\n', - ' today\'s articles, or articles of a specific date.\r\n', - '========================================================--%>\r\n', - '<%@inputencoding="ISO-8859-1"%>\r\n', - '<%@pagetemplate=TEMPLATE.y%>\r\n', - '<%@import=import frog.util, frog%>\r\n', - '<%@import=import frog.objects%>\r\n', - '<%@import=from frog.storageerrors import StorageError%>\r\n', - '<%\r\n', - '\r\n', - 'import logging\r\n', - 'log=logging.getLogger("Snakelets.logger")\r\n', - '\r\n', - '\r\n', - 'user=self.SessionCtx.user\r\n', - 'storageEngine=self.SessionCtx.storageEngine\r\n', - '\r\n', - '\r\n', - 'def readArticlesFromDate(date, count=None):\r\n', - ' entryids=storageEngine.listBlogEntries(date)\r\n', - ' entryids.reverse() # descending\r\n', - ' if count:\r\n', - ' entryids=entryids[:count]\r\n', - ' try:\r\n', - ' return [ frog.objects.BlogEntry.load(storageEngine, date, Id) for Id in entryids ]\r\n', - ' except StorageError,x:\r\n', - ' log.error("Error loading articles: "+str(x))\r\n', - ' self.abort("cannot load articles")\r\n', - '\r\n', - 'showdate=None\r\n', - '\r\n', - 'arg=self.Request.getArg()\r\n', - 'if arg=="today":\r\n', - ' #-------------------- TODAY\'S ARTICLES\r\n', - ' self.write("

Today\'s articles

")\r\n', - ' showdate = frog.util.isodatestr() \r\n', - ' entries = readArticlesFromDate(showdate)\r\n', - 'elif arg=="active":\r\n', - ' #-------------------- ACTIVE ARTICLES redirect\r\n', - ' self.Yredirect("active.y")\r\n', - 'elif arg=="login":\r\n', - ' #-------------------- LOGIN PAGE redirect\r\n', - ' self.Yredirect("login.y")\r\n', - 'elif arg=="date":\r\n', - ' #-------------------- ARTICLES OF A SPECIFIC DATE\r\n', - ' showdate = self.Request.getParameter("date")\r\n', - ' self.write("

Articles written on %s

"% frog.util.mediumdatestr(showdate))\r\n', - ' entries = readArticlesFromDate(showdate)\r\n', - 'else:\r\n', - ' #-------------------- RECENT ARTICLES\r\n', - ' self.write("

Recent articles

")\r\n', - ' dates=storageEngine.listBlogEntryDates()\r\n', - ' if dates:\r\n', - ' entries=[]\r\n', - ' SHOWAMOUNT=10\r\n', - ' for showdate in dates:\r\n', - ' entries.extend( readArticlesFromDate(showdate, SHOWAMOUNT-len(entries)) )\r\n', - ' if len(entries)>=SHOWAMOUNT:\r\n', - ' break\r\n', - ' \r\n', - ] - stream = io.BytesIO("".join(s).encode(self.encoding)) - reader = codecs.getreader(self.encoding)(stream) - for (i, line) in enumerate(reader): - self.assertEqual(line, s[i]) - - def test_readlinequeue(self): - q = Queue(b"") - writer = codecs.getwriter(self.encoding)(q) - reader = codecs.getreader(self.encoding)(q) - - # No lineends - writer.write("foo\r") - self.assertEqual(reader.readline(keepends=False), "foo") - writer.write("\nbar\r") - self.assertEqual(reader.readline(keepends=False), "") - self.assertEqual(reader.readline(keepends=False), "bar") - writer.write("baz") - self.assertEqual(reader.readline(keepends=False), "baz") - self.assertEqual(reader.readline(keepends=False), "") - - # Lineends - writer.write("foo\r") - self.assertEqual(reader.readline(keepends=True), "foo\r") - writer.write("\nbar\r") - self.assertEqual(reader.readline(keepends=True), "\n") - self.assertEqual(reader.readline(keepends=True), "bar\r") - writer.write("baz") - self.assertEqual(reader.readline(keepends=True), "baz") - self.assertEqual(reader.readline(keepends=True), "") - writer.write("foo\r\n") - self.assertEqual(reader.readline(keepends=True), "foo\r\n") - - def test_bug1098990_a(self): - s1 = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy\r\n" - s2 = "offending line: ladfj askldfj klasdj fskla dfzaskdj fasklfj laskd fjasklfzzzzaa%whereisthis!!!\r\n" - s3 = "next line.\r\n" - - s = (s1+s2+s3).encode(self.encoding) - stream = io.BytesIO(s) - reader = codecs.getreader(self.encoding)(stream) - self.assertEqual(reader.readline(), s1) - self.assertEqual(reader.readline(), s2) - self.assertEqual(reader.readline(), s3) - self.assertEqual(reader.readline(), "") - - def test_bug1098990_b(self): - s1 = "aaaaaaaaaaaaaaaaaaaaaaaa\r\n" - s2 = "bbbbbbbbbbbbbbbbbbbbbbbb\r\n" - s3 = "stillokay:bbbbxx\r\n" - s4 = "broken!!!!badbad\r\n" - s5 = "againokay.\r\n" - - s = (s1+s2+s3+s4+s5).encode(self.encoding) - stream = io.BytesIO(s) - reader = codecs.getreader(self.encoding)(stream) - self.assertEqual(reader.readline(), s1) - self.assertEqual(reader.readline(), s2) - self.assertEqual(reader.readline(), s3) - self.assertEqual(reader.readline(), s4) - self.assertEqual(reader.readline(), s5) - self.assertEqual(reader.readline(), "") - - ill_formed_sequence_replace = "\ufffd" - - def test_lone_surrogates(self): - self.assertRaises(UnicodeEncodeError, "\ud800".encode, self.encoding) - self.assertEqual("[\uDC80]".encode(self.encoding, "backslashreplace"), - "[\\udc80]".encode(self.encoding)) - self.assertEqual("[\uDC80]".encode(self.encoding, "namereplace"), - "[\\udc80]".encode(self.encoding)) - self.assertEqual("[\uDC80]".encode(self.encoding, "xmlcharrefreplace"), - "[�]".encode(self.encoding)) - self.assertEqual("[\uDC80]".encode(self.encoding, "ignore"), - "[]".encode(self.encoding)) - self.assertEqual("[\uDC80]".encode(self.encoding, "replace"), - "[?]".encode(self.encoding)) - - # sequential surrogate characters - self.assertEqual("[\uD800\uDC80]".encode(self.encoding, "ignore"), - "[]".encode(self.encoding)) - self.assertEqual("[\uD800\uDC80]".encode(self.encoding, "replace"), - "[??]".encode(self.encoding)) - - bom = "".encode(self.encoding) - for before, after in [("\U00010fff", "A"), ("[", "]"), - ("A", "\U00010fff")]: - before_sequence = before.encode(self.encoding)[len(bom):] - after_sequence = after.encode(self.encoding)[len(bom):] - test_string = before + "\uDC80" + after - test_sequence = (bom + before_sequence + - self.ill_formed_sequence + after_sequence) - self.assertRaises(UnicodeDecodeError, test_sequence.decode, - self.encoding) - self.assertEqual(test_string.encode(self.encoding, - "surrogatepass"), - test_sequence) - self.assertEqual(test_sequence.decode(self.encoding, - "surrogatepass"), - test_string) - self.assertEqual(test_sequence.decode(self.encoding, "ignore"), - before + after) - self.assertEqual(test_sequence.decode(self.encoding, "replace"), - before + self.ill_formed_sequence_replace + after) - backslashreplace = ''.join('\\x%02x' % b - for b in self.ill_formed_sequence) - self.assertEqual(test_sequence.decode(self.encoding, "backslashreplace"), - before + backslashreplace + after) - - def test_incremental_surrogatepass(self): - # Test incremental decoder for surrogatepass handler: - # see issue #24214 - # High surrogate - data = '\uD901'.encode(self.encoding, 'surrogatepass') - for i in range(1, len(data)): - dec = codecs.getincrementaldecoder(self.encoding)('surrogatepass') - self.assertEqual(dec.decode(data[:i]), '') - self.assertEqual(dec.decode(data[i:], True), '\uD901') - # Low surrogate - data = '\uDC02'.encode(self.encoding, 'surrogatepass') - for i in range(1, len(data)): - dec = codecs.getincrementaldecoder(self.encoding)('surrogatepass') - self.assertEqual(dec.decode(data[:i]), '') - self.assertEqual(dec.decode(data[i:]), '\uDC02') - - - class UTF32Test(ReadTest, unittest.TestCase): - encoding = "utf-32" - if sys.byteorder == 'little': - ill_formed_sequence = b"\x80\xdc\x00\x00" - else: - ill_formed_sequence = b"\x00\x00\xdc\x80" - - spamle = (b'\xff\xfe\x00\x00' - b's\x00\x00\x00p\x00\x00\x00a\x00\x00\x00m\x00\x00\x00' - b's\x00\x00\x00p\x00\x00\x00a\x00\x00\x00m\x00\x00\x00') - spambe = (b'\x00\x00\xfe\xff' - b'\x00\x00\x00s\x00\x00\x00p\x00\x00\x00a\x00\x00\x00m' - b'\x00\x00\x00s\x00\x00\x00p\x00\x00\x00a\x00\x00\x00m') - - def test_only_one_bom(self): - _,_,reader,writer = codecs.lookup(self.encoding) - # encode some stream - s = io.BytesIO() - f = writer(s) - f.write("spam") - f.write("spam") - d = s.getvalue() - # check whether there is exactly one BOM in it - self.assertTrue(d == self.spamle or d == self.spambe) - # try to read it back - s = io.BytesIO(d) - f = reader(s) - self.assertEqual(f.read(), "spamspam") - - def test_badbom(self): - s = io.BytesIO(4*b"\xff") - f = codecs.getreader(self.encoding)(s) - self.assertRaises(UnicodeError, f.read) - - s = io.BytesIO(8*b"\xff") - f = codecs.getreader(self.encoding)(s) - self.assertRaises(UnicodeError, f.read) - - def test_partial(self): - self.check_partial( - "\x00\xff\u0100\uffff\U00010000", - [ - "", # first byte of BOM read - "", # second byte of BOM read - "", # third byte of BOM read - "", # fourth byte of BOM read => byteorder known - "", - "", - "", - "\x00", - "\x00", - "\x00", - "\x00", - "\x00\xff", - "\x00\xff", - "\x00\xff", - "\x00\xff", - "\x00\xff\u0100", - "\x00\xff\u0100", - "\x00\xff\u0100", - "\x00\xff\u0100", - "\x00\xff\u0100\uffff", - "\x00\xff\u0100\uffff", - "\x00\xff\u0100\uffff", - "\x00\xff\u0100\uffff", - "\x00\xff\u0100\uffff\U00010000", - ] - ) - - def test_handlers(self): - self.assertEqual(('\ufffd', 1), - codecs.utf_32_decode(b'\x01', 'replace', True)) - self.assertEqual(('', 1), - codecs.utf_32_decode(b'\x01', 'ignore', True)) - - def test_errors(self): - self.assertRaises(UnicodeDecodeError, codecs.utf_32_decode, - b"\xff", "strict", True) - - def test_decoder_state(self): - self.check_state_handling_decode(self.encoding, - "spamspam", self.spamle) - self.check_state_handling_decode(self.encoding, - "spamspam", self.spambe) - - def test_issue8941(self): - # Issue #8941: insufficient result allocation when decoding into - # surrogate pairs on UCS-2 builds. - encoded_le = b'\xff\xfe\x00\x00' + b'\x00\x00\x01\x00' * 1024 - self.assertEqual('\U00010000' * 1024, - codecs.utf_32_decode(encoded_le)[0]) - encoded_be = b'\x00\x00\xfe\xff' + b'\x00\x01\x00\x00' * 1024 - self.assertEqual('\U00010000' * 1024, - codecs.utf_32_decode(encoded_be)[0]) - - - class UTF32LETest(ReadTest, unittest.TestCase): - encoding = "utf-32-le" - ill_formed_sequence = b"\x80\xdc\x00\x00" - - def test_partial(self): - self.check_partial( - "\x00\xff\u0100\uffff\U00010000", - [ - "", - "", - "", - "\x00", - "\x00", - "\x00", - "\x00", - "\x00\xff", - "\x00\xff", - "\x00\xff", - "\x00\xff", - "\x00\xff\u0100", - "\x00\xff\u0100", - "\x00\xff\u0100", - "\x00\xff\u0100", - "\x00\xff\u0100\uffff", - "\x00\xff\u0100\uffff", - "\x00\xff\u0100\uffff", - "\x00\xff\u0100\uffff", - "\x00\xff\u0100\uffff\U00010000", - ] - ) - - def test_simple(self): - self.assertEqual("\U00010203".encode(self.encoding), b"\x03\x02\x01\x00") - - def test_errors(self): - self.assertRaises(UnicodeDecodeError, codecs.utf_32_le_decode, - b"\xff", "strict", True) - - def test_issue8941(self): - # Issue #8941: insufficient result allocation when decoding into - # surrogate pairs on UCS-2 builds. - encoded = b'\x00\x00\x01\x00' * 1024 - self.assertEqual('\U00010000' * 1024, - codecs.utf_32_le_decode(encoded)[0]) - - - class UTF32BETest(ReadTest, unittest.TestCase): - encoding = "utf-32-be" - ill_formed_sequence = b"\x00\x00\xdc\x80" - - def test_partial(self): - self.check_partial( - "\x00\xff\u0100\uffff\U00010000", - [ - "", - "", - "", - "\x00", - "\x00", - "\x00", - "\x00", - "\x00\xff", - "\x00\xff", - "\x00\xff", - "\x00\xff", - "\x00\xff\u0100", - "\x00\xff\u0100", - "\x00\xff\u0100", - "\x00\xff\u0100", - "\x00\xff\u0100\uffff", - "\x00\xff\u0100\uffff", - "\x00\xff\u0100\uffff", - "\x00\xff\u0100\uffff", - "\x00\xff\u0100\uffff\U00010000", - ] - ) - - def test_simple(self): - self.assertEqual("\U00010203".encode(self.encoding), b"\x00\x01\x02\x03") - - def test_errors(self): - self.assertRaises(UnicodeDecodeError, codecs.utf_32_be_decode, - b"\xff", "strict", True) - - def test_issue8941(self): - # Issue #8941: insufficient result allocation when decoding into - # surrogate pairs on UCS-2 builds. - encoded = b'\x00\x01\x00\x00' * 1024 - self.assertEqual('\U00010000' * 1024, - codecs.utf_32_be_decode(encoded)[0]) - - - class UTF16Test(ReadTest, unittest.TestCase): - encoding = "utf-16" - if sys.byteorder == 'little': - ill_formed_sequence = b"\x80\xdc" - else: - ill_formed_sequence = b"\xdc\x80" - - spamle = b'\xff\xfes\x00p\x00a\x00m\x00s\x00p\x00a\x00m\x00' - spambe = b'\xfe\xff\x00s\x00p\x00a\x00m\x00s\x00p\x00a\x00m' - - def test_only_one_bom(self): - _,_,reader,writer = codecs.lookup(self.encoding) - # encode some stream - s = io.BytesIO() - f = writer(s) - f.write("spam") - f.write("spam") - d = s.getvalue() - # check whether there is exactly one BOM in it - self.assertTrue(d == self.spamle or d == self.spambe) - # try to read it back - s = io.BytesIO(d) - f = reader(s) - self.assertEqual(f.read(), "spamspam") - - def test_badbom(self): - s = io.BytesIO(b"\xff\xff") - f = codecs.getreader(self.encoding)(s) - self.assertRaises(UnicodeError, f.read) - - s = io.BytesIO(b"\xff\xff\xff\xff") - f = codecs.getreader(self.encoding)(s) - self.assertRaises(UnicodeError, f.read) - - def test_partial(self): - self.check_partial( - "\x00\xff\u0100\uffff\U00010000", - [ - "", # first byte of BOM read - "", # second byte of BOM read => byteorder known - "", - "\x00", - "\x00", - "\x00\xff", - "\x00\xff", - "\x00\xff\u0100", - "\x00\xff\u0100", - "\x00\xff\u0100\uffff", - "\x00\xff\u0100\uffff", - "\x00\xff\u0100\uffff", - "\x00\xff\u0100\uffff", - "\x00\xff\u0100\uffff\U00010000", - ] - ) - - def test_handlers(self): - self.assertEqual(('\ufffd', 1), - codecs.utf_16_decode(b'\x01', 'replace', True)) - self.assertEqual(('', 1), - codecs.utf_16_decode(b'\x01', 'ignore', True)) - - def test_errors(self): - self.assertRaises(UnicodeDecodeError, codecs.utf_16_decode, - b"\xff", "strict", True) - - def test_decoder_state(self): - self.check_state_handling_decode(self.encoding, - "spamspam", self.spamle) - self.check_state_handling_decode(self.encoding, - "spamspam", self.spambe) - - def test_bug691291(self): - # Files are always opened in binary mode, even if no binary mode was - # specified. This means that no automatic conversion of '\n' is done - # on reading and writing. - s1 = 'Hello\r\nworld\r\n' - - s = s1.encode(self.encoding) - self.addCleanup(support.unlink, support.TESTFN) - with open(support.TESTFN, 'wb') as fp: - fp.write(s) - with support.check_warnings(('', DeprecationWarning)): - reader = codecs.open(support.TESTFN, 'U', encoding=self.encoding) - with reader: - self.assertEqual(reader.read(), s1) - - class UTF16LETest(ReadTest, unittest.TestCase): - encoding = "utf-16-le" - ill_formed_sequence = b"\x80\xdc" - - def test_partial(self): - self.check_partial( - "\x00\xff\u0100\uffff\U00010000", - [ - "", - "\x00", - "\x00", - "\x00\xff", - "\x00\xff", - "\x00\xff\u0100", - "\x00\xff\u0100", - "\x00\xff\u0100\uffff", - "\x00\xff\u0100\uffff", - "\x00\xff\u0100\uffff", - "\x00\xff\u0100\uffff", - "\x00\xff\u0100\uffff\U00010000", - ] - ) - - def test_errors(self): - tests = [ - (b'\xff', '\ufffd'), - (b'A\x00Z', 'A\ufffd'), - (b'A\x00B\x00C\x00D\x00Z', 'ABCD\ufffd'), - (b'\x00\xd8', '\ufffd'), - (b'\x00\xd8A', '\ufffd'), - (b'\x00\xd8A\x00', '\ufffdA'), - (b'\x00\xdcA\x00', '\ufffdA'), - ] - for raw, expected in tests: - self.assertRaises(UnicodeDecodeError, codecs.utf_16_le_decode, - raw, 'strict', True) - self.assertEqual(raw.decode('utf-16le', 'replace'), expected) - - def test_nonbmp(self): - self.assertEqual("\U00010203".encode(self.encoding), - b'\x00\xd8\x03\xde') - self.assertEqual(b'\x00\xd8\x03\xde'.decode(self.encoding), - "\U00010203") - - class UTF16BETest(ReadTest, unittest.TestCase): - encoding = "utf-16-be" - ill_formed_sequence = b"\xdc\x80" - - def test_partial(self): - self.check_partial( - "\x00\xff\u0100\uffff\U00010000", - [ - "", - "\x00", - "\x00", - "\x00\xff", - "\x00\xff", - "\x00\xff\u0100", - "\x00\xff\u0100", - "\x00\xff\u0100\uffff", - "\x00\xff\u0100\uffff", - "\x00\xff\u0100\uffff", - "\x00\xff\u0100\uffff", - "\x00\xff\u0100\uffff\U00010000", - ] - ) - - def test_errors(self): - tests = [ - (b'\xff', '\ufffd'), - (b'\x00A\xff', 'A\ufffd'), - (b'\x00A\x00B\x00C\x00DZ', 'ABCD\ufffd'), - (b'\xd8\x00', '\ufffd'), - (b'\xd8\x00\xdc', '\ufffd'), - (b'\xd8\x00\x00A', '\ufffdA'), - (b'\xdc\x00\x00A', '\ufffdA'), - ] - for raw, expected in tests: - self.assertRaises(UnicodeDecodeError, codecs.utf_16_be_decode, - raw, 'strict', True) - self.assertEqual(raw.decode('utf-16be', 'replace'), expected) - - def test_nonbmp(self): - self.assertEqual("\U00010203".encode(self.encoding), - b'\xd8\x00\xde\x03') - self.assertEqual(b'\xd8\x00\xde\x03'.decode(self.encoding), - "\U00010203") - - class UTF8Test(ReadTest, unittest.TestCase): - encoding = "utf-8" - ill_formed_sequence = b"\xed\xb2\x80" - ill_formed_sequence_replace = "\ufffd" * 3 - BOM = b'' - - def test_partial(self): - self.check_partial( - "\x00\xff\u07ff\u0800\uffff\U00010000", - [ - "\x00", - "\x00", - "\x00\xff", - "\x00\xff", - "\x00\xff\u07ff", - "\x00\xff\u07ff", - "\x00\xff\u07ff", - "\x00\xff\u07ff\u0800", - "\x00\xff\u07ff\u0800", - "\x00\xff\u07ff\u0800", - "\x00\xff\u07ff\u0800\uffff", - "\x00\xff\u07ff\u0800\uffff", - "\x00\xff\u07ff\u0800\uffff", - "\x00\xff\u07ff\u0800\uffff", - "\x00\xff\u07ff\u0800\uffff\U00010000", - ] - ) - - def test_decoder_state(self): - u = "\x00\x7f\x80\xff\u0100\u07ff\u0800\uffff\U0010ffff" - self.check_state_handling_decode(self.encoding, - u, u.encode(self.encoding)) - - def test_decode_error(self): - for data, error_handler, expected in ( - (b'[\x80\xff]', 'ignore', '[]'), - (b'[\x80\xff]', 'replace', '[\ufffd\ufffd]'), - (b'[\x80\xff]', 'surrogateescape', '[\udc80\udcff]'), - (b'[\x80\xff]', 'backslashreplace', '[\\x80\\xff]'), - ): - with self.subTest(data=data, error_handler=error_handler, - expected=expected): - self.assertEqual(data.decode(self.encoding, error_handler), - expected) - - def test_lone_surrogates(self): - super().test_lone_surrogates() - # not sure if this is making sense for - # UTF-16 and UTF-32 - self.assertEqual("[\uDC80]".encode(self.encoding, "surrogateescape"), - self.BOM + b'[\x80]') - - with self.assertRaises(UnicodeEncodeError) as cm: - "[\uDC80\uD800\uDFFF]".encode(self.encoding, "surrogateescape") - exc = cm.exception - self.assertEqual(exc.object[exc.start:exc.end], '\uD800\uDFFF') - - def test_surrogatepass_handler(self): - self.assertEqual("abc\ud800def".encode(self.encoding, "surrogatepass"), - self.BOM + b"abc\xed\xa0\x80def") - self.assertEqual("\U00010fff\uD800".encode(self.encoding, "surrogatepass"), - self.BOM + b"\xf0\x90\xbf\xbf\xed\xa0\x80") - self.assertEqual("[\uD800\uDC80]".encode(self.encoding, "surrogatepass"), - self.BOM + b'[\xed\xa0\x80\xed\xb2\x80]') - - self.assertEqual(b"abc\xed\xa0\x80def".decode(self.encoding, "surrogatepass"), - "abc\ud800def") - self.assertEqual(b"\xf0\x90\xbf\xbf\xed\xa0\x80".decode(self.encoding, "surrogatepass"), - "\U00010fff\uD800") - - self.assertTrue(codecs.lookup_error("surrogatepass")) - with self.assertRaises(UnicodeDecodeError): - b"abc\xed\xa0".decode(self.encoding, "surrogatepass") - with self.assertRaises(UnicodeDecodeError): - b"abc\xed\xa0z".decode(self.encoding, "surrogatepass") - - def test_incremental_errors(self): - # Test that the incremental decoder can fail with final=False. - # See issue #24214 - cases = [b'\x80', b'\xBF', b'\xC0', b'\xC1', b'\xF5', b'\xF6', b'\xFF'] - for prefix in (b'\xC2', b'\xDF', b'\xE0', b'\xE0\xA0', b'\xEF', - b'\xEF\xBF', b'\xF0', b'\xF0\x90', b'\xF0\x90\x80', - b'\xF4', b'\xF4\x8F', b'\xF4\x8F\xBF'): - for suffix in b'\x7F', b'\xC0': - cases.append(prefix + suffix) - cases.extend((b'\xE0\x80', b'\xE0\x9F', b'\xED\xA0\x80', - b'\xED\xBF\xBF', b'\xF0\x80', b'\xF0\x8F', b'\xF4\x90')) - - for data in cases: - with self.subTest(data=data): - dec = codecs.getincrementaldecoder(self.encoding)() - self.assertRaises(UnicodeDecodeError, dec.decode, data) - - - class UTF7Test(ReadTest, unittest.TestCase): - encoding = "utf-7" - - def test_ascii(self): - # Set D (directly encoded characters) - set_d = ('ABCDEFGHIJKLMNOPQRSTUVWXYZ' - 'abcdefghijklmnopqrstuvwxyz' - '0123456789' - '\'(),-./:?') - self.assertEqual(set_d.encode(self.encoding), set_d.encode('ascii')) - self.assertEqual(set_d.encode('ascii').decode(self.encoding), set_d) - # Set O (optional direct characters) - set_o = ' !"#$%&*;<=>@[]^_`{|}' - self.assertEqual(set_o.encode(self.encoding), set_o.encode('ascii')) - self.assertEqual(set_o.encode('ascii').decode(self.encoding), set_o) - # + - self.assertEqual('a+b'.encode(self.encoding), b'a+-b') - self.assertEqual(b'a+-b'.decode(self.encoding), 'a+b') - # White spaces - ws = ' \t\n\r' - self.assertEqual(ws.encode(self.encoding), ws.encode('ascii')) - self.assertEqual(ws.encode('ascii').decode(self.encoding), ws) - # Other ASCII characters - other_ascii = ''.join(sorted(set(bytes(range(0x80)).decode()) - - set(set_d + set_o + '+' + ws))) - self.assertEqual(other_ascii.encode(self.encoding), - b'+AAAAAQACAAMABAAFAAYABwAIAAsADAAOAA8AEAARABIAEwAU' - b'ABUAFgAXABgAGQAaABsAHAAdAB4AHwBcAH4Afw-') - - def test_partial(self): - self.check_partial( - 'a+-b\x00c\x80d\u0100e\U00010000f', - [ - 'a', - 'a', - 'a+', - 'a+-', - 'a+-b', - 'a+-b', - 'a+-b', - 'a+-b', - 'a+-b', - 'a+-b\x00', - 'a+-b\x00c', - 'a+-b\x00c', - 'a+-b\x00c', - 'a+-b\x00c', - 'a+-b\x00c', - 'a+-b\x00c\x80', - 'a+-b\x00c\x80d', - 'a+-b\x00c\x80d', - 'a+-b\x00c\x80d', - 'a+-b\x00c\x80d', - 'a+-b\x00c\x80d', - 'a+-b\x00c\x80d\u0100', - 'a+-b\x00c\x80d\u0100e', - 'a+-b\x00c\x80d\u0100e', - 'a+-b\x00c\x80d\u0100e', - 'a+-b\x00c\x80d\u0100e', - 'a+-b\x00c\x80d\u0100e', - 'a+-b\x00c\x80d\u0100e', - 'a+-b\x00c\x80d\u0100e', - 'a+-b\x00c\x80d\u0100e', - 'a+-b\x00c\x80d\u0100e\U00010000', - 'a+-b\x00c\x80d\u0100e\U00010000f', - ] - ) - - def test_errors(self): - tests = [ - (b'\xffb', '\ufffdb'), - (b'a\xffb', 'a\ufffdb'), - (b'a\xff\xffb', 'a\ufffd\ufffdb'), - (b'a+IK', 'a\ufffd'), - (b'a+IK-b', 'a\ufffdb'), - (b'a+IK,b', 'a\ufffdb'), - (b'a+IKx', 'a\u20ac\ufffd'), - (b'a+IKx-b', 'a\u20ac\ufffdb'), - (b'a+IKwgr', 'a\u20ac\ufffd'), - (b'a+IKwgr-b', 'a\u20ac\ufffdb'), - (b'a+IKwgr,', 'a\u20ac\ufffd'), - (b'a+IKwgr,-b', 'a\u20ac\ufffd-b'), - (b'a+IKwgrB', 'a\u20ac\u20ac\ufffd'), - (b'a+IKwgrB-b', 'a\u20ac\u20ac\ufffdb'), - (b'a+/,+IKw-b', 'a\ufffd\u20acb'), - (b'a+//,+IKw-b', 'a\ufffd\u20acb'), - (b'a+///,+IKw-b', 'a\uffff\ufffd\u20acb'), - (b'a+////,+IKw-b', 'a\uffff\ufffd\u20acb'), - (b'a+IKw-b\xff', 'a\u20acb\ufffd'), - (b'a+IKw\xffb', 'a\u20ac\ufffdb'), - (b'a+@b', 'a\ufffdb'), - ] - for raw, expected in tests: - with self.subTest(raw=raw): - self.assertRaises(UnicodeDecodeError, codecs.utf_7_decode, - raw, 'strict', True) - self.assertEqual(raw.decode('utf-7', 'replace'), expected) - - def test_nonbmp(self): - self.assertEqual('\U000104A0'.encode(self.encoding), b'+2AHcoA-') - self.assertEqual('\ud801\udca0'.encode(self.encoding), b'+2AHcoA-') - self.assertEqual(b'+2AHcoA-'.decode(self.encoding), '\U000104A0') - self.assertEqual(b'+2AHcoA'.decode(self.encoding), '\U000104A0') - self.assertEqual('\u20ac\U000104A0'.encode(self.encoding), b'+IKzYAdyg-') - self.assertEqual(b'+IKzYAdyg-'.decode(self.encoding), '\u20ac\U000104A0') - self.assertEqual(b'+IKzYAdyg'.decode(self.encoding), '\u20ac\U000104A0') - self.assertEqual('\u20ac\u20ac\U000104A0'.encode(self.encoding), - b'+IKwgrNgB3KA-') - self.assertEqual(b'+IKwgrNgB3KA-'.decode(self.encoding), - '\u20ac\u20ac\U000104A0') - self.assertEqual(b'+IKwgrNgB3KA'.decode(self.encoding), - '\u20ac\u20ac\U000104A0') - - def test_lone_surrogates(self): - tests = [ - (b'a+2AE-b', 'a\ud801b'), - (b'a+2AE\xffb', 'a\ufffdb'), - (b'a+2AE', 'a\ufffd'), - (b'a+2AEA-b', 'a\ufffdb'), - (b'a+2AH-b', 'a\ufffdb'), - (b'a+IKzYAQ-b', 'a\u20ac\ud801b'), - (b'a+IKzYAQ\xffb', 'a\u20ac\ufffdb'), - (b'a+IKzYAQA-b', 'a\u20ac\ufffdb'), - (b'a+IKzYAd-b', 'a\u20ac\ufffdb'), - (b'a+IKwgrNgB-b', 'a\u20ac\u20ac\ud801b'), - (b'a+IKwgrNgB\xffb', 'a\u20ac\u20ac\ufffdb'), - (b'a+IKwgrNgB', 'a\u20ac\u20ac\ufffd'), - (b'a+IKwgrNgBA-b', 'a\u20ac\u20ac\ufffdb'), - ] - for raw, expected in tests: - with self.subTest(raw=raw): - self.assertEqual(raw.decode('utf-7', 'replace'), expected) - - - class UTF16ExTest(unittest.TestCase): - - def test_errors(self): - self.assertRaises(UnicodeDecodeError, codecs.utf_16_ex_decode, b"\xff", "strict", 0, True) - - def test_bad_args(self): - self.assertRaises(TypeError, codecs.utf_16_ex_decode) - - class ReadBufferTest(unittest.TestCase): - - def test_array(self): - import array - self.assertEqual( - codecs.readbuffer_encode(array.array("b", b"spam")), - (b"spam", 4) - ) - - def test_empty(self): - self.assertEqual(codecs.readbuffer_encode(""), (b"", 0)) - - def test_bad_args(self): - self.assertRaises(TypeError, codecs.readbuffer_encode) - self.assertRaises(TypeError, codecs.readbuffer_encode, 42) - - class UTF8SigTest(UTF8Test, unittest.TestCase): - encoding = "utf-8-sig" - BOM = codecs.BOM_UTF8 - - def test_partial(self): - self.check_partial( - "\ufeff\x00\xff\u07ff\u0800\uffff\U00010000", - [ - "", - "", - "", # First BOM has been read and skipped - "", - "", - "\ufeff", # Second BOM has been read and emitted - "\ufeff\x00", # "\x00" read and emitted - "\ufeff\x00", # First byte of encoded "\xff" read - "\ufeff\x00\xff", # Second byte of encoded "\xff" read - "\ufeff\x00\xff", # First byte of encoded "\u07ff" read - "\ufeff\x00\xff\u07ff", # Second byte of encoded "\u07ff" read - "\ufeff\x00\xff\u07ff", - "\ufeff\x00\xff\u07ff", - "\ufeff\x00\xff\u07ff\u0800", - "\ufeff\x00\xff\u07ff\u0800", - "\ufeff\x00\xff\u07ff\u0800", - "\ufeff\x00\xff\u07ff\u0800\uffff", - "\ufeff\x00\xff\u07ff\u0800\uffff", - "\ufeff\x00\xff\u07ff\u0800\uffff", - "\ufeff\x00\xff\u07ff\u0800\uffff", - "\ufeff\x00\xff\u07ff\u0800\uffff\U00010000", - ] - ) - - def test_bug1601501(self): - # SF bug #1601501: check that the codec works with a buffer - self.assertEqual(str(b"\xef\xbb\xbf", "utf-8-sig"), "") - - def test_bom(self): - d = codecs.getincrementaldecoder("utf-8-sig")() - s = "spam" - self.assertEqual(d.decode(s.encode("utf-8-sig")), s) - - def test_stream_bom(self): - unistring = "ABC\u00A1\u2200XYZ" - bytestring = codecs.BOM_UTF8 + b"ABC\xC2\xA1\xE2\x88\x80XYZ" - - reader = codecs.getreader("utf-8-sig") - for sizehint in [None] + list(range(1, 11)) + \ - [64, 128, 256, 512, 1024]: - istream = reader(io.BytesIO(bytestring)) - ostream = io.StringIO() - while 1: - if sizehint is not None: - data = istream.read(sizehint) - else: - data = istream.read() - - if not data: - break - ostream.write(data) - - got = ostream.getvalue() - self.assertEqual(got, unistring) - - def test_stream_bare(self): - unistring = "ABC\u00A1\u2200XYZ" - bytestring = b"ABC\xC2\xA1\xE2\x88\x80XYZ" - - reader = codecs.getreader("utf-8-sig") - for sizehint in [None] + list(range(1, 11)) + \ - [64, 128, 256, 512, 1024]: - istream = reader(io.BytesIO(bytestring)) - ostream = io.StringIO() - while 1: - if sizehint is not None: - data = istream.read(sizehint) - else: - data = istream.read() - - if not data: - break - ostream.write(data) - - got = ostream.getvalue() - self.assertEqual(got, unistring) - - - class EscapeDecodeTest(unittest.TestCase): - def test_empty(self): - self.assertEqual(codecs.escape_decode(b""), (b"", 0)) - self.assertEqual(codecs.escape_decode(bytearray()), (b"", 0)) - - def test_raw(self): - decode = codecs.escape_decode - for b in range(256): - b = bytes([b]) - if b != b'\\': - self.assertEqual(decode(b + b'0'), (b + b'0', 2)) - - def test_escape(self): - decode = codecs.escape_decode - check = coding_checker(self, decode) - check(b"[\\\n]", b"[]") - check(br'[\"]', b'["]') - check(br"[\']", b"[']") - check(br"[\\]", b"[\\]") - check(br"[\a]", b"[\x07]") - check(br"[\b]", b"[\x08]") - check(br"[\t]", b"[\x09]") - check(br"[\n]", b"[\x0a]") - check(br"[\v]", b"[\x0b]") - check(br"[\f]", b"[\x0c]") - check(br"[\r]", b"[\x0d]") - check(br"[\7]", b"[\x07]") - check(br"[\78]", b"[\x078]") - check(br"[\41]", b"[!]") - check(br"[\418]", b"[!8]") - check(br"[\101]", b"[A]") - check(br"[\1010]", b"[A0]") - check(br"[\501]", b"[A]") - check(br"[\x41]", b"[A]") - check(br"[\x410]", b"[A0]") - for i in range(97, 123): - b = bytes([i]) - if b not in b'abfnrtvx': - with self.assertWarns(DeprecationWarning): - check(b"\\" + b, b"\\" + b) - with self.assertWarns(DeprecationWarning): - check(b"\\" + b.upper(), b"\\" + b.upper()) - with self.assertWarns(DeprecationWarning): - check(br"\8", b"\\8") - with self.assertWarns(DeprecationWarning): - check(br"\9", b"\\9") - with self.assertWarns(DeprecationWarning): - check(b"\\\xfa", b"\\\xfa") - - def test_errors(self): - decode = codecs.escape_decode - self.assertRaises(ValueError, decode, br"\x") - self.assertRaises(ValueError, decode, br"[\x]") - self.assertEqual(decode(br"[\x]\x", "ignore"), (b"[]", 6)) - self.assertEqual(decode(br"[\x]\x", "replace"), (b"[?]?", 6)) - self.assertRaises(ValueError, decode, br"\x0") - self.assertRaises(ValueError, decode, br"[\x0]") - self.assertEqual(decode(br"[\x0]\x0", "ignore"), (b"[]", 8)) - self.assertEqual(decode(br"[\x0]\x0", "replace"), (b"[?]?", 8)) - - - # From RFC 3492 - punycode_testcases = [ - # A Arabic (Egyptian): - ("\u0644\u064A\u0647\u0645\u0627\u0628\u062A\u0643\u0644" - "\u0645\u0648\u0634\u0639\u0631\u0628\u064A\u061F", - b"egbpdaj6bu4bxfgehfvwxn"), - # B Chinese (simplified): - ("\u4ED6\u4EEC\u4E3A\u4EC0\u4E48\u4E0D\u8BF4\u4E2D\u6587", - b"ihqwcrb4cv8a8dqg056pqjye"), - # C Chinese (traditional): - ("\u4ED6\u5011\u7232\u4EC0\u9EBD\u4E0D\u8AAA\u4E2D\u6587", - b"ihqwctvzc91f659drss3x8bo0yb"), - # D Czech: Proprostnemluvesky - ("\u0050\u0072\u006F\u010D\u0070\u0072\u006F\u0073\u0074" - "\u011B\u006E\u0065\u006D\u006C\u0075\u0076\u00ED\u010D" - "\u0065\u0073\u006B\u0079", - b"Proprostnemluvesky-uyb24dma41a"), - # E Hebrew: - ("\u05DC\u05DE\u05D4\u05D4\u05DD\u05E4\u05E9\u05D5\u05D8" - "\u05DC\u05D0\u05DE\u05D3\u05D1\u05E8\u05D9\u05DD\u05E2" - "\u05D1\u05E8\u05D9\u05EA", - b"4dbcagdahymbxekheh6e0a7fei0b"), - # F Hindi (Devanagari): - ("\u092F\u0939\u0932\u094B\u0917\u0939\u093F\u0928\u094D" - "\u0926\u0940\u0915\u094D\u092F\u094B\u0902\u0928\u0939" - "\u0940\u0902\u092C\u094B\u0932\u0938\u0915\u0924\u0947" - "\u0939\u0948\u0902", - b"i1baa7eci9glrd9b2ae1bj0hfcgg6iyaf8o0a1dig0cd"), - - #(G) Japanese (kanji and hiragana): - ("\u306A\u305C\u307F\u3093\u306A\u65E5\u672C\u8A9E\u3092" - "\u8A71\u3057\u3066\u304F\u308C\u306A\u3044\u306E\u304B", - b"n8jok5ay5dzabd5bym9f0cm5685rrjetr6pdxa"), - - # (H) Korean (Hangul syllables): - ("\uC138\uACC4\uC758\uBAA8\uB4E0\uC0AC\uB78C\uB4E4\uC774" - "\uD55C\uAD6D\uC5B4\uB97C\uC774\uD574\uD55C\uB2E4\uBA74" - "\uC5BC\uB9C8\uB098\uC88B\uC744\uAE4C", - b"989aomsvi5e83db1d2a355cv1e0vak1dwrv93d5xbh15a0dt30a5j" - b"psd879ccm6fea98c"), - - # (I) Russian (Cyrillic): - ("\u043F\u043E\u0447\u0435\u043C\u0443\u0436\u0435\u043E" - "\u043D\u0438\u043D\u0435\u0433\u043E\u0432\u043E\u0440" - "\u044F\u0442\u043F\u043E\u0440\u0443\u0441\u0441\u043A" - "\u0438", - b"b1abfaaepdrnnbgefbaDotcwatmq2g4l"), - - # (J) Spanish: PorqunopuedensimplementehablarenEspaol - ("\u0050\u006F\u0072\u0071\u0075\u00E9\u006E\u006F\u0070" - "\u0075\u0065\u0064\u0065\u006E\u0073\u0069\u006D\u0070" - "\u006C\u0065\u006D\u0065\u006E\u0074\u0065\u0068\u0061" - "\u0062\u006C\u0061\u0072\u0065\u006E\u0045\u0073\u0070" - "\u0061\u00F1\u006F\u006C", - b"PorqunopuedensimplementehablarenEspaol-fmd56a"), - - # (K) Vietnamese: - # Tisaohkhngthch\ - # nitingVit - ("\u0054\u1EA1\u0069\u0073\u0061\u006F\u0068\u1ECD\u006B" - "\u0068\u00F4\u006E\u0067\u0074\u0068\u1EC3\u0063\u0068" - "\u1EC9\u006E\u00F3\u0069\u0074\u0069\u1EBF\u006E\u0067" - "\u0056\u0069\u1EC7\u0074", - b"TisaohkhngthchnitingVit-kjcr8268qyxafd2f1b9g"), - - #(L) 3B - ("\u0033\u5E74\u0042\u7D44\u91D1\u516B\u5148\u751F", - b"3B-ww4c5e180e575a65lsy2b"), - - # (M) -with-SUPER-MONKEYS - ("\u5B89\u5BA4\u5948\u7F8E\u6075\u002D\u0077\u0069\u0074" - "\u0068\u002D\u0053\u0055\u0050\u0045\u0052\u002D\u004D" - "\u004F\u004E\u004B\u0045\u0059\u0053", - b"-with-SUPER-MONKEYS-pc58ag80a8qai00g7n9n"), - - # (N) Hello-Another-Way- - ("\u0048\u0065\u006C\u006C\u006F\u002D\u0041\u006E\u006F" - "\u0074\u0068\u0065\u0072\u002D\u0057\u0061\u0079\u002D" - "\u305D\u308C\u305E\u308C\u306E\u5834\u6240", - b"Hello-Another-Way--fc4qua05auwb3674vfr0b"), - - # (O) 2 - ("\u3072\u3068\u3064\u5C4B\u6839\u306E\u4E0B\u0032", - b"2-u9tlzr9756bt3uc0v"), - - # (P) MajiKoi5 - ("\u004D\u0061\u006A\u0069\u3067\u004B\u006F\u0069\u3059" - "\u308B\u0035\u79D2\u524D", - b"MajiKoi5-783gue6qz075azm5e"), - - # (Q) de - ("\u30D1\u30D5\u30A3\u30FC\u0064\u0065\u30EB\u30F3\u30D0", - b"de-jg4avhby1noc0d"), - - # (R) - ("\u305D\u306E\u30B9\u30D4\u30FC\u30C9\u3067", - b"d9juau41awczczp"), - - # (S) -> $1.00 <- - ("\u002D\u003E\u0020\u0024\u0031\u002E\u0030\u0030\u0020" - "\u003C\u002D", - b"-> $1.00 <--") - ] - - for i in punycode_testcases: - if len(i)!=2: - print(repr(i)) - - - class PunycodeTest(unittest.TestCase): - def test_encode(self): - for uni, puny in punycode_testcases: - # Need to convert both strings to lower case, since - # some of the extended encodings use upper case, but our - # code produces only lower case. Converting just puny to - # lower is also insufficient, since some of the input characters - # are upper case. - self.assertEqual( - str(uni.encode("punycode"), "ascii").lower(), - str(puny, "ascii").lower() - ) - - def test_decode(self): - for uni, puny in punycode_testcases: - self.assertEqual(uni, puny.decode("punycode")) - puny = puny.decode("ascii").encode("ascii") - self.assertEqual(uni, puny.decode("punycode")) - - def test_decode_invalid(self): - testcases = [ - (b"xn--w&", "strict", UnicodeError()), - (b"xn--w&", "ignore", "xn-"), - ] - for puny, errors, expected in testcases: - with self.subTest(puny=puny, errors=errors): - if isinstance(expected, Exception): - self.assertRaises(UnicodeError, puny.decode, "punycode", errors) - else: - self.assertEqual(puny.decode("punycode", errors), expected) - - - # From http://www.gnu.org/software/libidn/draft-josefsson-idn-test-vectors.html - nameprep_tests = [ - # 3.1 Map to nothing. - (b'foo\xc2\xad\xcd\x8f\xe1\xa0\x86\xe1\xa0\x8bbar' - b'\xe2\x80\x8b\xe2\x81\xa0baz\xef\xb8\x80\xef\xb8\x88\xef' - b'\xb8\x8f\xef\xbb\xbf', - b'foobarbaz'), - # 3.2 Case folding ASCII U+0043 U+0041 U+0046 U+0045. - (b'CAFE', - b'cafe'), - # 3.3 Case folding 8bit U+00DF (german sharp s). - # The original test case is bogus; it says \xc3\xdf - (b'\xc3\x9f', - b'ss'), - # 3.4 Case folding U+0130 (turkish capital I with dot). - (b'\xc4\xb0', - b'i\xcc\x87'), - # 3.5 Case folding multibyte U+0143 U+037A. - (b'\xc5\x83\xcd\xba', - b'\xc5\x84 \xce\xb9'), - # 3.6 Case folding U+2121 U+33C6 U+1D7BB. - # XXX: skip this as it fails in UCS-2 mode - #('\xe2\x84\xa1\xe3\x8f\x86\xf0\x9d\x9e\xbb', - # 'telc\xe2\x88\x95kg\xcf\x83'), - (None, None), - # 3.7 Normalization of U+006a U+030c U+00A0 U+00AA. - (b'j\xcc\x8c\xc2\xa0\xc2\xaa', - b'\xc7\xb0 a'), - # 3.8 Case folding U+1FB7 and normalization. - (b'\xe1\xbe\xb7', - b'\xe1\xbe\xb6\xce\xb9'), - # 3.9 Self-reverting case folding U+01F0 and normalization. - # The original test case is bogus, it says `\xc7\xf0' - (b'\xc7\xb0', - b'\xc7\xb0'), - # 3.10 Self-reverting case folding U+0390 and normalization. - (b'\xce\x90', - b'\xce\x90'), - # 3.11 Self-reverting case folding U+03B0 and normalization. - (b'\xce\xb0', - b'\xce\xb0'), - # 3.12 Self-reverting case folding U+1E96 and normalization. - (b'\xe1\xba\x96', - b'\xe1\xba\x96'), - # 3.13 Self-reverting case folding U+1F56 and normalization. - (b'\xe1\xbd\x96', - b'\xe1\xbd\x96'), - # 3.14 ASCII space character U+0020. - (b' ', - b' '), - # 3.15 Non-ASCII 8bit space character U+00A0. - (b'\xc2\xa0', - b' '), - # 3.16 Non-ASCII multibyte space character U+1680. - (b'\xe1\x9a\x80', - None), - # 3.17 Non-ASCII multibyte space character U+2000. - (b'\xe2\x80\x80', - b' '), - # 3.18 Zero Width Space U+200b. - (b'\xe2\x80\x8b', - b''), - # 3.19 Non-ASCII multibyte space character U+3000. - (b'\xe3\x80\x80', - b' '), - # 3.20 ASCII control characters U+0010 U+007F. - (b'\x10\x7f', - b'\x10\x7f'), - # 3.21 Non-ASCII 8bit control character U+0085. - (b'\xc2\x85', - None), - # 3.22 Non-ASCII multibyte control character U+180E. - (b'\xe1\xa0\x8e', - None), - # 3.23 Zero Width No-Break Space U+FEFF. - (b'\xef\xbb\xbf', - b''), - # 3.24 Non-ASCII control character U+1D175. - (b'\xf0\x9d\x85\xb5', - None), - # 3.25 Plane 0 private use character U+F123. - (b'\xef\x84\xa3', - None), - # 3.26 Plane 15 private use character U+F1234. - (b'\xf3\xb1\x88\xb4', - None), - # 3.27 Plane 16 private use character U+10F234. - (b'\xf4\x8f\x88\xb4', - None), - # 3.28 Non-character code point U+8FFFE. - (b'\xf2\x8f\xbf\xbe', - None), - # 3.29 Non-character code point U+10FFFF. - (b'\xf4\x8f\xbf\xbf', - None), - # 3.30 Surrogate code U+DF42. - (b'\xed\xbd\x82', - None), - # 3.31 Non-plain text character U+FFFD. - (b'\xef\xbf\xbd', - None), - # 3.32 Ideographic description character U+2FF5. - (b'\xe2\xbf\xb5', - None), - # 3.33 Display property character U+0341. - (b'\xcd\x81', - b'\xcc\x81'), - # 3.34 Left-to-right mark U+200E. - (b'\xe2\x80\x8e', - None), - # 3.35 Deprecated U+202A. - (b'\xe2\x80\xaa', - None), - # 3.36 Language tagging character U+E0001. - (b'\xf3\xa0\x80\x81', - None), - # 3.37 Language tagging character U+E0042. - (b'\xf3\xa0\x81\x82', - None), - # 3.38 Bidi: RandALCat character U+05BE and LCat characters. - (b'foo\xd6\xbebar', - None), - # 3.39 Bidi: RandALCat character U+FD50 and LCat characters. - (b'foo\xef\xb5\x90bar', - None), - # 3.40 Bidi: RandALCat character U+FB38 and LCat characters. - (b'foo\xef\xb9\xb6bar', - b'foo \xd9\x8ebar'), - # 3.41 Bidi: RandALCat without trailing RandALCat U+0627 U+0031. - (b'\xd8\xa71', - None), - # 3.42 Bidi: RandALCat character U+0627 U+0031 U+0628. - (b'\xd8\xa71\xd8\xa8', - b'\xd8\xa71\xd8\xa8'), - # 3.43 Unassigned code point U+E0002. - # Skip this test as we allow unassigned - #(b'\xf3\xa0\x80\x82', - # None), - (None, None), - # 3.44 Larger test (shrinking). - # Original test case reads \xc3\xdf - (b'X\xc2\xad\xc3\x9f\xc4\xb0\xe2\x84\xa1j\xcc\x8c\xc2\xa0\xc2' - b'\xaa\xce\xb0\xe2\x80\x80', - b'xssi\xcc\x87tel\xc7\xb0 a\xce\xb0 '), - # 3.45 Larger test (expanding). - # Original test case reads \xc3\x9f - (b'X\xc3\x9f\xe3\x8c\x96\xc4\xb0\xe2\x84\xa1\xe2\x92\x9f\xe3\x8c' - b'\x80', - b'xss\xe3\x82\xad\xe3\x83\xad\xe3\x83\xa1\xe3\x83\xbc\xe3' - b'\x83\x88\xe3\x83\xabi\xcc\x87tel\x28d\x29\xe3\x82' - b'\xa2\xe3\x83\x91\xe3\x83\xbc\xe3\x83\x88') - ] - - - class NameprepTest(unittest.TestCase): - def test_nameprep(self): - from encodings.idna import nameprep - for pos, (orig, prepped) in enumerate(nameprep_tests): - if orig is None: - # Skipped - continue - # The Unicode strings are given in UTF-8 - orig = str(orig, "utf-8", "surrogatepass") - if prepped is None: - # Input contains prohibited characters - self.assertRaises(UnicodeError, nameprep, orig) - else: - prepped = str(prepped, "utf-8", "surrogatepass") - try: - self.assertEqual(nameprep(orig), prepped) - except Exception as e: - raise support.TestFailed("Test 3.%d: %s" % (pos+1, str(e))) - - - class IDNACodecTest(unittest.TestCase): - def test_builtin_decode(self): - self.assertEqual(str(b"python.org", "idna"), "python.org") - self.assertEqual(str(b"python.org.", "idna"), "python.org.") - self.assertEqual(str(b"xn--pythn-mua.org", "idna"), "pyth\xf6n.org") - self.assertEqual(str(b"xn--pythn-mua.org.", "idna"), "pyth\xf6n.org.") - - def test_builtin_encode(self): - self.assertEqual("python.org".encode("idna"), b"python.org") - self.assertEqual("python.org.".encode("idna"), b"python.org.") - self.assertEqual("pyth\xf6n.org".encode("idna"), b"xn--pythn-mua.org") - self.assertEqual("pyth\xf6n.org.".encode("idna"), b"xn--pythn-mua.org.") - - def test_stream(self): - r = codecs.getreader("idna")(io.BytesIO(b"abc")) - r.read(3) - self.assertEqual(r.read(), "") - - def test_incremental_decode(self): - self.assertEqual( - "".join(codecs.iterdecode((bytes([c]) for c in b"python.org"), "idna")), - "python.org" - ) - self.assertEqual( - "".join(codecs.iterdecode((bytes([c]) for c in b"python.org."), "idna")), - "python.org." - ) - self.assertEqual( - "".join(codecs.iterdecode((bytes([c]) for c in b"xn--pythn-mua.org."), "idna")), - "pyth\xf6n.org." - ) - self.assertEqual( - "".join(codecs.iterdecode((bytes([c]) for c in b"xn--pythn-mua.org."), "idna")), - "pyth\xf6n.org." - ) - - decoder = codecs.getincrementaldecoder("idna")() - self.assertEqual(decoder.decode(b"xn--xam", ), "") - self.assertEqual(decoder.decode(b"ple-9ta.o", ), "\xe4xample.") - self.assertEqual(decoder.decode(b"rg"), "") - self.assertEqual(decoder.decode(b"", True), "org") - - decoder.reset() - self.assertEqual(decoder.decode(b"xn--xam", ), "") - self.assertEqual(decoder.decode(b"ple-9ta.o", ), "\xe4xample.") - self.assertEqual(decoder.decode(b"rg."), "org.") - self.assertEqual(decoder.decode(b"", True), "") - - def test_incremental_encode(self): - self.assertEqual( - b"".join(codecs.iterencode("python.org", "idna")), - b"python.org" - ) - self.assertEqual( - b"".join(codecs.iterencode("python.org.", "idna")), - b"python.org." - ) - self.assertEqual( - b"".join(codecs.iterencode("pyth\xf6n.org.", "idna")), - b"xn--pythn-mua.org." - ) - self.assertEqual( - b"".join(codecs.iterencode("pyth\xf6n.org.", "idna")), - b"xn--pythn-mua.org." - ) - - encoder = codecs.getincrementalencoder("idna")() - self.assertEqual(encoder.encode("\xe4x"), b"") - self.assertEqual(encoder.encode("ample.org"), b"xn--xample-9ta.") - self.assertEqual(encoder.encode("", True), b"org") - - encoder.reset() - self.assertEqual(encoder.encode("\xe4x"), b"") - self.assertEqual(encoder.encode("ample.org."), b"xn--xample-9ta.org.") - self.assertEqual(encoder.encode("", True), b"") - - def test_errors(self): - """Only supports "strict" error handler""" - "python.org".encode("idna", "strict") - b"python.org".decode("idna", "strict") - for errors in ("ignore", "replace", "backslashreplace", - "surrogateescape"): - self.assertRaises(Exception, "python.org".encode, "idna", errors) - self.assertRaises(Exception, - b"python.org".decode, "idna", errors) - - - class CodecsModuleTest(unittest.TestCase): - - def test_decode(self): - self.assertEqual(codecs.decode(b'\xe4\xf6\xfc', 'latin-1'), - '\xe4\xf6\xfc') - self.assertRaises(TypeError, codecs.decode) - self.assertEqual(codecs.decode(b'abc'), 'abc') - self.assertRaises(UnicodeDecodeError, codecs.decode, b'\xff', 'ascii') - - # test keywords - self.assertEqual(codecs.decode(obj=b'\xe4\xf6\xfc', encoding='latin-1'), - '\xe4\xf6\xfc') - self.assertEqual(codecs.decode(b'[\xff]', 'ascii', errors='ignore'), - '[]') - - def test_encode(self): - self.assertEqual(codecs.encode('\xe4\xf6\xfc', 'latin-1'), - b'\xe4\xf6\xfc') - self.assertRaises(TypeError, codecs.encode) - self.assertRaises(LookupError, codecs.encode, "foo", "__spam__") - self.assertEqual(codecs.encode('abc'), b'abc') - self.assertRaises(UnicodeEncodeError, codecs.encode, '\xffff', 'ascii') - - # test keywords - self.assertEqual(codecs.encode(obj='\xe4\xf6\xfc', encoding='latin-1'), - b'\xe4\xf6\xfc') - self.assertEqual(codecs.encode('[\xff]', 'ascii', errors='ignore'), - b'[]') - - def test_register(self): - self.assertRaises(TypeError, codecs.register) - self.assertRaises(TypeError, codecs.register, 42) - - def test_lookup(self): - self.assertRaises(TypeError, codecs.lookup) - self.assertRaises(LookupError, codecs.lookup, "__spam__") - self.assertRaises(LookupError, codecs.lookup, " ") - - def test_getencoder(self): - self.assertRaises(TypeError, codecs.getencoder) - self.assertRaises(LookupError, codecs.getencoder, "__spam__") - - def test_getdecoder(self): - self.assertRaises(TypeError, codecs.getdecoder) - self.assertRaises(LookupError, codecs.getdecoder, "__spam__") - - def test_getreader(self): - self.assertRaises(TypeError, codecs.getreader) - self.assertRaises(LookupError, codecs.getreader, "__spam__") - - def test_getwriter(self): - self.assertRaises(TypeError, codecs.getwriter) - self.assertRaises(LookupError, codecs.getwriter, "__spam__") - - def test_lookup_issue1813(self): - # Issue #1813: under Turkish locales, lookup of some codecs failed - # because 'I' is lowercased as "ı" (dotless i) - oldlocale = locale.setlocale(locale.LC_CTYPE) - self.addCleanup(locale.setlocale, locale.LC_CTYPE, oldlocale) - try: - locale.setlocale(locale.LC_CTYPE, 'tr_TR') - except locale.Error: - # Unsupported locale on this system - self.skipTest('test needs Turkish locale') - c = codecs.lookup('ASCII') - self.assertEqual(c.name, 'ascii') - - def test_all(self): - api = ( - "encode", "decode", - "register", "CodecInfo", "Codec", "IncrementalEncoder", - "IncrementalDecoder", "StreamReader", "StreamWriter", "lookup", - "getencoder", "getdecoder", "getincrementalencoder", - "getincrementaldecoder", "getreader", "getwriter", - "register_error", "lookup_error", - "strict_errors", "replace_errors", "ignore_errors", - "xmlcharrefreplace_errors", "backslashreplace_errors", - "namereplace_errors", - "open", "EncodedFile", - "iterencode", "iterdecode", - "BOM", "BOM_BE", "BOM_LE", - "BOM_UTF8", "BOM_UTF16", "BOM_UTF16_BE", "BOM_UTF16_LE", - "BOM_UTF32", "BOM_UTF32_BE", "BOM_UTF32_LE", - "BOM32_BE", "BOM32_LE", "BOM64_BE", "BOM64_LE", # Undocumented - "StreamReaderWriter", "StreamRecoder", - ) - self.assertCountEqual(api, codecs.__all__) - for api in codecs.__all__: - getattr(codecs, api) - - def test_open(self): - self.addCleanup(support.unlink, support.TESTFN) - for mode in ('w', 'r', 'r+', 'w+', 'a', 'a+'): - with self.subTest(mode), \ - codecs.open(support.TESTFN, mode, 'ascii') as file: - self.assertIsInstance(file, codecs.StreamReaderWriter) - - def test_undefined(self): - self.assertRaises(UnicodeError, codecs.encode, 'abc', 'undefined') - self.assertRaises(UnicodeError, codecs.decode, b'abc', 'undefined') - self.assertRaises(UnicodeError, codecs.encode, '', 'undefined') - self.assertRaises(UnicodeError, codecs.decode, b'', 'undefined') - for errors in ('strict', 'ignore', 'replace', 'backslashreplace'): - self.assertRaises(UnicodeError, - codecs.encode, 'abc', 'undefined', errors) - self.assertRaises(UnicodeError, - codecs.decode, b'abc', 'undefined', errors) - - def test_file_closes_if_lookup_error_raised(self): - mock_open = mock.mock_open() - with mock.patch('builtins.open', mock_open) as file: - with self.assertRaises(LookupError): - codecs.open(support.TESTFN, 'wt', 'invalid-encoding') - - file().close.assert_called() - - - class StreamReaderTest(unittest.TestCase): - - def setUp(self): - self.reader = codecs.getreader('utf-8') - self.stream = io.BytesIO(b'\xed\x95\x9c\n\xea\xb8\x80') - - def test_readlines(self): - f = self.reader(self.stream) - self.assertEqual(f.readlines(), ['\ud55c\n', '\uae00']) - - - class EncodedFileTest(unittest.TestCase): - - def test_basic(self): - f = io.BytesIO(b'\xed\x95\x9c\n\xea\xb8\x80') - ef = codecs.EncodedFile(f, 'utf-16-le', 'utf-8') - self.assertEqual(ef.read(), b'\\\xd5\n\x00\x00\xae') - - f = io.BytesIO() - ef = codecs.EncodedFile(f, 'utf-8', 'latin-1') - ef.write(b'\xc3\xbc') - self.assertEqual(f.getvalue(), b'\xfc') - - all_unicode_encodings = [ - "ascii", - "big5", - "big5hkscs", - "charmap", - "cp037", - "cp1006", - "cp1026", - "cp1125", - "cp1140", - "cp1250", - "cp1251", - "cp1252", - "cp1253", - "cp1254", - "cp1255", - "cp1256", - "cp1257", - "cp1258", - "cp424", - "cp437", - "cp500", - "cp720", - "cp737", - "cp775", - "cp850", - "cp852", - "cp855", - "cp856", - "cp857", - "cp858", - "cp860", - "cp861", - "cp862", - "cp863", - "cp864", - "cp865", - "cp866", - "cp869", - "cp874", - "cp875", - "cp932", - "cp949", - "cp950", - "euc_jis_2004", - "euc_jisx0213", - "euc_jp", - "euc_kr", - "gb18030", - "gb2312", - "gbk", - "hp_roman8", - "hz", - "idna", - "iso2022_jp", - "iso2022_jp_1", - "iso2022_jp_2", - "iso2022_jp_2004", - "iso2022_jp_3", - "iso2022_jp_ext", - "iso2022_kr", - "iso8859_1", - "iso8859_10", - "iso8859_11", - "iso8859_13", - "iso8859_14", - "iso8859_15", - "iso8859_16", - "iso8859_2", - "iso8859_3", - "iso8859_4", - "iso8859_5", - "iso8859_6", - "iso8859_7", - "iso8859_8", - "iso8859_9", - "johab", - "koi8_r", - "koi8_t", - "koi8_u", - "kz1048", - "latin_1", - "mac_cyrillic", - "mac_greek", - "mac_iceland", - "mac_latin2", - "mac_roman", - "mac_turkish", - "palmos", - "ptcp154", - "punycode", - "raw_unicode_escape", - "shift_jis", - "shift_jis_2004", - "shift_jisx0213", - "tis_620", - "unicode_escape", - "utf_16", - "utf_16_be", - "utf_16_le", - "utf_7", - "utf_8", - ] - - if hasattr(codecs, "mbcs_encode"): - all_unicode_encodings.append("mbcs") - if hasattr(codecs, "oem_encode"): - all_unicode_encodings.append("oem") - - # The following encoding is not tested, because it's not supposed - # to work: - # "undefined" - - # The following encodings don't work in stateful mode - broken_unicode_with_stateful = [ - "punycode", - ] - - - class BasicUnicodeTest(unittest.TestCase, MixInCheckStateHandling): - def test_basics(self): - s = "abc123" # all codecs should be able to encode these - for encoding in all_unicode_encodings: - name = codecs.lookup(encoding).name - if encoding.endswith("_codec"): - name += "_codec" - elif encoding == "latin_1": - name = "latin_1" - self.assertEqual(encoding.replace("_", "-"), name.replace("_", "-")) - - (b, size) = codecs.getencoder(encoding)(s) - self.assertEqual(size, len(s), "encoding=%r" % encoding) - (chars, size) = codecs.getdecoder(encoding)(b) - self.assertEqual(chars, s, "encoding=%r" % encoding) - - if encoding not in broken_unicode_with_stateful: - # check stream reader/writer - q = Queue(b"") - writer = codecs.getwriter(encoding)(q) - encodedresult = b"" - for c in s: - writer.write(c) - chunk = q.read() - self.assertTrue(type(chunk) is bytes, type(chunk)) - encodedresult += chunk - q = Queue(b"") - reader = codecs.getreader(encoding)(q) - decodedresult = "" - for c in encodedresult: - q.write(bytes([c])) - decodedresult += reader.read() - self.assertEqual(decodedresult, s, "encoding=%r" % encoding) - - if encoding not in broken_unicode_with_stateful: - # check incremental decoder/encoder and iterencode()/iterdecode() - try: - encoder = codecs.getincrementalencoder(encoding)() - except LookupError: # no IncrementalEncoder - pass - else: - # check incremental decoder/encoder - encodedresult = b"" - for c in s: - encodedresult += encoder.encode(c) - encodedresult += encoder.encode("", True) - decoder = codecs.getincrementaldecoder(encoding)() - decodedresult = "" - for c in encodedresult: - decodedresult += decoder.decode(bytes([c])) - decodedresult += decoder.decode(b"", True) - self.assertEqual(decodedresult, s, - "encoding=%r" % encoding) - - # check iterencode()/iterdecode() - result = "".join(codecs.iterdecode( - codecs.iterencode(s, encoding), encoding)) - self.assertEqual(result, s, "encoding=%r" % encoding) - - # check iterencode()/iterdecode() with empty string - result = "".join(codecs.iterdecode( - codecs.iterencode("", encoding), encoding)) - self.assertEqual(result, "") - - if encoding not in ("idna", "mbcs"): - # check incremental decoder/encoder with errors argument - try: - encoder = codecs.getincrementalencoder(encoding)("ignore") - except LookupError: # no IncrementalEncoder - pass - else: - encodedresult = b"".join(encoder.encode(c) for c in s) - decoder = codecs.getincrementaldecoder(encoding)("ignore") - decodedresult = "".join(decoder.decode(bytes([c])) - for c in encodedresult) - self.assertEqual(decodedresult, s, - "encoding=%r" % encoding) - - @support.cpython_only - def test_basics_capi(self): - s = "abc123" # all codecs should be able to encode these - for encoding in all_unicode_encodings: - if encoding not in broken_unicode_with_stateful: - # check incremental decoder/encoder (fetched via the C API) - try: - cencoder = _testcapi.codec_incrementalencoder(encoding) - except LookupError: # no IncrementalEncoder - pass - else: - # check C API - encodedresult = b"" - for c in s: - encodedresult += cencoder.encode(c) - encodedresult += cencoder.encode("", True) - cdecoder = _testcapi.codec_incrementaldecoder(encoding) - decodedresult = "" - for c in encodedresult: - decodedresult += cdecoder.decode(bytes([c])) - decodedresult += cdecoder.decode(b"", True) - self.assertEqual(decodedresult, s, - "encoding=%r" % encoding) - - if encoding not in ("idna", "mbcs"): - # check incremental decoder/encoder with errors argument - try: - cencoder = _testcapi.codec_incrementalencoder(encoding, "ignore") - except LookupError: # no IncrementalEncoder - pass - else: - encodedresult = b"".join(cencoder.encode(c) for c in s) - cdecoder = _testcapi.codec_incrementaldecoder(encoding, "ignore") - decodedresult = "".join(cdecoder.decode(bytes([c])) - for c in encodedresult) - self.assertEqual(decodedresult, s, - "encoding=%r" % encoding) - - def test_seek(self): - # all codecs should be able to encode these - s = "%s\n%s\n" % (100*"abc123", 100*"def456") - for encoding in all_unicode_encodings: - if encoding == "idna": # FIXME: See SF bug #1163178 - continue - if encoding in broken_unicode_with_stateful: - continue - reader = codecs.getreader(encoding)(io.BytesIO(s.encode(encoding))) - for t in range(5): - # Test that calling seek resets the internal codec state and buffers - reader.seek(0, 0) - data = reader.read() - self.assertEqual(s, data) - - def test_bad_decode_args(self): - for encoding in all_unicode_encodings: - decoder = codecs.getdecoder(encoding) - self.assertRaises(TypeError, decoder) - if encoding not in ("idna", "punycode"): - self.assertRaises(TypeError, decoder, 42) - - def test_bad_encode_args(self): - for encoding in all_unicode_encodings: - encoder = codecs.getencoder(encoding) - self.assertRaises(TypeError, encoder) - - def test_encoding_map_type_initialized(self): - from encodings import cp1140 - # This used to crash, we are only verifying there's no crash. - table_type = type(cp1140.encoding_table) - self.assertEqual(table_type, table_type) - - def test_decoder_state(self): - # Check that getstate() and setstate() handle the state properly - u = "abc123" - for encoding in all_unicode_encodings: - if encoding not in broken_unicode_with_stateful: - self.check_state_handling_decode(encoding, u, u.encode(encoding)) - self.check_state_handling_encode(encoding, u, u.encode(encoding)) - - - class CharmapTest(unittest.TestCase): - def test_decode_with_string_map(self): - self.assertEqual( - codecs.charmap_decode(b"\x00\x01\x02", "strict", "abc"), - ("abc", 3) - ) - - self.assertEqual( - codecs.charmap_decode(b"\x00\x01\x02", "strict", "\U0010FFFFbc"), - ("\U0010FFFFbc", 3) - ) - - self.assertRaises(UnicodeDecodeError, - codecs.charmap_decode, b"\x00\x01\x02", "strict", "ab" - ) - - self.assertRaises(UnicodeDecodeError, - codecs.charmap_decode, b"\x00\x01\x02", "strict", "ab\ufffe" - ) - - self.assertEqual( - codecs.charmap_decode(b"\x00\x01\x02", "replace", "ab"), - ("ab\ufffd", 3) - ) - - self.assertEqual( - codecs.charmap_decode(b"\x00\x01\x02", "replace", "ab\ufffe"), - ("ab\ufffd", 3) - ) - - self.assertEqual( - codecs.charmap_decode(b"\x00\x01\x02", "backslashreplace", "ab"), - ("ab\\x02", 3) - ) - - self.assertEqual( - codecs.charmap_decode(b"\x00\x01\x02", "backslashreplace", "ab\ufffe"), - ("ab\\x02", 3) - ) - - self.assertEqual( - codecs.charmap_decode(b"\x00\x01\x02", "ignore", "ab"), - ("ab", 3) - ) - - self.assertEqual( - codecs.charmap_decode(b"\x00\x01\x02", "ignore", "ab\ufffe"), - ("ab", 3) - ) - - allbytes = bytes(range(256)) - self.assertEqual( - codecs.charmap_decode(allbytes, "ignore", ""), - ("", len(allbytes)) - ) - - def test_decode_with_int2str_map(self): - self.assertEqual( - codecs.charmap_decode(b"\x00\x01\x02", "strict", - {0: 'a', 1: 'b', 2: 'c'}), - ("abc", 3) - ) - - self.assertEqual( - codecs.charmap_decode(b"\x00\x01\x02", "strict", - {0: 'Aa', 1: 'Bb', 2: 'Cc'}), - ("AaBbCc", 3) - ) - - self.assertEqual( - codecs.charmap_decode(b"\x00\x01\x02", "strict", - {0: '\U0010FFFF', 1: 'b', 2: 'c'}), - ("\U0010FFFFbc", 3) - ) - - self.assertEqual( - codecs.charmap_decode(b"\x00\x01\x02", "strict", - {0: 'a', 1: 'b', 2: ''}), - ("ab", 3) - ) - - self.assertRaises(UnicodeDecodeError, - codecs.charmap_decode, b"\x00\x01\x02", "strict", - {0: 'a', 1: 'b'} - ) - - self.assertRaises(UnicodeDecodeError, - codecs.charmap_decode, b"\x00\x01\x02", "strict", - {0: 'a', 1: 'b', 2: None} - ) - - # Issue #14850 - self.assertRaises(UnicodeDecodeError, - codecs.charmap_decode, b"\x00\x01\x02", "strict", - {0: 'a', 1: 'b', 2: '\ufffe'} - ) - - self.assertEqual( - codecs.charmap_decode(b"\x00\x01\x02", "replace", - {0: 'a', 1: 'b'}), - ("ab\ufffd", 3) - ) - - self.assertEqual( - codecs.charmap_decode(b"\x00\x01\x02", "replace", - {0: 'a', 1: 'b', 2: None}), - ("ab\ufffd", 3) - ) - - # Issue #14850 - self.assertEqual( - codecs.charmap_decode(b"\x00\x01\x02", "replace", - {0: 'a', 1: 'b', 2: '\ufffe'}), - ("ab\ufffd", 3) - ) - - self.assertEqual( - codecs.charmap_decode(b"\x00\x01\x02", "backslashreplace", - {0: 'a', 1: 'b'}), - ("ab\\x02", 3) - ) - - self.assertEqual( - codecs.charmap_decode(b"\x00\x01\x02", "backslashreplace", - {0: 'a', 1: 'b', 2: None}), - ("ab\\x02", 3) - ) - - # Issue #14850 - self.assertEqual( - codecs.charmap_decode(b"\x00\x01\x02", "backslashreplace", - {0: 'a', 1: 'b', 2: '\ufffe'}), - ("ab\\x02", 3) - ) - - self.assertEqual( - codecs.charmap_decode(b"\x00\x01\x02", "ignore", - {0: 'a', 1: 'b'}), - ("ab", 3) - ) - - self.assertEqual( - codecs.charmap_decode(b"\x00\x01\x02", "ignore", - {0: 'a', 1: 'b', 2: None}), - ("ab", 3) - ) - - # Issue #14850 - self.assertEqual( - codecs.charmap_decode(b"\x00\x01\x02", "ignore", - {0: 'a', 1: 'b', 2: '\ufffe'}), - ("ab", 3) - ) - - allbytes = bytes(range(256)) - self.assertEqual( - codecs.charmap_decode(allbytes, "ignore", {}), - ("", len(allbytes)) - ) - - self.assertRaisesRegex(TypeError, - "character mapping must be in range\\(0x110000\\)", - codecs.charmap_decode, - b"\x00\x01\x02", "strict", {0: "A", 1: 'Bb', 2: -2} - ) - - self.assertRaisesRegex(TypeError, - "character mapping must be in range\\(0x110000\\)", - codecs.charmap_decode, - b"\x00\x01\x02", "strict", {0: "A", 1: 'Bb', 2: 999999999} - ) - - def test_decode_with_int2int_map(self): - a = ord('a') - b = ord('b') - c = ord('c') - - self.assertEqual( - codecs.charmap_decode(b"\x00\x01\x02", "strict", - {0: a, 1: b, 2: c}), - ("abc", 3) - ) - - # Issue #15379 - self.assertEqual( - codecs.charmap_decode(b"\x00\x01\x02", "strict", - {0: 0x10FFFF, 1: b, 2: c}), - ("\U0010FFFFbc", 3) - ) - - self.assertEqual( - codecs.charmap_decode(b"\x00\x01\x02", "strict", - {0: sys.maxunicode, 1: b, 2: c}), - (chr(sys.maxunicode) + "bc", 3) - ) - - self.assertRaises(TypeError, - codecs.charmap_decode, b"\x00\x01\x02", "strict", - {0: sys.maxunicode + 1, 1: b, 2: c} - ) - - self.assertRaises(UnicodeDecodeError, - codecs.charmap_decode, b"\x00\x01\x02", "strict", - {0: a, 1: b}, - ) - - self.assertRaises(UnicodeDecodeError, - codecs.charmap_decode, b"\x00\x01\x02", "strict", - {0: a, 1: b, 2: 0xFFFE}, - ) - - self.assertEqual( - codecs.charmap_decode(b"\x00\x01\x02", "replace", - {0: a, 1: b}), - ("ab\ufffd", 3) - ) - - self.assertEqual( - codecs.charmap_decode(b"\x00\x01\x02", "replace", - {0: a, 1: b, 2: 0xFFFE}), - ("ab\ufffd", 3) - ) - - self.assertEqual( - codecs.charmap_decode(b"\x00\x01\x02", "backslashreplace", - {0: a, 1: b}), - ("ab\\x02", 3) - ) - - self.assertEqual( - codecs.charmap_decode(b"\x00\x01\x02", "backslashreplace", - {0: a, 1: b, 2: 0xFFFE}), - ("ab\\x02", 3) - ) - - self.assertEqual( - codecs.charmap_decode(b"\x00\x01\x02", "ignore", - {0: a, 1: b}), - ("ab", 3) - ) - - self.assertEqual( - codecs.charmap_decode(b"\x00\x01\x02", "ignore", - {0: a, 1: b, 2: 0xFFFE}), - ("ab", 3) - ) - - - class WithStmtTest(unittest.TestCase): - def test_encodedfile(self): - f = io.BytesIO(b"\xc3\xbc") - with codecs.EncodedFile(f, "latin-1", "utf-8") as ef: - self.assertEqual(ef.read(), b"\xfc") - self.assertTrue(f.closed) - - def test_streamreaderwriter(self): - f = io.BytesIO(b"\xc3\xbc") - info = codecs.lookup("utf-8") - with codecs.StreamReaderWriter(f, info.streamreader, - info.streamwriter, 'strict') as srw: - self.assertEqual(srw.read(), "\xfc") - - - class TypesTest(unittest.TestCase): - def test_decode_unicode(self): - # Most decoders don't accept unicode input - decoders = [ - codecs.utf_7_decode, - codecs.utf_8_decode, - codecs.utf_16_le_decode, - codecs.utf_16_be_decode, - codecs.utf_16_ex_decode, - codecs.utf_32_decode, - codecs.utf_32_le_decode, - codecs.utf_32_be_decode, - codecs.utf_32_ex_decode, - codecs.latin_1_decode, - codecs.ascii_decode, - codecs.charmap_decode, - ] - if hasattr(codecs, "mbcs_decode"): - decoders.append(codecs.mbcs_decode) - for decoder in decoders: - self.assertRaises(TypeError, decoder, "xxx") - - def test_unicode_escape(self): - # Escape-decoding a unicode string is supported and gives the same - # result as decoding the equivalent ASCII bytes string. - self.assertEqual(codecs.unicode_escape_decode(r"\u1234"), ("\u1234", 6)) - self.assertEqual(codecs.unicode_escape_decode(br"\u1234"), ("\u1234", 6)) - self.assertEqual(codecs.raw_unicode_escape_decode(r"\u1234"), ("\u1234", 6)) - self.assertEqual(codecs.raw_unicode_escape_decode(br"\u1234"), ("\u1234", 6)) - - self.assertRaises(UnicodeDecodeError, codecs.unicode_escape_decode, br"\U00110000") - self.assertEqual(codecs.unicode_escape_decode(r"\U00110000", "replace"), ("\ufffd", 10)) - self.assertEqual(codecs.unicode_escape_decode(r"\U00110000", "backslashreplace"), - (r"\x5c\x55\x30\x30\x31\x31\x30\x30\x30\x30", 10)) - - self.assertRaises(UnicodeDecodeError, codecs.raw_unicode_escape_decode, br"\U00110000") - self.assertEqual(codecs.raw_unicode_escape_decode(r"\U00110000", "replace"), ("\ufffd", 10)) - self.assertEqual(codecs.raw_unicode_escape_decode(r"\U00110000", "backslashreplace"), - (r"\x5c\x55\x30\x30\x31\x31\x30\x30\x30\x30", 10)) - - - class UnicodeEscapeTest(unittest.TestCase): - def test_empty(self): - self.assertEqual(codecs.unicode_escape_encode(""), (b"", 0)) - self.assertEqual(codecs.unicode_escape_decode(b""), ("", 0)) - - def test_raw_encode(self): - encode = codecs.unicode_escape_encode - for b in range(32, 127): - if b != b'\\'[0]: - self.assertEqual(encode(chr(b)), (bytes([b]), 1)) - - def test_raw_decode(self): - decode = codecs.unicode_escape_decode - for b in range(256): - if b != b'\\'[0]: - self.assertEqual(decode(bytes([b]) + b'0'), (chr(b) + '0', 2)) - - def test_escape_encode(self): - encode = codecs.unicode_escape_encode - check = coding_checker(self, encode) - check('\t', br'\t') - check('\n', br'\n') - check('\r', br'\r') - check('\\', br'\\') - for b in range(32): - if chr(b) not in '\t\n\r': - check(chr(b), ('\\x%02x' % b).encode()) - for b in range(127, 256): - check(chr(b), ('\\x%02x' % b).encode()) - check('\u20ac', br'\u20ac') - check('\U0001d120', br'\U0001d120') - - def test_escape_decode(self): - decode = codecs.unicode_escape_decode - check = coding_checker(self, decode) - check(b"[\\\n]", "[]") - check(br'[\"]', '["]') - check(br"[\']", "[']") - check(br"[\\]", r"[\]") - check(br"[\a]", "[\x07]") - check(br"[\b]", "[\x08]") - check(br"[\t]", "[\x09]") - check(br"[\n]", "[\x0a]") - check(br"[\v]", "[\x0b]") - check(br"[\f]", "[\x0c]") - check(br"[\r]", "[\x0d]") - check(br"[\7]", "[\x07]") - check(br"[\78]", "[\x078]") - check(br"[\41]", "[!]") - check(br"[\418]", "[!8]") - check(br"[\101]", "[A]") - check(br"[\1010]", "[A0]") - check(br"[\x41]", "[A]") - check(br"[\x410]", "[A0]") - check(br"\u20ac", "\u20ac") - check(br"\U0001d120", "\U0001d120") - for i in range(97, 123): - b = bytes([i]) - if b not in b'abfnrtuvx': - with self.assertWarns(DeprecationWarning): - check(b"\\" + b, "\\" + chr(i)) - if b.upper() not in b'UN': - with self.assertWarns(DeprecationWarning): - check(b"\\" + b.upper(), "\\" + chr(i-32)) - with self.assertWarns(DeprecationWarning): - check(br"\8", "\\8") - with self.assertWarns(DeprecationWarning): - check(br"\9", "\\9") - with self.assertWarns(DeprecationWarning): - check(b"\\\xfa", "\\\xfa") - - def test_decode_errors(self): - decode = codecs.unicode_escape_decode - for c, d in (b'x', 2), (b'u', 4), (b'U', 4): - for i in range(d): - self.assertRaises(UnicodeDecodeError, decode, - b"\\" + c + b"0"*i) - self.assertRaises(UnicodeDecodeError, decode, - b"[\\" + c + b"0"*i + b"]") - data = b"[\\" + c + b"0"*i + b"]\\" + c + b"0"*i - self.assertEqual(decode(data, "ignore"), ("[]", len(data))) - self.assertEqual(decode(data, "replace"), - ("[\ufffd]\ufffd", len(data))) - self.assertRaises(UnicodeDecodeError, decode, br"\U00110000") - self.assertEqual(decode(br"\U00110000", "ignore"), ("", 10)) - self.assertEqual(decode(br"\U00110000", "replace"), ("\ufffd", 10)) - - - class RawUnicodeEscapeTest(unittest.TestCase): - def test_empty(self): - self.assertEqual(codecs.raw_unicode_escape_encode(""), (b"", 0)) - self.assertEqual(codecs.raw_unicode_escape_decode(b""), ("", 0)) - - def test_raw_encode(self): - encode = codecs.raw_unicode_escape_encode - for b in range(256): - self.assertEqual(encode(chr(b)), (bytes([b]), 1)) - - def test_raw_decode(self): - decode = codecs.raw_unicode_escape_decode - for b in range(256): - self.assertEqual(decode(bytes([b]) + b'0'), (chr(b) + '0', 2)) - - def test_escape_encode(self): - encode = codecs.raw_unicode_escape_encode - check = coding_checker(self, encode) - for b in range(256): - if b not in b'uU': - check('\\' + chr(b), b'\\' + bytes([b])) - check('\u20ac', br'\u20ac') - check('\U0001d120', br'\U0001d120') - - def test_escape_decode(self): - decode = codecs.raw_unicode_escape_decode - check = coding_checker(self, decode) - for b in range(256): - if b not in b'uU': - check(b'\\' + bytes([b]), '\\' + chr(b)) - check(br"\u20ac", "\u20ac") - check(br"\U0001d120", "\U0001d120") - - def test_decode_errors(self): - decode = codecs.raw_unicode_escape_decode - for c, d in (b'u', 4), (b'U', 4): - for i in range(d): - self.assertRaises(UnicodeDecodeError, decode, - b"\\" + c + b"0"*i) - self.assertRaises(UnicodeDecodeError, decode, - b"[\\" + c + b"0"*i + b"]") - data = b"[\\" + c + b"0"*i + b"]\\" + c + b"0"*i - self.assertEqual(decode(data, "ignore"), ("[]", len(data))) - self.assertEqual(decode(data, "replace"), - ("[\ufffd]\ufffd", len(data))) - self.assertRaises(UnicodeDecodeError, decode, br"\U00110000") - self.assertEqual(decode(br"\U00110000", "ignore"), ("", 10)) - self.assertEqual(decode(br"\U00110000", "replace"), ("\ufffd", 10)) - - - class EscapeEncodeTest(unittest.TestCase): - - def test_escape_encode(self): - tests = [ - (b'', (b'', 0)), - (b'foobar', (b'foobar', 6)), - (b'spam\0eggs', (b'spam\\x00eggs', 9)), - (b'a\'b', (b"a\\'b", 3)), - (b'b\\c', (b'b\\\\c', 3)), - (b'c\nd', (b'c\\nd', 3)), - (b'd\re', (b'd\\re', 3)), - (b'f\x7fg', (b'f\\x7fg', 3)), - ] - for data, output in tests: - with self.subTest(data=data): - self.assertEqual(codecs.escape_encode(data), output) - self.assertRaises(TypeError, codecs.escape_encode, 'spam') - self.assertRaises(TypeError, codecs.escape_encode, bytearray(b'spam')) - - - class SurrogateEscapeTest(unittest.TestCase): - - def test_utf8(self): - # Bad byte - self.assertEqual(b"foo\x80bar".decode("utf-8", "surrogateescape"), - "foo\udc80bar") - self.assertEqual("foo\udc80bar".encode("utf-8", "surrogateescape"), - b"foo\x80bar") - # bad-utf-8 encoded surrogate - self.assertEqual(b"\xed\xb0\x80".decode("utf-8", "surrogateescape"), - "\udced\udcb0\udc80") - self.assertEqual("\udced\udcb0\udc80".encode("utf-8", "surrogateescape"), - b"\xed\xb0\x80") - - def test_ascii(self): - # bad byte - self.assertEqual(b"foo\x80bar".decode("ascii", "surrogateescape"), - "foo\udc80bar") - self.assertEqual("foo\udc80bar".encode("ascii", "surrogateescape"), - b"foo\x80bar") - - def test_charmap(self): - # bad byte: \xa5 is unmapped in iso-8859-3 - self.assertEqual(b"foo\xa5bar".decode("iso-8859-3", "surrogateescape"), - "foo\udca5bar") - self.assertEqual("foo\udca5bar".encode("iso-8859-3", "surrogateescape"), - b"foo\xa5bar") - - def test_latin1(self): - # Issue6373 - self.assertEqual("\udce4\udceb\udcef\udcf6\udcfc".encode("latin-1", "surrogateescape"), - b"\xe4\xeb\xef\xf6\xfc") - - - class BomTest(unittest.TestCase): - def test_seek0(self): - data = "1234567890" - tests = ("utf-16", - "utf-16-le", - "utf-16-be", - "utf-32", - "utf-32-le", - "utf-32-be") - self.addCleanup(support.unlink, support.TESTFN) - for encoding in tests: - # Check if the BOM is written only once - with codecs.open(support.TESTFN, 'w+', encoding=encoding) as f: - f.write(data) - f.write(data) - f.seek(0) - self.assertEqual(f.read(), data * 2) - f.seek(0) - self.assertEqual(f.read(), data * 2) - - # Check that the BOM is written after a seek(0) - with codecs.open(support.TESTFN, 'w+', encoding=encoding) as f: - f.write(data[0]) - self.assertNotEqual(f.tell(), 0) - f.seek(0) - f.write(data) - f.seek(0) - self.assertEqual(f.read(), data) - - # (StreamWriter) Check that the BOM is written after a seek(0) - with codecs.open(support.TESTFN, 'w+', encoding=encoding) as f: - f.writer.write(data[0]) - self.assertNotEqual(f.writer.tell(), 0) - f.writer.seek(0) - f.writer.write(data) - f.seek(0) - self.assertEqual(f.read(), data) - - # Check that the BOM is not written after a seek() at a position - # different than the start - with codecs.open(support.TESTFN, 'w+', encoding=encoding) as f: - f.write(data) - f.seek(f.tell()) - f.write(data) - f.seek(0) - self.assertEqual(f.read(), data * 2) - - # (StreamWriter) Check that the BOM is not written after a seek() - # at a position different than the start - with codecs.open(support.TESTFN, 'w+', encoding=encoding) as f: - f.writer.write(data) - f.writer.seek(f.writer.tell()) - f.writer.write(data) - f.seek(0) - self.assertEqual(f.read(), data * 2) - - - bytes_transform_encodings = [ - "base64_codec", - "uu_codec", - "quopri_codec", - "hex_codec", - ] - - transform_aliases = { - "base64_codec": ["base64", "base_64"], - "uu_codec": ["uu"], - "quopri_codec": ["quopri", "quoted_printable", "quotedprintable"], - "hex_codec": ["hex"], - "rot_13": ["rot13"], - } - - try: - import zlib - except ImportError: - zlib = None - else: - bytes_transform_encodings.append("zlib_codec") - transform_aliases["zlib_codec"] = ["zip", "zlib"] - try: - import bz2 - except ImportError: - pass - else: - bytes_transform_encodings.append("bz2_codec") - transform_aliases["bz2_codec"] = ["bz2"] - - - class TransformCodecTest(unittest.TestCase): - - def test_basics(self): - binput = bytes(range(256)) - for encoding in bytes_transform_encodings: - with self.subTest(encoding=encoding): - # generic codecs interface - (o, size) = codecs.getencoder(encoding)(binput) - self.assertEqual(size, len(binput)) - (i, size) = codecs.getdecoder(encoding)(o) - self.assertEqual(size, len(o)) - self.assertEqual(i, binput) - - def test_read(self): - for encoding in bytes_transform_encodings: - with self.subTest(encoding=encoding): - sin = codecs.encode(b"\x80", encoding) - reader = codecs.getreader(encoding)(io.BytesIO(sin)) - sout = reader.read() - self.assertEqual(sout, b"\x80") - - def test_readline(self): - for encoding in bytes_transform_encodings: - with self.subTest(encoding=encoding): - sin = codecs.encode(b"\x80", encoding) - reader = codecs.getreader(encoding)(io.BytesIO(sin)) - sout = reader.readline() - self.assertEqual(sout, b"\x80") - - def test_buffer_api_usage(self): - # We check all the transform codecs accept memoryview input - # for encoding and decoding - # and also that they roundtrip correctly - original = b"12345\x80" - for encoding in bytes_transform_encodings: - with self.subTest(encoding=encoding): - data = original - view = memoryview(data) - data = codecs.encode(data, encoding) - view_encoded = codecs.encode(view, encoding) - self.assertEqual(view_encoded, data) - view = memoryview(data) - data = codecs.decode(data, encoding) - self.assertEqual(data, original) - view_decoded = codecs.decode(view, encoding) - self.assertEqual(view_decoded, data) - - def test_text_to_binary_blacklists_binary_transforms(self): - # Check binary -> binary codecs give a good error for str input - bad_input = "bad input type" - for encoding in bytes_transform_encodings: - with self.subTest(encoding=encoding): - fmt = (r"{!r} is not a text encoding; " - r"use codecs.encode\(\) to handle arbitrary codecs") - msg = fmt.format(encoding) - with self.assertRaisesRegex(LookupError, msg) as failure: - bad_input.encode(encoding) - self.assertIsNone(failure.exception.__cause__) - - def test_text_to_binary_blacklists_text_transforms(self): - # Check str.encode gives a good error message for str -> str codecs - msg = (r"^'rot_13' is not a text encoding; " - r"use codecs.encode\(\) to handle arbitrary codecs") - with self.assertRaisesRegex(LookupError, msg): - "just an example message".encode("rot_13") - - def test_binary_to_text_blacklists_binary_transforms(self): - # Check bytes.decode and bytearray.decode give a good error - # message for binary -> binary codecs - data = b"encode first to ensure we meet any format restrictions" - for encoding in bytes_transform_encodings: - with self.subTest(encoding=encoding): - encoded_data = codecs.encode(data, encoding) - fmt = (r"{!r} is not a text encoding; " - r"use codecs.decode\(\) to handle arbitrary codecs") - msg = fmt.format(encoding) - with self.assertRaisesRegex(LookupError, msg): - encoded_data.decode(encoding) - with self.assertRaisesRegex(LookupError, msg): - bytearray(encoded_data).decode(encoding) - - def test_binary_to_text_blacklists_text_transforms(self): - # Check str -> str codec gives a good error for binary input - for bad_input in (b"immutable", bytearray(b"mutable")): - with self.subTest(bad_input=bad_input): - msg = (r"^'rot_13' is not a text encoding; " - r"use codecs.decode\(\) to handle arbitrary codecs") - with self.assertRaisesRegex(LookupError, msg) as failure: - bad_input.decode("rot_13") - self.assertIsNone(failure.exception.__cause__) - - @unittest.skipUnless(zlib, "Requires zlib support") - def test_custom_zlib_error_is_wrapped(self): - # Check zlib codec gives a good error for malformed input - msg = "^decoding with 'zlib_codec' codec failed" - with self.assertRaisesRegex(Exception, msg) as failure: - codecs.decode(b"hello", "zlib_codec") - self.assertIsInstance(failure.exception.__cause__, - type(failure.exception)) - - def test_custom_hex_error_is_wrapped(self): - # Check hex codec gives a good error for malformed input - msg = "^decoding with 'hex_codec' codec failed" - with self.assertRaisesRegex(Exception, msg) as failure: - codecs.decode(b"hello", "hex_codec") - self.assertIsInstance(failure.exception.__cause__, - type(failure.exception)) - - # Unfortunately, the bz2 module throws OSError, which the codec - # machinery currently can't wrap :( - - # Ensure codec aliases from http://bugs.python.org/issue7475 work - def test_aliases(self): - for codec_name, aliases in transform_aliases.items(): - expected_name = codecs.lookup(codec_name).name - for alias in aliases: - with self.subTest(alias=alias): - info = codecs.lookup(alias) - self.assertEqual(info.name, expected_name) - - def test_quopri_stateless(self): - # Should encode with quotetabs=True - encoded = codecs.encode(b"space tab\teol \n", "quopri-codec") - self.assertEqual(encoded, b"space=20tab=09eol=20\n") - # But should still support unescaped tabs and spaces - unescaped = b"space tab eol\n" - self.assertEqual(codecs.decode(unescaped, "quopri-codec"), unescaped) - - def test_uu_invalid(self): - # Missing "begin" line - self.assertRaises(ValueError, codecs.decode, b"", "uu-codec") - - - # The codec system tries to wrap exceptions in order to ensure the error - # mentions the operation being performed and the codec involved. We - # currently *only* want this to happen for relatively stateless - # exceptions, where the only significant information they contain is their - # type and a single str argument. - - # Use a local codec registry to avoid appearing to leak objects when - # registering multiple search functions - _TEST_CODECS = {} - - def _get_test_codec(codec_name): - return _TEST_CODECS.get(codec_name) - codecs.register(_get_test_codec) # Returns None, not usable as a decorator - - try: - # Issue #22166: Also need to clear the internal cache in CPython - from _codecs import _forget_codec - except ImportError: - def _forget_codec(codec_name): - pass - - - class ExceptionChainingTest(unittest.TestCase): - - def setUp(self): - # There's no way to unregister a codec search function, so we just - # ensure we render this one fairly harmless after the test - # case finishes by using the test case repr as the codec name - # The codecs module normalizes codec names, although this doesn't - # appear to be formally documented... - # We also make sure we use a truly unique id for the custom codec - # to avoid issues with the codec cache when running these tests - # multiple times (e.g. when hunting for refleaks) - unique_id = repr(self) + str(id(self)) - self.codec_name = encodings.normalize_encoding(unique_id).lower() - - # We store the object to raise on the instance because of a bad - # interaction between the codec caching (which means we can't - # recreate the codec entry) and regrtest refleak hunting (which - # runs the same test instance multiple times). This means we - # need to ensure the codecs call back in to the instance to find - # out which exception to raise rather than binding them in a - # closure to an object that may change on the next run - self.obj_to_raise = RuntimeError - - def tearDown(self): - _TEST_CODECS.pop(self.codec_name, None) - # Issue #22166: Also pop from caches to avoid appearance of ref leaks - encodings._cache.pop(self.codec_name, None) - try: - _forget_codec(self.codec_name) - except KeyError: - pass - - def set_codec(self, encode, decode): - codec_info = codecs.CodecInfo(encode, decode, - name=self.codec_name) - _TEST_CODECS[self.codec_name] = codec_info - - @contextlib.contextmanager - def assertWrapped(self, operation, exc_type, msg): - full_msg = r"{} with {!r} codec failed \({}: {}\)".format( - operation, self.codec_name, exc_type.__name__, msg) - with self.assertRaisesRegex(exc_type, full_msg) as caught: - yield caught - self.assertIsInstance(caught.exception.__cause__, exc_type) - self.assertIsNotNone(caught.exception.__cause__.__traceback__) - - def raise_obj(self, *args, **kwds): - # Helper to dynamically change the object raised by a test codec - raise self.obj_to_raise - - def check_wrapped(self, obj_to_raise, msg, exc_type=RuntimeError): - self.obj_to_raise = obj_to_raise - self.set_codec(self.raise_obj, self.raise_obj) - with self.assertWrapped("encoding", exc_type, msg): - "str_input".encode(self.codec_name) - with self.assertWrapped("encoding", exc_type, msg): - codecs.encode("str_input", self.codec_name) - with self.assertWrapped("decoding", exc_type, msg): - b"bytes input".decode(self.codec_name) - with self.assertWrapped("decoding", exc_type, msg): - codecs.decode(b"bytes input", self.codec_name) - - def test_raise_by_type(self): - self.check_wrapped(RuntimeError, "") - - def test_raise_by_value(self): - msg = "This should be wrapped" - self.check_wrapped(RuntimeError(msg), msg) - - def test_raise_grandchild_subclass_exact_size(self): - msg = "This should be wrapped" - class MyRuntimeError(RuntimeError): - __slots__ = () - self.check_wrapped(MyRuntimeError(msg), msg, MyRuntimeError) - - def test_raise_subclass_with_weakref_support(self): - msg = "This should be wrapped" - class MyRuntimeError(RuntimeError): - pass - self.check_wrapped(MyRuntimeError(msg), msg, MyRuntimeError) - - def check_not_wrapped(self, obj_to_raise, msg): - def raise_obj(*args, **kwds): - raise obj_to_raise - self.set_codec(raise_obj, raise_obj) - with self.assertRaisesRegex(RuntimeError, msg): - "str input".encode(self.codec_name) - with self.assertRaisesRegex(RuntimeError, msg): - codecs.encode("str input", self.codec_name) - with self.assertRaisesRegex(RuntimeError, msg): - b"bytes input".decode(self.codec_name) - with self.assertRaisesRegex(RuntimeError, msg): - codecs.decode(b"bytes input", self.codec_name) - - def test_init_override_is_not_wrapped(self): - class CustomInit(RuntimeError): - def __init__(self): - pass - self.check_not_wrapped(CustomInit, "") - - def test_new_override_is_not_wrapped(self): - class CustomNew(RuntimeError): - def __new__(cls): - return super().__new__(cls) - self.check_not_wrapped(CustomNew, "") - - def test_instance_attribute_is_not_wrapped(self): - msg = "This should NOT be wrapped" - exc = RuntimeError(msg) - exc.attr = 1 - self.check_not_wrapped(exc, "^{}$".format(msg)) - - def test_non_str_arg_is_not_wrapped(self): - self.check_not_wrapped(RuntimeError(1), "1") - - def test_multiple_args_is_not_wrapped(self): - msg_re = r"^\('a', 'b', 'c'\)$" - self.check_not_wrapped(RuntimeError('a', 'b', 'c'), msg_re) - - # http://bugs.python.org/issue19609 - def test_codec_lookup_failure_not_wrapped(self): - msg = "^unknown encoding: {}$".format(self.codec_name) - # The initial codec lookup should not be wrapped - with self.assertRaisesRegex(LookupError, msg): - "str input".encode(self.codec_name) - with self.assertRaisesRegex(LookupError, msg): - codecs.encode("str input", self.codec_name) - with self.assertRaisesRegex(LookupError, msg): - b"bytes input".decode(self.codec_name) - with self.assertRaisesRegex(LookupError, msg): - codecs.decode(b"bytes input", self.codec_name) - - def test_unflagged_non_text_codec_handling(self): - # The stdlib non-text codecs are now marked so they're - # pre-emptively skipped by the text model related methods - # However, third party codecs won't be flagged, so we still make - # sure the case where an inappropriate output type is produced is - # handled appropriately - def encode_to_str(*args, **kwds): - return "not bytes!", 0 - def decode_to_bytes(*args, **kwds): - return b"not str!", 0 - self.set_codec(encode_to_str, decode_to_bytes) - # No input or output type checks on the codecs module functions - encoded = codecs.encode(None, self.codec_name) - self.assertEqual(encoded, "not bytes!") - decoded = codecs.decode(None, self.codec_name) - self.assertEqual(decoded, b"not str!") - # Text model methods should complain - fmt = (r"^{!r} encoder returned 'str' instead of 'bytes'; " - r"use codecs.encode\(\) to encode to arbitrary types$") - msg = fmt.format(self.codec_name) - with self.assertRaisesRegex(TypeError, msg): - "str_input".encode(self.codec_name) - fmt = (r"^{!r} decoder returned 'bytes' instead of 'str'; " - r"use codecs.decode\(\) to decode to arbitrary types$") - msg = fmt.format(self.codec_name) - with self.assertRaisesRegex(TypeError, msg): - b"bytes input".decode(self.codec_name) - - - - @unittest.skipUnless(sys.platform == 'win32', - 'code pages are specific to Windows') - class CodePageTest(unittest.TestCase): - CP_UTF8 = 65001 - - def test_invalid_code_page(self): - self.assertRaises(ValueError, codecs.code_page_encode, -1, 'a') - self.assertRaises(ValueError, codecs.code_page_decode, -1, b'a') - self.assertRaises(OSError, codecs.code_page_encode, 123, 'a') - self.assertRaises(OSError, codecs.code_page_decode, 123, b'a') - - def test_code_page_name(self): - self.assertRaisesRegex(UnicodeEncodeError, 'cp932', - codecs.code_page_encode, 932, '\xff') - self.assertRaisesRegex(UnicodeDecodeError, 'cp932', - codecs.code_page_decode, 932, b'\x81\x00', 'strict', True) - self.assertRaisesRegex(UnicodeDecodeError, 'CP_UTF8', - codecs.code_page_decode, self.CP_UTF8, b'\xff', 'strict', True) - - def check_decode(self, cp, tests): - for raw, errors, expected in tests: - if expected is not None: - try: - decoded = codecs.code_page_decode(cp, raw, errors, True) - except UnicodeDecodeError as err: - self.fail('Unable to decode %a from "cp%s" with ' - 'errors=%r: %s' % (raw, cp, errors, err)) - self.assertEqual(decoded[0], expected, - '%a.decode("cp%s", %r)=%a != %a' - % (raw, cp, errors, decoded[0], expected)) - # assert 0 <= decoded[1] <= len(raw) - self.assertGreaterEqual(decoded[1], 0) - self.assertLessEqual(decoded[1], len(raw)) - else: - self.assertRaises(UnicodeDecodeError, - codecs.code_page_decode, cp, raw, errors, True) - - def check_encode(self, cp, tests): - for text, errors, expected in tests: - if expected is not None: - try: - encoded = codecs.code_page_encode(cp, text, errors) - except UnicodeEncodeError as err: - self.fail('Unable to encode %a to "cp%s" with ' - 'errors=%r: %s' % (text, cp, errors, err)) - self.assertEqual(encoded[0], expected, - '%a.encode("cp%s", %r)=%a != %a' - % (text, cp, errors, encoded[0], expected)) - self.assertEqual(encoded[1], len(text)) - else: - self.assertRaises(UnicodeEncodeError, - codecs.code_page_encode, cp, text, errors) - - def test_cp932(self): - self.check_encode(932, ( - ('abc', 'strict', b'abc'), - ('\uff44\u9a3e', 'strict', b'\x82\x84\xe9\x80'), - # test error handlers - ('\xff', 'strict', None), - ('[\xff]', 'ignore', b'[]'), - ('[\xff]', 'replace', b'[y]'), - ('[\u20ac]', 'replace', b'[?]'), - ('[\xff]', 'backslashreplace', b'[\\xff]'), - ('[\xff]', 'namereplace', - b'[\\N{LATIN SMALL LETTER Y WITH DIAERESIS}]'), - ('[\xff]', 'xmlcharrefreplace', b'[ÿ]'), - ('\udcff', 'strict', None), - ('[\udcff]', 'surrogateescape', b'[\xff]'), - ('[\udcff]', 'surrogatepass', None), - )) - self.check_decode(932, ( - (b'abc', 'strict', 'abc'), - (b'\x82\x84\xe9\x80', 'strict', '\uff44\u9a3e'), - # invalid bytes - (b'[\xff]', 'strict', None), - (b'[\xff]', 'ignore', '[]'), - (b'[\xff]', 'replace', '[\ufffd]'), - (b'[\xff]', 'backslashreplace', '[\\xff]'), - (b'[\xff]', 'surrogateescape', '[\udcff]'), - (b'[\xff]', 'surrogatepass', None), - (b'\x81\x00abc', 'strict', None), - (b'\x81\x00abc', 'ignore', '\x00abc'), - (b'\x81\x00abc', 'replace', '\ufffd\x00abc'), - (b'\x81\x00abc', 'backslashreplace', '\\x81\x00abc'), - )) - - def test_cp1252(self): - self.check_encode(1252, ( - ('abc', 'strict', b'abc'), - ('\xe9\u20ac', 'strict', b'\xe9\x80'), - ('\xff', 'strict', b'\xff'), - # test error handlers - ('\u0141', 'strict', None), - ('\u0141', 'ignore', b''), - ('\u0141', 'replace', b'L'), - ('\udc98', 'surrogateescape', b'\x98'), - ('\udc98', 'surrogatepass', None), - )) - self.check_decode(1252, ( - (b'abc', 'strict', 'abc'), - (b'\xe9\x80', 'strict', '\xe9\u20ac'), - (b'\xff', 'strict', '\xff'), - )) - - def test_cp_utf7(self): - cp = 65000 - self.check_encode(cp, ( - ('abc', 'strict', b'abc'), - ('\xe9\u20ac', 'strict', b'+AOkgrA-'), - ('\U0010ffff', 'strict', b'+2//f/w-'), - ('\udc80', 'strict', b'+3IA-'), - ('\ufffd', 'strict', b'+//0-'), - )) - self.check_decode(cp, ( - (b'abc', 'strict', 'abc'), - (b'+AOkgrA-', 'strict', '\xe9\u20ac'), - (b'+2//f/w-', 'strict', '\U0010ffff'), - (b'+3IA-', 'strict', '\udc80'), - (b'+//0-', 'strict', '\ufffd'), - # invalid bytes - (b'[+/]', 'strict', '[]'), - (b'[\xff]', 'strict', '[\xff]'), - )) - - def test_multibyte_encoding(self): - self.check_decode(932, ( - (b'\x84\xe9\x80', 'ignore', '\u9a3e'), - (b'\x84\xe9\x80', 'replace', '\ufffd\u9a3e'), - )) - self.check_decode(self.CP_UTF8, ( - (b'\xff\xf4\x8f\xbf\xbf', 'ignore', '\U0010ffff'), - (b'\xff\xf4\x8f\xbf\xbf', 'replace', '\ufffd\U0010ffff'), - )) - self.check_encode(self.CP_UTF8, ( - ('[\U0010ffff\uDC80]', 'ignore', b'[\xf4\x8f\xbf\xbf]'), - ('[\U0010ffff\uDC80]', 'replace', b'[\xf4\x8f\xbf\xbf?]'), - )) - - def test_code_page_decode_flags(self): - # Issue #36312: For some code pages (e.g. UTF-7) flags for - # MultiByteToWideChar() must be set to 0. - if support.verbose: - sys.stdout.write('\n') - for cp in (50220, 50221, 50222, 50225, 50227, 50229, - *range(57002, 57011+1), 65000): - # On small versions of Windows like Windows IoT - # not all codepages are present. - # A missing codepage causes an OSError exception - # so check for the codepage before decoding - if is_code_page_present(cp): - self.assertEqual(codecs.code_page_decode(cp, b'abc'), ('abc', 3), f'cp{cp}') - else: - if support.verbose: - print(f" skipping cp={cp}") - self.assertEqual(codecs.code_page_decode(42, b'abc'), - ('\uf061\uf062\uf063', 3)) - - def test_incremental(self): - decoded = codecs.code_page_decode(932, b'\x82', 'strict', False) - self.assertEqual(decoded, ('', 0)) - - decoded = codecs.code_page_decode(932, - b'\xe9\x80\xe9', 'strict', - False) - self.assertEqual(decoded, ('\u9a3e', 2)) - - decoded = codecs.code_page_decode(932, - b'\xe9\x80\xe9\x80', 'strict', - False) - self.assertEqual(decoded, ('\u9a3e\u9a3e', 4)) - - decoded = codecs.code_page_decode(932, - b'abc', 'strict', - False) - self.assertEqual(decoded, ('abc', 3)) - - def test_mbcs_alias(self): - # Check that looking up our 'default' codepage will return - # mbcs when we don't have a more specific one available - with mock.patch('_winapi.GetACP', return_value=123): - codec = codecs.lookup('cp123') - self.assertEqual(codec.name, 'mbcs') - - @support.bigmemtest(size=2**31, memuse=7, dry_run=False) - def test_large_input(self, size): - # Test input longer than INT_MAX. - # Input should contain undecodable bytes before and after - # the INT_MAX limit. - encoded = (b'01234567' * ((size//8)-1) + - b'\x85\x86\xea\xeb\xec\xef\xfc\xfd\xfe\xff') - self.assertEqual(len(encoded), size+2) - decoded = codecs.code_page_decode(932, encoded, 'surrogateescape', True) - self.assertEqual(decoded[1], len(encoded)) - del encoded - self.assertEqual(len(decoded[0]), decoded[1]) - self.assertEqual(decoded[0][:10], '0123456701') - self.assertEqual(decoded[0][-20:], - '6701234567' - '\udc85\udc86\udcea\udceb\udcec' - '\udcef\udcfc\udcfd\udcfe\udcff') - - @support.bigmemtest(size=2**31, memuse=6, dry_run=False) - def test_large_utf8_input(self, size): - # Test input longer than INT_MAX. - # Input should contain a decodable multi-byte character - # surrounding INT_MAX - encoded = (b'0123456\xed\x84\x80' * (size//8)) - self.assertEqual(len(encoded), size // 8 * 10) - decoded = codecs.code_page_decode(65001, encoded, 'ignore', True) - self.assertEqual(decoded[1], len(encoded)) - del encoded - self.assertEqual(len(decoded[0]), size) - self.assertEqual(decoded[0][:10], '0123456\ud10001') - self.assertEqual(decoded[0][-11:], '56\ud1000123456\ud100') - - - class ASCIITest(unittest.TestCase): - def test_encode(self): - self.assertEqual('abc123'.encode('ascii'), b'abc123') - - def test_encode_error(self): - for data, error_handler, expected in ( - ('[\x80\xff\u20ac]', 'ignore', b'[]'), - ('[\x80\xff\u20ac]', 'replace', b'[???]'), - ('[\x80\xff\u20ac]', 'xmlcharrefreplace', b'[€ÿ€]'), - ('[\x80\xff\u20ac\U000abcde]', 'backslashreplace', - b'[\\x80\\xff\\u20ac\\U000abcde]'), - ('[\udc80\udcff]', 'surrogateescape', b'[\x80\xff]'), - ): - with self.subTest(data=data, error_handler=error_handler, - expected=expected): - self.assertEqual(data.encode('ascii', error_handler), - expected) - - def test_encode_surrogateescape_error(self): - with self.assertRaises(UnicodeEncodeError): - # the first character can be decoded, but not the second - '\udc80\xff'.encode('ascii', 'surrogateescape') - - def test_decode(self): - self.assertEqual(b'abc'.decode('ascii'), 'abc') - - def test_decode_error(self): - for data, error_handler, expected in ( - (b'[\x80\xff]', 'ignore', '[]'), - (b'[\x80\xff]', 'replace', '[\ufffd\ufffd]'), - (b'[\x80\xff]', 'surrogateescape', '[\udc80\udcff]'), - (b'[\x80\xff]', 'backslashreplace', '[\\x80\\xff]'), - ): - with self.subTest(data=data, error_handler=error_handler, - expected=expected): - self.assertEqual(data.decode('ascii', error_handler), - expected) - - - class Latin1Test(unittest.TestCase): - def test_encode(self): - for data, expected in ( - ('abc', b'abc'), - ('\x80\xe9\xff', b'\x80\xe9\xff'), - ): - with self.subTest(data=data, expected=expected): - self.assertEqual(data.encode('latin1'), expected) - - def test_encode_errors(self): - for data, error_handler, expected in ( - ('[\u20ac\udc80]', 'ignore', b'[]'), - ('[\u20ac\udc80]', 'replace', b'[??]'), - ('[\u20ac\U000abcde]', 'backslashreplace', - b'[\\u20ac\\U000abcde]'), - ('[\u20ac\udc80]', 'xmlcharrefreplace', b'[€�]'), - ('[\udc80\udcff]', 'surrogateescape', b'[\x80\xff]'), - ): - with self.subTest(data=data, error_handler=error_handler, - expected=expected): - self.assertEqual(data.encode('latin1', error_handler), - expected) - - def test_encode_surrogateescape_error(self): - with self.assertRaises(UnicodeEncodeError): - # the first character can be decoded, but not the second - '\udc80\u20ac'.encode('latin1', 'surrogateescape') - - def test_decode(self): - for data, expected in ( - (b'abc', 'abc'), - (b'[\x80\xff]', '[\x80\xff]'), - ): - with self.subTest(data=data, expected=expected): - self.assertEqual(data.decode('latin1'), expected) - - - class StreamRecoderTest(unittest.TestCase): - def test_writelines(self): - bio = io.BytesIO() - codec = codecs.lookup('ascii') - sr = codecs.StreamRecoder(bio, codec.encode, codec.decode, - encodings.ascii.StreamReader, encodings.ascii.StreamWriter) - sr.writelines([b'a', b'b']) - self.assertEqual(bio.getvalue(), b'ab') - - def test_write(self): - bio = io.BytesIO() - codec = codecs.lookup('latin1') - # Recode from Latin-1 to utf-8. - sr = codecs.StreamRecoder(bio, codec.encode, codec.decode, - encodings.utf_8.StreamReader, encodings.utf_8.StreamWriter) - - text = 'àñé' - sr.write(text.encode('latin1')) - self.assertEqual(bio.getvalue(), text.encode('utf-8')) - - def test_seeking_read(self): - bio = io.BytesIO('line1\nline2\nline3\n'.encode('utf-16-le')) - sr = codecs.EncodedFile(bio, 'utf-8', 'utf-16-le') - - self.assertEqual(sr.readline(), b'line1\n') - sr.seek(0) - self.assertEqual(sr.readline(), b'line1\n') - self.assertEqual(sr.readline(), b'line2\n') - self.assertEqual(sr.readline(), b'line3\n') - self.assertEqual(sr.readline(), b'') - - def test_seeking_write(self): - bio = io.BytesIO('123456789\n'.encode('utf-16-le')) - sr = codecs.EncodedFile(bio, 'utf-8', 'utf-16-le') - - # Test that seek() only resets its internal buffer when offset - # and whence are zero. - sr.seek(2) - sr.write(b'\nabc\n') - self.assertEqual(sr.readline(), b'789\n') - sr.seek(0) - self.assertEqual(sr.readline(), b'1\n') - self.assertEqual(sr.readline(), b'abc\n') - self.assertEqual(sr.readline(), b'789\n') - - - @unittest.skipIf(_testcapi is None, 'need _testcapi module') - class LocaleCodecTest(unittest.TestCase): - """ - Test indirectly _Py_DecodeUTF8Ex() and _Py_EncodeUTF8Ex(). - """ - ENCODING = sys.getfilesystemencoding() - STRINGS = ("ascii", "ulatin1:\xa7\xe9", - "u255:\xff", - "UCS:\xe9\u20ac\U0010ffff", - "surrogates:\uDC80\uDCFF") - BYTES_STRINGS = (b"blatin1:\xa7\xe9", b"b255:\xff") - SURROGATES = "\uDC80\uDCFF" - - def encode(self, text, errors="strict"): - return _testcapi.EncodeLocaleEx(text, 0, errors) - - def check_encode_strings(self, errors): - for text in self.STRINGS: - with self.subTest(text=text): - try: - expected = text.encode(self.ENCODING, errors) - except UnicodeEncodeError: - with self.assertRaises(RuntimeError) as cm: - self.encode(text, errors) - errmsg = str(cm.exception) - self.assertRegex(errmsg, r"encode error: pos=[0-9]+, reason=") - else: - encoded = self.encode(text, errors) - self.assertEqual(encoded, expected) - - def test_encode_strict(self): - self.check_encode_strings("strict") - - def test_encode_surrogateescape(self): - self.check_encode_strings("surrogateescape") - - def test_encode_surrogatepass(self): - try: - self.encode('', 'surrogatepass') - except ValueError as exc: - if str(exc) == 'unsupported error handler': - self.skipTest(f"{self.ENCODING!r} encoder doesn't support " - f"surrogatepass error handler") - else: - raise - - self.check_encode_strings("surrogatepass") - - def test_encode_unsupported_error_handler(self): - with self.assertRaises(ValueError) as cm: - self.encode('', 'backslashreplace') - self.assertEqual(str(cm.exception), 'unsupported error handler') - - def decode(self, encoded, errors="strict"): - return _testcapi.DecodeLocaleEx(encoded, 0, errors) - - def check_decode_strings(self, errors): - is_utf8 = (self.ENCODING == "utf-8") - if is_utf8: - encode_errors = 'surrogateescape' - else: - encode_errors = 'strict' - - strings = list(self.BYTES_STRINGS) - for text in self.STRINGS: - try: - encoded = text.encode(self.ENCODING, encode_errors) - if encoded not in strings: - strings.append(encoded) - except UnicodeEncodeError: - encoded = None - - if is_utf8: - encoded2 = text.encode(self.ENCODING, 'surrogatepass') - if encoded2 != encoded: - strings.append(encoded2) - - for encoded in strings: - with self.subTest(encoded=encoded): - try: - expected = encoded.decode(self.ENCODING, errors) - except UnicodeDecodeError: - with self.assertRaises(RuntimeError) as cm: - self.decode(encoded, errors) - errmsg = str(cm.exception) - self.assertTrue(errmsg.startswith("decode error: "), errmsg) - else: - decoded = self.decode(encoded, errors) - self.assertEqual(decoded, expected) - - def test_decode_strict(self): - self.check_decode_strings("strict") - - def test_decode_surrogateescape(self): - self.check_decode_strings("surrogateescape") - - def test_decode_surrogatepass(self): - try: - self.decode(b'', 'surrogatepass') - except ValueError as exc: - if str(exc) == 'unsupported error handler': - self.skipTest(f"{self.ENCODING!r} decoder doesn't support " - f"surrogatepass error handler") - else: - raise - - self.check_decode_strings("surrogatepass") - - def test_decode_unsupported_error_handler(self): - with self.assertRaises(ValueError) as cm: - self.decode(b'', 'backslashreplace') - self.assertEqual(str(cm.exception), 'unsupported error handler') - - - class Rot13Test(unittest.TestCase): - """Test the educational ROT-13 codec.""" - def test_encode(self): - ciphertext = codecs.encode("Caesar liked ciphers", 'rot-13') - self.assertEqual(ciphertext, 'Pnrfne yvxrq pvcuref') - - def test_decode(self): - plaintext = codecs.decode('Rg gh, Oehgr?', 'rot-13') - self.assertEqual(plaintext, 'Et tu, Brute?') - - def test_incremental_encode(self): - encoder = codecs.getincrementalencoder('rot-13')() - ciphertext = encoder.encode('ABBA nag Cheryl Baker') - self.assertEqual(ciphertext, 'NOON ant Purely Onxre') - - def test_incremental_decode(self): - decoder = codecs.getincrementaldecoder('rot-13')() - plaintext = decoder.decode('terra Ares envy tha') - self.assertEqual(plaintext, 'green Nerf rail gun') - - - class Rot13UtilTest(unittest.TestCase): - """Test the ROT-13 codec via rot13 function, - i.e. the user has done something like: - $ echo "Hello World" | python -m encodings.rot_13 - """ - def test_rot13_func(self): - infile = io.StringIO('Gb or, be abg gb or, gung vf gur dhrfgvba') - outfile = io.StringIO() - encodings.rot_13.rot13(infile, outfile) - outfile.seek(0) - plain_text = outfile.read() - self.assertEqual( - plain_text, - 'To be, or not to be, that is the question') - - - if __name__ == "__main__": - unittest.main() diff --git a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_codeop.yaml b/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_codeop.yaml deleted file mode 100644 index 701c890aa..000000000 --- a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_codeop.yaml +++ /dev/null @@ -1,315 +0,0 @@ -python: | - """ - Test cases for codeop.py - Nick Mathewson - """ - import unittest - import warnings - from test import support - - from codeop import compile_command, PyCF_DONT_IMPLY_DEDENT - import io - - if support.is_jython: - import sys - - def unify_callables(d): - for n,v in d.items(): - if hasattr(v, '__call__'): - d[n] = True - return d - - class CodeopTests(unittest.TestCase): - - def assertValid(self, str, symbol='single'): - '''succeed iff str is a valid piece of code''' - if support.is_jython: - code = compile_command(str, "", symbol) - self.assertTrue(code) - if symbol == "single": - d,r = {},{} - saved_stdout = sys.stdout - sys.stdout = io.StringIO() - try: - exec(code, d) - exec(compile(str,"","single"), r) - finally: - sys.stdout = saved_stdout - elif symbol == 'eval': - ctx = {'a': 2} - d = { 'value': eval(code,ctx) } - r = { 'value': eval(str,ctx) } - self.assertEqual(unify_callables(r),unify_callables(d)) - else: - expected = compile(str, "", symbol, PyCF_DONT_IMPLY_DEDENT) - self.assertEqual(compile_command(str, "", symbol), expected) - - def assertIncomplete(self, str, symbol='single'): - '''succeed iff str is the start of a valid piece of code''' - self.assertEqual(compile_command(str, symbol=symbol), None) - - def assertInvalid(self, str, symbol='single', is_syntax=1): - '''succeed iff str is the start of an invalid piece of code''' - try: - compile_command(str,symbol=symbol) - self.fail("No exception raised for invalid code") - except SyntaxError: - self.assertTrue(is_syntax) - except OverflowError: - self.assertTrue(not is_syntax) - - def test_valid(self): - av = self.assertValid - - # special case - if not support.is_jython: - self.assertEqual(compile_command(""), - compile("pass", "", 'single', - PyCF_DONT_IMPLY_DEDENT)) - self.assertEqual(compile_command("\n"), - compile("pass", "", 'single', - PyCF_DONT_IMPLY_DEDENT)) - else: - av("") - av("\n") - - av("a = 1") - av("\na = 1") - av("a = 1\n") - av("a = 1\n\n") - av("\n\na = 1\n\n") - - av("def x():\n pass\n") - av("if 1:\n pass\n") - - av("\n\nif 1: pass\n") - av("\n\nif 1: pass\n\n") - - av("def x():\n\n pass\n") - av("def x():\n pass\n \n") - av("def x():\n pass\n \n") - - av("pass\n") - av("3**3\n") - - av("if 9==3:\n pass\nelse:\n pass\n") - av("if 1:\n pass\n if 1:\n pass\n else:\n pass\n") - - av("#a\n#b\na = 3\n") - av("#a\n\n \na=3\n") - av("a=3\n\n") - av("a = 9+ \\\n3") - - av("3**3","eval") - av("(lambda z: \n z**3)","eval") - - av("9+ \\\n3","eval") - av("9+ \\\n3\n","eval") - - av("\n\na**3","eval") - av("\n \na**3","eval") - av("#a\n#b\na**3","eval") - - av("\n\na = 1\n\n") - av("\n\nif 1: a=1\n\n") - - av("if 1:\n pass\n if 1:\n pass\n else:\n pass\n") - av("#a\n\n \na=3\n\n") - - av("\n\na**3","eval") - av("\n \na**3","eval") - av("#a\n#b\na**3","eval") - - av("def f():\n try: pass\n finally: [x for x in (1,2)]\n") - av("def f():\n pass\n#foo\n") - av("@a.b.c\ndef f():\n pass\n") - - def test_incomplete(self): - ai = self.assertIncomplete - - ai("(a **") - ai("(a,b,") - ai("(a,b,(") - ai("(a,b,(") - ai("a = (") - ai("a = {") - ai("b + {") - - ai("if 9==3:\n pass\nelse:") - ai("if 9==3:\n pass\nelse:\n") - ai("if 9==3:\n pass\nelse:\n pass") - ai("if 1:") - ai("if 1:\n") - ai("if 1:\n pass\n if 1:\n pass\n else:") - ai("if 1:\n pass\n if 1:\n pass\n else:\n") - ai("if 1:\n pass\n if 1:\n pass\n else:\n pass") - - ai("def x():") - ai("def x():\n") - ai("def x():\n\n") - - ai("def x():\n pass") - ai("def x():\n pass\n ") - ai("def x():\n pass\n ") - ai("\n\ndef x():\n pass") - - ai("a = 9+ \\") - ai("a = 'a\\") - ai("a = '''xy") - - ai("","eval") - ai("\n","eval") - ai("(","eval") - ai("(\n\n\n","eval") - ai("(9+","eval") - ai("9+ \\","eval") - ai("lambda z: \\","eval") - - ai("if True:\n if True:\n if True: \n") - - ai("@a(") - ai("@a(b") - ai("@a(b,") - ai("@a(b,c") - ai("@a(b,c,") - - ai("from a import (") - ai("from a import (b") - ai("from a import (b,") - ai("from a import (b,c") - ai("from a import (b,c,") - - ai("["); - ai("[a"); - ai("[a,"); - ai("[a,b"); - ai("[a,b,"); - - ai("{"); - ai("{a"); - ai("{a:"); - ai("{a:b"); - ai("{a:b,"); - ai("{a:b,c"); - ai("{a:b,c:"); - ai("{a:b,c:d"); - ai("{a:b,c:d,"); - - ai("a(") - ai("a(b") - ai("a(b,") - ai("a(b,c") - ai("a(b,c,") - - ai("a[") - ai("a[b") - ai("a[b,") - ai("a[b:") - ai("a[b:c") - ai("a[b:c:") - ai("a[b:c:d") - - ai("def a(") - ai("def a(b") - ai("def a(b,") - ai("def a(b,c") - ai("def a(b,c,") - - ai("(") - ai("(a") - ai("(a,") - ai("(a,b") - ai("(a,b,") - - ai("if a:\n pass\nelif b:") - ai("if a:\n pass\nelif b:\n pass\nelse:") - - ai("while a:") - ai("while a:\n pass\nelse:") - - ai("for a in b:") - ai("for a in b:\n pass\nelse:") - - ai("try:") - ai("try:\n pass\nexcept:") - ai("try:\n pass\nfinally:") - ai("try:\n pass\nexcept:\n pass\nfinally:") - - ai("with a:") - ai("with a as b:") - - ai("class a:") - ai("class a(") - ai("class a(b") - ai("class a(b,") - ai("class a():") - - ai("[x for") - ai("[x for x in") - ai("[x for x in (") - - ai("(x for") - ai("(x for x in") - ai("(x for x in (") - - def test_invalid(self): - ai = self.assertInvalid - ai("a b") - - ai("a @") - ai("a b @") - ai("a ** @") - - ai("a = ") - ai("a = 9 +") - - ai("def x():\n\npass\n") - - ai("\n\n if 1: pass\n\npass") - - ai("a = 9+ \\\n") - ai("a = 'a\\ ") - ai("a = 'a\\\n") - - ai("a = 1","eval") - ai("a = (","eval") - ai("]","eval") - ai("())","eval") - ai("[}","eval") - ai("9+","eval") - ai("lambda z:","eval") - ai("a b","eval") - - ai("return 2.3") - ai("if (a == 1 and b = 2): pass") - - ai("del 1") - ai("del (1,)") - ai("del [1]") - ai("del '1'") - - ai("[i for i in range(10)] = (1, 2, 3)") - - def test_filename(self): - self.assertEqual(compile_command("a = 1\n", "abc").co_filename, - compile("a = 1\n", "abc", 'single').co_filename) - self.assertNotEqual(compile_command("a = 1\n", "abc").co_filename, - compile("a = 1\n", "def", 'single').co_filename) - - def test_warning(self): - # Test that the warning is only returned once. - with support.check_warnings( - (".*literal", SyntaxWarning), - (".*invalid", DeprecationWarning), - ) as w: - compile_command(r"'\e' is 0") - self.assertEqual(len(w.warnings), 2) - - # bpo-41520: check SyntaxWarning treated as an SyntaxError - with warnings.catch_warnings(), self.assertRaises(SyntaxError): - warnings.simplefilter('error', SyntaxWarning) - compile_command('1 is 1', symbol='exec') - - - if __name__ == "__main__": - unittest.main() diff --git a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_collections.yaml b/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_collections.yaml deleted file mode 100644 index 7d6f26fb1..000000000 --- a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_collections.yaml +++ /dev/null @@ -1,2165 +0,0 @@ -python: | - """Unit tests for collections.py.""" - - import collections - import copy - import doctest - import inspect - import operator - import pickle - from random import choice, randrange - import string - import sys - from test import support - import types - import unittest - - from collections import namedtuple, Counter, OrderedDict, _count_elements - from collections import UserDict, UserString, UserList - from collections import ChainMap - from collections import deque - from collections.abc import Awaitable, Coroutine - from collections.abc import AsyncIterator, AsyncIterable, AsyncGenerator - from collections.abc import Hashable, Iterable, Iterator, Generator, Reversible - from collections.abc import Sized, Container, Callable, Collection - from collections.abc import Set, MutableSet - from collections.abc import Mapping, MutableMapping, KeysView, ItemsView, ValuesView - from collections.abc import Sequence, MutableSequence - from collections.abc import ByteString - - - class TestUserObjects(unittest.TestCase): - def _superset_test(self, a, b): - self.assertGreaterEqual( - set(dir(a)), - set(dir(b)), - '{a} should have all the methods of {b}'.format( - a=a.__name__, - b=b.__name__, - ), - ) - - def _copy_test(self, obj): - # Test internal copy - obj_copy = obj.copy() - self.assertIsNot(obj.data, obj_copy.data) - self.assertEqual(obj.data, obj_copy.data) - - # Test copy.copy - obj.test = [1234] # Make sure instance vars are also copied. - obj_copy = copy.copy(obj) - self.assertIsNot(obj.data, obj_copy.data) - self.assertEqual(obj.data, obj_copy.data) - self.assertIs(obj.test, obj_copy.test) - - def test_str_protocol(self): - self._superset_test(UserString, str) - - def test_list_protocol(self): - self._superset_test(UserList, list) - - def test_dict_protocol(self): - self._superset_test(UserDict, dict) - - def test_list_copy(self): - obj = UserList() - obj.append(123) - self._copy_test(obj) - - def test_dict_copy(self): - obj = UserDict() - obj[123] = "abc" - self._copy_test(obj) - - - ################################################################################ - ### ChainMap (helper class for configparser and the string module) - ################################################################################ - - class TestChainMap(unittest.TestCase): - - def test_basics(self): - c = ChainMap() - c['a'] = 1 - c['b'] = 2 - d = c.new_child() - d['b'] = 20 - d['c'] = 30 - self.assertEqual(d.maps, [{'b':20, 'c':30}, {'a':1, 'b':2}]) # check internal state - self.assertEqual(d.items(), dict(a=1, b=20, c=30).items()) # check items/iter/getitem - self.assertEqual(len(d), 3) # check len - for key in 'abc': # check contains - self.assertIn(key, d) - for k, v in dict(a=1, b=20, c=30, z=100).items(): # check get - self.assertEqual(d.get(k, 100), v) - - del d['b'] # unmask a value - self.assertEqual(d.maps, [{'c':30}, {'a':1, 'b':2}]) # check internal state - self.assertEqual(d.items(), dict(a=1, b=2, c=30).items()) # check items/iter/getitem - self.assertEqual(len(d), 3) # check len - for key in 'abc': # check contains - self.assertIn(key, d) - for k, v in dict(a=1, b=2, c=30, z=100).items(): # check get - self.assertEqual(d.get(k, 100), v) - self.assertIn(repr(d), [ # check repr - type(d).__name__ + "({'c': 30}, {'a': 1, 'b': 2})", - type(d).__name__ + "({'c': 30}, {'b': 2, 'a': 1})" - ]) - - for e in d.copy(), copy.copy(d): # check shallow copies - self.assertEqual(d, e) - self.assertEqual(d.maps, e.maps) - self.assertIsNot(d, e) - self.assertIsNot(d.maps[0], e.maps[0]) - for m1, m2 in zip(d.maps[1:], e.maps[1:]): - self.assertIs(m1, m2) - - # check deep copies - for proto in range(pickle.HIGHEST_PROTOCOL + 1): - e = pickle.loads(pickle.dumps(d, proto)) - self.assertEqual(d, e) - self.assertEqual(d.maps, e.maps) - self.assertIsNot(d, e) - for m1, m2 in zip(d.maps, e.maps): - self.assertIsNot(m1, m2, e) - for e in [copy.deepcopy(d), - eval(repr(d)) - ]: - self.assertEqual(d, e) - self.assertEqual(d.maps, e.maps) - self.assertIsNot(d, e) - for m1, m2 in zip(d.maps, e.maps): - self.assertIsNot(m1, m2, e) - - f = d.new_child() - f['b'] = 5 - self.assertEqual(f.maps, [{'b': 5}, {'c':30}, {'a':1, 'b':2}]) - self.assertEqual(f.parents.maps, [{'c':30}, {'a':1, 'b':2}]) # check parents - self.assertEqual(f['b'], 5) # find first in chain - self.assertEqual(f.parents['b'], 2) # look beyond maps[0] - - def test_ordering(self): - # Combined order matches a series of dict updates from last to first. - # This test relies on the ordering of the underlying dicts. - - baseline = {'music': 'bach', 'art': 'rembrandt'} - adjustments = {'art': 'van gogh', 'opera': 'carmen'} - - cm = ChainMap(adjustments, baseline) - - combined = baseline.copy() - combined.update(adjustments) - - self.assertEqual(list(combined.items()), list(cm.items())) - - def test_constructor(self): - self.assertEqual(ChainMap().maps, [{}]) # no-args --> one new dict - self.assertEqual(ChainMap({1:2}).maps, [{1:2}]) # 1 arg --> list - - def test_bool(self): - self.assertFalse(ChainMap()) - self.assertFalse(ChainMap({}, {})) - self.assertTrue(ChainMap({1:2}, {})) - self.assertTrue(ChainMap({}, {1:2})) - - def test_missing(self): - class DefaultChainMap(ChainMap): - def __missing__(self, key): - return 999 - d = DefaultChainMap(dict(a=1, b=2), dict(b=20, c=30)) - for k, v in dict(a=1, b=2, c=30, d=999).items(): - self.assertEqual(d[k], v) # check __getitem__ w/missing - for k, v in dict(a=1, b=2, c=30, d=77).items(): - self.assertEqual(d.get(k, 77), v) # check get() w/ missing - for k, v in dict(a=True, b=True, c=True, d=False).items(): - self.assertEqual(k in d, v) # check __contains__ w/missing - self.assertEqual(d.pop('a', 1001), 1, d) - self.assertEqual(d.pop('a', 1002), 1002) # check pop() w/missing - self.assertEqual(d.popitem(), ('b', 2)) # check popitem() w/missing - with self.assertRaises(KeyError): - d.popitem() - - def test_order_preservation(self): - d = ChainMap( - OrderedDict(j=0, h=88888), - OrderedDict(), - OrderedDict(i=9999, d=4444, c=3333), - OrderedDict(f=666, b=222, g=777, c=333, h=888), - OrderedDict(), - OrderedDict(e=55, b=22), - OrderedDict(a=1, b=2, c=3, d=4, e=5), - OrderedDict(), - ) - self.assertEqual(''.join(d), 'abcdefghij') - self.assertEqual(list(d.items()), - [('a', 1), ('b', 222), ('c', 3333), ('d', 4444), - ('e', 55), ('f', 666), ('g', 777), ('h', 88888), - ('i', 9999), ('j', 0)]) - - def test_dict_coercion(self): - d = ChainMap(dict(a=1, b=2), dict(b=20, c=30)) - self.assertEqual(dict(d), dict(a=1, b=2, c=30)) - self.assertEqual(dict(d.items()), dict(a=1, b=2, c=30)) - - def test_new_child(self): - 'Tests for changes for issue #16613.' - c = ChainMap() - c['a'] = 1 - c['b'] = 2 - m = {'b':20, 'c': 30} - d = c.new_child(m) - self.assertEqual(d.maps, [{'b':20, 'c':30}, {'a':1, 'b':2}]) # check internal state - self.assertIs(m, d.maps[0]) - - # Use a different map than a dict - class lowerdict(dict): - def __getitem__(self, key): - if isinstance(key, str): - key = key.lower() - return dict.__getitem__(self, key) - def __contains__(self, key): - if isinstance(key, str): - key = key.lower() - return dict.__contains__(self, key) - - c = ChainMap() - c['a'] = 1 - c['b'] = 2 - m = lowerdict(b=20, c=30) - d = c.new_child(m) - self.assertIs(m, d.maps[0]) - for key in 'abc': # check contains - self.assertIn(key, d) - for k, v in dict(a=1, B=20, C=30, z=100).items(): # check get - self.assertEqual(d.get(k, 100), v) - - - ################################################################################ - ### Named Tuples - ################################################################################ - - TestNT = namedtuple('TestNT', 'x y z') # type used for pickle tests - - class TestNamedTuple(unittest.TestCase): - - def test_factory(self): - Point = namedtuple('Point', 'x y') - self.assertEqual(Point.__name__, 'Point') - self.assertEqual(Point.__slots__, ()) - self.assertEqual(Point.__module__, __name__) - self.assertEqual(Point.__getitem__, tuple.__getitem__) - self.assertEqual(Point._fields, ('x', 'y')) - - self.assertRaises(ValueError, namedtuple, 'abc%', 'efg ghi') # type has non-alpha char - self.assertRaises(ValueError, namedtuple, 'class', 'efg ghi') # type has keyword - self.assertRaises(ValueError, namedtuple, '9abc', 'efg ghi') # type starts with digit - - self.assertRaises(ValueError, namedtuple, 'abc', 'efg g%hi') # field with non-alpha char - self.assertRaises(ValueError, namedtuple, 'abc', 'abc class') # field has keyword - self.assertRaises(ValueError, namedtuple, 'abc', '8efg 9ghi') # field starts with digit - self.assertRaises(ValueError, namedtuple, 'abc', '_efg ghi') # field with leading underscore - self.assertRaises(ValueError, namedtuple, 'abc', 'efg efg ghi') # duplicate field - - namedtuple('Point0', 'x1 y2') # Verify that numbers are allowed in names - namedtuple('_', 'a b c') # Test leading underscores in a typename - - nt = namedtuple('nt', 'the quick brown fox') # check unicode input - self.assertNotIn("u'", repr(nt._fields)) - nt = namedtuple('nt', ('the', 'quick')) # check unicode input - self.assertNotIn("u'", repr(nt._fields)) - - self.assertRaises(TypeError, Point._make, [11]) # catch too few args - self.assertRaises(TypeError, Point._make, [11, 22, 33]) # catch too many args - - def test_defaults(self): - Point = namedtuple('Point', 'x y', defaults=(10, 20)) # 2 defaults - self.assertEqual(Point._field_defaults, {'x': 10, 'y': 20}) - self.assertEqual(Point(1, 2), (1, 2)) - self.assertEqual(Point(1), (1, 20)) - self.assertEqual(Point(), (10, 20)) - - Point = namedtuple('Point', 'x y', defaults=(20,)) # 1 default - self.assertEqual(Point._field_defaults, {'y': 20}) - self.assertEqual(Point(1, 2), (1, 2)) - self.assertEqual(Point(1), (1, 20)) - - Point = namedtuple('Point', 'x y', defaults=()) # 0 defaults - self.assertEqual(Point._field_defaults, {}) - self.assertEqual(Point(1, 2), (1, 2)) - with self.assertRaises(TypeError): - Point(1) - - with self.assertRaises(TypeError): # catch too few args - Point() - with self.assertRaises(TypeError): # catch too many args - Point(1, 2, 3) - with self.assertRaises(TypeError): # too many defaults - Point = namedtuple('Point', 'x y', defaults=(10, 20, 30)) - with self.assertRaises(TypeError): # non-iterable defaults - Point = namedtuple('Point', 'x y', defaults=10) - with self.assertRaises(TypeError): # another non-iterable default - Point = namedtuple('Point', 'x y', defaults=False) - - Point = namedtuple('Point', 'x y', defaults=None) # default is None - self.assertEqual(Point._field_defaults, {}) - self.assertIsNone(Point.__new__.__defaults__, None) - self.assertEqual(Point(10, 20), (10, 20)) - with self.assertRaises(TypeError): # catch too few args - Point(10) - - Point = namedtuple('Point', 'x y', defaults=[10, 20]) # allow non-tuple iterable - self.assertEqual(Point._field_defaults, {'x': 10, 'y': 20}) - self.assertEqual(Point.__new__.__defaults__, (10, 20)) - self.assertEqual(Point(1, 2), (1, 2)) - self.assertEqual(Point(1), (1, 20)) - self.assertEqual(Point(), (10, 20)) - - Point = namedtuple('Point', 'x y', defaults=iter([10, 20])) # allow plain iterator - self.assertEqual(Point._field_defaults, {'x': 10, 'y': 20}) - self.assertEqual(Point.__new__.__defaults__, (10, 20)) - self.assertEqual(Point(1, 2), (1, 2)) - self.assertEqual(Point(1), (1, 20)) - self.assertEqual(Point(), (10, 20)) - - def test_readonly(self): - Point = namedtuple('Point', 'x y') - p = Point(11, 22) - with self.assertRaises(AttributeError): - p.x = 33 - with self.assertRaises(AttributeError): - del p.x - with self.assertRaises(TypeError): - p[0] = 33 - with self.assertRaises(TypeError): - del p[0] - self.assertEqual(p.x, 11) - self.assertEqual(p[0], 11) - - @unittest.skipIf(sys.flags.optimize >= 2, - "Docstrings are omitted with -O2 and above") - def test_factory_doc_attr(self): - Point = namedtuple('Point', 'x y') - self.assertEqual(Point.__doc__, 'Point(x, y)') - Point.__doc__ = '2D point' - self.assertEqual(Point.__doc__, '2D point') - - @unittest.skipIf(sys.flags.optimize >= 2, - "Docstrings are omitted with -O2 and above") - def test_field_doc(self): - Point = namedtuple('Point', 'x y') - self.assertEqual(Point.x.__doc__, 'Alias for field number 0') - self.assertEqual(Point.y.__doc__, 'Alias for field number 1') - Point.x.__doc__ = 'docstring for Point.x' - self.assertEqual(Point.x.__doc__, 'docstring for Point.x') - # namedtuple can mutate doc of descriptors independently - Vector = namedtuple('Vector', 'x y') - self.assertEqual(Vector.x.__doc__, 'Alias for field number 0') - Vector.x.__doc__ = 'docstring for Vector.x' - self.assertEqual(Vector.x.__doc__, 'docstring for Vector.x') - - @support.cpython_only - @unittest.skipIf(sys.flags.optimize >= 2, - "Docstrings are omitted with -O2 and above") - def test_field_doc_reuse(self): - P = namedtuple('P', ['m', 'n']) - Q = namedtuple('Q', ['o', 'p']) - self.assertIs(P.m.__doc__, Q.o.__doc__) - self.assertIs(P.n.__doc__, Q.p.__doc__) - - def test_name_fixer(self): - for spec, renamed in [ - [('efg', 'g%hi'), ('efg', '_1')], # field with non-alpha char - [('abc', 'class'), ('abc', '_1')], # field has keyword - [('8efg', '9ghi'), ('_0', '_1')], # field starts with digit - [('abc', '_efg'), ('abc', '_1')], # field with leading underscore - [('abc', 'efg', 'efg', 'ghi'), ('abc', 'efg', '_2', 'ghi')], # duplicate field - [('abc', '', 'x'), ('abc', '_1', 'x')], # fieldname is a space - ]: - self.assertEqual(namedtuple('NT', spec, rename=True)._fields, renamed) - - def test_module_parameter(self): - NT = namedtuple('NT', ['x', 'y'], module=collections) - self.assertEqual(NT.__module__, collections) - - def test_instance(self): - Point = namedtuple('Point', 'x y') - p = Point(11, 22) - self.assertEqual(p, Point(x=11, y=22)) - self.assertEqual(p, Point(11, y=22)) - self.assertEqual(p, Point(y=22, x=11)) - self.assertEqual(p, Point(*(11, 22))) - self.assertEqual(p, Point(**dict(x=11, y=22))) - self.assertRaises(TypeError, Point, 1) # too few args - self.assertRaises(TypeError, Point, 1, 2, 3) # too many args - with self.assertRaises(TypeError): # wrong keyword argument - Point(XXX=1, y=2) - with self.assertRaises(TypeError): # missing keyword argument - Point(x=1) - self.assertEqual(repr(p), 'Point(x=11, y=22)') - self.assertNotIn('__weakref__', dir(p)) - self.assertEqual(p, Point._make([11, 22])) # test _make classmethod - self.assertEqual(p._fields, ('x', 'y')) # test _fields attribute - self.assertEqual(p._replace(x=1), (1, 22)) # test _replace method - self.assertEqual(p._asdict(), dict(x=11, y=22)) # test _asdict method - - try: - p._replace(x=1, error=2) - except ValueError: - pass - else: - self._fail('Did not detect an incorrect fieldname') - - # verify that field string can have commas - Point = namedtuple('Point', 'x, y') - p = Point(x=11, y=22) - self.assertEqual(repr(p), 'Point(x=11, y=22)') - - # verify that fieldspec can be a non-string sequence - Point = namedtuple('Point', ('x', 'y')) - p = Point(x=11, y=22) - self.assertEqual(repr(p), 'Point(x=11, y=22)') - - def test_tupleness(self): - Point = namedtuple('Point', 'x y') - p = Point(11, 22) - - self.assertIsInstance(p, tuple) - self.assertEqual(p, (11, 22)) # matches a real tuple - self.assertEqual(tuple(p), (11, 22)) # coercable to a real tuple - self.assertEqual(list(p), [11, 22]) # coercable to a list - self.assertEqual(max(p), 22) # iterable - self.assertEqual(max(*p), 22) # star-able - x, y = p - self.assertEqual(p, (x, y)) # unpacks like a tuple - self.assertEqual((p[0], p[1]), (11, 22)) # indexable like a tuple - with self.assertRaises(IndexError): - p[3] - self.assertEqual(p[-1], 22) - self.assertEqual(hash(p), hash((11, 22))) - - self.assertEqual(p.x, x) - self.assertEqual(p.y, y) - with self.assertRaises(AttributeError): - p.z - - def test_odd_sizes(self): - Zero = namedtuple('Zero', '') - self.assertEqual(Zero(), ()) - self.assertEqual(Zero._make([]), ()) - self.assertEqual(repr(Zero()), 'Zero()') - self.assertEqual(Zero()._asdict(), {}) - self.assertEqual(Zero()._fields, ()) - - Dot = namedtuple('Dot', 'd') - self.assertEqual(Dot(1), (1,)) - self.assertEqual(Dot._make([1]), (1,)) - self.assertEqual(Dot(1).d, 1) - self.assertEqual(repr(Dot(1)), 'Dot(d=1)') - self.assertEqual(Dot(1)._asdict(), {'d':1}) - self.assertEqual(Dot(1)._replace(d=999), (999,)) - self.assertEqual(Dot(1)._fields, ('d',)) - - n = 5000 - names = list(set(''.join([choice(string.ascii_letters) - for j in range(10)]) for i in range(n))) - n = len(names) - Big = namedtuple('Big', names) - b = Big(*range(n)) - self.assertEqual(b, tuple(range(n))) - self.assertEqual(Big._make(range(n)), tuple(range(n))) - for pos, name in enumerate(names): - self.assertEqual(getattr(b, name), pos) - repr(b) # make sure repr() doesn't blow-up - d = b._asdict() - d_expected = dict(zip(names, range(n))) - self.assertEqual(d, d_expected) - b2 = b._replace(**dict([(names[1], 999),(names[-5], 42)])) - b2_expected = list(range(n)) - b2_expected[1] = 999 - b2_expected[-5] = 42 - self.assertEqual(b2, tuple(b2_expected)) - self.assertEqual(b._fields, tuple(names)) - - def test_pickle(self): - p = TestNT(x=10, y=20, z=30) - for module in (pickle,): - loads = getattr(module, 'loads') - dumps = getattr(module, 'dumps') - for protocol in range(-1, module.HIGHEST_PROTOCOL + 1): - q = loads(dumps(p, protocol)) - self.assertEqual(p, q) - self.assertEqual(p._fields, q._fields) - self.assertNotIn(b'OrderedDict', dumps(p, protocol)) - - def test_copy(self): - p = TestNT(x=10, y=20, z=30) - for copier in copy.copy, copy.deepcopy: - q = copier(p) - self.assertEqual(p, q) - self.assertEqual(p._fields, q._fields) - - def test_name_conflicts(self): - # Some names like "self", "cls", "tuple", "itemgetter", and "property" - # failed when used as field names. Test to make sure these now work. - T = namedtuple('T', 'itemgetter property self cls tuple') - t = T(1, 2, 3, 4, 5) - self.assertEqual(t, (1,2,3,4,5)) - newt = t._replace(itemgetter=10, property=20, self=30, cls=40, tuple=50) - self.assertEqual(newt, (10,20,30,40,50)) - - # Broader test of all interesting names taken from the code, old - # template, and an example - words = {'Alias', 'At', 'AttributeError', 'Build', 'Bypass', 'Create', - 'Encountered', 'Expected', 'Field', 'For', 'Got', 'Helper', - 'IronPython', 'Jython', 'KeyError', 'Make', 'Modify', 'Note', - 'OrderedDict', 'Point', 'Return', 'Returns', 'Type', 'TypeError', - 'Used', 'Validate', 'ValueError', 'Variables', 'a', 'accessible', 'add', - 'added', 'all', 'also', 'an', 'arg_list', 'args', 'arguments', - 'automatically', 'be', 'build', 'builtins', 'but', 'by', 'cannot', - 'class_namespace', 'classmethod', 'cls', 'collections', 'convert', - 'copy', 'created', 'creation', 'd', 'debugging', 'defined', 'dict', - 'dictionary', 'doc', 'docstring', 'docstrings', 'duplicate', 'effect', - 'either', 'enumerate', 'environments', 'error', 'example', 'exec', 'f', - 'f_globals', 'field', 'field_names', 'fields', 'formatted', 'frame', - 'function', 'functions', 'generate', 'get', 'getter', 'got', 'greater', - 'has', 'help', 'identifiers', 'index', 'indexable', 'instance', - 'instantiate', 'interning', 'introspection', 'isidentifier', - 'isinstance', 'itemgetter', 'iterable', 'join', 'keyword', 'keywords', - 'kwds', 'len', 'like', 'list', 'map', 'maps', 'message', 'metadata', - 'method', 'methods', 'module', 'module_name', 'must', 'name', 'named', - 'namedtuple', 'namedtuple_', 'names', 'namespace', 'needs', 'new', - 'nicely', 'num_fields', 'number', 'object', 'of', 'operator', 'option', - 'p', 'particular', 'pickle', 'pickling', 'plain', 'pop', 'positional', - 'property', 'r', 'regular', 'rename', 'replace', 'replacing', 'repr', - 'repr_fmt', 'representation', 'result', 'reuse_itemgetter', 's', 'seen', - 'self', 'sequence', 'set', 'side', 'specified', 'split', 'start', - 'startswith', 'step', 'str', 'string', 'strings', 'subclass', 'sys', - 'targets', 'than', 'the', 'their', 'this', 'to', 'tuple', 'tuple_new', - 'type', 'typename', 'underscore', 'unexpected', 'unpack', 'up', 'use', - 'used', 'user', 'valid', 'values', 'variable', 'verbose', 'where', - 'which', 'work', 'x', 'y', 'z', 'zip'} - T = namedtuple('T', words) - # test __new__ - values = tuple(range(len(words))) - t = T(*values) - self.assertEqual(t, values) - t = T(**dict(zip(T._fields, values))) - self.assertEqual(t, values) - # test _make - t = T._make(values) - self.assertEqual(t, values) - # exercise __repr__ - repr(t) - # test _asdict - self.assertEqual(t._asdict(), dict(zip(T._fields, values))) - # test _replace - t = T._make(values) - newvalues = tuple(v*10 for v in values) - newt = t._replace(**dict(zip(T._fields, newvalues))) - self.assertEqual(newt, newvalues) - # test _fields - self.assertEqual(T._fields, tuple(words)) - # test __getnewargs__ - self.assertEqual(t.__getnewargs__(), values) - - def test_repr(self): - A = namedtuple('A', 'x') - self.assertEqual(repr(A(1)), 'A(x=1)') - # repr should show the name of the subclass - class B(A): - pass - self.assertEqual(repr(B(1)), 'B(x=1)') - - def test_keyword_only_arguments(self): - # See issue 25628 - with self.assertRaises(TypeError): - NT = namedtuple('NT', ['x', 'y'], True) - - NT = namedtuple('NT', ['abc', 'def'], rename=True) - self.assertEqual(NT._fields, ('abc', '_1')) - with self.assertRaises(TypeError): - NT = namedtuple('NT', ['abc', 'def'], False, True) - - def test_namedtuple_subclass_issue_24931(self): - class Point(namedtuple('_Point', ['x', 'y'])): - pass - - a = Point(3, 4) - self.assertEqual(a._asdict(), OrderedDict([('x', 3), ('y', 4)])) - - a.w = 5 - self.assertEqual(a.__dict__, {'w': 5}) - - def test_field_descriptor(self): - Point = namedtuple('Point', 'x y') - p = Point(11, 22) - self.assertTrue(inspect.isdatadescriptor(Point.x)) - self.assertEqual(Point.x.__get__(p), 11) - self.assertRaises(AttributeError, Point.x.__set__, p, 33) - self.assertRaises(AttributeError, Point.x.__delete__, p) - - class NewPoint(tuple): - x = pickle.loads(pickle.dumps(Point.x)) - y = pickle.loads(pickle.dumps(Point.y)) - - np = NewPoint([1, 2]) - - self.assertEqual(np.x, 1) - self.assertEqual(np.y, 2) - - - ################################################################################ - ### Abstract Base Classes - ################################################################################ - - class ABCTestCase(unittest.TestCase): - - def validate_abstract_methods(self, abc, *names): - methodstubs = dict.fromkeys(names, lambda s, *args: 0) - - # everything should work will all required methods are present - C = type('C', (abc,), methodstubs) - C() - - # instantiation should fail if a required method is missing - for name in names: - stubs = methodstubs.copy() - del stubs[name] - C = type('C', (abc,), stubs) - self.assertRaises(TypeError, C, name) - - def validate_isinstance(self, abc, name): - stub = lambda s, *args: 0 - - C = type('C', (object,), {'__hash__': None}) - setattr(C, name, stub) - self.assertIsInstance(C(), abc) - self.assertTrue(issubclass(C, abc)) - - C = type('C', (object,), {'__hash__': None}) - self.assertNotIsInstance(C(), abc) - self.assertFalse(issubclass(C, abc)) - - def validate_comparison(self, instance): - ops = ['lt', 'gt', 'le', 'ge', 'ne', 'or', 'and', 'xor', 'sub'] - operators = {} - for op in ops: - name = '__' + op + '__' - operators[name] = getattr(operator, name) - - class Other: - def __init__(self): - self.right_side = False - def __eq__(self, other): - self.right_side = True - return True - __lt__ = __eq__ - __gt__ = __eq__ - __le__ = __eq__ - __ge__ = __eq__ - __ne__ = __eq__ - __ror__ = __eq__ - __rand__ = __eq__ - __rxor__ = __eq__ - __rsub__ = __eq__ - - for name, op in operators.items(): - if not hasattr(instance, name): - continue - other = Other() - op(instance, other) - self.assertTrue(other.right_side,'Right side not called for %s.%s' - % (type(instance), name)) - - def _test_gen(): - yield - - class TestOneTrickPonyABCs(ABCTestCase): - - def test_Awaitable(self): - def gen(): - yield - - @types.coroutine - def coro(): - yield - - async def new_coro(): - pass - - class Bar: - def __await__(self): - yield - - class MinimalCoro(Coroutine): - def send(self, value): - return value - def throw(self, typ, val=None, tb=None): - super().throw(typ, val, tb) - def __await__(self): - yield - - non_samples = [None, int(), gen(), object()] - for x in non_samples: - self.assertNotIsInstance(x, Awaitable) - self.assertFalse(issubclass(type(x), Awaitable), repr(type(x))) - - samples = [Bar(), MinimalCoro()] - for x in samples: - self.assertIsInstance(x, Awaitable) - self.assertTrue(issubclass(type(x), Awaitable)) - - c = coro() - # Iterable coroutines (generators with CO_ITERABLE_COROUTINE - # flag don't have '__await__' method, hence can't be instances - # of Awaitable. Use inspect.isawaitable to detect them. - self.assertNotIsInstance(c, Awaitable) - - c = new_coro() - self.assertIsInstance(c, Awaitable) - c.close() # avoid RuntimeWarning that coro() was not awaited - - class CoroLike: pass - Coroutine.register(CoroLike) - self.assertTrue(isinstance(CoroLike(), Awaitable)) - self.assertTrue(issubclass(CoroLike, Awaitable)) - CoroLike = None - support.gc_collect() # Kill CoroLike to clean-up ABCMeta cache - - def test_Coroutine(self): - def gen(): - yield - - @types.coroutine - def coro(): - yield - - async def new_coro(): - pass - - class Bar: - def __await__(self): - yield - - class MinimalCoro(Coroutine): - def send(self, value): - return value - def throw(self, typ, val=None, tb=None): - super().throw(typ, val, tb) - def __await__(self): - yield - - non_samples = [None, int(), gen(), object(), Bar()] - for x in non_samples: - self.assertNotIsInstance(x, Coroutine) - self.assertFalse(issubclass(type(x), Coroutine), repr(type(x))) - - samples = [MinimalCoro()] - for x in samples: - self.assertIsInstance(x, Awaitable) - self.assertTrue(issubclass(type(x), Awaitable)) - - c = coro() - # Iterable coroutines (generators with CO_ITERABLE_COROUTINE - # flag don't have '__await__' method, hence can't be instances - # of Coroutine. Use inspect.isawaitable to detect them. - self.assertNotIsInstance(c, Coroutine) - - c = new_coro() - self.assertIsInstance(c, Coroutine) - c.close() # avoid RuntimeWarning that coro() was not awaited - - class CoroLike: - def send(self, value): - pass - def throw(self, typ, val=None, tb=None): - pass - def close(self): - pass - def __await__(self): - pass - self.assertTrue(isinstance(CoroLike(), Coroutine)) - self.assertTrue(issubclass(CoroLike, Coroutine)) - - class CoroLike: - def send(self, value): - pass - def close(self): - pass - def __await__(self): - pass - self.assertFalse(isinstance(CoroLike(), Coroutine)) - self.assertFalse(issubclass(CoroLike, Coroutine)) - - def test_Hashable(self): - # Check some non-hashables - non_samples = [bytearray(), list(), set(), dict()] - for x in non_samples: - self.assertNotIsInstance(x, Hashable) - self.assertFalse(issubclass(type(x), Hashable), repr(type(x))) - # Check some hashables - samples = [None, - int(), float(), complex(), - str(), - tuple(), frozenset(), - int, list, object, type, bytes() - ] - for x in samples: - self.assertIsInstance(x, Hashable) - self.assertTrue(issubclass(type(x), Hashable), repr(type(x))) - self.assertRaises(TypeError, Hashable) - # Check direct subclassing - class H(Hashable): - def __hash__(self): - return super().__hash__() - self.assertEqual(hash(H()), 0) - self.assertFalse(issubclass(int, H)) - self.validate_abstract_methods(Hashable, '__hash__') - self.validate_isinstance(Hashable, '__hash__') - - def test_AsyncIterable(self): - class AI: - def __aiter__(self): - return self - self.assertTrue(isinstance(AI(), AsyncIterable)) - self.assertTrue(issubclass(AI, AsyncIterable)) - # Check some non-iterables - non_samples = [None, object, []] - for x in non_samples: - self.assertNotIsInstance(x, AsyncIterable) - self.assertFalse(issubclass(type(x), AsyncIterable), repr(type(x))) - self.validate_abstract_methods(AsyncIterable, '__aiter__') - self.validate_isinstance(AsyncIterable, '__aiter__') - - def test_AsyncIterator(self): - class AI: - def __aiter__(self): - return self - async def __anext__(self): - raise StopAsyncIteration - self.assertTrue(isinstance(AI(), AsyncIterator)) - self.assertTrue(issubclass(AI, AsyncIterator)) - non_samples = [None, object, []] - # Check some non-iterables - for x in non_samples: - self.assertNotIsInstance(x, AsyncIterator) - self.assertFalse(issubclass(type(x), AsyncIterator), repr(type(x))) - # Similarly to regular iterators (see issue 10565) - class AnextOnly: - async def __anext__(self): - raise StopAsyncIteration - self.assertNotIsInstance(AnextOnly(), AsyncIterator) - self.validate_abstract_methods(AsyncIterator, '__anext__', '__aiter__') - - def test_Iterable(self): - # Check some non-iterables - non_samples = [None, 42, 3.14, 1j] - for x in non_samples: - self.assertNotIsInstance(x, Iterable) - self.assertFalse(issubclass(type(x), Iterable), repr(type(x))) - # Check some iterables - samples = [bytes(), str(), - tuple(), list(), set(), frozenset(), dict(), - dict().keys(), dict().items(), dict().values(), - _test_gen(), - (x for x in []), - ] - for x in samples: - self.assertIsInstance(x, Iterable) - self.assertTrue(issubclass(type(x), Iterable), repr(type(x))) - # Check direct subclassing - class I(Iterable): - def __iter__(self): - return super().__iter__() - self.assertEqual(list(I()), []) - self.assertFalse(issubclass(str, I)) - self.validate_abstract_methods(Iterable, '__iter__') - self.validate_isinstance(Iterable, '__iter__') - # Check None blocking - class It: - def __iter__(self): return iter([]) - class ItBlocked(It): - __iter__ = None - self.assertTrue(issubclass(It, Iterable)) - self.assertTrue(isinstance(It(), Iterable)) - self.assertFalse(issubclass(ItBlocked, Iterable)) - self.assertFalse(isinstance(ItBlocked(), Iterable)) - - def test_Reversible(self): - # Check some non-reversibles - non_samples = [None, 42, 3.14, 1j, set(), frozenset()] - for x in non_samples: - self.assertNotIsInstance(x, Reversible) - self.assertFalse(issubclass(type(x), Reversible), repr(type(x))) - # Check some non-reversible iterables - non_reversibles = [_test_gen(), (x for x in []), iter([]), reversed([])] - for x in non_reversibles: - self.assertNotIsInstance(x, Reversible) - self.assertFalse(issubclass(type(x), Reversible), repr(type(x))) - # Check some reversible iterables - samples = [bytes(), str(), tuple(), list(), OrderedDict(), - OrderedDict().keys(), OrderedDict().items(), - OrderedDict().values(), Counter(), Counter().keys(), - Counter().items(), Counter().values(), dict(), - dict().keys(), dict().items(), dict().values()] - for x in samples: - self.assertIsInstance(x, Reversible) - self.assertTrue(issubclass(type(x), Reversible), repr(type(x))) - # Check also Mapping, MutableMapping, and Sequence - self.assertTrue(issubclass(Sequence, Reversible), repr(Sequence)) - self.assertFalse(issubclass(Mapping, Reversible), repr(Mapping)) - self.assertFalse(issubclass(MutableMapping, Reversible), repr(MutableMapping)) - # Check direct subclassing - class R(Reversible): - def __iter__(self): - return iter(list()) - def __reversed__(self): - return iter(list()) - self.assertEqual(list(reversed(R())), []) - self.assertFalse(issubclass(float, R)) - self.validate_abstract_methods(Reversible, '__reversed__', '__iter__') - # Check reversible non-iterable (which is not Reversible) - class RevNoIter: - def __reversed__(self): return reversed([]) - class RevPlusIter(RevNoIter): - def __iter__(self): return iter([]) - self.assertFalse(issubclass(RevNoIter, Reversible)) - self.assertFalse(isinstance(RevNoIter(), Reversible)) - self.assertTrue(issubclass(RevPlusIter, Reversible)) - self.assertTrue(isinstance(RevPlusIter(), Reversible)) - # Check None blocking - class Rev: - def __iter__(self): return iter([]) - def __reversed__(self): return reversed([]) - class RevItBlocked(Rev): - __iter__ = None - class RevRevBlocked(Rev): - __reversed__ = None - self.assertTrue(issubclass(Rev, Reversible)) - self.assertTrue(isinstance(Rev(), Reversible)) - self.assertFalse(issubclass(RevItBlocked, Reversible)) - self.assertFalse(isinstance(RevItBlocked(), Reversible)) - self.assertFalse(issubclass(RevRevBlocked, Reversible)) - self.assertFalse(isinstance(RevRevBlocked(), Reversible)) - - def test_Collection(self): - # Check some non-collections - non_collections = [None, 42, 3.14, 1j, lambda x: 2*x] - for x in non_collections: - self.assertNotIsInstance(x, Collection) - self.assertFalse(issubclass(type(x), Collection), repr(type(x))) - # Check some non-collection iterables - non_col_iterables = [_test_gen(), iter(b''), iter(bytearray()), - (x for x in [])] - for x in non_col_iterables: - self.assertNotIsInstance(x, Collection) - self.assertFalse(issubclass(type(x), Collection), repr(type(x))) - # Check some collections - samples = [set(), frozenset(), dict(), bytes(), str(), tuple(), - list(), dict().keys(), dict().items(), dict().values()] - for x in samples: - self.assertIsInstance(x, Collection) - self.assertTrue(issubclass(type(x), Collection), repr(type(x))) - # Check also Mapping, MutableMapping, etc. - self.assertTrue(issubclass(Sequence, Collection), repr(Sequence)) - self.assertTrue(issubclass(Mapping, Collection), repr(Mapping)) - self.assertTrue(issubclass(MutableMapping, Collection), - repr(MutableMapping)) - self.assertTrue(issubclass(Set, Collection), repr(Set)) - self.assertTrue(issubclass(MutableSet, Collection), repr(MutableSet)) - self.assertTrue(issubclass(Sequence, Collection), repr(MutableSet)) - # Check direct subclassing - class Col(Collection): - def __iter__(self): - return iter(list()) - def __len__(self): - return 0 - def __contains__(self, item): - return False - class DerCol(Col): pass - self.assertEqual(list(iter(Col())), []) - self.assertFalse(issubclass(list, Col)) - self.assertFalse(issubclass(set, Col)) - self.assertFalse(issubclass(float, Col)) - self.assertEqual(list(iter(DerCol())), []) - self.assertFalse(issubclass(list, DerCol)) - self.assertFalse(issubclass(set, DerCol)) - self.assertFalse(issubclass(float, DerCol)) - self.validate_abstract_methods(Collection, '__len__', '__iter__', - '__contains__') - # Check sized container non-iterable (which is not Collection) etc. - class ColNoIter: - def __len__(self): return 0 - def __contains__(self, item): return False - class ColNoSize: - def __iter__(self): return iter([]) - def __contains__(self, item): return False - class ColNoCont: - def __iter__(self): return iter([]) - def __len__(self): return 0 - self.assertFalse(issubclass(ColNoIter, Collection)) - self.assertFalse(isinstance(ColNoIter(), Collection)) - self.assertFalse(issubclass(ColNoSize, Collection)) - self.assertFalse(isinstance(ColNoSize(), Collection)) - self.assertFalse(issubclass(ColNoCont, Collection)) - self.assertFalse(isinstance(ColNoCont(), Collection)) - # Check None blocking - class SizeBlock: - def __iter__(self): return iter([]) - def __contains__(self): return False - __len__ = None - class IterBlock: - def __len__(self): return 0 - def __contains__(self): return True - __iter__ = None - self.assertFalse(issubclass(SizeBlock, Collection)) - self.assertFalse(isinstance(SizeBlock(), Collection)) - self.assertFalse(issubclass(IterBlock, Collection)) - self.assertFalse(isinstance(IterBlock(), Collection)) - # Check None blocking in subclass - class ColImpl: - def __iter__(self): - return iter(list()) - def __len__(self): - return 0 - def __contains__(self, item): - return False - class NonCol(ColImpl): - __contains__ = None - self.assertFalse(issubclass(NonCol, Collection)) - self.assertFalse(isinstance(NonCol(), Collection)) - - - def test_Iterator(self): - non_samples = [None, 42, 3.14, 1j, b"", "", (), [], {}, set()] - for x in non_samples: - self.assertNotIsInstance(x, Iterator) - self.assertFalse(issubclass(type(x), Iterator), repr(type(x))) - samples = [iter(bytes()), iter(str()), - iter(tuple()), iter(list()), iter(dict()), - iter(set()), iter(frozenset()), - iter(dict().keys()), iter(dict().items()), - iter(dict().values()), - _test_gen(), - (x for x in []), - ] - for x in samples: - self.assertIsInstance(x, Iterator) - self.assertTrue(issubclass(type(x), Iterator), repr(type(x))) - self.validate_abstract_methods(Iterator, '__next__', '__iter__') - - # Issue 10565 - class NextOnly: - def __next__(self): - yield 1 - return - self.assertNotIsInstance(NextOnly(), Iterator) - - def test_Generator(self): - class NonGen1: - def __iter__(self): return self - def __next__(self): return None - def close(self): pass - def throw(self, typ, val=None, tb=None): pass - - class NonGen2: - def __iter__(self): return self - def __next__(self): return None - def close(self): pass - def send(self, value): return value - - class NonGen3: - def close(self): pass - def send(self, value): return value - def throw(self, typ, val=None, tb=None): pass - - non_samples = [ - None, 42, 3.14, 1j, b"", "", (), [], {}, set(), - iter(()), iter([]), NonGen1(), NonGen2(), NonGen3()] - for x in non_samples: - self.assertNotIsInstance(x, Generator) - self.assertFalse(issubclass(type(x), Generator), repr(type(x))) - - class Gen: - def __iter__(self): return self - def __next__(self): return None - def close(self): pass - def send(self, value): return value - def throw(self, typ, val=None, tb=None): pass - - class MinimalGen(Generator): - def send(self, value): - return value - def throw(self, typ, val=None, tb=None): - super().throw(typ, val, tb) - - def gen(): - yield 1 - - samples = [gen(), (lambda: (yield))(), Gen(), MinimalGen()] - for x in samples: - self.assertIsInstance(x, Iterator) - self.assertIsInstance(x, Generator) - self.assertTrue(issubclass(type(x), Generator), repr(type(x))) - self.validate_abstract_methods(Generator, 'send', 'throw') - - # mixin tests - mgen = MinimalGen() - self.assertIs(mgen, iter(mgen)) - self.assertIs(mgen.send(None), next(mgen)) - self.assertEqual(2, mgen.send(2)) - self.assertIsNone(mgen.close()) - self.assertRaises(ValueError, mgen.throw, ValueError) - self.assertRaisesRegex(ValueError, "^huhu$", - mgen.throw, ValueError, ValueError("huhu")) - self.assertRaises(StopIteration, mgen.throw, StopIteration()) - - class FailOnClose(Generator): - def send(self, value): return value - def throw(self, *args): raise ValueError - - self.assertRaises(ValueError, FailOnClose().close) - - class IgnoreGeneratorExit(Generator): - def send(self, value): return value - def throw(self, *args): pass - - self.assertRaises(RuntimeError, IgnoreGeneratorExit().close) - - def test_AsyncGenerator(self): - class NonAGen1: - def __aiter__(self): return self - def __anext__(self): return None - def aclose(self): pass - def athrow(self, typ, val=None, tb=None): pass - - class NonAGen2: - def __aiter__(self): return self - def __anext__(self): return None - def aclose(self): pass - def asend(self, value): return value - - class NonAGen3: - def aclose(self): pass - def asend(self, value): return value - def athrow(self, typ, val=None, tb=None): pass - - non_samples = [ - None, 42, 3.14, 1j, b"", "", (), [], {}, set(), - iter(()), iter([]), NonAGen1(), NonAGen2(), NonAGen3()] - for x in non_samples: - self.assertNotIsInstance(x, AsyncGenerator) - self.assertFalse(issubclass(type(x), AsyncGenerator), repr(type(x))) - - class Gen: - def __aiter__(self): return self - async def __anext__(self): return None - async def aclose(self): pass - async def asend(self, value): return value - async def athrow(self, typ, val=None, tb=None): pass - - class MinimalAGen(AsyncGenerator): - async def asend(self, value): - return value - async def athrow(self, typ, val=None, tb=None): - await super().athrow(typ, val, tb) - - async def gen(): - yield 1 - - samples = [gen(), Gen(), MinimalAGen()] - for x in samples: - self.assertIsInstance(x, AsyncIterator) - self.assertIsInstance(x, AsyncGenerator) - self.assertTrue(issubclass(type(x), AsyncGenerator), repr(type(x))) - self.validate_abstract_methods(AsyncGenerator, 'asend', 'athrow') - - def run_async(coro): - result = None - while True: - try: - coro.send(None) - except StopIteration as ex: - result = ex.args[0] if ex.args else None - break - return result - - # mixin tests - mgen = MinimalAGen() - self.assertIs(mgen, mgen.__aiter__()) - self.assertIs(run_async(mgen.asend(None)), run_async(mgen.__anext__())) - self.assertEqual(2, run_async(mgen.asend(2))) - self.assertIsNone(run_async(mgen.aclose())) - with self.assertRaises(ValueError): - run_async(mgen.athrow(ValueError)) - - class FailOnClose(AsyncGenerator): - async def asend(self, value): return value - async def athrow(self, *args): raise ValueError - - with self.assertRaises(ValueError): - run_async(FailOnClose().aclose()) - - class IgnoreGeneratorExit(AsyncGenerator): - async def asend(self, value): return value - async def athrow(self, *args): pass - - with self.assertRaises(RuntimeError): - run_async(IgnoreGeneratorExit().aclose()) - - def test_Sized(self): - non_samples = [None, 42, 3.14, 1j, - _test_gen(), - (x for x in []), - ] - for x in non_samples: - self.assertNotIsInstance(x, Sized) - self.assertFalse(issubclass(type(x), Sized), repr(type(x))) - samples = [bytes(), str(), - tuple(), list(), set(), frozenset(), dict(), - dict().keys(), dict().items(), dict().values(), - ] - for x in samples: - self.assertIsInstance(x, Sized) - self.assertTrue(issubclass(type(x), Sized), repr(type(x))) - self.validate_abstract_methods(Sized, '__len__') - self.validate_isinstance(Sized, '__len__') - - def test_Container(self): - non_samples = [None, 42, 3.14, 1j, - _test_gen(), - (x for x in []), - ] - for x in non_samples: - self.assertNotIsInstance(x, Container) - self.assertFalse(issubclass(type(x), Container), repr(type(x))) - samples = [bytes(), str(), - tuple(), list(), set(), frozenset(), dict(), - dict().keys(), dict().items(), - ] - for x in samples: - self.assertIsInstance(x, Container) - self.assertTrue(issubclass(type(x), Container), repr(type(x))) - self.validate_abstract_methods(Container, '__contains__') - self.validate_isinstance(Container, '__contains__') - - def test_Callable(self): - non_samples = [None, 42, 3.14, 1j, - "", b"", (), [], {}, set(), - _test_gen(), - (x for x in []), - ] - for x in non_samples: - self.assertNotIsInstance(x, Callable) - self.assertFalse(issubclass(type(x), Callable), repr(type(x))) - samples = [lambda: None, - type, int, object, - len, - list.append, [].append, - ] - for x in samples: - self.assertIsInstance(x, Callable) - self.assertTrue(issubclass(type(x), Callable), repr(type(x))) - self.validate_abstract_methods(Callable, '__call__') - self.validate_isinstance(Callable, '__call__') - - def test_direct_subclassing(self): - for B in Hashable, Iterable, Iterator, Reversible, Sized, Container, Callable: - class C(B): - pass - self.assertTrue(issubclass(C, B)) - self.assertFalse(issubclass(int, C)) - - def test_registration(self): - for B in Hashable, Iterable, Iterator, Reversible, Sized, Container, Callable: - class C: - __hash__ = None # Make sure it isn't hashable by default - self.assertFalse(issubclass(C, B), B.__name__) - B.register(C) - self.assertTrue(issubclass(C, B)) - - class WithSet(MutableSet): - - def __init__(self, it=()): - self.data = set(it) - - def __len__(self): - return len(self.data) - - def __iter__(self): - return iter(self.data) - - def __contains__(self, item): - return item in self.data - - def add(self, item): - self.data.add(item) - - def discard(self, item): - self.data.discard(item) - - class TestCollectionABCs(ABCTestCase): - - # XXX For now, we only test some virtual inheritance properties. - # We should also test the proper behavior of the collection ABCs - # as real base classes or mix-in classes. - - def test_Set(self): - for sample in [set, frozenset]: - self.assertIsInstance(sample(), Set) - self.assertTrue(issubclass(sample, Set)) - self.validate_abstract_methods(Set, '__contains__', '__iter__', '__len__') - class MySet(Set): - def __contains__(self, x): - return False - def __len__(self): - return 0 - def __iter__(self): - return iter([]) - self.validate_comparison(MySet()) - - def test_hash_Set(self): - class OneTwoThreeSet(Set): - def __init__(self): - self.contents = [1, 2, 3] - def __contains__(self, x): - return x in self.contents - def __len__(self): - return len(self.contents) - def __iter__(self): - return iter(self.contents) - def __hash__(self): - return self._hash() - a, b = OneTwoThreeSet(), OneTwoThreeSet() - self.assertTrue(hash(a) == hash(b)) - - def test_isdisjoint_Set(self): - class MySet(Set): - def __init__(self, itr): - self.contents = itr - def __contains__(self, x): - return x in self.contents - def __iter__(self): - return iter(self.contents) - def __len__(self): - return len([x for x in self.contents]) - s1 = MySet((1, 2, 3)) - s2 = MySet((4, 5, 6)) - s3 = MySet((1, 5, 6)) - self.assertTrue(s1.isdisjoint(s2)) - self.assertFalse(s1.isdisjoint(s3)) - - def test_equality_Set(self): - class MySet(Set): - def __init__(self, itr): - self.contents = itr - def __contains__(self, x): - return x in self.contents - def __iter__(self): - return iter(self.contents) - def __len__(self): - return len([x for x in self.contents]) - s1 = MySet((1,)) - s2 = MySet((1, 2)) - s3 = MySet((3, 4)) - s4 = MySet((3, 4)) - self.assertTrue(s2 > s1) - self.assertTrue(s1 < s2) - self.assertFalse(s2 <= s1) - self.assertFalse(s2 <= s3) - self.assertFalse(s1 >= s2) - self.assertEqual(s3, s4) - self.assertNotEqual(s2, s3) - - def test_arithmetic_Set(self): - class MySet(Set): - def __init__(self, itr): - self.contents = itr - def __contains__(self, x): - return x in self.contents - def __iter__(self): - return iter(self.contents) - def __len__(self): - return len([x for x in self.contents]) - s1 = MySet((1, 2, 3)) - s2 = MySet((3, 4, 5)) - s3 = s1 & s2 - self.assertEqual(s3, MySet((3,))) - - def test_MutableSet(self): - self.assertIsInstance(set(), MutableSet) - self.assertTrue(issubclass(set, MutableSet)) - self.assertNotIsInstance(frozenset(), MutableSet) - self.assertFalse(issubclass(frozenset, MutableSet)) - self.validate_abstract_methods(MutableSet, '__contains__', '__iter__', '__len__', - 'add', 'discard') - - def test_issue_5647(self): - # MutableSet.__iand__ mutated the set during iteration - s = WithSet('abcd') - s &= WithSet('cdef') # This used to fail - self.assertEqual(set(s), set('cd')) - - def test_issue_4920(self): - # MutableSet.pop() method did not work - class MySet(MutableSet): - __slots__=['__s'] - def __init__(self,items=None): - if items is None: - items=[] - self.__s=set(items) - def __contains__(self,v): - return v in self.__s - def __iter__(self): - return iter(self.__s) - def __len__(self): - return len(self.__s) - def add(self,v): - result=v not in self.__s - self.__s.add(v) - return result - def discard(self,v): - result=v in self.__s - self.__s.discard(v) - return result - def __repr__(self): - return "MySet(%s)" % repr(list(self)) - items = [5,43,2,1] - s = MySet(items) - r = s.pop() - self.assertEquals(len(s), len(items) - 1) - self.assertNotIn(r, s) - self.assertIn(r, items) - - def test_issue8750(self): - empty = WithSet() - full = WithSet(range(10)) - s = WithSet(full) - s -= s - self.assertEqual(s, empty) - s = WithSet(full) - s ^= s - self.assertEqual(s, empty) - s = WithSet(full) - s &= s - self.assertEqual(s, full) - s |= s - self.assertEqual(s, full) - - def test_issue16373(self): - # Recursion error comparing comparable and noncomparable - # Set instances - class MyComparableSet(Set): - def __contains__(self, x): - return False - def __len__(self): - return 0 - def __iter__(self): - return iter([]) - class MyNonComparableSet(Set): - def __contains__(self, x): - return False - def __len__(self): - return 0 - def __iter__(self): - return iter([]) - def __le__(self, x): - return NotImplemented - def __lt__(self, x): - return NotImplemented - - cs = MyComparableSet() - ncs = MyNonComparableSet() - self.assertFalse(ncs < cs) - self.assertTrue(ncs <= cs) - self.assertFalse(ncs > cs) - self.assertTrue(ncs >= cs) - - def test_issue26915(self): - # Container membership test should check identity first - class CustomEqualObject: - def __eq__(self, other): - return False - class CustomSequence(Sequence): - def __init__(self, seq): - self._seq = seq - def __getitem__(self, index): - return self._seq[index] - def __len__(self): - return len(self._seq) - - nan = float('nan') - obj = CustomEqualObject() - seq = CustomSequence([nan, obj, nan]) - containers = [ - seq, - ItemsView({1: nan, 2: obj}), - ValuesView({1: nan, 2: obj}) - ] - for container in containers: - for elem in container: - self.assertIn(elem, container) - self.assertEqual(seq.index(nan), 0) - self.assertEqual(seq.index(obj), 1) - self.assertEqual(seq.count(nan), 2) - self.assertEqual(seq.count(obj), 1) - - def assertSameSet(self, s1, s2): - # coerce both to a real set then check equality - self.assertSetEqual(set(s1), set(s2)) - - def test_Set_interoperability_with_real_sets(self): - # Issue: 8743 - class ListSet(Set): - def __init__(self, elements=()): - self.data = [] - for elem in elements: - if elem not in self.data: - self.data.append(elem) - def __contains__(self, elem): - return elem in self.data - def __iter__(self): - return iter(self.data) - def __len__(self): - return len(self.data) - def __repr__(self): - return 'Set({!r})'.format(self.data) - - r1 = set('abc') - r2 = set('bcd') - r3 = set('abcde') - f1 = ListSet('abc') - f2 = ListSet('bcd') - f3 = ListSet('abcde') - l1 = list('abccba') - l2 = list('bcddcb') - l3 = list('abcdeedcba') - - target = r1 & r2 - self.assertSameSet(f1 & f2, target) - self.assertSameSet(f1 & r2, target) - self.assertSameSet(r2 & f1, target) - self.assertSameSet(f1 & l2, target) - - target = r1 | r2 - self.assertSameSet(f1 | f2, target) - self.assertSameSet(f1 | r2, target) - self.assertSameSet(r2 | f1, target) - self.assertSameSet(f1 | l2, target) - - fwd_target = r1 - r2 - rev_target = r2 - r1 - self.assertSameSet(f1 - f2, fwd_target) - self.assertSameSet(f2 - f1, rev_target) - self.assertSameSet(f1 - r2, fwd_target) - self.assertSameSet(f2 - r1, rev_target) - self.assertSameSet(r1 - f2, fwd_target) - self.assertSameSet(r2 - f1, rev_target) - self.assertSameSet(f1 - l2, fwd_target) - self.assertSameSet(f2 - l1, rev_target) - - target = r1 ^ r2 - self.assertSameSet(f1 ^ f2, target) - self.assertSameSet(f1 ^ r2, target) - self.assertSameSet(r2 ^ f1, target) - self.assertSameSet(f1 ^ l2, target) - - # Don't change the following to use assertLess or other - # "more specific" unittest assertions. The current - # assertTrue/assertFalse style makes the pattern of test - # case combinations clear and allows us to know for sure - # the exact operator being invoked. - - # proper subset - self.assertTrue(f1 < f3) - self.assertFalse(f1 < f1) - self.assertFalse(f1 < f2) - self.assertTrue(r1 < f3) - self.assertFalse(r1 < f1) - self.assertFalse(r1 < f2) - self.assertTrue(r1 < r3) - self.assertFalse(r1 < r1) - self.assertFalse(r1 < r2) - with self.assertRaises(TypeError): - f1 < l3 - with self.assertRaises(TypeError): - f1 < l1 - with self.assertRaises(TypeError): - f1 < l2 - - # any subset - self.assertTrue(f1 <= f3) - self.assertTrue(f1 <= f1) - self.assertFalse(f1 <= f2) - self.assertTrue(r1 <= f3) - self.assertTrue(r1 <= f1) - self.assertFalse(r1 <= f2) - self.assertTrue(r1 <= r3) - self.assertTrue(r1 <= r1) - self.assertFalse(r1 <= r2) - with self.assertRaises(TypeError): - f1 <= l3 - with self.assertRaises(TypeError): - f1 <= l1 - with self.assertRaises(TypeError): - f1 <= l2 - - # proper superset - self.assertTrue(f3 > f1) - self.assertFalse(f1 > f1) - self.assertFalse(f2 > f1) - self.assertTrue(r3 > r1) - self.assertFalse(f1 > r1) - self.assertFalse(f2 > r1) - self.assertTrue(r3 > r1) - self.assertFalse(r1 > r1) - self.assertFalse(r2 > r1) - with self.assertRaises(TypeError): - f1 > l3 - with self.assertRaises(TypeError): - f1 > l1 - with self.assertRaises(TypeError): - f1 > l2 - - # any superset - self.assertTrue(f3 >= f1) - self.assertTrue(f1 >= f1) - self.assertFalse(f2 >= f1) - self.assertTrue(r3 >= r1) - self.assertTrue(f1 >= r1) - self.assertFalse(f2 >= r1) - self.assertTrue(r3 >= r1) - self.assertTrue(r1 >= r1) - self.assertFalse(r2 >= r1) - with self.assertRaises(TypeError): - f1 >= l3 - with self.assertRaises(TypeError): - f1 >=l1 - with self.assertRaises(TypeError): - f1 >= l2 - - # equality - self.assertTrue(f1 == f1) - self.assertTrue(r1 == f1) - self.assertTrue(f1 == r1) - self.assertFalse(f1 == f3) - self.assertFalse(r1 == f3) - self.assertFalse(f1 == r3) - self.assertFalse(f1 == l3) - self.assertFalse(f1 == l1) - self.assertFalse(f1 == l2) - - # inequality - self.assertFalse(f1 != f1) - self.assertFalse(r1 != f1) - self.assertFalse(f1 != r1) - self.assertTrue(f1 != f3) - self.assertTrue(r1 != f3) - self.assertTrue(f1 != r3) - self.assertTrue(f1 != l3) - self.assertTrue(f1 != l1) - self.assertTrue(f1 != l2) - - def test_Mapping(self): - for sample in [dict]: - self.assertIsInstance(sample(), Mapping) - self.assertTrue(issubclass(sample, Mapping)) - self.validate_abstract_methods(Mapping, '__contains__', '__iter__', '__len__', - '__getitem__') - class MyMapping(Mapping): - def __len__(self): - return 0 - def __getitem__(self, i): - raise IndexError - def __iter__(self): - return iter(()) - self.validate_comparison(MyMapping()) - self.assertRaises(TypeError, reversed, MyMapping()) - - def test_MutableMapping(self): - for sample in [dict]: - self.assertIsInstance(sample(), MutableMapping) - self.assertTrue(issubclass(sample, MutableMapping)) - self.validate_abstract_methods(MutableMapping, '__contains__', '__iter__', '__len__', - '__getitem__', '__setitem__', '__delitem__') - - def test_MutableMapping_subclass(self): - # Test issue 9214 - mymap = UserDict() - mymap['red'] = 5 - self.assertIsInstance(mymap.keys(), Set) - self.assertIsInstance(mymap.keys(), KeysView) - self.assertIsInstance(mymap.items(), Set) - self.assertIsInstance(mymap.items(), ItemsView) - - mymap = UserDict() - mymap['red'] = 5 - z = mymap.keys() | {'orange'} - self.assertIsInstance(z, set) - list(z) - mymap['blue'] = 7 # Shouldn't affect 'z' - self.assertEqual(sorted(z), ['orange', 'red']) - - mymap = UserDict() - mymap['red'] = 5 - z = mymap.items() | {('orange', 3)} - self.assertIsInstance(z, set) - list(z) - mymap['blue'] = 7 # Shouldn't affect 'z' - self.assertEqual(z, {('orange', 3), ('red', 5)}) - - def test_Sequence(self): - for sample in [tuple, list, bytes, str]: - self.assertIsInstance(sample(), Sequence) - self.assertTrue(issubclass(sample, Sequence)) - self.assertIsInstance(range(10), Sequence) - self.assertTrue(issubclass(range, Sequence)) - self.assertIsInstance(memoryview(b""), Sequence) - self.assertTrue(issubclass(memoryview, Sequence)) - self.assertTrue(issubclass(str, Sequence)) - self.validate_abstract_methods(Sequence, '__contains__', '__iter__', '__len__', - '__getitem__') - - def test_Sequence_mixins(self): - class SequenceSubclass(Sequence): - def __init__(self, seq=()): - self.seq = seq - - def __getitem__(self, index): - return self.seq[index] - - def __len__(self): - return len(self.seq) - - # Compare Sequence.index() behavior to (list|str).index() behavior - def assert_index_same(seq1, seq2, index_args): - try: - expected = seq1.index(*index_args) - except ValueError: - with self.assertRaises(ValueError): - seq2.index(*index_args) - else: - actual = seq2.index(*index_args) - self.assertEqual( - actual, expected, '%r.index%s' % (seq1, index_args)) - - for ty in list, str: - nativeseq = ty('abracadabra') - indexes = [-10000, -9999] + list(range(-3, len(nativeseq) + 3)) - seqseq = SequenceSubclass(nativeseq) - for letter in set(nativeseq) | {'z'}: - assert_index_same(nativeseq, seqseq, (letter,)) - for start in range(-3, len(nativeseq) + 3): - assert_index_same(nativeseq, seqseq, (letter, start)) - for stop in range(-3, len(nativeseq) + 3): - assert_index_same( - nativeseq, seqseq, (letter, start, stop)) - - def test_ByteString(self): - for sample in [bytes, bytearray]: - self.assertIsInstance(sample(), ByteString) - self.assertTrue(issubclass(sample, ByteString)) - for sample in [str, list, tuple]: - self.assertNotIsInstance(sample(), ByteString) - self.assertFalse(issubclass(sample, ByteString)) - self.assertNotIsInstance(memoryview(b""), ByteString) - self.assertFalse(issubclass(memoryview, ByteString)) - - def test_MutableSequence(self): - for sample in [tuple, str, bytes]: - self.assertNotIsInstance(sample(), MutableSequence) - self.assertFalse(issubclass(sample, MutableSequence)) - for sample in [list, bytearray, deque]: - self.assertIsInstance(sample(), MutableSequence) - self.assertTrue(issubclass(sample, MutableSequence)) - self.assertFalse(issubclass(str, MutableSequence)) - self.validate_abstract_methods(MutableSequence, '__contains__', '__iter__', - '__len__', '__getitem__', '__setitem__', '__delitem__', 'insert') - - def test_MutableSequence_mixins(self): - # Test the mixins of MutableSequence by creating a minimal concrete - # class inherited from it. - class MutableSequenceSubclass(MutableSequence): - def __init__(self): - self.lst = [] - - def __setitem__(self, index, value): - self.lst[index] = value - - def __getitem__(self, index): - return self.lst[index] - - def __len__(self): - return len(self.lst) - - def __delitem__(self, index): - del self.lst[index] - - def insert(self, index, value): - self.lst.insert(index, value) - - mss = MutableSequenceSubclass() - mss.append(0) - mss.extend((1, 2, 3, 4)) - self.assertEqual(len(mss), 5) - self.assertEqual(mss[3], 3) - mss.reverse() - self.assertEqual(mss[3], 1) - mss.pop() - self.assertEqual(len(mss), 4) - mss.remove(3) - self.assertEqual(len(mss), 3) - mss += (10, 20, 30) - self.assertEqual(len(mss), 6) - self.assertEqual(mss[-1], 30) - mss.clear() - self.assertEqual(len(mss), 0) - - # issue 34427 - # extending self should not cause infinite loop - items = 'ABCD' - mss2 = MutableSequenceSubclass() - mss2.extend(items + items) - mss.clear() - mss.extend(items) - mss.extend(mss) - self.assertEqual(len(mss), len(mss2)) - self.assertEqual(list(mss), list(mss2)) - - - ################################################################################ - ### Counter - ################################################################################ - - class CounterSubclassWithSetItem(Counter): - # Test a counter subclass that overrides __setitem__ - def __init__(self, *args, **kwds): - self.called = False - Counter.__init__(self, *args, **kwds) - def __setitem__(self, key, value): - self.called = True - Counter.__setitem__(self, key, value) - - class CounterSubclassWithGet(Counter): - # Test a counter subclass that overrides get() - def __init__(self, *args, **kwds): - self.called = False - Counter.__init__(self, *args, **kwds) - def get(self, key, default): - self.called = True - return Counter.get(self, key, default) - - class TestCounter(unittest.TestCase): - - def test_basics(self): - c = Counter('abcaba') - self.assertEqual(c, Counter({'a':3 , 'b': 2, 'c': 1})) - self.assertEqual(c, Counter(a=3, b=2, c=1)) - self.assertIsInstance(c, dict) - self.assertIsInstance(c, Mapping) - self.assertTrue(issubclass(Counter, dict)) - self.assertTrue(issubclass(Counter, Mapping)) - self.assertEqual(len(c), 3) - self.assertEqual(sum(c.values()), 6) - self.assertEqual(list(c.values()), [3, 2, 1]) - self.assertEqual(list(c.keys()), ['a', 'b', 'c']) - self.assertEqual(list(c), ['a', 'b', 'c']) - self.assertEqual(list(c.items()), - [('a', 3), ('b', 2), ('c', 1)]) - self.assertEqual(c['b'], 2) - self.assertEqual(c['z'], 0) - self.assertEqual(c.__contains__('c'), True) - self.assertEqual(c.__contains__('z'), False) - self.assertEqual(c.get('b', 10), 2) - self.assertEqual(c.get('z', 10), 10) - self.assertEqual(c, dict(a=3, b=2, c=1)) - self.assertEqual(repr(c), "Counter({'a': 3, 'b': 2, 'c': 1})") - self.assertEqual(c.most_common(), [('a', 3), ('b', 2), ('c', 1)]) - for i in range(5): - self.assertEqual(c.most_common(i), - [('a', 3), ('b', 2), ('c', 1)][:i]) - self.assertEqual(''.join(c.elements()), 'aaabbc') - c['a'] += 1 # increment an existing value - c['b'] -= 2 # sub existing value to zero - del c['c'] # remove an entry - del c['c'] # make sure that del doesn't raise KeyError - c['d'] -= 2 # sub from a missing value - c['e'] = -5 # directly assign a missing value - c['f'] += 4 # add to a missing value - self.assertEqual(c, dict(a=4, b=0, d=-2, e=-5, f=4)) - self.assertEqual(''.join(c.elements()), 'aaaaffff') - self.assertEqual(c.pop('f'), 4) - self.assertNotIn('f', c) - for i in range(3): - elem, cnt = c.popitem() - self.assertNotIn(elem, c) - c.clear() - self.assertEqual(c, {}) - self.assertEqual(repr(c), 'Counter()') - self.assertRaises(NotImplementedError, Counter.fromkeys, 'abc') - self.assertRaises(TypeError, hash, c) - c.update(dict(a=5, b=3)) - c.update(c=1) - c.update(Counter('a' * 50 + 'b' * 30)) - c.update() # test case with no args - c.__init__('a' * 500 + 'b' * 300) - c.__init__('cdc') - c.__init__() - self.assertEqual(c, dict(a=555, b=333, c=3, d=1)) - self.assertEqual(c.setdefault('d', 5), 1) - self.assertEqual(c['d'], 1) - self.assertEqual(c.setdefault('e', 5), 5) - self.assertEqual(c['e'], 5) - - def test_init(self): - self.assertEqual(list(Counter(self=42).items()), [('self', 42)]) - self.assertEqual(list(Counter(iterable=42).items()), [('iterable', 42)]) - self.assertEqual(list(Counter(iterable=None).items()), [('iterable', None)]) - self.assertRaises(TypeError, Counter, 42) - self.assertRaises(TypeError, Counter, (), ()) - self.assertRaises(TypeError, Counter.__init__) - - def test_order_preservation(self): - # Input order dictates items() order - self.assertEqual(list(Counter('abracadabra').items()), - [('a', 5), ('b', 2), ('r', 2), ('c', 1), ('d', 1)]) - # letters with same count: ^----------^ ^---------^ - - # Verify retention of order even when all counts are equal - self.assertEqual(list(Counter('xyzpdqqdpzyx').items()), - [('x', 2), ('y', 2), ('z', 2), ('p', 2), ('d', 2), ('q', 2)]) - - # Input order dictates elements() order - self.assertEqual(list(Counter('abracadabra simsalabim').elements()), - ['a', 'a', 'a', 'a', 'a', 'a', 'a', 'b', 'b', 'b','r', - 'r', 'c', 'd', ' ', 's', 's', 'i', 'i', 'm', 'm', 'l']) - - # Math operations order first by the order encountered in the left - # operand and then by the order encountered in the right operand. - ps = 'aaabbcdddeefggghhijjjkkl' - qs = 'abbcccdeefffhkkllllmmnno' - order = {letter: i for i, letter in enumerate(dict.fromkeys(ps + qs))} - def correctly_ordered(seq): - 'Return true if the letters occur in the expected order' - positions = [order[letter] for letter in seq] - return positions == sorted(positions) - - p, q = Counter(ps), Counter(qs) - self.assertTrue(correctly_ordered(+p)) - self.assertTrue(correctly_ordered(-p)) - self.assertTrue(correctly_ordered(p + q)) - self.assertTrue(correctly_ordered(p - q)) - self.assertTrue(correctly_ordered(p | q)) - self.assertTrue(correctly_ordered(p & q)) - - p, q = Counter(ps), Counter(qs) - p += q - self.assertTrue(correctly_ordered(p)) - - p, q = Counter(ps), Counter(qs) - p -= q - self.assertTrue(correctly_ordered(p)) - - p, q = Counter(ps), Counter(qs) - p |= q - self.assertTrue(correctly_ordered(p)) - - p, q = Counter(ps), Counter(qs) - p &= q - self.assertTrue(correctly_ordered(p)) - - p, q = Counter(ps), Counter(qs) - p.update(q) - self.assertTrue(correctly_ordered(p)) - - p, q = Counter(ps), Counter(qs) - p.subtract(q) - self.assertTrue(correctly_ordered(p)) - - def test_update(self): - c = Counter() - c.update(self=42) - self.assertEqual(list(c.items()), [('self', 42)]) - c = Counter() - c.update(iterable=42) - self.assertEqual(list(c.items()), [('iterable', 42)]) - c = Counter() - c.update(iterable=None) - self.assertEqual(list(c.items()), [('iterable', None)]) - self.assertRaises(TypeError, Counter().update, 42) - self.assertRaises(TypeError, Counter().update, {}, {}) - self.assertRaises(TypeError, Counter.update) - - def test_copying(self): - # Check that counters are copyable, deepcopyable, picklable, and - #have a repr/eval round-trip - words = Counter('which witch had which witches wrist watch'.split()) - def check(dup): - msg = "\ncopy: %s\nwords: %s" % (dup, words) - self.assertIsNot(dup, words, msg) - self.assertEqual(dup, words) - check(words.copy()) - check(copy.copy(words)) - check(copy.deepcopy(words)) - for proto in range(pickle.HIGHEST_PROTOCOL + 1): - with self.subTest(proto=proto): - check(pickle.loads(pickle.dumps(words, proto))) - check(eval(repr(words))) - update_test = Counter() - update_test.update(words) - check(update_test) - check(Counter(words)) - - def test_copy_subclass(self): - class MyCounter(Counter): - pass - c = MyCounter('slartibartfast') - d = c.copy() - self.assertEqual(d, c) - self.assertEqual(len(d), len(c)) - self.assertEqual(type(d), type(c)) - - def test_conversions(self): - # Convert to: set, list, dict - s = 'she sells sea shells by the sea shore' - self.assertEqual(sorted(Counter(s).elements()), sorted(s)) - self.assertEqual(sorted(Counter(s)), sorted(set(s))) - self.assertEqual(dict(Counter(s)), dict(Counter(s).items())) - self.assertEqual(set(Counter(s)), set(s)) - - def test_invariant_for_the_in_operator(self): - c = Counter(a=10, b=-2, c=0) - for elem in c: - self.assertTrue(elem in c) - self.assertIn(elem, c) - - def test_multiset_operations(self): - # Verify that adding a zero counter will strip zeros and negatives - c = Counter(a=10, b=-2, c=0) + Counter() - self.assertEqual(dict(c), dict(a=10)) - - elements = 'abcd' - for i in range(1000): - # test random pairs of multisets - p = Counter(dict((elem, randrange(-2,4)) for elem in elements)) - p.update(e=1, f=-1, g=0) - q = Counter(dict((elem, randrange(-2,4)) for elem in elements)) - q.update(h=1, i=-1, j=0) - for counterop, numberop in [ - (Counter.__add__, lambda x, y: max(0, x+y)), - (Counter.__sub__, lambda x, y: max(0, x-y)), - (Counter.__or__, lambda x, y: max(0,x,y)), - (Counter.__and__, lambda x, y: max(0, min(x,y))), - ]: - result = counterop(p, q) - for x in elements: - self.assertEqual(numberop(p[x], q[x]), result[x], - (counterop, x, p, q)) - # verify that results exclude non-positive counts - self.assertTrue(x>0 for x in result.values()) - - elements = 'abcdef' - for i in range(100): - # verify that random multisets with no repeats are exactly like sets - p = Counter(dict((elem, randrange(0, 2)) for elem in elements)) - q = Counter(dict((elem, randrange(0, 2)) for elem in elements)) - for counterop, setop in [ - (Counter.__sub__, set.__sub__), - (Counter.__or__, set.__or__), - (Counter.__and__, set.__and__), - ]: - counter_result = counterop(p, q) - set_result = setop(set(p.elements()), set(q.elements())) - self.assertEqual(counter_result, dict.fromkeys(set_result, 1)) - - def test_inplace_operations(self): - elements = 'abcd' - for i in range(1000): - # test random pairs of multisets - p = Counter(dict((elem, randrange(-2,4)) for elem in elements)) - p.update(e=1, f=-1, g=0) - q = Counter(dict((elem, randrange(-2,4)) for elem in elements)) - q.update(h=1, i=-1, j=0) - for inplace_op, regular_op in [ - (Counter.__iadd__, Counter.__add__), - (Counter.__isub__, Counter.__sub__), - (Counter.__ior__, Counter.__or__), - (Counter.__iand__, Counter.__and__), - ]: - c = p.copy() - c_id = id(c) - regular_result = regular_op(c, q) - inplace_result = inplace_op(c, q) - self.assertEqual(inplace_result, regular_result) - self.assertEqual(id(inplace_result), c_id) - - def test_subtract(self): - c = Counter(a=-5, b=0, c=5, d=10, e=15,g=40) - c.subtract(a=1, b=2, c=-3, d=10, e=20, f=30, h=-50) - self.assertEqual(c, Counter(a=-6, b=-2, c=8, d=0, e=-5, f=-30, g=40, h=50)) - c = Counter(a=-5, b=0, c=5, d=10, e=15,g=40) - c.subtract(Counter(a=1, b=2, c=-3, d=10, e=20, f=30, h=-50)) - self.assertEqual(c, Counter(a=-6, b=-2, c=8, d=0, e=-5, f=-30, g=40, h=50)) - c = Counter('aaabbcd') - c.subtract('aaaabbcce') - self.assertEqual(c, Counter(a=-1, b=0, c=-1, d=1, e=-1)) - - c = Counter() - c.subtract(self=42) - self.assertEqual(list(c.items()), [('self', -42)]) - c = Counter() - c.subtract(iterable=42) - self.assertEqual(list(c.items()), [('iterable', -42)]) - self.assertRaises(TypeError, Counter().subtract, 42) - self.assertRaises(TypeError, Counter().subtract, {}, {}) - self.assertRaises(TypeError, Counter.subtract) - - def test_unary(self): - c = Counter(a=-5, b=0, c=5, d=10, e=15,g=40) - self.assertEqual(dict(+c), dict(c=5, d=10, e=15, g=40)) - self.assertEqual(dict(-c), dict(a=5)) - - def test_repr_nonsortable(self): - c = Counter(a=2, b=None) - r = repr(c) - self.assertIn("'a': 2", r) - self.assertIn("'b': None", r) - - def test_helper_function(self): - # two paths, one for real dicts and one for other mappings - elems = list('abracadabra') - - d = dict() - _count_elements(d, elems) - self.assertEqual(d, {'a': 5, 'r': 2, 'b': 2, 'c': 1, 'd': 1}) - - m = OrderedDict() - _count_elements(m, elems) - self.assertEqual(m, - OrderedDict([('a', 5), ('b', 2), ('r', 2), ('c', 1), ('d', 1)])) - - # test fidelity to the pure python version - c = CounterSubclassWithSetItem('abracadabra') - self.assertTrue(c.called) - self.assertEqual(dict(c), {'a': 5, 'b': 2, 'c': 1, 'd': 1, 'r':2 }) - c = CounterSubclassWithGet('abracadabra') - self.assertTrue(c.called) - self.assertEqual(dict(c), {'a': 5, 'b': 2, 'c': 1, 'd': 1, 'r':2 }) - - - ################################################################################ - ### Run tests - ################################################################################ - - def test_main(verbose=None): - NamedTupleDocs = doctest.DocTestSuite(module=collections) - test_classes = [TestNamedTuple, NamedTupleDocs, TestOneTrickPonyABCs, - TestCollectionABCs, TestCounter, TestChainMap, - TestUserObjects, - ] - support.run_unittest(*test_classes) - support.run_doctest(collections, verbose) - - - if __name__ == "__main__": - test_main(verbose=True) diff --git a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_colorsys.yaml b/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_colorsys.yaml deleted file mode 100644 index 796e04073..000000000 --- a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_colorsys.yaml +++ /dev/null @@ -1,101 +0,0 @@ -python: | - import unittest - import colorsys - - def frange(start, stop, step): - while start <= stop: - yield start - start += step - - class ColorsysTest(unittest.TestCase): - - def assertTripleEqual(self, tr1, tr2): - self.assertEqual(len(tr1), 3) - self.assertEqual(len(tr2), 3) - self.assertAlmostEqual(tr1[0], tr2[0]) - self.assertAlmostEqual(tr1[1], tr2[1]) - self.assertAlmostEqual(tr1[2], tr2[2]) - - def test_hsv_roundtrip(self): - for r in frange(0.0, 1.0, 0.2): - for g in frange(0.0, 1.0, 0.2): - for b in frange(0.0, 1.0, 0.2): - rgb = (r, g, b) - self.assertTripleEqual( - rgb, - colorsys.hsv_to_rgb(*colorsys.rgb_to_hsv(*rgb)) - ) - - def test_hsv_values(self): - values = [ - # rgb, hsv - ((0.0, 0.0, 0.0), ( 0 , 0.0, 0.0)), # black - ((0.0, 0.0, 1.0), (4./6., 1.0, 1.0)), # blue - ((0.0, 1.0, 0.0), (2./6., 1.0, 1.0)), # green - ((0.0, 1.0, 1.0), (3./6., 1.0, 1.0)), # cyan - ((1.0, 0.0, 0.0), ( 0 , 1.0, 1.0)), # red - ((1.0, 0.0, 1.0), (5./6., 1.0, 1.0)), # purple - ((1.0, 1.0, 0.0), (1./6., 1.0, 1.0)), # yellow - ((1.0, 1.0, 1.0), ( 0 , 0.0, 1.0)), # white - ((0.5, 0.5, 0.5), ( 0 , 0.0, 0.5)), # grey - ] - for (rgb, hsv) in values: - self.assertTripleEqual(hsv, colorsys.rgb_to_hsv(*rgb)) - self.assertTripleEqual(rgb, colorsys.hsv_to_rgb(*hsv)) - - def test_hls_roundtrip(self): - for r in frange(0.0, 1.0, 0.2): - for g in frange(0.0, 1.0, 0.2): - for b in frange(0.0, 1.0, 0.2): - rgb = (r, g, b) - self.assertTripleEqual( - rgb, - colorsys.hls_to_rgb(*colorsys.rgb_to_hls(*rgb)) - ) - - def test_hls_values(self): - values = [ - # rgb, hls - ((0.0, 0.0, 0.0), ( 0 , 0.0, 0.0)), # black - ((0.0, 0.0, 1.0), (4./6., 0.5, 1.0)), # blue - ((0.0, 1.0, 0.0), (2./6., 0.5, 1.0)), # green - ((0.0, 1.0, 1.0), (3./6., 0.5, 1.0)), # cyan - ((1.0, 0.0, 0.0), ( 0 , 0.5, 1.0)), # red - ((1.0, 0.0, 1.0), (5./6., 0.5, 1.0)), # purple - ((1.0, 1.0, 0.0), (1./6., 0.5, 1.0)), # yellow - ((1.0, 1.0, 1.0), ( 0 , 1.0, 0.0)), # white - ((0.5, 0.5, 0.5), ( 0 , 0.5, 0.0)), # grey - ] - for (rgb, hls) in values: - self.assertTripleEqual(hls, colorsys.rgb_to_hls(*rgb)) - self.assertTripleEqual(rgb, colorsys.hls_to_rgb(*hls)) - - def test_yiq_roundtrip(self): - for r in frange(0.0, 1.0, 0.2): - for g in frange(0.0, 1.0, 0.2): - for b in frange(0.0, 1.0, 0.2): - rgb = (r, g, b) - self.assertTripleEqual( - rgb, - colorsys.yiq_to_rgb(*colorsys.rgb_to_yiq(*rgb)) - ) - - def test_yiq_values(self): - values = [ - # rgb, yiq - ((0.0, 0.0, 0.0), (0.0, 0.0, 0.0)), # black - ((0.0, 0.0, 1.0), (0.11, -0.3217, 0.3121)), # blue - ((0.0, 1.0, 0.0), (0.59, -0.2773, -0.5251)), # green - ((0.0, 1.0, 1.0), (0.7, -0.599, -0.213)), # cyan - ((1.0, 0.0, 0.0), (0.3, 0.599, 0.213)), # red - ((1.0, 0.0, 1.0), (0.41, 0.2773, 0.5251)), # purple - ((1.0, 1.0, 0.0), (0.89, 0.3217, -0.3121)), # yellow - ((1.0, 1.0, 1.0), (1.0, 0.0, 0.0)), # white - ((0.5, 0.5, 0.5), (0.5, 0.0, 0.0)), # grey - ] - for (rgb, yiq) in values: - self.assertTripleEqual(yiq, colorsys.rgb_to_yiq(*rgb)) - self.assertTripleEqual(rgb, colorsys.yiq_to_rgb(*yiq)) - - if __name__ == "__main__": - unittest.main() diff --git a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_compare.yaml b/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_compare.yaml deleted file mode 100644 index 1c1b4a533..000000000 --- a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_compare.yaml +++ /dev/null @@ -1,125 +0,0 @@ -python: | - import unittest - - class Empty: - def __repr__(self): - return '' - - class Cmp: - def __init__(self,arg): - self.arg = arg - - def __repr__(self): - return '' % self.arg - - def __eq__(self, other): - return self.arg == other - - class Anything: - def __eq__(self, other): - return True - - def __ne__(self, other): - return False - - class ComparisonTest(unittest.TestCase): - set1 = [2, 2.0, 2, 2+0j, Cmp(2.0)] - set2 = [[1], (3,), None, Empty()] - candidates = set1 + set2 - - def test_comparisons(self): - for a in self.candidates: - for b in self.candidates: - if ((a in self.set1) and (b in self.set1)) or a is b: - self.assertEqual(a, b) - else: - self.assertNotEqual(a, b) - - def test_id_comparisons(self): - # Ensure default comparison compares id() of args - L = [] - for i in range(10): - L.insert(len(L)//2, Empty()) - for a in L: - for b in L: - self.assertEqual(a == b, id(a) == id(b), - 'a=%r, b=%r' % (a, b)) - - def test_ne_defaults_to_not_eq(self): - a = Cmp(1) - b = Cmp(1) - c = Cmp(2) - self.assertIs(a == b, True) - self.assertIs(a != b, False) - self.assertIs(a != c, True) - - def test_ne_high_priority(self): - """object.__ne__() should allow reflected __ne__() to be tried""" - calls = [] - class Left: - # Inherits object.__ne__() - def __eq__(*args): - calls.append('Left.__eq__') - return NotImplemented - class Right: - def __eq__(*args): - calls.append('Right.__eq__') - return NotImplemented - def __ne__(*args): - calls.append('Right.__ne__') - return NotImplemented - Left() != Right() - self.assertSequenceEqual(calls, ['Left.__eq__', 'Right.__ne__']) - - def test_ne_low_priority(self): - """object.__ne__() should not invoke reflected __eq__()""" - calls = [] - class Base: - # Inherits object.__ne__() - def __eq__(*args): - calls.append('Base.__eq__') - return NotImplemented - class Derived(Base): # Subclassing forces higher priority - def __eq__(*args): - calls.append('Derived.__eq__') - return NotImplemented - def __ne__(*args): - calls.append('Derived.__ne__') - return NotImplemented - Base() != Derived() - self.assertSequenceEqual(calls, ['Derived.__ne__', 'Base.__eq__']) - - def test_other_delegation(self): - """No default delegation between operations except __ne__()""" - ops = ( - ('__eq__', lambda a, b: a == b), - ('__lt__', lambda a, b: a < b), - ('__le__', lambda a, b: a <= b), - ('__gt__', lambda a, b: a > b), - ('__ge__', lambda a, b: a >= b), - ) - for name, func in ops: - with self.subTest(name): - def unexpected(*args): - self.fail('Unexpected operator method called') - class C: - __ne__ = unexpected - for other, _ in ops: - if other != name: - setattr(C, other, unexpected) - if name == '__eq__': - self.assertIs(func(C(), object()), False) - else: - self.assertRaises(TypeError, func, C(), object()) - - def test_issue_1393(self): - x = lambda: None - self.assertEqual(x, Anything()) - self.assertEqual(Anything(), x) - y = object() - self.assertEqual(y, Anything()) - self.assertEqual(Anything(), y) - - - if __name__ == '__main__': - unittest.main() diff --git a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_compile.yaml b/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_compile.yaml deleted file mode 100644 index 70c2e9e0c..000000000 --- a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_compile.yaml +++ /dev/null @@ -1,1084 +0,0 @@ -python: | - import dis - import math - import os - import unittest - import sys - import _ast - import tempfile - import types - from test import support - from test.support import script_helper, FakePath - - class TestSpecifics(unittest.TestCase): - - def compile_single(self, source): - compile(source, "", "single") - - def assertInvalidSingle(self, source): - self.assertRaises(SyntaxError, self.compile_single, source) - - def test_no_ending_newline(self): - compile("hi", "", "exec") - compile("hi\r", "", "exec") - - def test_empty(self): - compile("", "", "exec") - - def test_other_newlines(self): - compile("\r\n", "", "exec") - compile("\r", "", "exec") - compile("hi\r\nstuff\r\ndef f():\n pass\r", "", "exec") - compile("this_is\rreally_old_mac\rdef f():\n pass", "", "exec") - - def test_debug_assignment(self): - # catch assignments to __debug__ - self.assertRaises(SyntaxError, compile, '__debug__ = 1', '?', 'single') - import builtins - prev = builtins.__debug__ - setattr(builtins, '__debug__', 'sure') - self.assertEqual(__debug__, prev) - setattr(builtins, '__debug__', prev) - - def test_argument_handling(self): - # detect duplicate positional and keyword arguments - self.assertRaises(SyntaxError, eval, 'lambda a,a:0') - self.assertRaises(SyntaxError, eval, 'lambda a,a=1:0') - self.assertRaises(SyntaxError, eval, 'lambda a=1,a=1:0') - self.assertRaises(SyntaxError, exec, 'def f(a, a): pass') - self.assertRaises(SyntaxError, exec, 'def f(a = 0, a = 1): pass') - self.assertRaises(SyntaxError, exec, 'def f(a): global a; a = 1') - - def test_syntax_error(self): - self.assertRaises(SyntaxError, compile, "1+*3", "filename", "exec") - - def test_none_keyword_arg(self): - self.assertRaises(SyntaxError, compile, "f(None=1)", "", "exec") - - def test_duplicate_global_local(self): - self.assertRaises(SyntaxError, exec, 'def f(a): global a; a = 1') - - def test_exec_with_general_mapping_for_locals(self): - - class M: - "Test mapping interface versus possible calls from eval()." - def __getitem__(self, key): - if key == 'a': - return 12 - raise KeyError - def __setitem__(self, key, value): - self.results = (key, value) - def keys(self): - return list('xyz') - - m = M() - g = globals() - exec('z = a', g, m) - self.assertEqual(m.results, ('z', 12)) - try: - exec('z = b', g, m) - except NameError: - pass - else: - self.fail('Did not detect a KeyError') - exec('z = dir()', g, m) - self.assertEqual(m.results, ('z', list('xyz'))) - exec('z = globals()', g, m) - self.assertEqual(m.results, ('z', g)) - exec('z = locals()', g, m) - self.assertEqual(m.results, ('z', m)) - self.assertRaises(TypeError, exec, 'z = b', m) - - class A: - "Non-mapping" - pass - m = A() - self.assertRaises(TypeError, exec, 'z = a', g, m) - - # Verify that dict subclasses work as well - class D(dict): - def __getitem__(self, key): - if key == 'a': - return 12 - return dict.__getitem__(self, key) - d = D() - exec('z = a', g, d) - self.assertEqual(d['z'], 12) - - def test_extended_arg(self): - longexpr = 'x = x or ' + '-x' * 2500 - g = {} - code = ''' - def f(x): - %s - %s - %s - %s - %s - %s - %s - %s - %s - %s - # the expressions above have no effect, x == argument - while x: - x -= 1 - # EXTENDED_ARG/JUMP_ABSOLUTE here - return x - ''' % ((longexpr,)*10) - exec(code, g) - self.assertEqual(g['f'](5), 0) - - def test_argument_order(self): - self.assertRaises(SyntaxError, exec, 'def f(a=1, b): pass') - - def test_float_literals(self): - # testing bad float literals - self.assertRaises(SyntaxError, eval, "2e") - self.assertRaises(SyntaxError, eval, "2.0e+") - self.assertRaises(SyntaxError, eval, "1e-") - self.assertRaises(SyntaxError, eval, "3-4e/21") - - def test_indentation(self): - # testing compile() of indented block w/o trailing newline" - s = """ - if 1: - if 2: - pass""" - compile(s, "", "exec") - - # This test is probably specific to CPython and may not generalize - # to other implementations. We are trying to ensure that when - # the first line of code starts after 256, correct line numbers - # in tracebacks are still produced. - def test_leading_newlines(self): - s256 = "".join(["\n"] * 256 + ["spam"]) - co = compile(s256, 'fn', 'exec') - self.assertEqual(co.co_firstlineno, 257) - self.assertEqual(co.co_lnotab, bytes()) - - def test_literals_with_leading_zeroes(self): - for arg in ["077787", "0xj", "0x.", "0e", "090000000000000", - "080000000000000", "000000000000009", "000000000000008", - "0b42", "0BADCAFE", "0o123456789", "0b1.1", "0o4.2", - "0b101j2", "0o153j2", "0b100e1", "0o777e1", "0777", - "000777", "000000000000007"]: - self.assertRaises(SyntaxError, eval, arg) - - self.assertEqual(eval("0xff"), 255) - self.assertEqual(eval("0777."), 777) - self.assertEqual(eval("0777.0"), 777) - self.assertEqual(eval("000000000000000000000000000000000000000000000000000777e0"), 777) - self.assertEqual(eval("0777e1"), 7770) - self.assertEqual(eval("0e0"), 0) - self.assertEqual(eval("0000e-012"), 0) - self.assertEqual(eval("09.5"), 9.5) - self.assertEqual(eval("0777j"), 777j) - self.assertEqual(eval("000"), 0) - self.assertEqual(eval("00j"), 0j) - self.assertEqual(eval("00.0"), 0) - self.assertEqual(eval("0e3"), 0) - self.assertEqual(eval("090000000000000."), 90000000000000.) - self.assertEqual(eval("090000000000000.0000000000000000000000"), 90000000000000.) - self.assertEqual(eval("090000000000000e0"), 90000000000000.) - self.assertEqual(eval("090000000000000e-0"), 90000000000000.) - self.assertEqual(eval("090000000000000j"), 90000000000000j) - self.assertEqual(eval("000000000000008."), 8.) - self.assertEqual(eval("000000000000009."), 9.) - self.assertEqual(eval("0b101010"), 42) - self.assertEqual(eval("-0b000000000010"), -2) - self.assertEqual(eval("0o777"), 511) - self.assertEqual(eval("-0o0000010"), -8) - - def test_unary_minus(self): - # Verify treatment of unary minus on negative numbers SF bug #660455 - if sys.maxsize == 2147483647: - # 32-bit machine - all_one_bits = '0xffffffff' - self.assertEqual(eval(all_one_bits), 4294967295) - self.assertEqual(eval("-" + all_one_bits), -4294967295) - elif sys.maxsize == 9223372036854775807: - # 64-bit machine - all_one_bits = '0xffffffffffffffff' - self.assertEqual(eval(all_one_bits), 18446744073709551615) - self.assertEqual(eval("-" + all_one_bits), -18446744073709551615) - else: - self.fail("How many bits *does* this machine have???") - # Verify treatment of constant folding on -(sys.maxsize+1) - # i.e. -2147483648 on 32 bit platforms. Should return int. - self.assertIsInstance(eval("%s" % (-sys.maxsize - 1)), int) - self.assertIsInstance(eval("%s" % (-sys.maxsize - 2)), int) - - if sys.maxsize == 9223372036854775807: - def test_32_63_bit_values(self): - a = +4294967296 # 1 << 32 - b = -4294967296 # 1 << 32 - c = +281474976710656 # 1 << 48 - d = -281474976710656 # 1 << 48 - e = +4611686018427387904 # 1 << 62 - f = -4611686018427387904 # 1 << 62 - g = +9223372036854775807 # 1 << 63 - 1 - h = -9223372036854775807 # 1 << 63 - 1 - - for variable in self.test_32_63_bit_values.__code__.co_consts: - if variable is not None: - self.assertIsInstance(variable, int) - - def test_sequence_unpacking_error(self): - # Verify sequence packing/unpacking with "or". SF bug #757818 - i,j = (1, -1) or (-1, 1) - self.assertEqual(i, 1) - self.assertEqual(j, -1) - - def test_none_assignment(self): - stmts = [ - 'None = 0', - 'None += 0', - '__builtins__.None = 0', - 'def None(): pass', - 'class None: pass', - '(a, None) = 0, 0', - 'for None in range(10): pass', - 'def f(None): pass', - 'import None', - 'import x as None', - 'from x import None', - 'from x import y as None' - ] - for stmt in stmts: - stmt += "\n" - self.assertRaises(SyntaxError, compile, stmt, 'tmp', 'single') - self.assertRaises(SyntaxError, compile, stmt, 'tmp', 'exec') - - def test_import(self): - succeed = [ - 'import sys', - 'import os, sys', - 'import os as bar', - 'import os.path as bar', - 'from __future__ import nested_scopes, generators', - 'from __future__ import (nested_scopes,\ngenerators)', - 'from __future__ import (nested_scopes,\ngenerators,)', - 'from sys import stdin, stderr, stdout', - 'from sys import (stdin, stderr,\nstdout)', - 'from sys import (stdin, stderr,\nstdout,)', - 'from sys import (stdin\n, stderr, stdout)', - 'from sys import (stdin\n, stderr, stdout,)', - 'from sys import stdin as si, stdout as so, stderr as se', - 'from sys import (stdin as si, stdout as so, stderr as se)', - 'from sys import (stdin as si, stdout as so, stderr as se,)', - ] - fail = [ - 'import (os, sys)', - 'import (os), (sys)', - 'import ((os), (sys))', - 'import (sys', - 'import sys)', - 'import (os,)', - 'import os As bar', - 'import os.path a bar', - 'from sys import stdin As stdout', - 'from sys import stdin a stdout', - 'from (sys) import stdin', - 'from __future__ import (nested_scopes', - 'from __future__ import nested_scopes)', - 'from __future__ import nested_scopes,\ngenerators', - 'from sys import (stdin', - 'from sys import stdin)', - 'from sys import stdin, stdout,\nstderr', - 'from sys import stdin si', - 'from sys import stdin,', - 'from sys import (*)', - 'from sys import (stdin,, stdout, stderr)', - 'from sys import (stdin, stdout),', - ] - for stmt in succeed: - compile(stmt, 'tmp', 'exec') - for stmt in fail: - self.assertRaises(SyntaxError, compile, stmt, 'tmp', 'exec') - - def test_for_distinct_code_objects(self): - # SF bug 1048870 - def f(): - f1 = lambda x=1: x - f2 = lambda x=2: x - return f1, f2 - f1, f2 = f() - self.assertNotEqual(id(f1.__code__), id(f2.__code__)) - - def test_lambda_doc(self): - l = lambda: "foo" - self.assertIsNone(l.__doc__) - - def test_encoding(self): - code = b'# -*- coding: badencoding -*-\npass\n' - self.assertRaises(SyntaxError, compile, code, 'tmp', 'exec') - code = '# -*- coding: badencoding -*-\n"\xc2\xa4"\n' - compile(code, 'tmp', 'exec') - self.assertEqual(eval(code), '\xc2\xa4') - code = '"\xc2\xa4"\n' - self.assertEqual(eval(code), '\xc2\xa4') - code = b'"\xc2\xa4"\n' - self.assertEqual(eval(code), '\xa4') - code = b'# -*- coding: latin1 -*-\n"\xc2\xa4"\n' - self.assertEqual(eval(code), '\xc2\xa4') - code = b'# -*- coding: utf-8 -*-\n"\xc2\xa4"\n' - self.assertEqual(eval(code), '\xa4') - code = b'# -*- coding: iso8859-15 -*-\n"\xc2\xa4"\n' - self.assertEqual(eval(code), '\xc2\u20ac') - code = '"""\\\n# -*- coding: iso8859-15 -*-\n\xc2\xa4"""\n' - self.assertEqual(eval(code), '# -*- coding: iso8859-15 -*-\n\xc2\xa4') - code = b'"""\\\n# -*- coding: iso8859-15 -*-\n\xc2\xa4"""\n' - self.assertEqual(eval(code), '# -*- coding: iso8859-15 -*-\n\xa4') - - def test_subscripts(self): - # SF bug 1448804 - # Class to make testing subscript results easy - class str_map(object): - def __init__(self): - self.data = {} - def __getitem__(self, key): - return self.data[str(key)] - def __setitem__(self, key, value): - self.data[str(key)] = value - def __delitem__(self, key): - del self.data[str(key)] - def __contains__(self, key): - return str(key) in self.data - d = str_map() - # Index - d[1] = 1 - self.assertEqual(d[1], 1) - d[1] += 1 - self.assertEqual(d[1], 2) - del d[1] - self.assertNotIn(1, d) - # Tuple of indices - d[1, 1] = 1 - self.assertEqual(d[1, 1], 1) - d[1, 1] += 1 - self.assertEqual(d[1, 1], 2) - del d[1, 1] - self.assertNotIn((1, 1), d) - # Simple slice - d[1:2] = 1 - self.assertEqual(d[1:2], 1) - d[1:2] += 1 - self.assertEqual(d[1:2], 2) - del d[1:2] - self.assertNotIn(slice(1, 2), d) - # Tuple of simple slices - d[1:2, 1:2] = 1 - self.assertEqual(d[1:2, 1:2], 1) - d[1:2, 1:2] += 1 - self.assertEqual(d[1:2, 1:2], 2) - del d[1:2, 1:2] - self.assertNotIn((slice(1, 2), slice(1, 2)), d) - # Extended slice - d[1:2:3] = 1 - self.assertEqual(d[1:2:3], 1) - d[1:2:3] += 1 - self.assertEqual(d[1:2:3], 2) - del d[1:2:3] - self.assertNotIn(slice(1, 2, 3), d) - # Tuple of extended slices - d[1:2:3, 1:2:3] = 1 - self.assertEqual(d[1:2:3, 1:2:3], 1) - d[1:2:3, 1:2:3] += 1 - self.assertEqual(d[1:2:3, 1:2:3], 2) - del d[1:2:3, 1:2:3] - self.assertNotIn((slice(1, 2, 3), slice(1, 2, 3)), d) - # Ellipsis - d[...] = 1 - self.assertEqual(d[...], 1) - d[...] += 1 - self.assertEqual(d[...], 2) - del d[...] - self.assertNotIn(Ellipsis, d) - # Tuple of Ellipses - d[..., ...] = 1 - self.assertEqual(d[..., ...], 1) - d[..., ...] += 1 - self.assertEqual(d[..., ...], 2) - del d[..., ...] - self.assertNotIn((Ellipsis, Ellipsis), d) - - def test_annotation_limit(self): - # more than 255 annotations, should compile ok - s = "def f(%s): pass" - s %= ', '.join('a%d:%d' % (i,i) for i in range(300)) - compile(s, '?', 'exec') - - def test_mangling(self): - class A: - def f(): - __mangled = 1 - __not_mangled__ = 2 - import __mangled_mod - import __package__.module - - self.assertIn("_A__mangled", A.f.__code__.co_varnames) - self.assertIn("__not_mangled__", A.f.__code__.co_varnames) - self.assertIn("_A__mangled_mod", A.f.__code__.co_varnames) - self.assertIn("__package__", A.f.__code__.co_varnames) - - def test_compile_ast(self): - fname = __file__ - if fname.lower().endswith('pyc'): - fname = fname[:-1] - with open(fname, 'r') as f: - fcontents = f.read() - sample_code = [ - ['', 'x = 5'], - ['', """if True:\n pass\n"""], - ['', """for n in [1, 2, 3]:\n print(n)\n"""], - ['', """def foo():\n pass\nfoo()\n"""], - [fname, fcontents], - ] - - for fname, code in sample_code: - co1 = compile(code, '%s1' % fname, 'exec') - ast = compile(code, '%s2' % fname, 'exec', _ast.PyCF_ONLY_AST) - self.assertTrue(type(ast) == _ast.Module) - co2 = compile(ast, '%s3' % fname, 'exec') - self.assertEqual(co1, co2) - # the code object's filename comes from the second compilation step - self.assertEqual(co2.co_filename, '%s3' % fname) - - # raise exception when node type doesn't match with compile mode - co1 = compile('print(1)', '', 'exec', _ast.PyCF_ONLY_AST) - self.assertRaises(TypeError, compile, co1, '', 'eval') - - # raise exception when node type is no start node - self.assertRaises(TypeError, compile, _ast.If(), '', 'exec') - - # raise exception when node has invalid children - ast = _ast.Module() - ast.body = [_ast.BoolOp()] - self.assertRaises(TypeError, compile, ast, '', 'exec') - - def test_dict_evaluation_order(self): - i = 0 - - def f(): - nonlocal i - i += 1 - return i - - d = {f(): f(), f(): f()} - self.assertEqual(d, {1: 2, 3: 4}) - - def test_compile_filename(self): - for filename in 'file.py', b'file.py': - code = compile('pass', filename, 'exec') - self.assertEqual(code.co_filename, 'file.py') - for filename in bytearray(b'file.py'), memoryview(b'file.py'): - with self.assertWarns(DeprecationWarning): - code = compile('pass', filename, 'exec') - self.assertEqual(code.co_filename, 'file.py') - self.assertRaises(TypeError, compile, 'pass', list(b'file.py'), 'exec') - - @support.cpython_only - def test_same_filename_used(self): - s = """def f(): pass\ndef g(): pass""" - c = compile(s, "myfile", "exec") - for obj in c.co_consts: - if isinstance(obj, types.CodeType): - self.assertIs(obj.co_filename, c.co_filename) - - def test_single_statement(self): - self.compile_single("1 + 2") - self.compile_single("\n1 + 2") - self.compile_single("1 + 2\n") - self.compile_single("1 + 2\n\n") - self.compile_single("1 + 2\t\t\n") - self.compile_single("1 + 2\t\t\n ") - self.compile_single("1 + 2 # one plus two") - self.compile_single("1; 2") - self.compile_single("import sys; sys") - self.compile_single("def f():\n pass") - self.compile_single("while False:\n pass") - self.compile_single("if x:\n f(x)") - self.compile_single("if x:\n f(x)\nelse:\n g(x)") - self.compile_single("class T:\n pass") - - def test_bad_single_statement(self): - self.assertInvalidSingle('1\n2') - self.assertInvalidSingle('def f(): pass') - self.assertInvalidSingle('a = 13\nb = 187') - self.assertInvalidSingle('del x\ndel y') - self.assertInvalidSingle('f()\ng()') - self.assertInvalidSingle('f()\n# blah\nblah()') - self.assertInvalidSingle('f()\nxy # blah\nblah()') - self.assertInvalidSingle('x = 5 # comment\nx = 6\n') - - def test_particularly_evil_undecodable(self): - # Issue 24022 - src = b'0000\x00\n00000000000\n\x00\n\x9e\n' - with tempfile.TemporaryDirectory() as tmpd: - fn = os.path.join(tmpd, "bad.py") - with open(fn, "wb") as fp: - fp.write(src) - res = script_helper.run_python_until_end(fn)[0] - self.assertIn(b"Non-UTF-8", res.err) - - def test_yet_more_evil_still_undecodable(self): - # Issue #25388 - src = b"#\x00\n#\xfd\n" - with tempfile.TemporaryDirectory() as tmpd: - fn = os.path.join(tmpd, "bad.py") - with open(fn, "wb") as fp: - fp.write(src) - res = script_helper.run_python_until_end(fn)[0] - self.assertIn(b"Non-UTF-8", res.err) - - @support.cpython_only - def test_compiler_recursion_limit(self): - # Expected limit is sys.getrecursionlimit() * the scaling factor - # in symtable.c (currently 3) - # We expect to fail *at* that limit, because we use up some of - # the stack depth limit in the test suite code - # So we check the expected limit and 75% of that - # XXX (ncoghlan): duplicating the scaling factor here is a little - # ugly. Perhaps it should be exposed somewhere... - fail_depth = sys.getrecursionlimit() * 3 - success_depth = int(fail_depth * 0.75) - - def check_limit(prefix, repeated): - expect_ok = prefix + repeated * success_depth - self.compile_single(expect_ok) - broken = prefix + repeated * fail_depth - details = "Compiling ({!r} + {!r} * {})".format( - prefix, repeated, fail_depth) - with self.assertRaises(RecursionError, msg=details): - self.compile_single(broken) - - check_limit("a", "()") - check_limit("a", ".b") - check_limit("a", "[0]") - check_limit("a", "*a") - - def test_null_terminated(self): - # The source code is null-terminated internally, but bytes-like - # objects are accepted, which could be not terminated. - with self.assertRaisesRegex(ValueError, "cannot contain null"): - compile("123\x00", "", "eval") - with self.assertRaisesRegex(ValueError, "cannot contain null"): - compile(memoryview(b"123\x00"), "", "eval") - code = compile(memoryview(b"123\x00")[1:-1], "", "eval") - self.assertEqual(eval(code), 23) - code = compile(memoryview(b"1234")[1:-1], "", "eval") - self.assertEqual(eval(code), 23) - code = compile(memoryview(b"$23$")[1:-1], "", "eval") - self.assertEqual(eval(code), 23) - - # Also test when eval() and exec() do the compilation step - self.assertEqual(eval(memoryview(b"1234")[1:-1]), 23) - namespace = dict() - exec(memoryview(b"ax = 123")[1:-1], namespace) - self.assertEqual(namespace['x'], 12) - - def check_constant(self, func, expected): - for const in func.__code__.co_consts: - if repr(const) == repr(expected): - break - else: - self.fail("unable to find constant %r in %r" - % (expected, func.__code__.co_consts)) - - # Merging equal constants is not a strict requirement for the Python - # semantics, it's a more an implementation detail. - @support.cpython_only - def test_merge_constants(self): - # Issue #25843: compile() must merge constants which are equal - # and have the same type. - - def check_same_constant(const): - ns = {} - code = "f1, f2 = lambda: %r, lambda: %r" % (const, const) - exec(code, ns) - f1 = ns['f1'] - f2 = ns['f2'] - self.assertIs(f1.__code__, f2.__code__) - self.check_constant(f1, const) - self.assertEqual(repr(f1()), repr(const)) - - check_same_constant(None) - check_same_constant(0) - check_same_constant(0.0) - check_same_constant(b'abc') - check_same_constant('abc') - - # Note: "lambda: ..." emits "LOAD_CONST Ellipsis", - # whereas "lambda: Ellipsis" emits "LOAD_GLOBAL Ellipsis" - f1, f2 = lambda: ..., lambda: ... - self.assertIs(f1.__code__, f2.__code__) - self.check_constant(f1, Ellipsis) - self.assertEqual(repr(f1()), repr(Ellipsis)) - - # Merge constants in tuple or frozenset - f1, f2 = lambda: "not a name", lambda: ("not a name",) - f3 = lambda x: x in {("not a name",)} - self.assertIs(f1.__code__.co_consts[1], - f2.__code__.co_consts[1][0]) - self.assertIs(next(iter(f3.__code__.co_consts[1])), - f2.__code__.co_consts[1]) - - # {0} is converted to a constant frozenset({0}) by the peephole - # optimizer - f1, f2 = lambda x: x in {0}, lambda x: x in {0} - self.assertIs(f1.__code__, f2.__code__) - self.check_constant(f1, frozenset({0})) - self.assertTrue(f1(0)) - - # This is a regression test for a CPython specific peephole optimizer - # implementation bug present in a few releases. It's assertion verifies - # that peephole optimization was actually done though that isn't an - # indication of the bugs presence or not (crashing is). - @support.cpython_only - def test_peephole_opt_unreachable_code_array_access_in_bounds(self): - """Regression test for issue35193 when run under clang msan.""" - def unused_code_at_end(): - return 3 - raise RuntimeError("unreachable") - # The above function definition will trigger the out of bounds - # bug in the peephole optimizer as it scans opcodes past the - # RETURN_VALUE opcode. This does not always crash an interpreter. - # When you build with the clang memory sanitizer it reliably aborts. - self.assertEqual( - 'RETURN_VALUE', - list(dis.get_instructions(unused_code_at_end))[-1].opname) - - def test_dont_merge_constants(self): - # Issue #25843: compile() must not merge constants which are equal - # but have a different type. - - def check_different_constants(const1, const2): - ns = {} - exec("f1, f2 = lambda: %r, lambda: %r" % (const1, const2), ns) - f1 = ns['f1'] - f2 = ns['f2'] - self.assertIsNot(f1.__code__, f2.__code__) - self.assertNotEqual(f1.__code__, f2.__code__) - self.check_constant(f1, const1) - self.check_constant(f2, const2) - self.assertEqual(repr(f1()), repr(const1)) - self.assertEqual(repr(f2()), repr(const2)) - - check_different_constants(0, 0.0) - check_different_constants(+0.0, -0.0) - check_different_constants((0,), (0.0,)) - check_different_constants('a', b'a') - check_different_constants(('a',), (b'a',)) - - # check_different_constants() cannot be used because repr(-0j) is - # '(-0-0j)', but when '(-0-0j)' is evaluated to 0j: we loose the sign. - f1, f2 = lambda: +0.0j, lambda: -0.0j - self.assertIsNot(f1.__code__, f2.__code__) - self.check_constant(f1, +0.0j) - self.check_constant(f2, -0.0j) - self.assertEqual(repr(f1()), repr(+0.0j)) - self.assertEqual(repr(f2()), repr(-0.0j)) - - # {0} is converted to a constant frozenset({0}) by the peephole - # optimizer - f1, f2 = lambda x: x in {0}, lambda x: x in {0.0} - self.assertIsNot(f1.__code__, f2.__code__) - self.check_constant(f1, frozenset({0})) - self.check_constant(f2, frozenset({0.0})) - self.assertTrue(f1(0)) - self.assertTrue(f2(0.0)) - - def test_path_like_objects(self): - # An implicit test for PyUnicode_FSDecoder(). - compile("42", FakePath("test_compile_pathlike"), "single") - - def test_stack_overflow(self): - # bpo-31113: Stack overflow when compile a long sequence of - # complex statements. - compile("if a: b\n" * 200000, "", "exec") - - # Multiple users rely on the fact that CPython does not generate - # bytecode for dead code blocks. See bpo-37500 for more context. - @support.cpython_only - def test_dead_blocks_do_not_generate_bytecode(self): - def unused_block_if(): - if 0: - return 42 - - def unused_block_while(): - while 0: - return 42 - - def unused_block_if_else(): - if 1: - return None - else: - return 42 - - def unused_block_while_else(): - while 1: - return None - else: - return 42 - - funcs = [unused_block_if, unused_block_while, - unused_block_if_else, unused_block_while_else] - - for func in funcs: - opcodes = list(dis.get_instructions(func)) - self.assertEqual(2, len(opcodes)) - self.assertEqual('LOAD_CONST', opcodes[0].opname) - self.assertEqual(None, opcodes[0].argval) - self.assertEqual('RETURN_VALUE', opcodes[1].opname) - - def test_false_while_loop(self): - def break_in_while(): - while False: - break - - def continue_in_while(): - while False: - continue - - funcs = [break_in_while, continue_in_while] - - # Check that we did not raise but we also don't generate bytecode - for func in funcs: - opcodes = list(dis.get_instructions(func)) - self.assertEqual(2, len(opcodes)) - self.assertEqual('LOAD_CONST', opcodes[0].opname) - self.assertEqual(None, opcodes[0].argval) - self.assertEqual('RETURN_VALUE', opcodes[1].opname) - - class TestExpressionStackSize(unittest.TestCase): - # These tests check that the computed stack size for a code object - # stays within reasonable bounds (see issue #21523 for an example - # dysfunction). - N = 100 - - def check_stack_size(self, code): - # To assert that the alleged stack size is not O(N), we - # check that it is smaller than log(N). - if isinstance(code, str): - code = compile(code, "", "single") - max_size = math.ceil(math.log(len(code.co_code))) - self.assertLessEqual(code.co_stacksize, max_size) - - def test_and(self): - self.check_stack_size("x and " * self.N + "x") - - def test_or(self): - self.check_stack_size("x or " * self.N + "x") - - def test_and_or(self): - self.check_stack_size("x and x or " * self.N + "x") - - def test_chained_comparison(self): - self.check_stack_size("x < " * self.N + "x") - - def test_if_else(self): - self.check_stack_size("x if x else " * self.N + "x") - - def test_binop(self): - self.check_stack_size("x + " * self.N + "x") - - def test_func_and(self): - code = "def f(x):\n" - code += " x and x\n" * self.N - self.check_stack_size(code) - - - class TestStackSizeStability(unittest.TestCase): - # Check that repeating certain snippets doesn't increase the stack size - # beyond what a single snippet requires. - - def check_stack_size(self, snippet, async_=False): - def compile_snippet(i): - ns = {} - script = """def func():\n""" + i * snippet - if async_: - script = "async " + script - code = compile(script, "\''), - ''<script>"&foo;"</script>'') - self.assertEqual( - html.escape('\'\'', False), - '\'<script>"&foo;"</script>\'') - - def test_unescape(self): - numeric_formats = ['&#%d', '&#%d;', '&#x%x', '&#x%x;'] - errmsg = 'unescape(%r) should have returned %r' - def check(text, expected): - self.assertEqual(html.unescape(text), expected, - msg=errmsg % (text, expected)) - def check_num(num, expected): - for format in numeric_formats: - text = format % num - self.assertEqual(html.unescape(text), expected, - msg=errmsg % (text, expected)) - # check text with no character references - check('no character references', 'no character references') - # check & followed by invalid chars - check('&\n&\t& &&', '&\n&\t& &&') - # check & followed by numbers and letters - check('&0 &9 &a &0; &9; &a;', '&0 &9 &a &0; &9; &a;') - # check incomplete entities at the end of the string - for x in ['&', '&#', '&#x', '&#X', '&#y', '&#xy', '&#Xy']: - check(x, x) - check(x+';', x+';') - # check several combinations of numeric character references, - # possibly followed by different characters - formats = ['&#%d', '&#%07d', '&#%d;', '&#%07d;', - '&#x%x', '&#x%06x', '&#x%x;', '&#x%06x;', - '&#x%X', '&#x%06X', '&#X%x;', '&#X%06x;'] - for num, char in zip([65, 97, 34, 38, 0x2603, 0x101234], - ['A', 'a', '"', '&', '\u2603', '\U00101234']): - for s in formats: - check(s % num, char) - for end in [' ', 'X']: - check((s+end) % num, char+end) - # check invalid code points - for cp in [0xD800, 0xDB00, 0xDC00, 0xDFFF, 0x110000]: - check_num(cp, '\uFFFD') - # check more invalid code points - for cp in [0x1, 0xb, 0xe, 0x7f, 0xfffe, 0xffff, 0x10fffe, 0x10ffff]: - check_num(cp, '') - # check invalid numbers - for num, ch in zip([0x0d, 0x80, 0x95, 0x9d], '\r\u20ac\u2022\x9d'): - check_num(num, ch) - # check small numbers - check_num(0, '\uFFFD') - check_num(9, '\t') - # check a big number - check_num(1000000000000000000, '\uFFFD') - # check that multiple trailing semicolons are handled correctly - for e in ['";', '";', '";', '";']: - check(e, '";') - # check that semicolons in the middle don't create problems - for e in ['"quot;', '"quot;', '"quot;', '"quot;']: - check(e, '"quot;') - # check triple adjacent charrefs - for e in ['"', '"', '"', '"']: - check(e*3, '"""') - check((e+';')*3, '"""') - # check that the case is respected - for e in ['&', '&', '&', '&']: - check(e, '&') - for e in ['&Amp', '&Amp;']: - check(e, e) - # check that non-existent named entities are returned unchanged - check('&svadilfari;', '&svadilfari;') - # the following examples are in the html5 specs - check('¬it', '¬it') - check('¬it;', '¬it;') - check('¬in', '¬in') - check('∉', '∉') - # a similar example with a long name - check('¬ReallyAnExistingNamedCharacterReference;', - '¬ReallyAnExistingNamedCharacterReference;') - # longest valid name - check('∳', '∳') - # check a charref that maps to two unicode chars - check('∾̳', '\u223E\u0333') - check('&acE', '&acE') - # see #12888 - check('{ ' * 1050, '{ ' * 1050) - # see #15156 - check('ÉricÉric&alphacentauriαcentauri', - 'ÉricÉric&alphacentauriαcentauri') - check('&co;', '&co;') - - - if __name__ == '__main__': - unittest.main() diff --git a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_htmlparser.yaml b/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_htmlparser.yaml deleted file mode 100644 index 0d9f84ce3..000000000 --- a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_htmlparser.yaml +++ /dev/null @@ -1,799 +0,0 @@ -python: | - """Tests for HTMLParser.py.""" - - import html.parser - import pprint - import unittest - - - class EventCollector(html.parser.HTMLParser): - - def __init__(self, *args, **kw): - self.events = [] - self.append = self.events.append - html.parser.HTMLParser.__init__(self, *args, **kw) - - def get_events(self): - # Normalize the list of events so that buffer artefacts don't - # separate runs of contiguous characters. - L = [] - prevtype = None - for event in self.events: - type = event[0] - if type == prevtype == "data": - L[-1] = ("data", L[-1][1] + event[1]) - else: - L.append(event) - prevtype = type - self.events = L - return L - - # structure markup - - def handle_starttag(self, tag, attrs): - self.append(("starttag", tag, attrs)) - - def handle_startendtag(self, tag, attrs): - self.append(("startendtag", tag, attrs)) - - def handle_endtag(self, tag): - self.append(("endtag", tag)) - - # all other markup - - def handle_comment(self, data): - self.append(("comment", data)) - - def handle_charref(self, data): - self.append(("charref", data)) - - def handle_data(self, data): - self.append(("data", data)) - - def handle_decl(self, data): - self.append(("decl", data)) - - def handle_entityref(self, data): - self.append(("entityref", data)) - - def handle_pi(self, data): - self.append(("pi", data)) - - def unknown_decl(self, decl): - self.append(("unknown decl", decl)) - - - class EventCollectorExtra(EventCollector): - - def handle_starttag(self, tag, attrs): - EventCollector.handle_starttag(self, tag, attrs) - self.append(("starttag_text", self.get_starttag_text())) - - - class EventCollectorCharrefs(EventCollector): - - def handle_charref(self, data): - self.fail('This should never be called with convert_charrefs=True') - - def handle_entityref(self, data): - self.fail('This should never be called with convert_charrefs=True') - - - class TestCaseBase(unittest.TestCase): - - def get_collector(self): - return EventCollector(convert_charrefs=False) - - def _run_check(self, source, expected_events, collector=None): - if collector is None: - collector = self.get_collector() - parser = collector - for s in source: - parser.feed(s) - parser.close() - events = parser.get_events() - if events != expected_events: - self.fail("received events did not match expected events" + - "\nSource:\n" + repr(source) + - "\nExpected:\n" + pprint.pformat(expected_events) + - "\nReceived:\n" + pprint.pformat(events)) - - def _run_check_extra(self, source, events): - self._run_check(source, events, - EventCollectorExtra(convert_charrefs=False)) - - - class HTMLParserTestCase(TestCaseBase): - - def test_processing_instruction_only(self): - self._run_check("", [ - ("pi", "processing instruction"), - ]) - self._run_check("", [ - ("pi", "processing instruction ?"), - ]) - - def test_simple_html(self): - self._run_check(""" - - &entity; - - sample - text - “ - - - """, [ - ("data", "\n"), - ("decl", "DOCTYPE html PUBLIC 'foo'"), - ("data", "\n"), - ("starttag", "html", []), - ("entityref", "entity"), - ("charref", "32"), - ("data", "\n"), - ("comment", "comment1a\n-><&#bad;

", [ - ("starttag", "p", []), - ("data", "&#bad;"), - ("endtag", "p"), - ]) - # add the [] as a workaround to avoid buffering (see #20288) - self._run_check(["
&#bad;
"], [ - ("starttag", "div", []), - ("data", "&#bad;"), - ("endtag", "div"), - ]) - - def test_unclosed_entityref(self): - self._run_check("&entityref foo", [ - ("entityref", "entityref"), - ("data", " foo"), - ]) - - def test_bad_nesting(self): - # Strangely, this *is* supposed to test that overlapping - # elements are allowed. HTMLParser is more geared toward - # lexing the input that parsing the structure. - self._run_check("", [ - ("starttag", "a", []), - ("starttag", "b", []), - ("endtag", "a"), - ("endtag", "b"), - ]) - - def test_bare_ampersands(self): - self._run_check("this text & contains & ampersands &", [ - ("data", "this text & contains & ampersands &"), - ]) - - def test_bare_pointy_brackets(self): - self._run_check("this < text > contains < bare>pointy< brackets", [ - ("data", "this < text > contains < bare>pointy< brackets"), - ]) - - def test_starttag_end_boundary(self): - self._run_check("""""", [("starttag", "a", [("b", "<")])]) - self._run_check("""""", [("starttag", "a", [("b", ">")])]) - - def test_buffer_artefacts(self): - output = [("starttag", "a", [("b", "<")])] - self._run_check([""], output) - self._run_check([""], output) - self._run_check([""], output) - self._run_check([""], output) - self._run_check([""], output) - self._run_check([""], output) - - output = [("starttag", "a", [("b", ">")])] - self._run_check([""], output) - self._run_check([""], output) - self._run_check([""], output) - self._run_check(["'>"], output) - self._run_check([""], output) - self._run_check([""], output) - - output = [("comment", "abc")] - self._run_check(["", ""], output) - self._run_check(["<", "!--abc-->"], output) - self._run_check([""], output) - self._run_check([""], output) - self._run_check([""], output) - self._run_check([""], output) - self._run_check([""], output) - self._run_check([""], output) - self._run_check(["", ""], output) - - def test_valid_doctypes(self): - # from http://www.w3.org/QA/2002/04/valid-dtd-list.html - dtds = ['HTML', # HTML5 doctype - ('HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" ' - '"http://www.w3.org/TR/html4/strict.dtd"'), - ('HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" ' - '"http://www.w3.org/TR/html4/loose.dtd"'), - ('html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" ' - '"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"'), - ('html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" ' - '"http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd"'), - ('math PUBLIC "-//W3C//DTD MathML 2.0//EN" ' - '"http://www.w3.org/Math/DTD/mathml2/mathml2.dtd"'), - ('html PUBLIC "-//W3C//DTD ' - 'XHTML 1.1 plus MathML 2.0 plus SVG 1.1//EN" ' - '"http://www.w3.org/2002/04/xhtml-math-svg/xhtml-math-svg.dtd"'), - ('svg PUBLIC "-//W3C//DTD SVG 1.1//EN" ' - '"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"'), - 'html PUBLIC "-//IETF//DTD HTML 2.0//EN"', - 'html PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"'] - for dtd in dtds: - self._run_check("" % dtd, - [('decl', 'DOCTYPE ' + dtd)]) - - def test_startendtag(self): - self._run_check("

", [ - ("startendtag", "p", []), - ]) - self._run_check("

", [ - ("starttag", "p", []), - ("endtag", "p"), - ]) - self._run_check("

", [ - ("starttag", "p", []), - ("startendtag", "img", [("src", "foo")]), - ("endtag", "p"), - ]) - - def test_get_starttag_text(self): - s = """""" - self._run_check_extra(s, [ - ("starttag", "foo:bar", [("one", "1"), ("two", "2")]), - ("starttag_text", s)]) - - def test_cdata_content(self): - contents = [ - ' ¬-an-entity-ref;', - "", - '

', - 'foo = "";', - 'foo = "";', - 'foo = <\n/script> ', - '', - ('\n//<\\/s\'+\'cript>\');\n//]]>'), - '\n\n', - 'foo = "";', - '', - # these two should be invalid according to the HTML 5 spec, - # section 8.1.2.2 - #'foo = ', - #'foo = ', - ] - elements = ['script', 'style', 'SCRIPT', 'STYLE', 'Script', 'Style'] - for content in contents: - for element in elements: - element_lower = element.lower() - s = '<{element}>{content}'.format(element=element, - content=content) - self._run_check(s, [("starttag", element_lower, []), - ("data", content), - ("endtag", element_lower)]) - - def test_cdata_with_closing_tags(self): - # see issue #13358 - # make sure that HTMLParser calls handle_data only once for each CDATA. - # The normal event collector normalizes the events in get_events, - # so we override it to return the original list of events. - class Collector(EventCollector): - def get_events(self): - return self.events - - content = """ ¬-an-entity-ref; -

- ''""" - for element in [' script', 'script ', ' script ', - '\nscript', 'script\n', '\nscript\n']: - element_lower = element.lower().strip() - s = '{1}' - '{1}'.format(text, charref), - expected, collector=collector()) - # check truncated charrefs at the end of the file - html = '&quo &# &#x' - for x in range(1, len(html)): - self._run_check(html[:x], [('data', html[:x])], - collector=collector()) - # check a string with no charrefs - self._run_check('no charrefs here', [('data', 'no charrefs here')], - collector=collector()) - - # the remaining tests were for the "tolerant" parser (which is now - # the default), and check various kind of broken markup - def test_tolerant_parsing(self): - self._run_check('te>>xt&a<\n' - ''), - ('comment', '/img'), - ('endtag', 'html<')]) - - def test_starttag_junk_chars(self): - self._run_check("", []) - self._run_check("", [('comment', '$')]) - self._run_check("", [('starttag', 'a", [('endtag', 'a'", [('data', "", [('starttag', 'a$b', [])]) - self._run_check("", [('startendtag', 'a$b', [])]) - self._run_check("", [('starttag', 'a$b', [])]) - self._run_check("", [('startendtag', 'a$b', [])]) - - def test_slashes_in_starttag(self): - self._run_check('', [('startendtag', 'a', [('foo', 'var')])]) - html = ('') - expected = [( - 'startendtag', 'img', - [('width', '902'), ('height', '250px'), - ('src', '/sites/default/files/images/homepage/foo.jpg'), - ('*what', None), ('am', None), ('i', None), - ('doing', None), ('here*', None)] - )] - self._run_check(html, expected) - html = ('' - '') - expected = [ - ('startendtag', 'a', [('foo', None), ('=', None), ('bar', None)]), - ('starttag', 'a', [('foo', None), ('=', None), ('bar', None)]) - ] - self._run_check(html, expected) - #see issue #14538 - html = ('' - '') - expected = [ - ('starttag', 'meta', []), ('starttag', 'meta', []), - ('starttag', 'meta', []), ('starttag', 'meta', []), - ('startendtag', 'meta', []), ('startendtag', 'meta', []), - ('startendtag', 'meta', []), ('startendtag', 'meta', []), - ] - self._run_check(html, expected) - - def test_declaration_junk_chars(self): - self._run_check("", [('decl', 'DOCTYPE foo $ ')]) - - def test_illegal_declarations(self): - self._run_check('', - [('comment', 'spacer type="block" height="25"')]) - - def test_invalid_end_tags(self): - # A collection of broken end tags.
is used as separator. - # see http://www.w3.org/TR/html5/tokenization.html#end-tag-open-state - # and #13993 - html = ('



' - '


') - expected = [('starttag', 'br', []), - # < is part of the name, / is discarded, p is an attribute - ('endtag', 'label<'), - ('starttag', 'br', []), - # text and attributes are discarded - ('endtag', 'div'), - ('starttag', 'br', []), - # comment because the first char after is ignored - ('starttag', 'br', [])] - self._run_check(html, expected) - - def test_broken_invalid_end_tag(self): - # This is technically wrong (the "> shouldn't be included in the 'data') - # but is probably not worth fixing it (in addition to all the cases of - # the previous test, it would require a full attribute parsing). - # see #13993 - html = 'This confuses the parser' - expected = [('starttag', 'b', []), - ('data', 'This'), - ('endtag', 'b'), - ('data', '"> confuses the parser')] - self._run_check(html, expected) - - def test_correct_detection_of_start_tags(self): - # see #13273 - html = ('

The rain ' - '
in Spain
') - expected = [ - ('starttag', 'div', [('style', '')]), - ('starttag', 'b', []), - ('data', 'The '), - ('starttag', 'a', [('href', 'some_url')]), - ('data', 'rain'), - ('endtag', 'a'), - ('data', ' '), - ('startendtag', 'br', []), - ('data', ' in '), - ('starttag', 'span', []), - ('data', 'Spain'), - ('endtag', 'span'), - ('endtag', 'b'), - ('endtag', 'div') - ] - self._run_check(html, expected) - - html = '
The rain' - expected = [ - ('starttag', 'div', [('style', ''), (',', None), ('foo', 'bar')]), - ('starttag', 'b', []), - ('data', 'The '), - ('starttag', 'a', [('href', 'some_url')]), - ('data', 'rain'), - ('endtag', 'a'), - ] - self._run_check(html, expected) - - def test_EOF_in_charref(self): - # see #17802 - # This test checks that the UnboundLocalError reported in the issue - # is not raised, however I'm not sure the returned values are correct. - # Maybe HTMLParser should use self.unescape for these - data = [ - ('a&', [('data', 'a&')]), - ('a&b', [('data', 'ab')]), - ('a&b ', [('data', 'a'), ('entityref', 'b'), ('data', ' ')]), - ('a&b;', [('data', 'a'), ('entityref', 'b')]), - ] - for html, expected in data: - self._run_check(html, expected) - - def test_unescape_method(self): - from html import unescape - p = self.get_collector() - with self.assertWarns(DeprecationWarning): - s = '""""""&#bad;' - self.assertEqual(p.unescape(s), unescape(s)) - - def test_broken_comments(self): - html = ('' - '' - '' - '' - '') - expected = [ - ('comment', ' not really a comment '), - ('comment', ' not a comment either --'), - ('comment', ' -- close enough --'), - ('comment', ''), - ('comment', '<-- this was an empty comment'), - ('comment', '!! another bogus comment !!!'), - ] - self._run_check(html, expected) - - def test_broken_condcoms(self): - # these condcoms are missing the '--' after '' - html = ('broken condcom' - '' - '' - 'foo' - '') - # According to the HTML5 specs sections "8.2.4.44 Bogus comment state" - # and "8.2.4.45 Markup declaration open state", comment tokens should - # be emitted instead of 'unknown decl', but calling unknown_decl - # provides more flexibility. - # See also Lib/_markupbase.py:parse_declaration - expected = [ - ('unknown decl', 'if !(IE)'), - ('data', 'broken condcom'), - ('unknown decl', 'endif'), - ('unknown decl', 'if ! IE'), - ('startendtag', 'link', [('href', 'favicon.tiff')]), - ('unknown decl', 'endif'), - ('unknown decl', 'if !IE 6'), - ('startendtag', 'img', [('src', 'firefox.png')]), - ('unknown decl', 'endif'), - ('unknown decl', 'if !ie 6'), - ('starttag', 'b', []), - ('data', 'foo'), - ('endtag', 'b'), - ('unknown decl', 'endif'), - ('unknown decl', 'if (!IE)|(lt IE 9)'), - ('startendtag', 'img', [('src', 'mammoth.bmp')]), - ('unknown decl', 'endif') - ] - self._run_check(html, expected) - - def test_convert_charrefs_dropped_text(self): - # #23144: make sure that all the events are triggered when - # convert_charrefs is True, even if we don't call .close() - parser = EventCollector(convert_charrefs=True) - # before the fix, bar & baz was missing - parser.feed("foo link bar & baz") - self.assertEqual( - parser.get_events(), - [('data', 'foo '), ('starttag', 'a', []), ('data', 'link'), - ('endtag', 'a'), ('data', ' bar & baz')] - ) - - - class AttributesTestCase(TestCaseBase): - - def test_attr_syntax(self): - output = [ - ("starttag", "a", [("b", "v"), ("c", "v"), ("d", "v"), ("e", None)]) - ] - self._run_check("""""", output) - self._run_check("""""", output) - self._run_check("""""", output) - self._run_check("""""", output) - - def test_attr_values(self): - self._run_check("""""", - [("starttag", "a", [("b", "xxx\n\txxx"), - ("c", "yyy\t\nyyy"), - ("d", "\txyz\n")])]) - self._run_check("""""", - [("starttag", "a", [("b", ""), ("c", "")])]) - # Regression test for SF patch #669683. - self._run_check("", - [("starttag", "e", [("a", "rgb(1,2,3)")])]) - # Regression test for SF bug #921657. - self._run_check( - "", - [("starttag", "a", [("href", "mailto:xyz@example.com")])]) - - def test_attr_nonascii(self): - # see issue 7311 - self._run_check( - "\u4e2d\u6587", - [("starttag", "img", [("src", "/foo/bar.png"), - ("alt", "\u4e2d\u6587")])]) - self._run_check( - "", - [("starttag", "a", [("title", "\u30c6\u30b9\u30c8"), - ("href", "\u30c6\u30b9\u30c8.html")])]) - self._run_check( - '', - [("starttag", "a", [("title", "\u30c6\u30b9\u30c8"), - ("href", "\u30c6\u30b9\u30c8.html")])]) - - def test_attr_entity_replacement(self): - self._run_check( - "", - [("starttag", "a", [("b", "&><\"'")])]) - - def test_attr_funky_names(self): - self._run_check( - "", - [("starttag", "a", [("a.b", "v"), ("c:d", "v"), ("e-f", "v")])]) - - def test_entityrefs_in_attributes(self): - self._run_check( - "", - [("starttag", "html", [("foo", "\u20AC&aa&unsupported;")])]) - - - def test_attr_funky_names2(self): - self._run_check( - r"", - [("starttag", "a", [("$", None)]), - ("starttag", "b", [("$", "%")]), - ("starttag", "c", [("\\", "/")])]) - - def test_entities_in_attribute_value(self): - # see #1200313 - for entity in ['&', '&', '&', '&']: - self._run_check('' % entity, - [("starttag", "a", [("href", "&")])]) - self._run_check("" % entity, - [("starttag", "a", [("href", "&")])]) - self._run_check("" % entity, - [("starttag", "a", [("href", "&")])]) - - def test_malformed_attributes(self): - # see #13357 - html = ( - "test - bad1" - "test - bad2" - "test - bad3" - "test - bad4" - ) - expected = [ - ('starttag', 'a', [('href', "test'style='color:red;bad1'")]), - ('data', 'test - bad1'), ('endtag', 'a'), - ('starttag', 'a', [('href', "test'+style='color:red;ba2'")]), - ('data', 'test - bad2'), ('endtag', 'a'), - ('starttag', 'a', [('href', "test'\xa0style='color:red;bad3'")]), - ('data', 'test - bad3'), ('endtag', 'a'), - ('starttag', 'a', [('href', "test'\xa0style='color:red;bad4'")]), - ('data', 'test - bad4'), ('endtag', 'a') - ] - self._run_check(html, expected) - - def test_malformed_adjacent_attributes(self): - # see #12629 - self._run_check('', - [('starttag', 'x', []), - ('startendtag', 'y', [('z', ''), ('o""', None)]), - ('endtag', 'x')]) - self._run_check('', - [('starttag', 'x', []), - ('startendtag', 'y', [('z', ''), ('""', None)]), - ('endtag', 'x')]) - - # see #755670 for the following 3 tests - def test_adjacent_attributes(self): - self._run_check('', - [("starttag", "a", - [("width", "100%"), ("cellspacing","0")])]) - - self._run_check('', - [("starttag", "a", - [("id", "foo"), ("class","bar")])]) - - def test_missing_attribute_value(self): - self._run_check('', - [("starttag", "a", [("v", "")])]) - - def test_javascript_attribute_value(self): - self._run_check("", - [("starttag", "a", - [("href", "javascript:popup('/popup/help.html')")])]) - - def test_end_tag_in_attribute_value(self): - # see #1745761 - self._run_check("spam", - [("starttag", "a", - [("href", "http://www.example.org/\">;")]), - ("data", "spam"), ("endtag", "a")]) - - def test_with_unquoted_attributes(self): - # see #12008 - html = ("" - "
%s
" - "
" - "- software-and-i" - "- library
") - expected = [ - ('starttag', 'html', []), - ('starttag', 'body', [('bgcolor', 'd0ca90'), ('text', '181008')]), - ('starttag', 'table', - [('cellspacing', '0'), ('cellpadding', '1'), ('width', '100%')]), - ('starttag', 'tr', []), - ('starttag', 'td', [('align', 'left')]), - ('starttag', 'font', [('size', '-1')]), - ('data', '- '), ('starttag', 'a', [('href', '/rabota/')]), - ('starttag', 'span', [('class', 'en')]), ('data', ' software-and-i'), - ('endtag', 'span'), ('endtag', 'a'), - ('data', '- '), ('starttag', 'a', [('href', '/1/')]), - ('starttag', 'span', [('class', 'en')]), ('data', ' library'), - ('endtag', 'span'), ('endtag', 'a'), ('endtag', 'table') - ] - self._run_check(html, expected) - - def test_comma_between_attributes(self): - # see bpo 41478 - # HTMLParser preserves duplicate attributes, leaving the task of - # removing duplicate attributes to a conformant html tree builder - html = ('
' # between attrs (unquoted) - '
' # between attrs (quoted) - '
' # after values (unquoted) - '
' # after values (quoted) - '
' # one comma values (quoted) - '
' # before values (unquoted) - '
' # before values (quoted) - '
' # before names - '
' # after names - ) - expected = [ - ('starttag', 'div', [('class', 'bar,baz=asd'),]), - ('starttag', 'div', [('class', 'bar'), (',baz', 'asd')]), - ('starttag', 'div', [('class', 'bar,'), ('baz', 'asd,')]), - ('starttag', 'div', [('class', 'bar'), (',', None), - ('baz', 'asd'), (',', None)]), - ('starttag', 'div', [('class', 'bar'), (',', None)]), - ('starttag', 'div', [('class', ',bar'), ('baz', ',asd')]), - ('starttag', 'div', [('class', ',"bar"'), ('baz', ',"asd"')]), - ('starttag', 'div', [(',class', 'bar'), (',baz', 'asd')]), - ('starttag', 'div', [('class,', 'bar'), ('baz,', 'asd')]), - ] - self._run_check(html, expected) - - def test_weird_chars_in_unquoted_attribute_values(self): - self._run_check('
', [ - ('starttag', 'form', - [('action', 'bogus|&#()value')])]) - - if __name__ == "__main__": - unittest.main() diff --git a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_http_cookiejar.yaml b/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_http_cookiejar.yaml deleted file mode 100644 index 7b49d518e..000000000 --- a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_http_cookiejar.yaml +++ /dev/null @@ -1,1927 +0,0 @@ -python: | - """Tests for http/cookiejar.py.""" - - import os - import re - import test.support - import time - import unittest - import urllib.request - import pathlib - - from http.cookiejar import (time2isoz, http2time, iso2time, time2netscape, - parse_ns_headers, join_header_words, split_header_words, Cookie, - CookieJar, DefaultCookiePolicy, LWPCookieJar, MozillaCookieJar, - LoadError, lwp_cookie_str, DEFAULT_HTTP_PORT, escape_path, - reach, is_HDN, domain_match, user_domain_match, request_path, - request_port, request_host) - - - class DateTimeTests(unittest.TestCase): - - def test_time2isoz(self): - base = 1019227000 - day = 24*3600 - self.assertEqual(time2isoz(base), "2002-04-19 14:36:40Z") - self.assertEqual(time2isoz(base+day), "2002-04-20 14:36:40Z") - self.assertEqual(time2isoz(base+2*day), "2002-04-21 14:36:40Z") - self.assertEqual(time2isoz(base+3*day), "2002-04-22 14:36:40Z") - - az = time2isoz() - bz = time2isoz(500000) - for text in (az, bz): - self.assertRegex(text, r"^\d{4}-\d\d-\d\d \d\d:\d\d:\d\dZ$", - "bad time2isoz format: %s %s" % (az, bz)) - - def test_time2netscape(self): - base = 1019227000 - day = 24*3600 - self.assertEqual(time2netscape(base), "Fri, 19-Apr-2002 14:36:40 GMT") - self.assertEqual(time2netscape(base+day), - "Sat, 20-Apr-2002 14:36:40 GMT") - - self.assertEqual(time2netscape(base+2*day), - "Sun, 21-Apr-2002 14:36:40 GMT") - - self.assertEqual(time2netscape(base+3*day), - "Mon, 22-Apr-2002 14:36:40 GMT") - - az = time2netscape() - bz = time2netscape(500000) - for text in (az, bz): - # Format "%s, %02d-%s-%04d %02d:%02d:%02d GMT" - self.assertRegex( - text, - r"[a-zA-Z]{3}, \d{2}-[a-zA-Z]{3}-\d{4} \d{2}:\d{2}:\d{2} GMT$", - "bad time2netscape format: %s %s" % (az, bz)) - - def test_http2time(self): - def parse_date(text): - return time.gmtime(http2time(text))[:6] - - self.assertEqual(parse_date("01 Jan 2001"), (2001, 1, 1, 0, 0, 0.0)) - - # this test will break around year 2070 - self.assertEqual(parse_date("03-Feb-20"), (2020, 2, 3, 0, 0, 0.0)) - - # this test will break around year 2048 - self.assertEqual(parse_date("03-Feb-98"), (1998, 2, 3, 0, 0, 0.0)) - - def test_http2time_formats(self): - # test http2time for supported dates. Test cases with 2 digit year - # will probably break in year 2044. - tests = [ - 'Thu, 03 Feb 1994 00:00:00 GMT', # proposed new HTTP format - 'Thursday, 03-Feb-94 00:00:00 GMT', # old rfc850 HTTP format - 'Thursday, 03-Feb-1994 00:00:00 GMT', # broken rfc850 HTTP format - - '03 Feb 1994 00:00:00 GMT', # HTTP format (no weekday) - '03-Feb-94 00:00:00 GMT', # old rfc850 (no weekday) - '03-Feb-1994 00:00:00 GMT', # broken rfc850 (no weekday) - '03-Feb-1994 00:00 GMT', # broken rfc850 (no weekday, no seconds) - '03-Feb-1994 00:00', # broken rfc850 (no weekday, no seconds, no tz) - '02-Feb-1994 24:00', # broken rfc850 (no weekday, no seconds, - # no tz) using hour 24 with yesterday date - - '03-Feb-94', # old rfc850 HTTP format (no weekday, no time) - '03-Feb-1994', # broken rfc850 HTTP format (no weekday, no time) - '03 Feb 1994', # proposed new HTTP format (no weekday, no time) - - # A few tests with extra space at various places - ' 03 Feb 1994 0:00 ', - ' 03-Feb-1994 ', - ] - - test_t = 760233600 # assume broken POSIX counting of seconds - result = time2isoz(test_t) - expected = "1994-02-03 00:00:00Z" - self.assertEqual(result, expected, - "%s => '%s' (%s)" % (test_t, result, expected)) - - for s in tests: - self.assertEqual(http2time(s), test_t, s) - self.assertEqual(http2time(s.lower()), test_t, s.lower()) - self.assertEqual(http2time(s.upper()), test_t, s.upper()) - - def test_http2time_garbage(self): - for test in [ - '', - 'Garbage', - 'Mandag 16. September 1996', - '01-00-1980', - '01-13-1980', - '00-01-1980', - '32-01-1980', - '01-01-1980 25:00:00', - '01-01-1980 00:61:00', - '01-01-1980 00:00:62', - '08-Oct-3697739', - '08-01-3697739', - '09 Feb 19942632 22:23:32 GMT', - 'Wed, 09 Feb 1994834 22:23:32 GMT', - ]: - self.assertIsNone(http2time(test), - "http2time(%s) is not None\n" - "http2time(test) %s" % (test, http2time(test))) - - def test_http2time_redos_regression_actually_completes(self): - # LOOSE_HTTP_DATE_RE was vulnerable to malicious input which caused catastrophic backtracking (REDoS). - # If we regress to cubic complexity, this test will take a very long time to succeed. - # If fixed, it should complete within a fraction of a second. - http2time("01 Jan 1970{}00:00:00 GMT!".format(" " * 10 ** 5)) - http2time("01 Jan 1970 00:00:00{}GMT!".format(" " * 10 ** 5)) - - def test_iso2time(self): - def parse_date(text): - return time.gmtime(iso2time(text))[:6] - - # ISO 8601 compact format - self.assertEqual(parse_date("19940203T141529Z"), - (1994, 2, 3, 14, 15, 29)) - - # ISO 8601 with time behind UTC - self.assertEqual(parse_date("1994-02-03 07:15:29 -0700"), - (1994, 2, 3, 14, 15, 29)) - - # ISO 8601 with time ahead of UTC - self.assertEqual(parse_date("1994-02-03 19:45:29 +0530"), - (1994, 2, 3, 14, 15, 29)) - - def test_iso2time_formats(self): - # test iso2time for supported dates. - tests = [ - '1994-02-03 00:00:00 -0000', # ISO 8601 format - '1994-02-03 00:00:00 +0000', # ISO 8601 format - '1994-02-03 00:00:00', # zone is optional - '1994-02-03', # only date - '1994-02-03T00:00:00', # Use T as separator - '19940203', # only date - '1994-02-02 24:00:00', # using hour-24 yesterday date - '19940203T000000Z', # ISO 8601 compact format - - # A few tests with extra space at various places - ' 1994-02-03 ', - ' 1994-02-03T00:00:00 ', - ] - - test_t = 760233600 # assume broken POSIX counting of seconds - for s in tests: - self.assertEqual(iso2time(s), test_t, s) - self.assertEqual(iso2time(s.lower()), test_t, s.lower()) - self.assertEqual(iso2time(s.upper()), test_t, s.upper()) - - def test_iso2time_garbage(self): - for test in [ - '', - 'Garbage', - 'Thursday, 03-Feb-94 00:00:00 GMT', - '1980-00-01', - '1980-13-01', - '1980-01-00', - '1980-01-32', - '1980-01-01 25:00:00', - '1980-01-01 00:61:00', - '01-01-1980 00:00:62', - '01-01-1980T00:00:62', - '19800101T250000Z', - ]: - self.assertIsNone(iso2time(test), - "iso2time(%r)" % test) - - def test_iso2time_performance_regression(self): - # If ISO_DATE_RE regresses to quadratic complexity, this test will take a very long time to succeed. - # If fixed, it should complete within a fraction of a second. - iso2time('1994-02-03{}14:15:29 -0100!'.format(' '*10**6)) - iso2time('1994-02-03 14:15:29{}-0100!'.format(' '*10**6)) - - - class HeaderTests(unittest.TestCase): - - def test_parse_ns_headers(self): - # quotes should be stripped - expected = [[('foo', 'bar'), ('expires', 2209069412), ('version', '0')]] - for hdr in [ - 'foo=bar; expires=01 Jan 2040 22:23:32 GMT', - 'foo=bar; expires="01 Jan 2040 22:23:32 GMT"', - ]: - self.assertEqual(parse_ns_headers([hdr]), expected) - - def test_parse_ns_headers_version(self): - - # quotes should be stripped - expected = [[('foo', 'bar'), ('version', '1')]] - for hdr in [ - 'foo=bar; version="1"', - 'foo=bar; Version="1"', - ]: - self.assertEqual(parse_ns_headers([hdr]), expected) - - def test_parse_ns_headers_special_names(self): - # names such as 'expires' are not special in first name=value pair - # of Set-Cookie: header - # Cookie with name 'expires' - hdr = 'expires=01 Jan 2040 22:23:32 GMT' - expected = [[("expires", "01 Jan 2040 22:23:32 GMT"), ("version", "0")]] - self.assertEqual(parse_ns_headers([hdr]), expected) - - def test_join_header_words(self): - joined = join_header_words([[("foo", None), ("bar", "baz")]]) - self.assertEqual(joined, "foo; bar=baz") - - self.assertEqual(join_header_words([[]]), "") - - def test_split_header_words(self): - tests = [ - ("foo", [[("foo", None)]]), - ("foo=bar", [[("foo", "bar")]]), - (" foo ", [[("foo", None)]]), - (" foo= ", [[("foo", "")]]), - (" foo=", [[("foo", "")]]), - (" foo= ; ", [[("foo", "")]]), - (" foo= ; bar= baz ", [[("foo", ""), ("bar", "baz")]]), - ("foo=bar bar=baz", [[("foo", "bar"), ("bar", "baz")]]), - # doesn't really matter if this next fails, but it works ATM - ("foo= bar=baz", [[("foo", "bar=baz")]]), - ("foo=bar;bar=baz", [[("foo", "bar"), ("bar", "baz")]]), - ('foo bar baz', [[("foo", None), ("bar", None), ("baz", None)]]), - ("a, b, c", [[("a", None)], [("b", None)], [("c", None)]]), - (r'foo; bar=baz, spam=, foo="\,\;\"", bar= ', - [[("foo", None), ("bar", "baz")], - [("spam", "")], [("foo", ',;"')], [("bar", "")]]), - ] - - for arg, expect in tests: - try: - result = split_header_words([arg]) - except: - import traceback, io - f = io.StringIO() - traceback.print_exc(None, f) - result = "(error -- traceback follows)\n\n%s" % f.getvalue() - self.assertEqual(result, expect, """ - When parsing: '%s' - Expected: '%s' - Got: '%s' - """ % (arg, expect, result)) - - def test_roundtrip(self): - tests = [ - ("foo", "foo"), - ("foo=bar", "foo=bar"), - (" foo ", "foo"), - ("foo=", 'foo=""'), - ("foo=bar bar=baz", "foo=bar; bar=baz"), - ("foo=bar;bar=baz", "foo=bar; bar=baz"), - ('foo bar baz', "foo; bar; baz"), - (r'foo="\"" bar="\\"', r'foo="\""; bar="\\"'), - ('foo,,,bar', 'foo, bar'), - ('foo=bar,bar=baz', 'foo=bar, bar=baz'), - - ('text/html; charset=iso-8859-1', - 'text/html; charset="iso-8859-1"'), - - ('foo="bar"; port="80,81"; discard, bar=baz', - 'foo=bar; port="80,81"; discard, bar=baz'), - - (r'Basic realm="\"foo\\\\bar\""', - r'Basic; realm="\"foo\\\\bar\""') - ] - - for arg, expect in tests: - input = split_header_words([arg]) - res = join_header_words(input) - self.assertEqual(res, expect, """ - When parsing: '%s' - Expected: '%s' - Got: '%s' - Input was: '%s' - """ % (arg, expect, res, input)) - - - class FakeResponse: - def __init__(self, headers=[], url=None): - """ - headers: list of RFC822-style 'Key: value' strings - """ - import email - self._headers = email.message_from_string("\n".join(headers)) - self._url = url - def info(self): return self._headers - - def interact_2965(cookiejar, url, *set_cookie_hdrs): - return _interact(cookiejar, url, set_cookie_hdrs, "Set-Cookie2") - - def interact_netscape(cookiejar, url, *set_cookie_hdrs): - return _interact(cookiejar, url, set_cookie_hdrs, "Set-Cookie") - - def _interact(cookiejar, url, set_cookie_hdrs, hdr_name): - """Perform a single request / response cycle, returning Cookie: header.""" - req = urllib.request.Request(url) - cookiejar.add_cookie_header(req) - cookie_hdr = req.get_header("Cookie", "") - headers = [] - for hdr in set_cookie_hdrs: - headers.append("%s: %s" % (hdr_name, hdr)) - res = FakeResponse(headers, url) - cookiejar.extract_cookies(res, req) - return cookie_hdr - - - class FileCookieJarTests(unittest.TestCase): - def test_constructor_with_str(self): - filename = test.support.TESTFN - c = LWPCookieJar(filename) - self.assertEqual(c.filename, filename) - - def test_constructor_with_path_like(self): - filename = pathlib.Path(test.support.TESTFN) - c = LWPCookieJar(filename) - self.assertEqual(c.filename, os.fspath(filename)) - - def test_constructor_with_none(self): - c = LWPCookieJar(None) - self.assertIsNone(c.filename) - - def test_constructor_with_other_types(self): - class A: - pass - - for type_ in (int, float, A): - with self.subTest(filename=type_): - with self.assertRaises(TypeError): - instance = type_() - c = LWPCookieJar(filename=instance) - - def test_lwp_valueless_cookie(self): - # cookies with no value should be saved and loaded consistently - filename = test.support.TESTFN - c = LWPCookieJar() - interact_netscape(c, "http://www.acme.com/", 'boo') - self.assertEqual(c._cookies["www.acme.com"]["/"]["boo"].value, None) - try: - c.save(filename, ignore_discard=True) - c = LWPCookieJar() - c.load(filename, ignore_discard=True) - finally: - try: os.unlink(filename) - except OSError: pass - self.assertEqual(c._cookies["www.acme.com"]["/"]["boo"].value, None) - - def test_bad_magic(self): - # OSErrors (eg. file doesn't exist) are allowed to propagate - filename = test.support.TESTFN - for cookiejar_class in LWPCookieJar, MozillaCookieJar: - c = cookiejar_class() - try: - c.load(filename="for this test to work, a file with this " - "filename should not exist") - except OSError as exc: - # an OSError subclass (likely FileNotFoundError), but not - # LoadError - self.assertIsNot(exc.__class__, LoadError) - else: - self.fail("expected OSError for invalid filename") - # Invalid contents of cookies file (eg. bad magic string) - # causes a LoadError. - try: - with open(filename, "w") as f: - f.write("oops\n") - for cookiejar_class in LWPCookieJar, MozillaCookieJar: - c = cookiejar_class() - self.assertRaises(LoadError, c.load, filename) - finally: - try: os.unlink(filename) - except OSError: pass - - class CookieTests(unittest.TestCase): - # XXX - # Get rid of string comparisons where not actually testing str / repr. - # .clear() etc. - # IP addresses like 50 (single number, no dot) and domain-matching - # functions (and is_HDN)? See draft RFC 2965 errata. - # Strictness switches - # is_third_party() - # unverifiability / third-party blocking - # Netscape cookies work the same as RFC 2965 with regard to port. - # Set-Cookie with negative max age. - # If turn RFC 2965 handling off, Set-Cookie2 cookies should not clobber - # Set-Cookie cookies. - # Cookie2 should be sent if *any* cookies are not V1 (ie. V0 OR V2 etc.). - # Cookies (V1 and V0) with no expiry date should be set to be discarded. - # RFC 2965 Quoting: - # Should accept unquoted cookie-attribute values? check errata draft. - # Which are required on the way in and out? - # Should always return quoted cookie-attribute values? - # Proper testing of when RFC 2965 clobbers Netscape (waiting for errata). - # Path-match on return (same for V0 and V1). - # RFC 2965 acceptance and returning rules - # Set-Cookie2 without version attribute is rejected. - - # Netscape peculiarities list from Ronald Tschalar. - # The first two still need tests, the rest are covered. - ## - Quoting: only quotes around the expires value are recognized as such - ## (and yes, some folks quote the expires value); quotes around any other - ## value are treated as part of the value. - ## - White space: white space around names and values is ignored - ## - Default path: if no path parameter is given, the path defaults to the - ## path in the request-uri up to, but not including, the last '/'. Note - ## that this is entirely different from what the spec says. - ## - Commas and other delimiters: Netscape just parses until the next ';'. - ## This means it will allow commas etc inside values (and yes, both - ## commas and equals are commonly appear in the cookie value). This also - ## means that if you fold multiple Set-Cookie header fields into one, - ## comma-separated list, it'll be a headache to parse (at least my head - ## starts hurting every time I think of that code). - ## - Expires: You'll get all sorts of date formats in the expires, - ## including empty expires attributes ("expires="). Be as flexible as you - ## can, and certainly don't expect the weekday to be there; if you can't - ## parse it, just ignore it and pretend it's a session cookie. - ## - Domain-matching: Netscape uses the 2-dot rule for _all_ domains, not - ## just the 7 special TLD's listed in their spec. And folks rely on - ## that... - - def test_domain_return_ok(self): - # test optimization: .domain_return_ok() should filter out most - # domains in the CookieJar before we try to access them (because that - # may require disk access -- in particular, with MSIECookieJar) - # This is only a rough check for performance reasons, so it's not too - # critical as long as it's sufficiently liberal. - pol = DefaultCookiePolicy() - for url, domain, ok in [ - ("http://foo.bar.com/", "blah.com", False), - ("http://foo.bar.com/", "rhubarb.blah.com", False), - ("http://foo.bar.com/", "rhubarb.foo.bar.com", False), - ("http://foo.bar.com/", ".foo.bar.com", True), - ("http://foo.bar.com/", "foo.bar.com", True), - ("http://foo.bar.com/", ".bar.com", True), - ("http://foo.bar.com/", "bar.com", True), - ("http://foo.bar.com/", "com", True), - ("http://foo.com/", "rhubarb.foo.com", False), - ("http://foo.com/", ".foo.com", True), - ("http://foo.com/", "foo.com", True), - ("http://foo.com/", "com", True), - ("http://foo/", "rhubarb.foo", False), - ("http://foo/", ".foo", True), - ("http://foo/", "foo", True), - ("http://foo/", "foo.local", True), - ("http://foo/", ".local", True), - ("http://barfoo.com", ".foo.com", False), - ("http://barfoo.com", "foo.com", False), - ]: - request = urllib.request.Request(url) - r = pol.domain_return_ok(domain, request) - if ok: self.assertTrue(r) - else: self.assertFalse(r) - - def test_missing_value(self): - # missing = sign in Cookie: header is regarded by Mozilla as a missing - # name, and by http.cookiejar as a missing value - filename = test.support.TESTFN - c = MozillaCookieJar(filename) - interact_netscape(c, "http://www.acme.com/", 'eggs') - interact_netscape(c, "http://www.acme.com/", '"spam"; path=/foo/') - cookie = c._cookies["www.acme.com"]["/"]["eggs"] - self.assertIsNone(cookie.value) - self.assertEqual(cookie.name, "eggs") - cookie = c._cookies["www.acme.com"]['/foo/']['"spam"'] - self.assertIsNone(cookie.value) - self.assertEqual(cookie.name, '"spam"') - self.assertEqual(lwp_cookie_str(cookie), ( - r'"spam"; path="/foo/"; domain="www.acme.com"; ' - 'path_spec; discard; version=0')) - old_str = repr(c) - c.save(ignore_expires=True, ignore_discard=True) - try: - c = MozillaCookieJar(filename) - c.revert(ignore_expires=True, ignore_discard=True) - finally: - os.unlink(c.filename) - # cookies unchanged apart from lost info re. whether path was specified - self.assertEqual( - repr(c), - re.sub("path_specified=%s" % True, "path_specified=%s" % False, - old_str) - ) - self.assertEqual(interact_netscape(c, "http://www.acme.com/foo/"), - '"spam"; eggs') - - def test_rfc2109_handling(self): - # RFC 2109 cookies are handled as RFC 2965 or Netscape cookies, - # dependent on policy settings - for rfc2109_as_netscape, rfc2965, version in [ - # default according to rfc2965 if not explicitly specified - (None, False, 0), - (None, True, 1), - # explicit rfc2109_as_netscape - (False, False, None), # version None here means no cookie stored - (False, True, 1), - (True, False, 0), - (True, True, 0), - ]: - policy = DefaultCookiePolicy( - rfc2109_as_netscape=rfc2109_as_netscape, - rfc2965=rfc2965) - c = CookieJar(policy) - interact_netscape(c, "http://www.example.com/", "ni=ni; Version=1") - try: - cookie = c._cookies["www.example.com"]["/"]["ni"] - except KeyError: - self.assertIsNone(version) # didn't expect a stored cookie - else: - self.assertEqual(cookie.version, version) - # 2965 cookies are unaffected - interact_2965(c, "http://www.example.com/", - "foo=bar; Version=1") - if rfc2965: - cookie2965 = c._cookies["www.example.com"]["/"]["foo"] - self.assertEqual(cookie2965.version, 1) - - def test_ns_parser(self): - c = CookieJar() - interact_netscape(c, "http://www.acme.com/", - 'spam=eggs; DoMain=.acme.com; port; blArgh="feep"') - interact_netscape(c, "http://www.acme.com/", 'ni=ni; port=80,8080') - interact_netscape(c, "http://www.acme.com:80/", 'nini=ni') - interact_netscape(c, "http://www.acme.com:80/", 'foo=bar; expires=') - interact_netscape(c, "http://www.acme.com:80/", 'spam=eggs; ' - 'expires="Foo Bar 25 33:22:11 3022"') - interact_netscape(c, 'http://www.acme.com/', 'fortytwo=') - interact_netscape(c, 'http://www.acme.com/', '=unladenswallow') - interact_netscape(c, 'http://www.acme.com/', 'holyhandgrenade') - - cookie = c._cookies[".acme.com"]["/"]["spam"] - self.assertEqual(cookie.domain, ".acme.com") - self.assertTrue(cookie.domain_specified) - self.assertEqual(cookie.port, DEFAULT_HTTP_PORT) - self.assertFalse(cookie.port_specified) - # case is preserved - self.assertTrue(cookie.has_nonstandard_attr("blArgh")) - self.assertFalse(cookie.has_nonstandard_attr("blargh")) - - cookie = c._cookies["www.acme.com"]["/"]["ni"] - self.assertEqual(cookie.domain, "www.acme.com") - self.assertFalse(cookie.domain_specified) - self.assertEqual(cookie.port, "80,8080") - self.assertTrue(cookie.port_specified) - - cookie = c._cookies["www.acme.com"]["/"]["nini"] - self.assertIsNone(cookie.port) - self.assertFalse(cookie.port_specified) - - # invalid expires should not cause cookie to be dropped - foo = c._cookies["www.acme.com"]["/"]["foo"] - spam = c._cookies["www.acme.com"]["/"]["foo"] - self.assertIsNone(foo.expires) - self.assertIsNone(spam.expires) - - cookie = c._cookies['www.acme.com']['/']['fortytwo'] - self.assertIsNotNone(cookie.value) - self.assertEqual(cookie.value, '') - - # there should be a distinction between a present but empty value - # (above) and a value that's entirely missing (below) - - cookie = c._cookies['www.acme.com']['/']['holyhandgrenade'] - self.assertIsNone(cookie.value) - - def test_ns_parser_special_names(self): - # names such as 'expires' are not special in first name=value pair - # of Set-Cookie: header - c = CookieJar() - interact_netscape(c, "http://www.acme.com/", 'expires=eggs') - interact_netscape(c, "http://www.acme.com/", 'version=eggs; spam=eggs') - - cookies = c._cookies["www.acme.com"]["/"] - self.assertIn('expires', cookies) - self.assertIn('version', cookies) - - def test_expires(self): - # if expires is in future, keep cookie... - c = CookieJar() - future = time2netscape(time.time()+3600) - - with test.support.check_no_warnings(self): - headers = [f"Set-Cookie: FOO=BAR; path=/; expires={future}"] - req = urllib.request.Request("http://www.coyote.com/") - res = FakeResponse(headers, "http://www.coyote.com/") - cookies = c.make_cookies(res, req) - self.assertEqual(len(cookies), 1) - self.assertEqual(time2netscape(cookies[0].expires), future) - - interact_netscape(c, "http://www.acme.com/", 'spam="bar"; expires=%s' % - future) - self.assertEqual(len(c), 1) - now = time2netscape(time.time()-1) - # ... and if in past or present, discard it - interact_netscape(c, "http://www.acme.com/", 'foo="eggs"; expires=%s' % - now) - h = interact_netscape(c, "http://www.acme.com/") - self.assertEqual(len(c), 1) - self.assertIn('spam="bar"', h) - self.assertNotIn("foo", h) - - # max-age takes precedence over expires, and zero max-age is request to - # delete both new cookie and any old matching cookie - interact_netscape(c, "http://www.acme.com/", 'eggs="bar"; expires=%s' % - future) - interact_netscape(c, "http://www.acme.com/", 'bar="bar"; expires=%s' % - future) - self.assertEqual(len(c), 3) - interact_netscape(c, "http://www.acme.com/", 'eggs="bar"; ' - 'expires=%s; max-age=0' % future) - interact_netscape(c, "http://www.acme.com/", 'bar="bar"; ' - 'max-age=0; expires=%s' % future) - h = interact_netscape(c, "http://www.acme.com/") - self.assertEqual(len(c), 1) - - # test expiry at end of session for cookies with no expires attribute - interact_netscape(c, "http://www.rhubarb.net/", 'whum="fizz"') - self.assertEqual(len(c), 2) - c.clear_session_cookies() - self.assertEqual(len(c), 1) - self.assertIn('spam="bar"', h) - - # test if fractional expiry is accepted - cookie = Cookie(0, "name", "value", - None, False, "www.python.org", - True, False, "/", - False, False, "1444312383.018307", - False, None, None, - {}) - self.assertEqual(cookie.expires, 1444312383) - - # XXX RFC 2965 expiry rules (some apply to V0 too) - - def test_default_path(self): - # RFC 2965 - pol = DefaultCookiePolicy(rfc2965=True) - - c = CookieJar(pol) - interact_2965(c, "http://www.acme.com/", 'spam="bar"; Version="1"') - self.assertIn("/", c._cookies["www.acme.com"]) - - c = CookieJar(pol) - interact_2965(c, "http://www.acme.com/blah", 'eggs="bar"; Version="1"') - self.assertIn("/", c._cookies["www.acme.com"]) - - c = CookieJar(pol) - interact_2965(c, "http://www.acme.com/blah/rhubarb", - 'eggs="bar"; Version="1"') - self.assertIn("/blah/", c._cookies["www.acme.com"]) - - c = CookieJar(pol) - interact_2965(c, "http://www.acme.com/blah/rhubarb/", - 'eggs="bar"; Version="1"') - self.assertIn("/blah/rhubarb/", c._cookies["www.acme.com"]) - - # Netscape - - c = CookieJar() - interact_netscape(c, "http://www.acme.com/", 'spam="bar"') - self.assertIn("/", c._cookies["www.acme.com"]) - - c = CookieJar() - interact_netscape(c, "http://www.acme.com/blah", 'eggs="bar"') - self.assertIn("/", c._cookies["www.acme.com"]) - - c = CookieJar() - interact_netscape(c, "http://www.acme.com/blah/rhubarb", 'eggs="bar"') - self.assertIn("/blah", c._cookies["www.acme.com"]) - - c = CookieJar() - interact_netscape(c, "http://www.acme.com/blah/rhubarb/", 'eggs="bar"') - self.assertIn("/blah/rhubarb", c._cookies["www.acme.com"]) - - def test_default_path_with_query(self): - cj = CookieJar() - uri = "http://example.com/?spam/eggs" - value = 'eggs="bar"' - interact_netscape(cj, uri, value) - # Default path does not include query, so is "/", not "/?spam". - self.assertIn("/", cj._cookies["example.com"]) - # Cookie is sent back to the same URI. - self.assertEqual(interact_netscape(cj, uri), value) - - def test_escape_path(self): - cases = [ - # quoted safe - ("/foo%2f/bar", "/foo%2F/bar"), - ("/foo%2F/bar", "/foo%2F/bar"), - # quoted % - ("/foo%%/bar", "/foo%%/bar"), - # quoted unsafe - ("/fo%19o/bar", "/fo%19o/bar"), - ("/fo%7do/bar", "/fo%7Do/bar"), - # unquoted safe - ("/foo/bar&", "/foo/bar&"), - ("/foo//bar", "/foo//bar"), - ("\176/foo/bar", "\176/foo/bar"), - # unquoted unsafe - ("/foo\031/bar", "/foo%19/bar"), - ("/\175foo/bar", "/%7Dfoo/bar"), - # unicode, latin-1 range - ("/foo/bar\u00fc", "/foo/bar%C3%BC"), # UTF-8 encoded - # unicode - ("/foo/bar\uabcd", "/foo/bar%EA%AF%8D"), # UTF-8 encoded - ] - for arg, result in cases: - self.assertEqual(escape_path(arg), result) - - def test_request_path(self): - # with parameters - req = urllib.request.Request( - "http://www.example.com/rheum/rhaponticum;" - "foo=bar;sing=song?apples=pears&spam=eggs#ni") - self.assertEqual(request_path(req), - "/rheum/rhaponticum;foo=bar;sing=song") - # without parameters - req = urllib.request.Request( - "http://www.example.com/rheum/rhaponticum?" - "apples=pears&spam=eggs#ni") - self.assertEqual(request_path(req), "/rheum/rhaponticum") - # missing final slash - req = urllib.request.Request("http://www.example.com") - self.assertEqual(request_path(req), "/") - - def test_path_prefix_match(self): - pol = DefaultCookiePolicy() - strict_ns_path_pol = DefaultCookiePolicy(strict_ns_set_path=True) - - c = CookieJar(pol) - base_url = "http://bar.com" - interact_netscape(c, base_url, 'spam=eggs; Path=/foo') - cookie = c._cookies['bar.com']['/foo']['spam'] - - for path, ok in [('/foo', True), - ('/foo/', True), - ('/foo/bar', True), - ('/', False), - ('/foobad/foo', False)]: - url = f'{base_url}{path}' - req = urllib.request.Request(url) - h = interact_netscape(c, url) - if ok: - self.assertIn('spam=eggs', h, f"cookie not set for {path}") - self.assertTrue(strict_ns_path_pol.set_ok_path(cookie, req)) - else: - self.assertNotIn('spam=eggs', h, f"cookie set for {path}") - self.assertFalse(strict_ns_path_pol.set_ok_path(cookie, req)) - - def test_request_port(self): - req = urllib.request.Request("http://www.acme.com:1234/", - headers={"Host": "www.acme.com:4321"}) - self.assertEqual(request_port(req), "1234") - req = urllib.request.Request("http://www.acme.com/", - headers={"Host": "www.acme.com:4321"}) - self.assertEqual(request_port(req), DEFAULT_HTTP_PORT) - - def test_request_host(self): - # this request is illegal (RFC2616, 14.2.3) - req = urllib.request.Request("http://1.1.1.1/", - headers={"Host": "www.acme.com:80"}) - # libwww-perl wants this response, but that seems wrong (RFC 2616, - # section 5.2, point 1., and RFC 2965 section 1, paragraph 3) - #self.assertEqual(request_host(req), "www.acme.com") - self.assertEqual(request_host(req), "1.1.1.1") - req = urllib.request.Request("http://www.acme.com/", - headers={"Host": "irrelevant.com"}) - self.assertEqual(request_host(req), "www.acme.com") - # port shouldn't be in request-host - req = urllib.request.Request("http://www.acme.com:2345/resource.html", - headers={"Host": "www.acme.com:5432"}) - self.assertEqual(request_host(req), "www.acme.com") - - def test_is_HDN(self): - self.assertTrue(is_HDN("foo.bar.com")) - self.assertTrue(is_HDN("1foo2.3bar4.5com")) - self.assertFalse(is_HDN("192.168.1.1")) - self.assertFalse(is_HDN("")) - self.assertFalse(is_HDN(".")) - self.assertFalse(is_HDN(".foo.bar.com")) - self.assertFalse(is_HDN("..foo")) - self.assertFalse(is_HDN("foo.")) - - def test_reach(self): - self.assertEqual(reach("www.acme.com"), ".acme.com") - self.assertEqual(reach("acme.com"), "acme.com") - self.assertEqual(reach("acme.local"), ".local") - self.assertEqual(reach(".local"), ".local") - self.assertEqual(reach(".com"), ".com") - self.assertEqual(reach("."), ".") - self.assertEqual(reach(""), "") - self.assertEqual(reach("192.168.0.1"), "192.168.0.1") - - def test_domain_match(self): - self.assertTrue(domain_match("192.168.1.1", "192.168.1.1")) - self.assertFalse(domain_match("192.168.1.1", ".168.1.1")) - self.assertTrue(domain_match("x.y.com", "x.Y.com")) - self.assertTrue(domain_match("x.y.com", ".Y.com")) - self.assertFalse(domain_match("x.y.com", "Y.com")) - self.assertTrue(domain_match("a.b.c.com", ".c.com")) - self.assertFalse(domain_match(".c.com", "a.b.c.com")) - self.assertTrue(domain_match("example.local", ".local")) - self.assertFalse(domain_match("blah.blah", "")) - self.assertFalse(domain_match("", ".rhubarb.rhubarb")) - self.assertTrue(domain_match("", "")) - - self.assertTrue(user_domain_match("acme.com", "acme.com")) - self.assertFalse(user_domain_match("acme.com", ".acme.com")) - self.assertTrue(user_domain_match("rhubarb.acme.com", ".acme.com")) - self.assertTrue(user_domain_match("www.rhubarb.acme.com", ".acme.com")) - self.assertTrue(user_domain_match("x.y.com", "x.Y.com")) - self.assertTrue(user_domain_match("x.y.com", ".Y.com")) - self.assertFalse(user_domain_match("x.y.com", "Y.com")) - self.assertTrue(user_domain_match("y.com", "Y.com")) - self.assertFalse(user_domain_match(".y.com", "Y.com")) - self.assertTrue(user_domain_match(".y.com", ".Y.com")) - self.assertTrue(user_domain_match("x.y.com", ".com")) - self.assertFalse(user_domain_match("x.y.com", "com")) - self.assertFalse(user_domain_match("x.y.com", "m")) - self.assertFalse(user_domain_match("x.y.com", ".m")) - self.assertFalse(user_domain_match("x.y.com", "")) - self.assertFalse(user_domain_match("x.y.com", ".")) - self.assertTrue(user_domain_match("192.168.1.1", "192.168.1.1")) - # not both HDNs, so must string-compare equal to match - self.assertFalse(user_domain_match("192.168.1.1", ".168.1.1")) - self.assertFalse(user_domain_match("192.168.1.1", ".")) - # empty string is a special case - self.assertFalse(user_domain_match("192.168.1.1", "")) - - def test_wrong_domain(self): - # Cookies whose effective request-host name does not domain-match the - # domain are rejected. - - # XXX far from complete - c = CookieJar() - interact_2965(c, "http://www.nasty.com/", - 'foo=bar; domain=friendly.org; Version="1"') - self.assertEqual(len(c), 0) - - def test_strict_domain(self): - # Cookies whose domain is a country-code tld like .co.uk should - # not be set if CookiePolicy.strict_domain is true. - cp = DefaultCookiePolicy(strict_domain=True) - cj = CookieJar(policy=cp) - interact_netscape(cj, "http://example.co.uk/", 'no=problemo') - interact_netscape(cj, "http://example.co.uk/", - 'okey=dokey; Domain=.example.co.uk') - self.assertEqual(len(cj), 2) - for pseudo_tld in [".co.uk", ".org.za", ".tx.us", ".name.us"]: - interact_netscape(cj, "http://example.%s/" % pseudo_tld, - 'spam=eggs; Domain=.co.uk') - self.assertEqual(len(cj), 2) - - def test_two_component_domain_ns(self): - # Netscape: .www.bar.com, www.bar.com, .bar.com, bar.com, no domain - # should all get accepted, as should .acme.com, acme.com and no domain - # for 2-component domains like acme.com. - c = CookieJar() - - # two-component V0 domain is OK - interact_netscape(c, "http://foo.net/", 'ns=bar') - self.assertEqual(len(c), 1) - self.assertEqual(c._cookies["foo.net"]["/"]["ns"].value, "bar") - self.assertEqual(interact_netscape(c, "http://foo.net/"), "ns=bar") - # *will* be returned to any other domain (unlike RFC 2965)... - self.assertEqual(interact_netscape(c, "http://www.foo.net/"), - "ns=bar") - # ...unless requested otherwise - pol = DefaultCookiePolicy( - strict_ns_domain=DefaultCookiePolicy.DomainStrictNonDomain) - c.set_policy(pol) - self.assertEqual(interact_netscape(c, "http://www.foo.net/"), "") - - # unlike RFC 2965, even explicit two-component domain is OK, - # because .foo.net matches foo.net - interact_netscape(c, "http://foo.net/foo/", - 'spam1=eggs; domain=foo.net') - # even if starts with a dot -- in NS rules, .foo.net matches foo.net! - interact_netscape(c, "http://foo.net/foo/bar/", - 'spam2=eggs; domain=.foo.net') - self.assertEqual(len(c), 3) - self.assertEqual(c._cookies[".foo.net"]["/foo"]["spam1"].value, - "eggs") - self.assertEqual(c._cookies[".foo.net"]["/foo/bar"]["spam2"].value, - "eggs") - self.assertEqual(interact_netscape(c, "http://foo.net/foo/bar/"), - "spam2=eggs; spam1=eggs; ns=bar") - - # top-level domain is too general - interact_netscape(c, "http://foo.net/", 'nini="ni"; domain=.net') - self.assertEqual(len(c), 3) - - ## # Netscape protocol doesn't allow non-special top level domains (such - ## # as co.uk) in the domain attribute unless there are at least three - ## # dots in it. - # Oh yes it does! Real implementations don't check this, and real - # cookies (of course) rely on that behaviour. - interact_netscape(c, "http://foo.co.uk", 'nasty=trick; domain=.co.uk') - ## self.assertEqual(len(c), 2) - self.assertEqual(len(c), 4) - - def test_two_component_domain_rfc2965(self): - pol = DefaultCookiePolicy(rfc2965=True) - c = CookieJar(pol) - - # two-component V1 domain is OK - interact_2965(c, "http://foo.net/", 'foo=bar; Version="1"') - self.assertEqual(len(c), 1) - self.assertEqual(c._cookies["foo.net"]["/"]["foo"].value, "bar") - self.assertEqual(interact_2965(c, "http://foo.net/"), - "$Version=1; foo=bar") - # won't be returned to any other domain (because domain was implied) - self.assertEqual(interact_2965(c, "http://www.foo.net/"), "") - - # unless domain is given explicitly, because then it must be - # rewritten to start with a dot: foo.net --> .foo.net, which does - # not domain-match foo.net - interact_2965(c, "http://foo.net/foo", - 'spam=eggs; domain=foo.net; path=/foo; Version="1"') - self.assertEqual(len(c), 1) - self.assertEqual(interact_2965(c, "http://foo.net/foo"), - "$Version=1; foo=bar") - - # explicit foo.net from three-component domain www.foo.net *does* get - # set, because .foo.net domain-matches .foo.net - interact_2965(c, "http://www.foo.net/foo/", - 'spam=eggs; domain=foo.net; Version="1"') - self.assertEqual(c._cookies[".foo.net"]["/foo/"]["spam"].value, - "eggs") - self.assertEqual(len(c), 2) - self.assertEqual(interact_2965(c, "http://foo.net/foo/"), - "$Version=1; foo=bar") - self.assertEqual(interact_2965(c, "http://www.foo.net/foo/"), - '$Version=1; spam=eggs; $Domain="foo.net"') - - # top-level domain is too general - interact_2965(c, "http://foo.net/", - 'ni="ni"; domain=".net"; Version="1"') - self.assertEqual(len(c), 2) - - # RFC 2965 doesn't require blocking this - interact_2965(c, "http://foo.co.uk/", - 'nasty=trick; domain=.co.uk; Version="1"') - self.assertEqual(len(c), 3) - - def test_domain_allow(self): - c = CookieJar(policy=DefaultCookiePolicy( - blocked_domains=["acme.com"], - allowed_domains=["www.acme.com"])) - - req = urllib.request.Request("http://acme.com/") - headers = ["Set-Cookie: CUSTOMER=WILE_E_COYOTE; path=/"] - res = FakeResponse(headers, "http://acme.com/") - c.extract_cookies(res, req) - self.assertEqual(len(c), 0) - - req = urllib.request.Request("http://www.acme.com/") - res = FakeResponse(headers, "http://www.acme.com/") - c.extract_cookies(res, req) - self.assertEqual(len(c), 1) - - req = urllib.request.Request("http://www.coyote.com/") - res = FakeResponse(headers, "http://www.coyote.com/") - c.extract_cookies(res, req) - self.assertEqual(len(c), 1) - - # set a cookie with non-allowed domain... - req = urllib.request.Request("http://www.coyote.com/") - res = FakeResponse(headers, "http://www.coyote.com/") - cookies = c.make_cookies(res, req) - c.set_cookie(cookies[0]) - self.assertEqual(len(c), 2) - # ... and check is doesn't get returned - c.add_cookie_header(req) - self.assertFalse(req.has_header("Cookie")) - - def test_domain_block(self): - pol = DefaultCookiePolicy( - rfc2965=True, blocked_domains=[".acme.com"]) - c = CookieJar(policy=pol) - headers = ["Set-Cookie: CUSTOMER=WILE_E_COYOTE; path=/"] - - req = urllib.request.Request("http://www.acme.com/") - res = FakeResponse(headers, "http://www.acme.com/") - c.extract_cookies(res, req) - self.assertEqual(len(c), 0) - - p = pol.set_blocked_domains(["acme.com"]) - c.extract_cookies(res, req) - self.assertEqual(len(c), 1) - - c.clear() - req = urllib.request.Request("http://www.roadrunner.net/") - res = FakeResponse(headers, "http://www.roadrunner.net/") - c.extract_cookies(res, req) - self.assertEqual(len(c), 1) - req = urllib.request.Request("http://www.roadrunner.net/") - c.add_cookie_header(req) - self.assertTrue(req.has_header("Cookie")) - self.assertTrue(req.has_header("Cookie2")) - - c.clear() - pol.set_blocked_domains([".acme.com"]) - c.extract_cookies(res, req) - self.assertEqual(len(c), 1) - - # set a cookie with blocked domain... - req = urllib.request.Request("http://www.acme.com/") - res = FakeResponse(headers, "http://www.acme.com/") - cookies = c.make_cookies(res, req) - c.set_cookie(cookies[0]) - self.assertEqual(len(c), 2) - # ... and check is doesn't get returned - c.add_cookie_header(req) - self.assertFalse(req.has_header("Cookie")) - - c.clear() - - pol.set_blocked_domains([]) - req = urllib.request.Request("http://acme.com/") - res = FakeResponse(headers, "http://acme.com/") - cookies = c.make_cookies(res, req) - c.extract_cookies(res, req) - self.assertEqual(len(c), 1) - - req = urllib.request.Request("http://acme.com/") - c.add_cookie_header(req) - self.assertTrue(req.has_header("Cookie")) - - req = urllib.request.Request("http://badacme.com/") - c.add_cookie_header(req) - self.assertFalse(pol.return_ok(cookies[0], req)) - self.assertFalse(req.has_header("Cookie")) - - p = pol.set_blocked_domains(["acme.com"]) - req = urllib.request.Request("http://acme.com/") - c.add_cookie_header(req) - self.assertFalse(req.has_header("Cookie")) - - req = urllib.request.Request("http://badacme.com/") - c.add_cookie_header(req) - self.assertFalse(req.has_header("Cookie")) - - def test_secure(self): - for ns in True, False: - for whitespace in " ", "": - c = CookieJar() - if ns: - pol = DefaultCookiePolicy(rfc2965=False) - int = interact_netscape - vs = "" - else: - pol = DefaultCookiePolicy(rfc2965=True) - int = interact_2965 - vs = "; Version=1" - c.set_policy(pol) - url = "http://www.acme.com/" - int(c, url, "foo1=bar%s%s" % (vs, whitespace)) - int(c, url, "foo2=bar%s; secure%s" % (vs, whitespace)) - self.assertFalse( - c._cookies["www.acme.com"]["/"]["foo1"].secure, - "non-secure cookie registered secure") - self.assertTrue( - c._cookies["www.acme.com"]["/"]["foo2"].secure, - "secure cookie registered non-secure") - - def test_secure_block(self): - pol = DefaultCookiePolicy() - c = CookieJar(policy=pol) - - headers = ["Set-Cookie: session=narf; secure; path=/"] - req = urllib.request.Request("https://www.acme.com/") - res = FakeResponse(headers, "https://www.acme.com/") - c.extract_cookies(res, req) - self.assertEqual(len(c), 1) - - req = urllib.request.Request("https://www.acme.com/") - c.add_cookie_header(req) - self.assertTrue(req.has_header("Cookie")) - - req = urllib.request.Request("http://www.acme.com/") - c.add_cookie_header(req) - self.assertFalse(req.has_header("Cookie")) - - # secure websocket protocol - req = urllib.request.Request("wss://www.acme.com/") - c.add_cookie_header(req) - self.assertTrue(req.has_header("Cookie")) - - # non-secure websocket protocol - req = urllib.request.Request("ws://www.acme.com/") - c.add_cookie_header(req) - self.assertFalse(req.has_header("Cookie")) - - def test_custom_secure_protocols(self): - pol = DefaultCookiePolicy(secure_protocols=["foos"]) - c = CookieJar(policy=pol) - - headers = ["Set-Cookie: session=narf; secure; path=/"] - req = urllib.request.Request("https://www.acme.com/") - res = FakeResponse(headers, "https://www.acme.com/") - c.extract_cookies(res, req) - self.assertEqual(len(c), 1) - - # test https removed from secure protocol list - req = urllib.request.Request("https://www.acme.com/") - c.add_cookie_header(req) - self.assertFalse(req.has_header("Cookie")) - - req = urllib.request.Request("http://www.acme.com/") - c.add_cookie_header(req) - self.assertFalse(req.has_header("Cookie")) - - req = urllib.request.Request("foos://www.acme.com/") - c.add_cookie_header(req) - self.assertTrue(req.has_header("Cookie")) - - req = urllib.request.Request("foo://www.acme.com/") - c.add_cookie_header(req) - self.assertFalse(req.has_header("Cookie")) - - def test_quote_cookie_value(self): - c = CookieJar(policy=DefaultCookiePolicy(rfc2965=True)) - interact_2965(c, "http://www.acme.com/", r'foo=\b"a"r; Version=1') - h = interact_2965(c, "http://www.acme.com/") - self.assertEqual(h, r'$Version=1; foo=\\b\"a\"r') - - def test_missing_final_slash(self): - # Missing slash from request URL's abs_path should be assumed present. - url = "http://www.acme.com" - c = CookieJar(DefaultCookiePolicy(rfc2965=True)) - interact_2965(c, url, "foo=bar; Version=1") - req = urllib.request.Request(url) - self.assertEqual(len(c), 1) - c.add_cookie_header(req) - self.assertTrue(req.has_header("Cookie")) - - def test_domain_mirror(self): - pol = DefaultCookiePolicy(rfc2965=True) - - c = CookieJar(pol) - url = "http://foo.bar.com/" - interact_2965(c, url, "spam=eggs; Version=1") - h = interact_2965(c, url) - self.assertNotIn("Domain", h, - "absent domain returned with domain present") - - c = CookieJar(pol) - url = "http://foo.bar.com/" - interact_2965(c, url, 'spam=eggs; Version=1; Domain=.bar.com') - h = interact_2965(c, url) - self.assertIn('$Domain=".bar.com"', h, "domain not returned") - - c = CookieJar(pol) - url = "http://foo.bar.com/" - # note missing initial dot in Domain - interact_2965(c, url, 'spam=eggs; Version=1; Domain=bar.com') - h = interact_2965(c, url) - self.assertIn('$Domain="bar.com"', h, "domain not returned") - - def test_path_mirror(self): - pol = DefaultCookiePolicy(rfc2965=True) - - c = CookieJar(pol) - url = "http://foo.bar.com/" - interact_2965(c, url, "spam=eggs; Version=1") - h = interact_2965(c, url) - self.assertNotIn("Path", h, "absent path returned with path present") - - c = CookieJar(pol) - url = "http://foo.bar.com/" - interact_2965(c, url, 'spam=eggs; Version=1; Path=/') - h = interact_2965(c, url) - self.assertIn('$Path="/"', h, "path not returned") - - def test_port_mirror(self): - pol = DefaultCookiePolicy(rfc2965=True) - - c = CookieJar(pol) - url = "http://foo.bar.com/" - interact_2965(c, url, "spam=eggs; Version=1") - h = interact_2965(c, url) - self.assertNotIn("Port", h, "absent port returned with port present") - - c = CookieJar(pol) - url = "http://foo.bar.com/" - interact_2965(c, url, "spam=eggs; Version=1; Port") - h = interact_2965(c, url) - self.assertRegex(h, r"\$Port([^=]|$)", - "port with no value not returned with no value") - - c = CookieJar(pol) - url = "http://foo.bar.com/" - interact_2965(c, url, 'spam=eggs; Version=1; Port="80"') - h = interact_2965(c, url) - self.assertIn('$Port="80"', h, - "port with single value not returned with single value") - - c = CookieJar(pol) - url = "http://foo.bar.com/" - interact_2965(c, url, 'spam=eggs; Version=1; Port="80,8080"') - h = interact_2965(c, url) - self.assertIn('$Port="80,8080"', h, - "port with multiple values not returned with multiple " - "values") - - def test_no_return_comment(self): - c = CookieJar(DefaultCookiePolicy(rfc2965=True)) - url = "http://foo.bar.com/" - interact_2965(c, url, 'spam=eggs; Version=1; ' - 'Comment="does anybody read these?"; ' - 'CommentURL="http://foo.bar.net/comment.html"') - h = interact_2965(c, url) - self.assertNotIn("Comment", h, - "Comment or CommentURL cookie-attributes returned to server") - - def test_Cookie_iterator(self): - cs = CookieJar(DefaultCookiePolicy(rfc2965=True)) - # add some random cookies - interact_2965(cs, "http://blah.spam.org/", 'foo=eggs; Version=1; ' - 'Comment="does anybody read these?"; ' - 'CommentURL="http://foo.bar.net/comment.html"') - interact_netscape(cs, "http://www.acme.com/blah/", "spam=bar; secure") - interact_2965(cs, "http://www.acme.com/blah/", - "foo=bar; secure; Version=1") - interact_2965(cs, "http://www.acme.com/blah/", - "foo=bar; path=/; Version=1") - interact_2965(cs, "http://www.sol.no", - r'bang=wallop; version=1; domain=".sol.no"; ' - r'port="90,100, 80,8080"; ' - r'max-age=100; Comment = "Just kidding! (\"|\\\\) "') - - versions = [1, 1, 1, 0, 1] - names = ["bang", "foo", "foo", "spam", "foo"] - domains = [".sol.no", "blah.spam.org", "www.acme.com", - "www.acme.com", "www.acme.com"] - paths = ["/", "/", "/", "/blah", "/blah/"] - - for i in range(4): - i = 0 - for c in cs: - self.assertIsInstance(c, Cookie) - self.assertEqual(c.version, versions[i]) - self.assertEqual(c.name, names[i]) - self.assertEqual(c.domain, domains[i]) - self.assertEqual(c.path, paths[i]) - i = i + 1 - - def test_parse_ns_headers(self): - # missing domain value (invalid cookie) - self.assertEqual( - parse_ns_headers(["foo=bar; path=/; domain"]), - [[("foo", "bar"), - ("path", "/"), ("domain", None), ("version", "0")]] - ) - # invalid expires value - self.assertEqual( - parse_ns_headers(["foo=bar; expires=Foo Bar 12 33:22:11 2000"]), - [[("foo", "bar"), ("expires", None), ("version", "0")]] - ) - # missing cookie value (valid cookie) - self.assertEqual( - parse_ns_headers(["foo"]), - [[("foo", None), ("version", "0")]] - ) - # missing cookie values for parsed attributes - self.assertEqual( - parse_ns_headers(['foo=bar; expires']), - [[('foo', 'bar'), ('expires', None), ('version', '0')]]) - self.assertEqual( - parse_ns_headers(['foo=bar; version']), - [[('foo', 'bar'), ('version', None)]]) - # shouldn't add version if header is empty - self.assertEqual(parse_ns_headers([""]), []) - - def test_bad_cookie_header(self): - - def cookiejar_from_cookie_headers(headers): - c = CookieJar() - req = urllib.request.Request("http://www.example.com/") - r = FakeResponse(headers, "http://www.example.com/") - c.extract_cookies(r, req) - return c - - future = time2netscape(time.time()+3600) - - # none of these bad headers should cause an exception to be raised - for headers in [ - ["Set-Cookie: "], # actually, nothing wrong with this - ["Set-Cookie2: "], # ditto - # missing domain value - ["Set-Cookie2: a=foo; path=/; Version=1; domain"], - # bad max-age - ["Set-Cookie: b=foo; max-age=oops"], - # bad version - ["Set-Cookie: b=foo; version=spam"], - ["Set-Cookie:; Expires=%s" % future], - ]: - c = cookiejar_from_cookie_headers(headers) - # these bad cookies shouldn't be set - self.assertEqual(len(c), 0) - - # cookie with invalid expires is treated as session cookie - headers = ["Set-Cookie: c=foo; expires=Foo Bar 12 33:22:11 2000"] - c = cookiejar_from_cookie_headers(headers) - cookie = c._cookies["www.example.com"]["/"]["c"] - self.assertIsNone(cookie.expires) - - - class LWPCookieTests(unittest.TestCase): - # Tests taken from libwww-perl, with a few modifications and additions. - - def test_netscape_example_1(self): - #------------------------------------------------------------------- - # First we check that it works for the original example at - # http://www.netscape.com/newsref/std/cookie_spec.html - - # Client requests a document, and receives in the response: - # - # Set-Cookie: CUSTOMER=WILE_E_COYOTE; path=/; expires=Wednesday, 09-Nov-99 23:12:40 GMT - # - # When client requests a URL in path "/" on this server, it sends: - # - # Cookie: CUSTOMER=WILE_E_COYOTE - # - # Client requests a document, and receives in the response: - # - # Set-Cookie: PART_NUMBER=ROCKET_LAUNCHER_0001; path=/ - # - # When client requests a URL in path "/" on this server, it sends: - # - # Cookie: CUSTOMER=WILE_E_COYOTE; PART_NUMBER=ROCKET_LAUNCHER_0001 - # - # Client receives: - # - # Set-Cookie: SHIPPING=FEDEX; path=/fo - # - # When client requests a URL in path "/" on this server, it sends: - # - # Cookie: CUSTOMER=WILE_E_COYOTE; PART_NUMBER=ROCKET_LAUNCHER_0001 - # - # When client requests a URL in path "/foo" on this server, it sends: - # - # Cookie: CUSTOMER=WILE_E_COYOTE; PART_NUMBER=ROCKET_LAUNCHER_0001; SHIPPING=FEDEX - # - # The last Cookie is buggy, because both specifications say that the - # most specific cookie must be sent first. SHIPPING=FEDEX is the - # most specific and should thus be first. - - year_plus_one = time.localtime()[0] + 1 - - headers = [] - - c = CookieJar(DefaultCookiePolicy(rfc2965 = True)) - - #req = urllib.request.Request("http://1.1.1.1/", - # headers={"Host": "www.acme.com:80"}) - req = urllib.request.Request("http://www.acme.com:80/", - headers={"Host": "www.acme.com:80"}) - - headers.append( - "Set-Cookie: CUSTOMER=WILE_E_COYOTE; path=/ ; " - "expires=Wednesday, 09-Nov-%d 23:12:40 GMT" % year_plus_one) - res = FakeResponse(headers, "http://www.acme.com/") - c.extract_cookies(res, req) - - req = urllib.request.Request("http://www.acme.com/") - c.add_cookie_header(req) - - self.assertEqual(req.get_header("Cookie"), "CUSTOMER=WILE_E_COYOTE") - self.assertEqual(req.get_header("Cookie2"), '$Version="1"') - - headers.append("Set-Cookie: PART_NUMBER=ROCKET_LAUNCHER_0001; path=/") - res = FakeResponse(headers, "http://www.acme.com/") - c.extract_cookies(res, req) - - req = urllib.request.Request("http://www.acme.com/foo/bar") - c.add_cookie_header(req) - - h = req.get_header("Cookie") - self.assertIn("PART_NUMBER=ROCKET_LAUNCHER_0001", h) - self.assertIn("CUSTOMER=WILE_E_COYOTE", h) - - headers.append('Set-Cookie: SHIPPING=FEDEX; path=/foo') - res = FakeResponse(headers, "http://www.acme.com") - c.extract_cookies(res, req) - - req = urllib.request.Request("http://www.acme.com/") - c.add_cookie_header(req) - - h = req.get_header("Cookie") - self.assertIn("PART_NUMBER=ROCKET_LAUNCHER_0001", h) - self.assertIn("CUSTOMER=WILE_E_COYOTE", h) - self.assertNotIn("SHIPPING=FEDEX", h) - - req = urllib.request.Request("http://www.acme.com/foo/") - c.add_cookie_header(req) - - h = req.get_header("Cookie") - self.assertIn("PART_NUMBER=ROCKET_LAUNCHER_0001", h) - self.assertIn("CUSTOMER=WILE_E_COYOTE", h) - self.assertTrue(h.startswith("SHIPPING=FEDEX;")) - - def test_netscape_example_2(self): - # Second Example transaction sequence: - # - # Assume all mappings from above have been cleared. - # - # Client receives: - # - # Set-Cookie: PART_NUMBER=ROCKET_LAUNCHER_0001; path=/ - # - # When client requests a URL in path "/" on this server, it sends: - # - # Cookie: PART_NUMBER=ROCKET_LAUNCHER_0001 - # - # Client receives: - # - # Set-Cookie: PART_NUMBER=RIDING_ROCKET_0023; path=/ammo - # - # When client requests a URL in path "/ammo" on this server, it sends: - # - # Cookie: PART_NUMBER=RIDING_ROCKET_0023; PART_NUMBER=ROCKET_LAUNCHER_0001 - # - # NOTE: There are two name/value pairs named "PART_NUMBER" due to - # the inheritance of the "/" mapping in addition to the "/ammo" mapping. - - c = CookieJar() - headers = [] - - req = urllib.request.Request("http://www.acme.com/") - headers.append("Set-Cookie: PART_NUMBER=ROCKET_LAUNCHER_0001; path=/") - res = FakeResponse(headers, "http://www.acme.com/") - - c.extract_cookies(res, req) - - req = urllib.request.Request("http://www.acme.com/") - c.add_cookie_header(req) - - self.assertEqual(req.get_header("Cookie"), - "PART_NUMBER=ROCKET_LAUNCHER_0001") - - headers.append( - "Set-Cookie: PART_NUMBER=RIDING_ROCKET_0023; path=/ammo") - res = FakeResponse(headers, "http://www.acme.com/") - c.extract_cookies(res, req) - - req = urllib.request.Request("http://www.acme.com/ammo") - c.add_cookie_header(req) - - self.assertRegex(req.get_header("Cookie"), - r"PART_NUMBER=RIDING_ROCKET_0023;\s*" - "PART_NUMBER=ROCKET_LAUNCHER_0001") - - def test_ietf_example_1(self): - #------------------------------------------------------------------- - # Then we test with the examples from draft-ietf-http-state-man-mec-03.txt - # - # 5. EXAMPLES - - c = CookieJar(DefaultCookiePolicy(rfc2965=True)) - - # - # 5.1 Example 1 - # - # Most detail of request and response headers has been omitted. Assume - # the user agent has no stored cookies. - # - # 1. User Agent -> Server - # - # POST /acme/login HTTP/1.1 - # [form data] - # - # User identifies self via a form. - # - # 2. Server -> User Agent - # - # HTTP/1.1 200 OK - # Set-Cookie2: Customer="WILE_E_COYOTE"; Version="1"; Path="/acme" - # - # Cookie reflects user's identity. - - cookie = interact_2965( - c, 'http://www.acme.com/acme/login', - 'Customer="WILE_E_COYOTE"; Version="1"; Path="/acme"') - self.assertFalse(cookie) - - # - # 3. User Agent -> Server - # - # POST /acme/pickitem HTTP/1.1 - # Cookie: $Version="1"; Customer="WILE_E_COYOTE"; $Path="/acme" - # [form data] - # - # User selects an item for ``shopping basket.'' - # - # 4. Server -> User Agent - # - # HTTP/1.1 200 OK - # Set-Cookie2: Part_Number="Rocket_Launcher_0001"; Version="1"; - # Path="/acme" - # - # Shopping basket contains an item. - - cookie = interact_2965(c, 'http://www.acme.com/acme/pickitem', - 'Part_Number="Rocket_Launcher_0001"; ' - 'Version="1"; Path="/acme"'); - self.assertRegex(cookie, - r'^\$Version="?1"?; Customer="?WILE_E_COYOTE"?; \$Path="/acme"$') - - # - # 5. User Agent -> Server - # - # POST /acme/shipping HTTP/1.1 - # Cookie: $Version="1"; - # Customer="WILE_E_COYOTE"; $Path="/acme"; - # Part_Number="Rocket_Launcher_0001"; $Path="/acme" - # [form data] - # - # User selects shipping method from form. - # - # 6. Server -> User Agent - # - # HTTP/1.1 200 OK - # Set-Cookie2: Shipping="FedEx"; Version="1"; Path="/acme" - # - # New cookie reflects shipping method. - - cookie = interact_2965(c, "http://www.acme.com/acme/shipping", - 'Shipping="FedEx"; Version="1"; Path="/acme"') - - self.assertRegex(cookie, r'^\$Version="?1"?;') - self.assertRegex(cookie, r'Part_Number="?Rocket_Launcher_0001"?;' - r'\s*\$Path="\/acme"') - self.assertRegex(cookie, r'Customer="?WILE_E_COYOTE"?;' - r'\s*\$Path="\/acme"') - - # - # 7. User Agent -> Server - # - # POST /acme/process HTTP/1.1 - # Cookie: $Version="1"; - # Customer="WILE_E_COYOTE"; $Path="/acme"; - # Part_Number="Rocket_Launcher_0001"; $Path="/acme"; - # Shipping="FedEx"; $Path="/acme" - # [form data] - # - # User chooses to process order. - # - # 8. Server -> User Agent - # - # HTTP/1.1 200 OK - # - # Transaction is complete. - - cookie = interact_2965(c, "http://www.acme.com/acme/process") - self.assertRegex(cookie, r'Shipping="?FedEx"?;\s*\$Path="\/acme"') - self.assertIn("WILE_E_COYOTE", cookie) - - # - # The user agent makes a series of requests on the origin server, after - # each of which it receives a new cookie. All the cookies have the same - # Path attribute and (default) domain. Because the request URLs all have - # /acme as a prefix, and that matches the Path attribute, each request - # contains all the cookies received so far. - - def test_ietf_example_2(self): - # 5.2 Example 2 - # - # This example illustrates the effect of the Path attribute. All detail - # of request and response headers has been omitted. Assume the user agent - # has no stored cookies. - - c = CookieJar(DefaultCookiePolicy(rfc2965=True)) - - # Imagine the user agent has received, in response to earlier requests, - # the response headers - # - # Set-Cookie2: Part_Number="Rocket_Launcher_0001"; Version="1"; - # Path="/acme" - # - # and - # - # Set-Cookie2: Part_Number="Riding_Rocket_0023"; Version="1"; - # Path="/acme/ammo" - - interact_2965( - c, "http://www.acme.com/acme/ammo/specific", - 'Part_Number="Rocket_Launcher_0001"; Version="1"; Path="/acme"', - 'Part_Number="Riding_Rocket_0023"; Version="1"; Path="/acme/ammo"') - - # A subsequent request by the user agent to the (same) server for URLs of - # the form /acme/ammo/... would include the following request header: - # - # Cookie: $Version="1"; - # Part_Number="Riding_Rocket_0023"; $Path="/acme/ammo"; - # Part_Number="Rocket_Launcher_0001"; $Path="/acme" - # - # Note that the NAME=VALUE pair for the cookie with the more specific Path - # attribute, /acme/ammo, comes before the one with the less specific Path - # attribute, /acme. Further note that the same cookie name appears more - # than once. - - cookie = interact_2965(c, "http://www.acme.com/acme/ammo/...") - self.assertRegex(cookie, r"Riding_Rocket_0023.*Rocket_Launcher_0001") - - # A subsequent request by the user agent to the (same) server for a URL of - # the form /acme/parts/ would include the following request header: - # - # Cookie: $Version="1"; Part_Number="Rocket_Launcher_0001"; $Path="/acme" - # - # Here, the second cookie's Path attribute /acme/ammo is not a prefix of - # the request URL, /acme/parts/, so the cookie does not get forwarded to - # the server. - - cookie = interact_2965(c, "http://www.acme.com/acme/parts/") - self.assertIn("Rocket_Launcher_0001", cookie) - self.assertNotIn("Riding_Rocket_0023", cookie) - - def test_rejection(self): - # Test rejection of Set-Cookie2 responses based on domain, path, port. - pol = DefaultCookiePolicy(rfc2965=True) - - c = LWPCookieJar(policy=pol) - - max_age = "max-age=3600" - - # illegal domain (no embedded dots) - cookie = interact_2965(c, "http://www.acme.com", - 'foo=bar; domain=".com"; version=1') - self.assertFalse(c) - - # legal domain - cookie = interact_2965(c, "http://www.acme.com", - 'ping=pong; domain="acme.com"; version=1') - self.assertEqual(len(c), 1) - - # illegal domain (host prefix "www.a" contains a dot) - cookie = interact_2965(c, "http://www.a.acme.com", - 'whiz=bang; domain="acme.com"; version=1') - self.assertEqual(len(c), 1) - - # legal domain - cookie = interact_2965(c, "http://www.a.acme.com", - 'wow=flutter; domain=".a.acme.com"; version=1') - self.assertEqual(len(c), 2) - - # can't partially match an IP-address - cookie = interact_2965(c, "http://125.125.125.125", - 'zzzz=ping; domain="125.125.125"; version=1') - self.assertEqual(len(c), 2) - - # illegal path (must be prefix of request path) - cookie = interact_2965(c, "http://www.sol.no", - 'blah=rhubarb; domain=".sol.no"; path="/foo"; ' - 'version=1') - self.assertEqual(len(c), 2) - - # legal path - cookie = interact_2965(c, "http://www.sol.no/foo/bar", - 'bing=bong; domain=".sol.no"; path="/foo"; ' - 'version=1') - self.assertEqual(len(c), 3) - - # illegal port (request-port not in list) - cookie = interact_2965(c, "http://www.sol.no", - 'whiz=ffft; domain=".sol.no"; port="90,100"; ' - 'version=1') - self.assertEqual(len(c), 3) - - # legal port - cookie = interact_2965( - c, "http://www.sol.no", - r'bang=wallop; version=1; domain=".sol.no"; ' - r'port="90,100, 80,8080"; ' - r'max-age=100; Comment = "Just kidding! (\"|\\\\) "') - self.assertEqual(len(c), 4) - - # port attribute without any value (current port) - cookie = interact_2965(c, "http://www.sol.no", - 'foo9=bar; version=1; domain=".sol.no"; port; ' - 'max-age=100;') - self.assertEqual(len(c), 5) - - # encoded path - # LWP has this test, but unescaping allowed path characters seems - # like a bad idea, so I think this should fail: - ## cookie = interact_2965(c, "http://www.sol.no/foo/", - ## r'foo8=bar; version=1; path="/%66oo"') - # but this is OK, because '<' is not an allowed HTTP URL path - # character: - cookie = interact_2965(c, "http://www.sol.no/", - 'output': 'Set-Cookie: chips=ahoy\nSet-Cookie: vienna=finger'}, - - {'data': 'keebler="E=mc2; L=\\"Loves\\"; fudge=\\012;"', - 'dict': {'keebler' : 'E=mc2; L="Loves"; fudge=\012;'}, - 'repr': '''''', - 'output': 'Set-Cookie: keebler="E=mc2; L=\\"Loves\\"; fudge=\\012;"'}, - - # Check illegal cookies that have an '=' char in an unquoted value - {'data': 'keebler=E=mc2', - 'dict': {'keebler' : 'E=mc2'}, - 'repr': "", - 'output': 'Set-Cookie: keebler=E=mc2'}, - - # Cookies with ':' character in their name. Though not mentioned in - # RFC, servers / browsers allow it. - - {'data': 'key:term=value:term', - 'dict': {'key:term' : 'value:term'}, - 'repr': "", - 'output': 'Set-Cookie: key:term=value:term'}, - - # issue22931 - Adding '[' and ']' as valid characters in cookie - # values as defined in RFC 6265 - { - 'data': 'a=b; c=[; d=r; f=h', - 'dict': {'a':'b', 'c':'[', 'd':'r', 'f':'h'}, - 'repr': "", - 'output': '\n'.join(( - 'Set-Cookie: a=b', - 'Set-Cookie: c=[', - 'Set-Cookie: d=r', - 'Set-Cookie: f=h' - )) - } - ] - - for case in cases: - C = cookies.SimpleCookie() - C.load(case['data']) - self.assertEqual(repr(C), case['repr']) - self.assertEqual(C.output(sep='\n'), case['output']) - for k, v in sorted(case['dict'].items()): - self.assertEqual(C[k].value, v) - - def test_load(self): - C = cookies.SimpleCookie() - C.load('Customer="WILE_E_COYOTE"; Version=1; Path=/acme') - - self.assertEqual(C['Customer'].value, 'WILE_E_COYOTE') - self.assertEqual(C['Customer']['version'], '1') - self.assertEqual(C['Customer']['path'], '/acme') - - self.assertEqual(C.output(['path']), - 'Set-Cookie: Customer="WILE_E_COYOTE"; Path=/acme') - self.assertEqual(C.js_output(), r""" - - """) - self.assertEqual(C.js_output(['path']), r""" - - """) - - def test_extended_encode(self): - # Issue 9824: some browsers don't follow the standard; we now - # encode , and ; to keep them from tripping up. - C = cookies.SimpleCookie() - C['val'] = "some,funky;stuff" - self.assertEqual(C.output(['val']), - 'Set-Cookie: val="some\\054funky\\073stuff"') - - def test_special_attrs(self): - # 'expires' - C = cookies.SimpleCookie('Customer="WILE_E_COYOTE"') - C['Customer']['expires'] = 0 - # can't test exact output, it always depends on current date/time - self.assertTrue(C.output().endswith('GMT')) - - # loading 'expires' - C = cookies.SimpleCookie() - C.load('Customer="W"; expires=Wed, 01 Jan 2010 00:00:00 GMT') - self.assertEqual(C['Customer']['expires'], - 'Wed, 01 Jan 2010 00:00:00 GMT') - C = cookies.SimpleCookie() - C.load('Customer="W"; expires=Wed, 01 Jan 98 00:00:00 GMT') - self.assertEqual(C['Customer']['expires'], - 'Wed, 01 Jan 98 00:00:00 GMT') - - # 'max-age' - C = cookies.SimpleCookie('Customer="WILE_E_COYOTE"') - C['Customer']['max-age'] = 10 - self.assertEqual(C.output(), - 'Set-Cookie: Customer="WILE_E_COYOTE"; Max-Age=10') - - def test_set_secure_httponly_attrs(self): - C = cookies.SimpleCookie('Customer="WILE_E_COYOTE"') - C['Customer']['secure'] = True - C['Customer']['httponly'] = True - self.assertEqual(C.output(), - 'Set-Cookie: Customer="WILE_E_COYOTE"; HttpOnly; Secure') - - def test_samesite_attrs(self): - samesite_values = ['Strict', 'Lax', 'strict', 'lax'] - for val in samesite_values: - with self.subTest(val=val): - C = cookies.SimpleCookie('Customer="WILE_E_COYOTE"') - C['Customer']['samesite'] = val - self.assertEqual(C.output(), - 'Set-Cookie: Customer="WILE_E_COYOTE"; SameSite=%s' % val) - - C = cookies.SimpleCookie() - C.load('Customer="WILL_E_COYOTE"; SameSite=%s' % val) - self.assertEqual(C['Customer']['samesite'], val) - - def test_secure_httponly_false_if_not_present(self): - C = cookies.SimpleCookie() - C.load('eggs=scrambled; Path=/bacon') - self.assertFalse(C['eggs']['httponly']) - self.assertFalse(C['eggs']['secure']) - - def test_secure_httponly_true_if_present(self): - # Issue 16611 - C = cookies.SimpleCookie() - C.load('eggs=scrambled; httponly; secure; Path=/bacon') - self.assertTrue(C['eggs']['httponly']) - self.assertTrue(C['eggs']['secure']) - - def test_secure_httponly_true_if_have_value(self): - # This isn't really valid, but demonstrates what the current code - # is expected to do in this case. - C = cookies.SimpleCookie() - C.load('eggs=scrambled; httponly=foo; secure=bar; Path=/bacon') - self.assertTrue(C['eggs']['httponly']) - self.assertTrue(C['eggs']['secure']) - # Here is what it actually does; don't depend on this behavior. These - # checks are testing backward compatibility for issue 16611. - self.assertEqual(C['eggs']['httponly'], 'foo') - self.assertEqual(C['eggs']['secure'], 'bar') - - def test_extra_spaces(self): - C = cookies.SimpleCookie() - C.load('eggs = scrambled ; secure ; path = bar ; foo=foo ') - self.assertEqual(C.output(), - 'Set-Cookie: eggs=scrambled; Path=bar; Secure\r\nSet-Cookie: foo=foo') - - def test_quoted_meta(self): - # Try cookie with quoted meta-data - C = cookies.SimpleCookie() - C.load('Customer="WILE_E_COYOTE"; Version="1"; Path="/acme"') - self.assertEqual(C['Customer'].value, 'WILE_E_COYOTE') - self.assertEqual(C['Customer']['version'], '1') - self.assertEqual(C['Customer']['path'], '/acme') - - self.assertEqual(C.output(['path']), - 'Set-Cookie: Customer="WILE_E_COYOTE"; Path=/acme') - self.assertEqual(C.js_output(), r""" - - """) - self.assertEqual(C.js_output(['path']), r""" - - """) - - def test_invalid_cookies(self): - # Accepting these could be a security issue - C = cookies.SimpleCookie() - for s in (']foo=x', '[foo=x', 'blah]foo=x', 'blah[foo=x', - 'Set-Cookie: foo=bar', 'Set-Cookie: foo', - 'foo=bar; baz', 'baz; foo=bar', - 'secure;foo=bar', 'Version=1;foo=bar'): - C.load(s) - self.assertEqual(dict(C), {}) - self.assertEqual(C.output(), '') - - def test_pickle(self): - rawdata = 'Customer="WILE_E_COYOTE"; Path=/acme; Version=1' - expected_output = 'Set-Cookie: %s' % rawdata - - C = cookies.SimpleCookie() - C.load(rawdata) - self.assertEqual(C.output(), expected_output) - - for proto in range(pickle.HIGHEST_PROTOCOL + 1): - with self.subTest(proto=proto): - C1 = pickle.loads(pickle.dumps(C, protocol=proto)) - self.assertEqual(C1.output(), expected_output) - - def test_illegal_chars(self): - rawdata = "a=b; c,d=e" - C = cookies.SimpleCookie() - with self.assertRaises(cookies.CookieError): - C.load(rawdata) - - def test_comment_quoting(self): - c = cookies.SimpleCookie() - c['foo'] = '\N{COPYRIGHT SIGN}' - self.assertEqual(str(c['foo']), 'Set-Cookie: foo="\\251"') - c['foo']['comment'] = 'comment \N{COPYRIGHT SIGN}' - self.assertEqual( - str(c['foo']), - 'Set-Cookie: foo="\\251"; Comment="comment \\251"' - ) - - - class MorselTests(unittest.TestCase): - """Tests for the Morsel object.""" - - def test_defaults(self): - morsel = cookies.Morsel() - self.assertIsNone(morsel.key) - self.assertIsNone(morsel.value) - self.assertIsNone(morsel.coded_value) - self.assertEqual(morsel.keys(), cookies.Morsel._reserved.keys()) - for key, val in morsel.items(): - self.assertEqual(val, '', key) - - def test_reserved_keys(self): - M = cookies.Morsel() - # tests valid and invalid reserved keys for Morsels - for i in M._reserved: - # Test that all valid keys are reported as reserved and set them - self.assertTrue(M.isReservedKey(i)) - M[i] = '%s_value' % i - for i in M._reserved: - # Test that valid key values come out fine - self.assertEqual(M[i], '%s_value' % i) - for i in "the holy hand grenade".split(): - # Test that invalid keys raise CookieError - self.assertRaises(cookies.CookieError, - M.__setitem__, i, '%s_value' % i) - - def test_setter(self): - M = cookies.Morsel() - # tests the .set method to set keys and their values - for i in M._reserved: - # Makes sure that all reserved keys can't be set this way - self.assertRaises(cookies.CookieError, - M.set, i, '%s_value' % i, '%s_value' % i) - for i in "thou cast _the- !holy! ^hand| +*grenade~".split(): - # Try typical use case. Setting decent values. - # Check output and js_output. - M['path'] = '/foo' # Try a reserved key as well - M.set(i, "%s_val" % i, "%s_coded_val" % i) - self.assertEqual(M.key, i) - self.assertEqual(M.value, "%s_val" % i) - self.assertEqual(M.coded_value, "%s_coded_val" % i) - self.assertEqual( - M.output(), - "Set-Cookie: %s=%s; Path=/foo" % (i, "%s_coded_val" % i)) - expected_js_output = """ - - """ % (i, "%s_coded_val" % i) - self.assertEqual(M.js_output(), expected_js_output) - for i in ["foo bar", "foo@bar"]: - # Try some illegal characters - self.assertRaises(cookies.CookieError, - M.set, i, '%s_value' % i, '%s_value' % i) - - def test_set_properties(self): - morsel = cookies.Morsel() - with self.assertRaises(AttributeError): - morsel.key = '' - with self.assertRaises(AttributeError): - morsel.value = '' - with self.assertRaises(AttributeError): - morsel.coded_value = '' - - def test_eq(self): - base_case = ('key', 'value', '"value"') - attribs = { - 'path': '/', - 'comment': 'foo', - 'domain': 'example.com', - 'version': 2, - } - morsel_a = cookies.Morsel() - morsel_a.update(attribs) - morsel_a.set(*base_case) - morsel_b = cookies.Morsel() - morsel_b.update(attribs) - morsel_b.set(*base_case) - self.assertTrue(morsel_a == morsel_b) - self.assertFalse(morsel_a != morsel_b) - cases = ( - ('key', 'value', 'mismatch'), - ('key', 'mismatch', '"value"'), - ('mismatch', 'value', '"value"'), - ) - for case_b in cases: - with self.subTest(case_b): - morsel_b = cookies.Morsel() - morsel_b.update(attribs) - morsel_b.set(*case_b) - self.assertFalse(morsel_a == morsel_b) - self.assertTrue(morsel_a != morsel_b) - - morsel_b = cookies.Morsel() - morsel_b.update(attribs) - morsel_b.set(*base_case) - morsel_b['comment'] = 'bar' - self.assertFalse(morsel_a == morsel_b) - self.assertTrue(morsel_a != morsel_b) - - # test mismatched types - self.assertFalse(cookies.Morsel() == 1) - self.assertTrue(cookies.Morsel() != 1) - self.assertFalse(cookies.Morsel() == '') - self.assertTrue(cookies.Morsel() != '') - items = list(cookies.Morsel().items()) - self.assertFalse(cookies.Morsel() == items) - self.assertTrue(cookies.Morsel() != items) - - # morsel/dict - morsel = cookies.Morsel() - morsel.set(*base_case) - morsel.update(attribs) - self.assertTrue(morsel == dict(morsel)) - self.assertFalse(morsel != dict(morsel)) - - def test_copy(self): - morsel_a = cookies.Morsel() - morsel_a.set('foo', 'bar', 'baz') - morsel_a.update({ - 'version': 2, - 'comment': 'foo', - }) - morsel_b = morsel_a.copy() - self.assertIsInstance(morsel_b, cookies.Morsel) - self.assertIsNot(morsel_a, morsel_b) - self.assertEqual(morsel_a, morsel_b) - - morsel_b = copy.copy(morsel_a) - self.assertIsInstance(morsel_b, cookies.Morsel) - self.assertIsNot(morsel_a, morsel_b) - self.assertEqual(morsel_a, morsel_b) - - def test_setitem(self): - morsel = cookies.Morsel() - morsel['expires'] = 0 - self.assertEqual(morsel['expires'], 0) - morsel['Version'] = 2 - self.assertEqual(morsel['version'], 2) - morsel['DOMAIN'] = 'example.com' - self.assertEqual(morsel['domain'], 'example.com') - - with self.assertRaises(cookies.CookieError): - morsel['invalid'] = 'value' - self.assertNotIn('invalid', morsel) - - def test_setdefault(self): - morsel = cookies.Morsel() - morsel.update({ - 'domain': 'example.com', - 'version': 2, - }) - # this shouldn't override the default value - self.assertEqual(morsel.setdefault('expires', 'value'), '') - self.assertEqual(morsel['expires'], '') - self.assertEqual(morsel.setdefault('Version', 1), 2) - self.assertEqual(morsel['version'], 2) - self.assertEqual(morsel.setdefault('DOMAIN', 'value'), 'example.com') - self.assertEqual(morsel['domain'], 'example.com') - - with self.assertRaises(cookies.CookieError): - morsel.setdefault('invalid', 'value') - self.assertNotIn('invalid', morsel) - - def test_update(self): - attribs = {'expires': 1, 'Version': 2, 'DOMAIN': 'example.com'} - # test dict update - morsel = cookies.Morsel() - morsel.update(attribs) - self.assertEqual(morsel['expires'], 1) - self.assertEqual(morsel['version'], 2) - self.assertEqual(morsel['domain'], 'example.com') - # test iterable update - morsel = cookies.Morsel() - morsel.update(list(attribs.items())) - self.assertEqual(morsel['expires'], 1) - self.assertEqual(morsel['version'], 2) - self.assertEqual(morsel['domain'], 'example.com') - # test iterator update - morsel = cookies.Morsel() - morsel.update((k, v) for k, v in attribs.items()) - self.assertEqual(morsel['expires'], 1) - self.assertEqual(morsel['version'], 2) - self.assertEqual(morsel['domain'], 'example.com') - - with self.assertRaises(cookies.CookieError): - morsel.update({'invalid': 'value'}) - self.assertNotIn('invalid', morsel) - self.assertRaises(TypeError, morsel.update) - self.assertRaises(TypeError, morsel.update, 0) - - def test_pickle(self): - morsel_a = cookies.Morsel() - morsel_a.set('foo', 'bar', 'baz') - morsel_a.update({ - 'version': 2, - 'comment': 'foo', - }) - for proto in range(pickle.HIGHEST_PROTOCOL + 1): - with self.subTest(proto=proto): - morsel_b = pickle.loads(pickle.dumps(morsel_a, proto)) - self.assertIsInstance(morsel_b, cookies.Morsel) - self.assertEqual(morsel_b, morsel_a) - self.assertEqual(str(morsel_b), str(morsel_a)) - - def test_repr(self): - morsel = cookies.Morsel() - self.assertEqual(repr(morsel), '') - self.assertEqual(str(morsel), 'Set-Cookie: None=None') - morsel.set('key', 'val', 'coded_val') - self.assertEqual(repr(morsel), '') - self.assertEqual(str(morsel), 'Set-Cookie: key=coded_val') - morsel.update({ - 'path': '/', - 'comment': 'foo', - 'domain': 'example.com', - 'max-age': 0, - 'secure': 0, - 'version': 1, - }) - self.assertEqual(repr(morsel), - '') - self.assertEqual(str(morsel), - 'Set-Cookie: key=coded_val; Comment=foo; Domain=example.com; ' - 'Max-Age=0; Path=/; Version=1') - morsel['secure'] = True - morsel['httponly'] = 1 - self.assertEqual(repr(morsel), - '') - self.assertEqual(str(morsel), - 'Set-Cookie: key=coded_val; Comment=foo; Domain=example.com; ' - 'HttpOnly; Max-Age=0; Path=/; Secure; Version=1') - - morsel = cookies.Morsel() - morsel.set('key', 'val', 'coded_val') - morsel['expires'] = 0 - self.assertRegex(repr(morsel), - r'') - self.assertRegex(str(morsel), - r'Set-Cookie: key=coded_val; ' - r'expires=\w+, \d+ \w+ \d+ \d+:\d+:\d+ \w+') - - def test_main(): - run_unittest(CookieTests, MorselTests) - run_doctest(cookies) - - if __name__ == '__main__': - test_main() diff --git a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_httplib.yaml b/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_httplib.yaml deleted file mode 100644 index 77a17c54d..000000000 --- a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_httplib.yaml +++ /dev/null @@ -1,2044 +0,0 @@ -python: | - import errno - from http import client, HTTPStatus - import io - import itertools - import os - import array - import re - import socket - import threading - import warnings - - import unittest - TestCase = unittest.TestCase - - from test import support - - here = os.path.dirname(__file__) - # Self-signed cert file for 'localhost' - CERT_localhost = os.path.join(here, 'keycert.pem') - # Self-signed cert file for 'fakehostname' - CERT_fakehostname = os.path.join(here, 'keycert2.pem') - # Self-signed cert file for self-signed.pythontest.net - CERT_selfsigned_pythontestdotnet = os.path.join(here, 'selfsigned_pythontestdotnet.pem') - - # constants for testing chunked encoding - chunked_start = ( - 'HTTP/1.1 200 OK\r\n' - 'Transfer-Encoding: chunked\r\n\r\n' - 'a\r\n' - 'hello worl\r\n' - '3\r\n' - 'd! \r\n' - '8\r\n' - 'and now \r\n' - '22\r\n' - 'for something completely different\r\n' - ) - chunked_expected = b'hello world! and now for something completely different' - chunk_extension = ";foo=bar" - last_chunk = "0\r\n" - last_chunk_extended = "0" + chunk_extension + "\r\n" - trailers = "X-Dummy: foo\r\nX-Dumm2: bar\r\n" - chunked_end = "\r\n" - - HOST = support.HOST - - class FakeSocket: - def __init__(self, text, fileclass=io.BytesIO, host=None, port=None): - if isinstance(text, str): - text = text.encode("ascii") - self.text = text - self.fileclass = fileclass - self.data = b'' - self.sendall_calls = 0 - self.file_closed = False - self.host = host - self.port = port - - def sendall(self, data): - self.sendall_calls += 1 - self.data += data - - def makefile(self, mode, bufsize=None): - if mode != 'r' and mode != 'rb': - raise client.UnimplementedFileMode() - # keep the file around so we can check how much was read from it - self.file = self.fileclass(self.text) - self.file.close = self.file_close #nerf close () - return self.file - - def file_close(self): - self.file_closed = True - - def close(self): - pass - - def setsockopt(self, level, optname, value): - pass - - class EPipeSocket(FakeSocket): - - def __init__(self, text, pipe_trigger): - # When sendall() is called with pipe_trigger, raise EPIPE. - FakeSocket.__init__(self, text) - self.pipe_trigger = pipe_trigger - - def sendall(self, data): - if self.pipe_trigger in data: - raise OSError(errno.EPIPE, "gotcha") - self.data += data - - def close(self): - pass - - class NoEOFBytesIO(io.BytesIO): - """Like BytesIO, but raises AssertionError on EOF. - - This is used below to test that http.client doesn't try to read - more from the underlying file than it should. - """ - def read(self, n=-1): - data = io.BytesIO.read(self, n) - if data == b'': - raise AssertionError('caller tried to read past EOF') - return data - - def readline(self, length=None): - data = io.BytesIO.readline(self, length) - if data == b'': - raise AssertionError('caller tried to read past EOF') - return data - - class FakeSocketHTTPConnection(client.HTTPConnection): - """HTTPConnection subclass using FakeSocket; counts connect() calls""" - - def __init__(self, *args): - self.connections = 0 - super().__init__('example.com') - self.fake_socket_args = args - self._create_connection = self.create_connection - - def connect(self): - """Count the number of times connect() is invoked""" - self.connections += 1 - return super().connect() - - def create_connection(self, *pos, **kw): - return FakeSocket(*self.fake_socket_args) - - class HeaderTests(TestCase): - def test_auto_headers(self): - # Some headers are added automatically, but should not be added by - # .request() if they are explicitly set. - - class HeaderCountingBuffer(list): - def __init__(self): - self.count = {} - def append(self, item): - kv = item.split(b':') - if len(kv) > 1: - # item is a 'Key: Value' header string - lcKey = kv[0].decode('ascii').lower() - self.count.setdefault(lcKey, 0) - self.count[lcKey] += 1 - list.append(self, item) - - for explicit_header in True, False: - for header in 'Content-length', 'Host', 'Accept-encoding': - conn = client.HTTPConnection('example.com') - conn.sock = FakeSocket('blahblahblah') - conn._buffer = HeaderCountingBuffer() - - body = 'spamspamspam' - headers = {} - if explicit_header: - headers[header] = str(len(body)) - conn.request('POST', '/', body, headers) - self.assertEqual(conn._buffer.count[header.lower()], 1) - - def test_content_length_0(self): - - class ContentLengthChecker(list): - def __init__(self): - list.__init__(self) - self.content_length = None - def append(self, item): - kv = item.split(b':', 1) - if len(kv) > 1 and kv[0].lower() == b'content-length': - self.content_length = kv[1].strip() - list.append(self, item) - - # Here, we're testing that methods expecting a body get a - # content-length set to zero if the body is empty (either None or '') - bodies = (None, '') - methods_with_body = ('PUT', 'POST', 'PATCH') - for method, body in itertools.product(methods_with_body, bodies): - conn = client.HTTPConnection('example.com') - conn.sock = FakeSocket(None) - conn._buffer = ContentLengthChecker() - conn.request(method, '/', body) - self.assertEqual( - conn._buffer.content_length, b'0', - 'Header Content-Length incorrect on {}'.format(method) - ) - - # For these methods, we make sure that content-length is not set when - # the body is None because it might cause unexpected behaviour on the - # server. - methods_without_body = ( - 'GET', 'CONNECT', 'DELETE', 'HEAD', 'OPTIONS', 'TRACE', - ) - for method in methods_without_body: - conn = client.HTTPConnection('example.com') - conn.sock = FakeSocket(None) - conn._buffer = ContentLengthChecker() - conn.request(method, '/', None) - self.assertEqual( - conn._buffer.content_length, None, - 'Header Content-Length set for empty body on {}'.format(method) - ) - - # If the body is set to '', that's considered to be "present but - # empty" rather than "missing", so content length would be set, even - # for methods that don't expect a body. - for method in methods_without_body: - conn = client.HTTPConnection('example.com') - conn.sock = FakeSocket(None) - conn._buffer = ContentLengthChecker() - conn.request(method, '/', '') - self.assertEqual( - conn._buffer.content_length, b'0', - 'Header Content-Length incorrect on {}'.format(method) - ) - - # If the body is set, make sure Content-Length is set. - for method in itertools.chain(methods_without_body, methods_with_body): - conn = client.HTTPConnection('example.com') - conn.sock = FakeSocket(None) - conn._buffer = ContentLengthChecker() - conn.request(method, '/', ' ') - self.assertEqual( - conn._buffer.content_length, b'1', - 'Header Content-Length incorrect on {}'.format(method) - ) - - def test_putheader(self): - conn = client.HTTPConnection('example.com') - conn.sock = FakeSocket(None) - conn.putrequest('GET','/') - conn.putheader('Content-length', 42) - self.assertIn(b'Content-length: 42', conn._buffer) - - conn.putheader('Foo', ' bar ') - self.assertIn(b'Foo: bar ', conn._buffer) - conn.putheader('Bar', '\tbaz\t') - self.assertIn(b'Bar: \tbaz\t', conn._buffer) - conn.putheader('Authorization', 'Bearer mytoken') - self.assertIn(b'Authorization: Bearer mytoken', conn._buffer) - conn.putheader('IterHeader', 'IterA', 'IterB') - self.assertIn(b'IterHeader: IterA\r\n\tIterB', conn._buffer) - conn.putheader('LatinHeader', b'\xFF') - self.assertIn(b'LatinHeader: \xFF', conn._buffer) - conn.putheader('Utf8Header', b'\xc3\x80') - self.assertIn(b'Utf8Header: \xc3\x80', conn._buffer) - conn.putheader('C1-Control', b'next\x85line') - self.assertIn(b'C1-Control: next\x85line', conn._buffer) - conn.putheader('Embedded-Fold-Space', 'is\r\n allowed') - self.assertIn(b'Embedded-Fold-Space: is\r\n allowed', conn._buffer) - conn.putheader('Embedded-Fold-Tab', 'is\r\n\tallowed') - self.assertIn(b'Embedded-Fold-Tab: is\r\n\tallowed', conn._buffer) - conn.putheader('Key Space', 'value') - self.assertIn(b'Key Space: value', conn._buffer) - conn.putheader('KeySpace ', 'value') - self.assertIn(b'KeySpace : value', conn._buffer) - conn.putheader(b'Nonbreak\xa0Space', 'value') - self.assertIn(b'Nonbreak\xa0Space: value', conn._buffer) - conn.putheader(b'\xa0NonbreakSpace', 'value') - self.assertIn(b'\xa0NonbreakSpace: value', conn._buffer) - - def test_ipv6host_header(self): - # Default host header on IPv6 transaction should be wrapped by [] if - # it is an IPv6 address - expected = b'GET /foo HTTP/1.1\r\nHost: [2001::]:81\r\n' \ - b'Accept-Encoding: identity\r\n\r\n' - conn = client.HTTPConnection('[2001::]:81') - sock = FakeSocket('') - conn.sock = sock - conn.request('GET', '/foo') - self.assertTrue(sock.data.startswith(expected)) - - expected = b'GET /foo HTTP/1.1\r\nHost: [2001:102A::]\r\n' \ - b'Accept-Encoding: identity\r\n\r\n' - conn = client.HTTPConnection('[2001:102A::]') - sock = FakeSocket('') - conn.sock = sock - conn.request('GET', '/foo') - self.assertTrue(sock.data.startswith(expected)) - - def test_malformed_headers_coped_with(self): - # Issue 19996 - body = "HTTP/1.1 200 OK\r\nFirst: val\r\n: nval\r\nSecond: val\r\n\r\n" - sock = FakeSocket(body) - resp = client.HTTPResponse(sock) - resp.begin() - - self.assertEqual(resp.getheader('First'), 'val') - self.assertEqual(resp.getheader('Second'), 'val') - - def test_parse_all_octets(self): - # Ensure no valid header field octet breaks the parser - body = ( - b'HTTP/1.1 200 OK\r\n' - b"!#$%&'*+-.^_`|~: value\r\n" # Special token characters - b'VCHAR: ' + bytes(range(0x21, 0x7E + 1)) + b'\r\n' - b'obs-text: ' + bytes(range(0x80, 0xFF + 1)) + b'\r\n' - b'obs-fold: text\r\n' - b' folded with space\r\n' - b'\tfolded with tab\r\n' - b'Content-Length: 0\r\n' - b'\r\n' - ) - sock = FakeSocket(body) - resp = client.HTTPResponse(sock) - resp.begin() - self.assertEqual(resp.getheader('Content-Length'), '0') - self.assertEqual(resp.msg['Content-Length'], '0') - self.assertEqual(resp.getheader("!#$%&'*+-.^_`|~"), 'value') - self.assertEqual(resp.msg["!#$%&'*+-.^_`|~"], 'value') - vchar = ''.join(map(chr, range(0x21, 0x7E + 1))) - self.assertEqual(resp.getheader('VCHAR'), vchar) - self.assertEqual(resp.msg['VCHAR'], vchar) - self.assertIsNotNone(resp.getheader('obs-text')) - self.assertIn('obs-text', resp.msg) - for folded in (resp.getheader('obs-fold'), resp.msg['obs-fold']): - self.assertTrue(folded.startswith('text')) - self.assertIn(' folded with space', folded) - self.assertTrue(folded.endswith('folded with tab')) - - def test_invalid_headers(self): - conn = client.HTTPConnection('example.com') - conn.sock = FakeSocket('') - conn.putrequest('GET', '/') - - # http://tools.ietf.org/html/rfc7230#section-3.2.4, whitespace is no - # longer allowed in header names - cases = ( - (b'Invalid\r\nName', b'ValidValue'), - (b'Invalid\rName', b'ValidValue'), - (b'Invalid\nName', b'ValidValue'), - (b'\r\nInvalidName', b'ValidValue'), - (b'\rInvalidName', b'ValidValue'), - (b'\nInvalidName', b'ValidValue'), - (b' InvalidName', b'ValidValue'), - (b'\tInvalidName', b'ValidValue'), - (b'Invalid:Name', b'ValidValue'), - (b':InvalidName', b'ValidValue'), - (b'ValidName', b'Invalid\r\nValue'), - (b'ValidName', b'Invalid\rValue'), - (b'ValidName', b'Invalid\nValue'), - (b'ValidName', b'InvalidValue\r\n'), - (b'ValidName', b'InvalidValue\r'), - (b'ValidName', b'InvalidValue\n'), - ) - for name, value in cases: - with self.subTest((name, value)): - with self.assertRaisesRegex(ValueError, 'Invalid header'): - conn.putheader(name, value) - - def test_headers_debuglevel(self): - body = ( - b'HTTP/1.1 200 OK\r\n' - b'First: val\r\n' - b'Second: val1\r\n' - b'Second: val2\r\n' - ) - sock = FakeSocket(body) - resp = client.HTTPResponse(sock, debuglevel=1) - with support.captured_stdout() as output: - resp.begin() - lines = output.getvalue().splitlines() - self.assertEqual(lines[0], "reply: 'HTTP/1.1 200 OK\\r\\n'") - self.assertEqual(lines[1], "header: First: val") - self.assertEqual(lines[2], "header: Second: val1") - self.assertEqual(lines[3], "header: Second: val2") - - - class HttpMethodTests(TestCase): - def test_invalid_method_names(self): - methods = ( - 'GET\r', - 'POST\n', - 'PUT\n\r', - 'POST\nValue', - 'POST\nHOST:abc', - 'GET\nrHost:abc\n', - 'POST\rRemainder:\r', - 'GET\rHOST:\n', - '\nPUT' - ) - - for method in methods: - with self.assertRaisesRegex( - ValueError, "method can't contain control characters"): - conn = client.HTTPConnection('example.com') - conn.sock = FakeSocket(None) - conn.request(method=method, url="/") - - - class TransferEncodingTest(TestCase): - expected_body = b"It's just a flesh wound" - - def test_endheaders_chunked(self): - conn = client.HTTPConnection('example.com') - conn.sock = FakeSocket(b'') - conn.putrequest('POST', '/') - conn.endheaders(self._make_body(), encode_chunked=True) - - _, _, body = self._parse_request(conn.sock.data) - body = self._parse_chunked(body) - self.assertEqual(body, self.expected_body) - - def test_explicit_headers(self): - # explicit chunked - conn = client.HTTPConnection('example.com') - conn.sock = FakeSocket(b'') - # this shouldn't actually be automatically chunk-encoded because the - # calling code has explicitly stated that it's taking care of it - conn.request( - 'POST', '/', self._make_body(), {'Transfer-Encoding': 'chunked'}) - - _, headers, body = self._parse_request(conn.sock.data) - self.assertNotIn('content-length', [k.lower() for k in headers.keys()]) - self.assertEqual(headers['Transfer-Encoding'], 'chunked') - self.assertEqual(body, self.expected_body) - - # explicit chunked, string body - conn = client.HTTPConnection('example.com') - conn.sock = FakeSocket(b'') - conn.request( - 'POST', '/', self.expected_body.decode('latin-1'), - {'Transfer-Encoding': 'chunked'}) - - _, headers, body = self._parse_request(conn.sock.data) - self.assertNotIn('content-length', [k.lower() for k in headers.keys()]) - self.assertEqual(headers['Transfer-Encoding'], 'chunked') - self.assertEqual(body, self.expected_body) - - # User-specified TE, but request() does the chunk encoding - conn = client.HTTPConnection('example.com') - conn.sock = FakeSocket(b'') - conn.request('POST', '/', - headers={'Transfer-Encoding': 'gzip, chunked'}, - encode_chunked=True, - body=self._make_body()) - _, headers, body = self._parse_request(conn.sock.data) - self.assertNotIn('content-length', [k.lower() for k in headers]) - self.assertEqual(headers['Transfer-Encoding'], 'gzip, chunked') - self.assertEqual(self._parse_chunked(body), self.expected_body) - - def test_request(self): - for empty_lines in (False, True,): - conn = client.HTTPConnection('example.com') - conn.sock = FakeSocket(b'') - conn.request( - 'POST', '/', self._make_body(empty_lines=empty_lines)) - - _, headers, body = self._parse_request(conn.sock.data) - body = self._parse_chunked(body) - self.assertEqual(body, self.expected_body) - self.assertEqual(headers['Transfer-Encoding'], 'chunked') - - # Content-Length and Transfer-Encoding SHOULD not be sent in the - # same request - self.assertNotIn('content-length', [k.lower() for k in headers]) - - def test_empty_body(self): - # Zero-length iterable should be treated like any other iterable - conn = client.HTTPConnection('example.com') - conn.sock = FakeSocket(b'') - conn.request('POST', '/', ()) - _, headers, body = self._parse_request(conn.sock.data) - self.assertEqual(headers['Transfer-Encoding'], 'chunked') - self.assertNotIn('content-length', [k.lower() for k in headers]) - self.assertEqual(body, b"0\r\n\r\n") - - def _make_body(self, empty_lines=False): - lines = self.expected_body.split(b' ') - for idx, line in enumerate(lines): - # for testing handling empty lines - if empty_lines and idx % 2: - yield b'' - if idx < len(lines) - 1: - yield line + b' ' - else: - yield line - - def _parse_request(self, data): - lines = data.split(b'\r\n') - request = lines[0] - headers = {} - n = 1 - while n < len(lines) and len(lines[n]) > 0: - key, val = lines[n].split(b':') - key = key.decode('latin-1').strip() - headers[key] = val.decode('latin-1').strip() - n += 1 - - return request, headers, b'\r\n'.join(lines[n + 1:]) - - def _parse_chunked(self, data): - body = [] - trailers = {} - n = 0 - lines = data.split(b'\r\n') - # parse body - while True: - size, chunk = lines[n:n+2] - size = int(size, 16) - - if size == 0: - n += 1 - break - - self.assertEqual(size, len(chunk)) - body.append(chunk) - - n += 2 - # we /should/ hit the end chunk, but check against the size of - # lines so we're not stuck in an infinite loop should we get - # malformed data - if n > len(lines): - break - - return b''.join(body) - - - class BasicTest(TestCase): - def test_dir_with_added_behavior_on_status(self): - # see issue40084 - self.assertTrue({'description', 'name', 'phrase', 'value'} <= set(dir(HTTPStatus(404)))) - - def test_status_lines(self): - # Test HTTP status lines - - body = "HTTP/1.1 200 Ok\r\n\r\nText" - sock = FakeSocket(body) - resp = client.HTTPResponse(sock) - resp.begin() - self.assertEqual(resp.read(0), b'') # Issue #20007 - self.assertFalse(resp.isclosed()) - self.assertFalse(resp.closed) - self.assertEqual(resp.read(), b"Text") - self.assertTrue(resp.isclosed()) - self.assertFalse(resp.closed) - resp.close() - self.assertTrue(resp.closed) - - body = "HTTP/1.1 400.100 Not Ok\r\n\r\nText" - sock = FakeSocket(body) - resp = client.HTTPResponse(sock) - self.assertRaises(client.BadStatusLine, resp.begin) - - def test_bad_status_repr(self): - exc = client.BadStatusLine('') - self.assertEqual(repr(exc), '''BadStatusLine("''")''') - - def test_partial_reads(self): - # if we have Content-Length, HTTPResponse knows when to close itself, - # the same behaviour as when we read the whole thing with read() - body = "HTTP/1.1 200 Ok\r\nContent-Length: 4\r\n\r\nText" - sock = FakeSocket(body) - resp = client.HTTPResponse(sock) - resp.begin() - self.assertEqual(resp.read(2), b'Te') - self.assertFalse(resp.isclosed()) - self.assertEqual(resp.read(2), b'xt') - self.assertTrue(resp.isclosed()) - self.assertFalse(resp.closed) - resp.close() - self.assertTrue(resp.closed) - - def test_mixed_reads(self): - # readline() should update the remaining length, so that read() knows - # how much data is left and does not raise IncompleteRead - body = "HTTP/1.1 200 Ok\r\nContent-Length: 13\r\n\r\nText\r\nAnother" - sock = FakeSocket(body) - resp = client.HTTPResponse(sock) - resp.begin() - self.assertEqual(resp.readline(), b'Text\r\n') - self.assertFalse(resp.isclosed()) - self.assertEqual(resp.read(), b'Another') - self.assertTrue(resp.isclosed()) - self.assertFalse(resp.closed) - resp.close() - self.assertTrue(resp.closed) - - def test_partial_readintos(self): - # if we have Content-Length, HTTPResponse knows when to close itself, - # the same behaviour as when we read the whole thing with read() - body = "HTTP/1.1 200 Ok\r\nContent-Length: 4\r\n\r\nText" - sock = FakeSocket(body) - resp = client.HTTPResponse(sock) - resp.begin() - b = bytearray(2) - n = resp.readinto(b) - self.assertEqual(n, 2) - self.assertEqual(bytes(b), b'Te') - self.assertFalse(resp.isclosed()) - n = resp.readinto(b) - self.assertEqual(n, 2) - self.assertEqual(bytes(b), b'xt') - self.assertTrue(resp.isclosed()) - self.assertFalse(resp.closed) - resp.close() - self.assertTrue(resp.closed) - - def test_partial_reads_no_content_length(self): - # when no length is present, the socket should be gracefully closed when - # all data was read - body = "HTTP/1.1 200 Ok\r\n\r\nText" - sock = FakeSocket(body) - resp = client.HTTPResponse(sock) - resp.begin() - self.assertEqual(resp.read(2), b'Te') - self.assertFalse(resp.isclosed()) - self.assertEqual(resp.read(2), b'xt') - self.assertEqual(resp.read(1), b'') - self.assertTrue(resp.isclosed()) - self.assertFalse(resp.closed) - resp.close() - self.assertTrue(resp.closed) - - def test_partial_readintos_no_content_length(self): - # when no length is present, the socket should be gracefully closed when - # all data was read - body = "HTTP/1.1 200 Ok\r\n\r\nText" - sock = FakeSocket(body) - resp = client.HTTPResponse(sock) - resp.begin() - b = bytearray(2) - n = resp.readinto(b) - self.assertEqual(n, 2) - self.assertEqual(bytes(b), b'Te') - self.assertFalse(resp.isclosed()) - n = resp.readinto(b) - self.assertEqual(n, 2) - self.assertEqual(bytes(b), b'xt') - n = resp.readinto(b) - self.assertEqual(n, 0) - self.assertTrue(resp.isclosed()) - - def test_partial_reads_incomplete_body(self): - # if the server shuts down the connection before the whole - # content-length is delivered, the socket is gracefully closed - body = "HTTP/1.1 200 Ok\r\nContent-Length: 10\r\n\r\nText" - sock = FakeSocket(body) - resp = client.HTTPResponse(sock) - resp.begin() - self.assertEqual(resp.read(2), b'Te') - self.assertFalse(resp.isclosed()) - self.assertEqual(resp.read(2), b'xt') - self.assertEqual(resp.read(1), b'') - self.assertTrue(resp.isclosed()) - - def test_partial_readintos_incomplete_body(self): - # if the server shuts down the connection before the whole - # content-length is delivered, the socket is gracefully closed - body = "HTTP/1.1 200 Ok\r\nContent-Length: 10\r\n\r\nText" - sock = FakeSocket(body) - resp = client.HTTPResponse(sock) - resp.begin() - b = bytearray(2) - n = resp.readinto(b) - self.assertEqual(n, 2) - self.assertEqual(bytes(b), b'Te') - self.assertFalse(resp.isclosed()) - n = resp.readinto(b) - self.assertEqual(n, 2) - self.assertEqual(bytes(b), b'xt') - n = resp.readinto(b) - self.assertEqual(n, 0) - self.assertTrue(resp.isclosed()) - self.assertFalse(resp.closed) - resp.close() - self.assertTrue(resp.closed) - - def test_host_port(self): - # Check invalid host_port - - for hp in ("www.python.org:abc", "user:password@www.python.org"): - self.assertRaises(client.InvalidURL, client.HTTPConnection, hp) - - for hp, h, p in (("[fe80::207:e9ff:fe9b]:8000", - "fe80::207:e9ff:fe9b", 8000), - ("www.python.org:80", "www.python.org", 80), - ("www.python.org:", "www.python.org", 80), - ("www.python.org", "www.python.org", 80), - ("[fe80::207:e9ff:fe9b]", "fe80::207:e9ff:fe9b", 80), - ("[fe80::207:e9ff:fe9b]:", "fe80::207:e9ff:fe9b", 80)): - c = client.HTTPConnection(hp) - self.assertEqual(h, c.host) - self.assertEqual(p, c.port) - - def test_response_headers(self): - # test response with multiple message headers with the same field name. - text = ('HTTP/1.1 200 OK\r\n' - 'Set-Cookie: Customer="WILE_E_COYOTE"; ' - 'Version="1"; Path="/acme"\r\n' - 'Set-Cookie: Part_Number="Rocket_Launcher_0001"; Version="1";' - ' Path="/acme"\r\n' - '\r\n' - 'No body\r\n') - hdr = ('Customer="WILE_E_COYOTE"; Version="1"; Path="/acme"' - ', ' - 'Part_Number="Rocket_Launcher_0001"; Version="1"; Path="/acme"') - s = FakeSocket(text) - r = client.HTTPResponse(s) - r.begin() - cookies = r.getheader("Set-Cookie") - self.assertEqual(cookies, hdr) - - def test_read_head(self): - # Test that the library doesn't attempt to read any data - # from a HEAD request. (Tickles SF bug #622042.) - sock = FakeSocket( - 'HTTP/1.1 200 OK\r\n' - 'Content-Length: 14432\r\n' - '\r\n', - NoEOFBytesIO) - resp = client.HTTPResponse(sock, method="HEAD") - resp.begin() - if resp.read(): - self.fail("Did not expect response from HEAD request") - - def test_readinto_head(self): - # Test that the library doesn't attempt to read any data - # from a HEAD request. (Tickles SF bug #622042.) - sock = FakeSocket( - 'HTTP/1.1 200 OK\r\n' - 'Content-Length: 14432\r\n' - '\r\n', - NoEOFBytesIO) - resp = client.HTTPResponse(sock, method="HEAD") - resp.begin() - b = bytearray(5) - if resp.readinto(b) != 0: - self.fail("Did not expect response from HEAD request") - self.assertEqual(bytes(b), b'\x00'*5) - - def test_too_many_headers(self): - headers = '\r\n'.join('Header%d: foo' % i - for i in range(client._MAXHEADERS + 1)) + '\r\n' - text = ('HTTP/1.1 200 OK\r\n' + headers) - s = FakeSocket(text) - r = client.HTTPResponse(s) - self.assertRaisesRegex(client.HTTPException, - r"got more than \d+ headers", r.begin) - - def test_send_file(self): - expected = (b'GET /foo HTTP/1.1\r\nHost: example.com\r\n' - b'Accept-Encoding: identity\r\n' - b'Transfer-Encoding: chunked\r\n' - b'\r\n') - - with open(__file__, 'rb') as body: - conn = client.HTTPConnection('example.com') - sock = FakeSocket(body) - conn.sock = sock - conn.request('GET', '/foo', body) - self.assertTrue(sock.data.startswith(expected), '%r != %r' % - (sock.data[:len(expected)], expected)) - - def test_send(self): - expected = b'this is a test this is only a test' - conn = client.HTTPConnection('example.com') - sock = FakeSocket(None) - conn.sock = sock - conn.send(expected) - self.assertEqual(expected, sock.data) - sock.data = b'' - conn.send(array.array('b', expected)) - self.assertEqual(expected, sock.data) - sock.data = b'' - conn.send(io.BytesIO(expected)) - self.assertEqual(expected, sock.data) - - def test_send_updating_file(self): - def data(): - yield 'data' - yield None - yield 'data_two' - - class UpdatingFile(io.TextIOBase): - mode = 'r' - d = data() - def read(self, blocksize=-1): - return next(self.d) - - expected = b'data' - - conn = client.HTTPConnection('example.com') - sock = FakeSocket("") - conn.sock = sock - conn.send(UpdatingFile()) - self.assertEqual(sock.data, expected) - - - def test_send_iter(self): - expected = b'GET /foo HTTP/1.1\r\nHost: example.com\r\n' \ - b'Accept-Encoding: identity\r\nContent-Length: 11\r\n' \ - b'\r\nonetwothree' - - def body(): - yield b"one" - yield b"two" - yield b"three" - - conn = client.HTTPConnection('example.com') - sock = FakeSocket("") - conn.sock = sock - conn.request('GET', '/foo', body(), {'Content-Length': '11'}) - self.assertEqual(sock.data, expected) - - def test_blocksize_request(self): - """Check that request() respects the configured block size.""" - blocksize = 8 # For easy debugging. - conn = client.HTTPConnection('example.com', blocksize=blocksize) - sock = FakeSocket(None) - conn.sock = sock - expected = b"a" * blocksize + b"b" - conn.request("PUT", "/", io.BytesIO(expected), {"Content-Length": "9"}) - self.assertEqual(sock.sendall_calls, 3) - body = sock.data.split(b"\r\n\r\n", 1)[1] - self.assertEqual(body, expected) - - def test_blocksize_send(self): - """Check that send() respects the configured block size.""" - blocksize = 8 # For easy debugging. - conn = client.HTTPConnection('example.com', blocksize=blocksize) - sock = FakeSocket(None) - conn.sock = sock - expected = b"a" * blocksize + b"b" - conn.send(io.BytesIO(expected)) - self.assertEqual(sock.sendall_calls, 2) - self.assertEqual(sock.data, expected) - - def test_send_type_error(self): - # See: Issue #12676 - conn = client.HTTPConnection('example.com') - conn.sock = FakeSocket('') - with self.assertRaises(TypeError): - conn.request('POST', 'test', conn) - - def test_chunked(self): - expected = chunked_expected - sock = FakeSocket(chunked_start + last_chunk + chunked_end) - resp = client.HTTPResponse(sock, method="GET") - resp.begin() - self.assertEqual(resp.read(), expected) - resp.close() - - # Various read sizes - for n in range(1, 12): - sock = FakeSocket(chunked_start + last_chunk + chunked_end) - resp = client.HTTPResponse(sock, method="GET") - resp.begin() - self.assertEqual(resp.read(n) + resp.read(n) + resp.read(), expected) - resp.close() - - for x in ('', 'foo\r\n'): - sock = FakeSocket(chunked_start + x) - resp = client.HTTPResponse(sock, method="GET") - resp.begin() - try: - resp.read() - except client.IncompleteRead as i: - self.assertEqual(i.partial, expected) - expected_message = 'IncompleteRead(%d bytes read)' % len(expected) - self.assertEqual(repr(i), expected_message) - self.assertEqual(str(i), expected_message) - else: - self.fail('IncompleteRead expected') - finally: - resp.close() - - def test_readinto_chunked(self): - - expected = chunked_expected - nexpected = len(expected) - b = bytearray(128) - - sock = FakeSocket(chunked_start + last_chunk + chunked_end) - resp = client.HTTPResponse(sock, method="GET") - resp.begin() - n = resp.readinto(b) - self.assertEqual(b[:nexpected], expected) - self.assertEqual(n, nexpected) - resp.close() - - # Various read sizes - for n in range(1, 12): - sock = FakeSocket(chunked_start + last_chunk + chunked_end) - resp = client.HTTPResponse(sock, method="GET") - resp.begin() - m = memoryview(b) - i = resp.readinto(m[0:n]) - i += resp.readinto(m[i:n + i]) - i += resp.readinto(m[i:]) - self.assertEqual(b[:nexpected], expected) - self.assertEqual(i, nexpected) - resp.close() - - for x in ('', 'foo\r\n'): - sock = FakeSocket(chunked_start + x) - resp = client.HTTPResponse(sock, method="GET") - resp.begin() - try: - n = resp.readinto(b) - except client.IncompleteRead as i: - self.assertEqual(i.partial, expected) - expected_message = 'IncompleteRead(%d bytes read)' % len(expected) - self.assertEqual(repr(i), expected_message) - self.assertEqual(str(i), expected_message) - else: - self.fail('IncompleteRead expected') - finally: - resp.close() - - def test_chunked_head(self): - chunked_start = ( - 'HTTP/1.1 200 OK\r\n' - 'Transfer-Encoding: chunked\r\n\r\n' - 'a\r\n' - 'hello world\r\n' - '1\r\n' - 'd\r\n' - ) - sock = FakeSocket(chunked_start + last_chunk + chunked_end) - resp = client.HTTPResponse(sock, method="HEAD") - resp.begin() - self.assertEqual(resp.read(), b'') - self.assertEqual(resp.status, 200) - self.assertEqual(resp.reason, 'OK') - self.assertTrue(resp.isclosed()) - self.assertFalse(resp.closed) - resp.close() - self.assertTrue(resp.closed) - - def test_readinto_chunked_head(self): - chunked_start = ( - 'HTTP/1.1 200 OK\r\n' - 'Transfer-Encoding: chunked\r\n\r\n' - 'a\r\n' - 'hello world\r\n' - '1\r\n' - 'd\r\n' - ) - sock = FakeSocket(chunked_start + last_chunk + chunked_end) - resp = client.HTTPResponse(sock, method="HEAD") - resp.begin() - b = bytearray(5) - n = resp.readinto(b) - self.assertEqual(n, 0) - self.assertEqual(bytes(b), b'\x00'*5) - self.assertEqual(resp.status, 200) - self.assertEqual(resp.reason, 'OK') - self.assertTrue(resp.isclosed()) - self.assertFalse(resp.closed) - resp.close() - self.assertTrue(resp.closed) - - def test_negative_content_length(self): - sock = FakeSocket( - 'HTTP/1.1 200 OK\r\nContent-Length: -1\r\n\r\nHello\r\n') - resp = client.HTTPResponse(sock, method="GET") - resp.begin() - self.assertEqual(resp.read(), b'Hello\r\n') - self.assertTrue(resp.isclosed()) - - def test_incomplete_read(self): - sock = FakeSocket('HTTP/1.1 200 OK\r\nContent-Length: 10\r\n\r\nHello\r\n') - resp = client.HTTPResponse(sock, method="GET") - resp.begin() - try: - resp.read() - except client.IncompleteRead as i: - self.assertEqual(i.partial, b'Hello\r\n') - self.assertEqual(repr(i), - "IncompleteRead(7 bytes read, 3 more expected)") - self.assertEqual(str(i), - "IncompleteRead(7 bytes read, 3 more expected)") - self.assertTrue(resp.isclosed()) - else: - self.fail('IncompleteRead expected') - - def test_epipe(self): - sock = EPipeSocket( - "HTTP/1.0 401 Authorization Required\r\n" - "Content-type: text/html\r\n" - "WWW-Authenticate: Basic realm=\"example\"\r\n", - b"Content-Length") - conn = client.HTTPConnection("example.com") - conn.sock = sock - self.assertRaises(OSError, - lambda: conn.request("PUT", "/url", "body")) - resp = conn.getresponse() - self.assertEqual(401, resp.status) - self.assertEqual("Basic realm=\"example\"", - resp.getheader("www-authenticate")) - - # Test lines overflowing the max line size (_MAXLINE in http.client) - - def test_overflowing_status_line(self): - body = "HTTP/1.1 200 Ok" + "k" * 65536 + "\r\n" - resp = client.HTTPResponse(FakeSocket(body)) - self.assertRaises((client.LineTooLong, client.BadStatusLine), resp.begin) - - def test_overflowing_header_line(self): - body = ( - 'HTTP/1.1 200 OK\r\n' - 'X-Foo: bar' + 'r' * 65536 + '\r\n\r\n' - ) - resp = client.HTTPResponse(FakeSocket(body)) - self.assertRaises(client.LineTooLong, resp.begin) - - def test_overflowing_chunked_line(self): - body = ( - 'HTTP/1.1 200 OK\r\n' - 'Transfer-Encoding: chunked\r\n\r\n' - + '0' * 65536 + 'a\r\n' - 'hello world\r\n' - '0\r\n' - '\r\n' - ) - resp = client.HTTPResponse(FakeSocket(body)) - resp.begin() - self.assertRaises(client.LineTooLong, resp.read) - - def test_early_eof(self): - # Test httpresponse with no \r\n termination, - body = "HTTP/1.1 200 Ok" - sock = FakeSocket(body) - resp = client.HTTPResponse(sock) - resp.begin() - self.assertEqual(resp.read(), b'') - self.assertTrue(resp.isclosed()) - self.assertFalse(resp.closed) - resp.close() - self.assertTrue(resp.closed) - - def test_error_leak(self): - # Test that the socket is not leaked if getresponse() fails - conn = client.HTTPConnection('example.com') - response = None - class Response(client.HTTPResponse): - def __init__(self, *pos, **kw): - nonlocal response - response = self # Avoid garbage collector closing the socket - client.HTTPResponse.__init__(self, *pos, **kw) - conn.response_class = Response - conn.sock = FakeSocket('Invalid status line') - conn.request('GET', '/') - self.assertRaises(client.BadStatusLine, conn.getresponse) - self.assertTrue(response.closed) - self.assertTrue(conn.sock.file_closed) - - def test_chunked_extension(self): - extra = '3;foo=bar\r\n' + 'abc\r\n' - expected = chunked_expected + b'abc' - - sock = FakeSocket(chunked_start + extra + last_chunk_extended + chunked_end) - resp = client.HTTPResponse(sock, method="GET") - resp.begin() - self.assertEqual(resp.read(), expected) - resp.close() - - def test_chunked_missing_end(self): - """some servers may serve up a short chunked encoding stream""" - expected = chunked_expected - sock = FakeSocket(chunked_start + last_chunk) #no terminating crlf - resp = client.HTTPResponse(sock, method="GET") - resp.begin() - self.assertEqual(resp.read(), expected) - resp.close() - - def test_chunked_trailers(self): - """See that trailers are read and ignored""" - expected = chunked_expected - sock = FakeSocket(chunked_start + last_chunk + trailers + chunked_end) - resp = client.HTTPResponse(sock, method="GET") - resp.begin() - self.assertEqual(resp.read(), expected) - # we should have reached the end of the file - self.assertEqual(sock.file.read(), b"") #we read to the end - resp.close() - - def test_chunked_sync(self): - """Check that we don't read past the end of the chunked-encoding stream""" - expected = chunked_expected - extradata = "extradata" - sock = FakeSocket(chunked_start + last_chunk + trailers + chunked_end + extradata) - resp = client.HTTPResponse(sock, method="GET") - resp.begin() - self.assertEqual(resp.read(), expected) - # the file should now have our extradata ready to be read - self.assertEqual(sock.file.read(), extradata.encode("ascii")) #we read to the end - resp.close() - - def test_content_length_sync(self): - """Check that we don't read past the end of the Content-Length stream""" - extradata = b"extradata" - expected = b"Hello123\r\n" - sock = FakeSocket(b'HTTP/1.1 200 OK\r\nContent-Length: 10\r\n\r\n' + expected + extradata) - resp = client.HTTPResponse(sock, method="GET") - resp.begin() - self.assertEqual(resp.read(), expected) - # the file should now have our extradata ready to be read - self.assertEqual(sock.file.read(), extradata) #we read to the end - resp.close() - - def test_readlines_content_length(self): - extradata = b"extradata" - expected = b"Hello123\r\n" - sock = FakeSocket(b'HTTP/1.1 200 OK\r\nContent-Length: 10\r\n\r\n' + expected + extradata) - resp = client.HTTPResponse(sock, method="GET") - resp.begin() - self.assertEqual(resp.readlines(2000), [expected]) - # the file should now have our extradata ready to be read - self.assertEqual(sock.file.read(), extradata) #we read to the end - resp.close() - - def test_read1_content_length(self): - extradata = b"extradata" - expected = b"Hello123\r\n" - sock = FakeSocket(b'HTTP/1.1 200 OK\r\nContent-Length: 10\r\n\r\n' + expected + extradata) - resp = client.HTTPResponse(sock, method="GET") - resp.begin() - self.assertEqual(resp.read1(2000), expected) - # the file should now have our extradata ready to be read - self.assertEqual(sock.file.read(), extradata) #we read to the end - resp.close() - - def test_readline_bound_content_length(self): - extradata = b"extradata" - expected = b"Hello123\r\n" - sock = FakeSocket(b'HTTP/1.1 200 OK\r\nContent-Length: 10\r\n\r\n' + expected + extradata) - resp = client.HTTPResponse(sock, method="GET") - resp.begin() - self.assertEqual(resp.readline(10), expected) - self.assertEqual(resp.readline(10), b"") - # the file should now have our extradata ready to be read - self.assertEqual(sock.file.read(), extradata) #we read to the end - resp.close() - - def test_read1_bound_content_length(self): - extradata = b"extradata" - expected = b"Hello123\r\n" - sock = FakeSocket(b'HTTP/1.1 200 OK\r\nContent-Length: 30\r\n\r\n' + expected*3 + extradata) - resp = client.HTTPResponse(sock, method="GET") - resp.begin() - self.assertEqual(resp.read1(20), expected*2) - self.assertEqual(resp.read(), expected) - # the file should now have our extradata ready to be read - self.assertEqual(sock.file.read(), extradata) #we read to the end - resp.close() - - def test_response_fileno(self): - # Make sure fd returned by fileno is valid. - serv = socket.create_server((HOST, 0)) - self.addCleanup(serv.close) - - result = None - def run_server(): - [conn, address] = serv.accept() - with conn, conn.makefile("rb") as reader: - # Read the request header until a blank line - while True: - line = reader.readline() - if not line.rstrip(b"\r\n"): - break - conn.sendall(b"HTTP/1.1 200 Connection established\r\n\r\n") - nonlocal result - result = reader.read() - - thread = threading.Thread(target=run_server) - thread.start() - self.addCleanup(thread.join, float(1)) - conn = client.HTTPConnection(*serv.getsockname()) - conn.request("CONNECT", "dummy:1234") - response = conn.getresponse() - try: - self.assertEqual(response.status, client.OK) - s = socket.socket(fileno=response.fileno()) - try: - s.sendall(b"proxied data\n") - finally: - s.detach() - finally: - response.close() - conn.close() - thread.join() - self.assertEqual(result, b"proxied data\n") - - def test_putrequest_override_domain_validation(self): - """ - It should be possible to override the default validation - behavior in putrequest (bpo-38216). - """ - class UnsafeHTTPConnection(client.HTTPConnection): - def _validate_path(self, url): - pass - - conn = UnsafeHTTPConnection('example.com') - conn.sock = FakeSocket('') - conn.putrequest('GET', '/\x00') - - def test_putrequest_override_host_validation(self): - class UnsafeHTTPConnection(client.HTTPConnection): - def _validate_host(self, url): - pass - - conn = UnsafeHTTPConnection('example.com\r\n') - conn.sock = FakeSocket('') - # set skip_host so a ValueError is not raised upon adding the - # invalid URL as the value of the "Host:" header - conn.putrequest('GET', '/', skip_host=1) - - def test_putrequest_override_encoding(self): - """ - It should be possible to override the default encoding - to transmit bytes in another encoding even if invalid - (bpo-36274). - """ - class UnsafeHTTPConnection(client.HTTPConnection): - def _encode_request(self, str_url): - return str_url.encode('utf-8') - - conn = UnsafeHTTPConnection('example.com') - conn.sock = FakeSocket('') - conn.putrequest('GET', '/☃') - - - class ExtendedReadTest(TestCase): - """ - Test peek(), read1(), readline() - """ - lines = ( - 'HTTP/1.1 200 OK\r\n' - '\r\n' - 'hello world!\n' - 'and now \n' - 'for something completely different\n' - 'foo' - ) - lines_expected = lines[lines.find('hello'):].encode("ascii") - lines_chunked = ( - 'HTTP/1.1 200 OK\r\n' - 'Transfer-Encoding: chunked\r\n\r\n' - 'a\r\n' - 'hello worl\r\n' - '3\r\n' - 'd!\n\r\n' - '9\r\n' - 'and now \n\r\n' - '23\r\n' - 'for something completely different\n\r\n' - '3\r\n' - 'foo\r\n' - '0\r\n' # terminating chunk - '\r\n' # end of trailers - ) - - def setUp(self): - sock = FakeSocket(self.lines) - resp = client.HTTPResponse(sock, method="GET") - resp.begin() - resp.fp = io.BufferedReader(resp.fp) - self.resp = resp - - - - def test_peek(self): - resp = self.resp - # patch up the buffered peek so that it returns not too much stuff - oldpeek = resp.fp.peek - def mypeek(n=-1): - p = oldpeek(n) - if n >= 0: - return p[:n] - return p[:10] - resp.fp.peek = mypeek - - all = [] - while True: - # try a short peek - p = resp.peek(3) - if p: - self.assertGreater(len(p), 0) - # then unbounded peek - p2 = resp.peek() - self.assertGreaterEqual(len(p2), len(p)) - self.assertTrue(p2.startswith(p)) - next = resp.read(len(p2)) - self.assertEqual(next, p2) - else: - next = resp.read() - self.assertFalse(next) - all.append(next) - if not next: - break - self.assertEqual(b"".join(all), self.lines_expected) - - def test_readline(self): - resp = self.resp - self._verify_readline(self.resp.readline, self.lines_expected) - - def _verify_readline(self, readline, expected): - all = [] - while True: - # short readlines - line = readline(5) - if line and line != b"foo": - if len(line) < 5: - self.assertTrue(line.endswith(b"\n")) - all.append(line) - if not line: - break - self.assertEqual(b"".join(all), expected) - - def test_read1(self): - resp = self.resp - def r(): - res = resp.read1(4) - self.assertLessEqual(len(res), 4) - return res - readliner = Readliner(r) - self._verify_readline(readliner.readline, self.lines_expected) - - def test_read1_unbounded(self): - resp = self.resp - all = [] - while True: - data = resp.read1() - if not data: - break - all.append(data) - self.assertEqual(b"".join(all), self.lines_expected) - - def test_read1_bounded(self): - resp = self.resp - all = [] - while True: - data = resp.read1(10) - if not data: - break - self.assertLessEqual(len(data), 10) - all.append(data) - self.assertEqual(b"".join(all), self.lines_expected) - - def test_read1_0(self): - self.assertEqual(self.resp.read1(0), b"") - - def test_peek_0(self): - p = self.resp.peek(0) - self.assertLessEqual(0, len(p)) - - - class ExtendedReadTestChunked(ExtendedReadTest): - """ - Test peek(), read1(), readline() in chunked mode - """ - lines = ( - 'HTTP/1.1 200 OK\r\n' - 'Transfer-Encoding: chunked\r\n\r\n' - 'a\r\n' - 'hello worl\r\n' - '3\r\n' - 'd!\n\r\n' - '9\r\n' - 'and now \n\r\n' - '23\r\n' - 'for something completely different\n\r\n' - '3\r\n' - 'foo\r\n' - '0\r\n' # terminating chunk - '\r\n' # end of trailers - ) - - - class Readliner: - """ - a simple readline class that uses an arbitrary read function and buffering - """ - def __init__(self, readfunc): - self.readfunc = readfunc - self.remainder = b"" - - def readline(self, limit): - data = [] - datalen = 0 - read = self.remainder - try: - while True: - idx = read.find(b'\n') - if idx != -1: - break - if datalen + len(read) >= limit: - idx = limit - datalen - 1 - # read more data - data.append(read) - read = self.readfunc() - if not read: - idx = 0 #eof condition - break - idx += 1 - data.append(read[:idx]) - self.remainder = read[idx:] - return b"".join(data) - except: - self.remainder = b"".join(data) - raise - - - class OfflineTest(TestCase): - def test_all(self): - # Documented objects defined in the module should be in __all__ - expected = {"responses"} # White-list documented dict() object - # HTTPMessage, parse_headers(), and the HTTP status code constants are - # intentionally omitted for simplicity - blacklist = {"HTTPMessage", "parse_headers"} - for name in dir(client): - if name.startswith("_") or name in blacklist: - continue - module_object = getattr(client, name) - if getattr(module_object, "__module__", None) == "http.client": - expected.add(name) - self.assertCountEqual(client.__all__, expected) - - def test_responses(self): - self.assertEqual(client.responses[client.NOT_FOUND], "Not Found") - - def test_client_constants(self): - # Make sure we don't break backward compatibility with 3.4 - expected = [ - 'CONTINUE', - 'SWITCHING_PROTOCOLS', - 'PROCESSING', - 'OK', - 'CREATED', - 'ACCEPTED', - 'NON_AUTHORITATIVE_INFORMATION', - 'NO_CONTENT', - 'RESET_CONTENT', - 'PARTIAL_CONTENT', - 'MULTI_STATUS', - 'IM_USED', - 'MULTIPLE_CHOICES', - 'MOVED_PERMANENTLY', - 'FOUND', - 'SEE_OTHER', - 'NOT_MODIFIED', - 'USE_PROXY', - 'TEMPORARY_REDIRECT', - 'BAD_REQUEST', - 'UNAUTHORIZED', - 'PAYMENT_REQUIRED', - 'FORBIDDEN', - 'NOT_FOUND', - 'METHOD_NOT_ALLOWED', - 'NOT_ACCEPTABLE', - 'PROXY_AUTHENTICATION_REQUIRED', - 'REQUEST_TIMEOUT', - 'CONFLICT', - 'GONE', - 'LENGTH_REQUIRED', - 'PRECONDITION_FAILED', - 'REQUEST_ENTITY_TOO_LARGE', - 'REQUEST_URI_TOO_LONG', - 'UNSUPPORTED_MEDIA_TYPE', - 'REQUESTED_RANGE_NOT_SATISFIABLE', - 'EXPECTATION_FAILED', - 'MISDIRECTED_REQUEST', - 'UNPROCESSABLE_ENTITY', - 'LOCKED', - 'FAILED_DEPENDENCY', - 'UPGRADE_REQUIRED', - 'PRECONDITION_REQUIRED', - 'TOO_MANY_REQUESTS', - 'REQUEST_HEADER_FIELDS_TOO_LARGE', - 'UNAVAILABLE_FOR_LEGAL_REASONS', - 'INTERNAL_SERVER_ERROR', - 'NOT_IMPLEMENTED', - 'BAD_GATEWAY', - 'SERVICE_UNAVAILABLE', - 'GATEWAY_TIMEOUT', - 'HTTP_VERSION_NOT_SUPPORTED', - 'INSUFFICIENT_STORAGE', - 'NOT_EXTENDED', - 'NETWORK_AUTHENTICATION_REQUIRED', - ] - for const in expected: - with self.subTest(constant=const): - self.assertTrue(hasattr(client, const)) - - - class SourceAddressTest(TestCase): - def setUp(self): - self.serv = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - self.port = support.bind_port(self.serv) - self.source_port = support.find_unused_port() - self.serv.listen() - self.conn = None - - def tearDown(self): - if self.conn: - self.conn.close() - self.conn = None - self.serv.close() - self.serv = None - - def testHTTPConnectionSourceAddress(self): - self.conn = client.HTTPConnection(HOST, self.port, - source_address=('', self.source_port)) - self.conn.connect() - self.assertEqual(self.conn.sock.getsockname()[1], self.source_port) - - @unittest.skipIf(not hasattr(client, 'HTTPSConnection'), - 'http.client.HTTPSConnection not defined') - def testHTTPSConnectionSourceAddress(self): - self.conn = client.HTTPSConnection(HOST, self.port, - source_address=('', self.source_port)) - # We don't test anything here other than the constructor not barfing as - # this code doesn't deal with setting up an active running SSL server - # for an ssl_wrapped connect() to actually return from. - - - class TimeoutTest(TestCase): - PORT = None - - def setUp(self): - self.serv = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - TimeoutTest.PORT = support.bind_port(self.serv) - self.serv.listen() - - def tearDown(self): - self.serv.close() - self.serv = None - - def testTimeoutAttribute(self): - # This will prove that the timeout gets through HTTPConnection - # and into the socket. - - # default -- use global socket timeout - self.assertIsNone(socket.getdefaulttimeout()) - socket.setdefaulttimeout(30) - try: - httpConn = client.HTTPConnection(HOST, TimeoutTest.PORT) - httpConn.connect() - finally: - socket.setdefaulttimeout(None) - self.assertEqual(httpConn.sock.gettimeout(), 30) - httpConn.close() - - # no timeout -- do not use global socket default - self.assertIsNone(socket.getdefaulttimeout()) - socket.setdefaulttimeout(30) - try: - httpConn = client.HTTPConnection(HOST, TimeoutTest.PORT, - timeout=None) - httpConn.connect() - finally: - socket.setdefaulttimeout(None) - self.assertEqual(httpConn.sock.gettimeout(), None) - httpConn.close() - - # a value - httpConn = client.HTTPConnection(HOST, TimeoutTest.PORT, timeout=30) - httpConn.connect() - self.assertEqual(httpConn.sock.gettimeout(), 30) - httpConn.close() - - - class PersistenceTest(TestCase): - - def test_reuse_reconnect(self): - # Should reuse or reconnect depending on header from server - tests = ( - ('1.0', '', False), - ('1.0', 'Connection: keep-alive\r\n', True), - ('1.1', '', True), - ('1.1', 'Connection: close\r\n', False), - ('1.0', 'Connection: keep-ALIVE\r\n', True), - ('1.1', 'Connection: cloSE\r\n', False), - ) - for version, header, reuse in tests: - with self.subTest(version=version, header=header): - msg = ( - 'HTTP/{} 200 OK\r\n' - '{}' - 'Content-Length: 12\r\n' - '\r\n' - 'Dummy body\r\n' - ).format(version, header) - conn = FakeSocketHTTPConnection(msg) - self.assertIsNone(conn.sock) - conn.request('GET', '/open-connection') - with conn.getresponse() as response: - self.assertEqual(conn.sock is None, not reuse) - response.read() - self.assertEqual(conn.sock is None, not reuse) - self.assertEqual(conn.connections, 1) - conn.request('GET', '/subsequent-request') - self.assertEqual(conn.connections, 1 if reuse else 2) - - def test_disconnected(self): - - def make_reset_reader(text): - """Return BufferedReader that raises ECONNRESET at EOF""" - stream = io.BytesIO(text) - def readinto(buffer): - size = io.BytesIO.readinto(stream, buffer) - if size == 0: - raise ConnectionResetError() - return size - stream.readinto = readinto - return io.BufferedReader(stream) - - tests = ( - (io.BytesIO, client.RemoteDisconnected), - (make_reset_reader, ConnectionResetError), - ) - for stream_factory, exception in tests: - with self.subTest(exception=exception): - conn = FakeSocketHTTPConnection(b'', stream_factory) - conn.request('GET', '/eof-response') - self.assertRaises(exception, conn.getresponse) - self.assertIsNone(conn.sock) - # HTTPConnection.connect() should be automatically invoked - conn.request('GET', '/reconnect') - self.assertEqual(conn.connections, 2) - - def test_100_close(self): - conn = FakeSocketHTTPConnection( - b'HTTP/1.1 100 Continue\r\n' - b'\r\n' - # Missing final response - ) - conn.request('GET', '/', headers={'Expect': '100-continue'}) - self.assertRaises(client.RemoteDisconnected, conn.getresponse) - self.assertIsNone(conn.sock) - conn.request('GET', '/reconnect') - self.assertEqual(conn.connections, 2) - - - class HTTPSTest(TestCase): - - def setUp(self): - if not hasattr(client, 'HTTPSConnection'): - self.skipTest('ssl support required') - - def make_server(self, certfile): - from test.ssl_servers import make_https_server - return make_https_server(self, certfile=certfile) - - def test_attributes(self): - # simple test to check it's storing the timeout - h = client.HTTPSConnection(HOST, TimeoutTest.PORT, timeout=30) - self.assertEqual(h.timeout, 30) - - def test_networked(self): - # Default settings: requires a valid cert from a trusted CA - import ssl - support.requires('network') - with support.transient_internet('self-signed.pythontest.net'): - h = client.HTTPSConnection('self-signed.pythontest.net', 443) - with self.assertRaises(ssl.SSLError) as exc_info: - h.request('GET', '/') - self.assertEqual(exc_info.exception.reason, 'CERTIFICATE_VERIFY_FAILED') - - def test_networked_noverification(self): - # Switch off cert verification - import ssl - support.requires('network') - with support.transient_internet('self-signed.pythontest.net'): - context = ssl._create_unverified_context() - h = client.HTTPSConnection('self-signed.pythontest.net', 443, - context=context) - h.request('GET', '/') - resp = h.getresponse() - h.close() - self.assertIn('nginx', resp.getheader('server')) - resp.close() - - @support.system_must_validate_cert - def test_networked_trusted_by_default_cert(self): - # Default settings: requires a valid cert from a trusted CA - support.requires('network') - with support.transient_internet('www.python.org'): - h = client.HTTPSConnection('www.python.org', 443) - h.request('GET', '/') - resp = h.getresponse() - content_type = resp.getheader('content-type') - resp.close() - h.close() - self.assertIn('text/html', content_type) - - def test_networked_good_cert(self): - # We feed the server's cert as a validating cert - import ssl - support.requires('network') - selfsigned_pythontestdotnet = 'self-signed.pythontest.net' - with support.transient_internet(selfsigned_pythontestdotnet): - context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT) - self.assertEqual(context.verify_mode, ssl.CERT_REQUIRED) - self.assertEqual(context.check_hostname, True) - context.load_verify_locations(CERT_selfsigned_pythontestdotnet) - try: - h = client.HTTPSConnection(selfsigned_pythontestdotnet, 443, - context=context) - h.request('GET', '/') - resp = h.getresponse() - except ssl.SSLError as ssl_err: - ssl_err_str = str(ssl_err) - # In the error message of [SSL: CERTIFICATE_VERIFY_FAILED] on - # modern Linux distros (Debian Buster, etc) default OpenSSL - # configurations it'll fail saying "key too weak" until we - # address https://bugs.python.org/issue36816 to use a proper - # key size on self-signed.pythontest.net. - if re.search(r'(?i)key.too.weak', ssl_err_str): - raise unittest.SkipTest( - f'Got {ssl_err_str} trying to connect ' - f'to {selfsigned_pythontestdotnet}. ' - 'See https://bugs.python.org/issue36816.') - raise - server_string = resp.getheader('server') - resp.close() - h.close() - self.assertIn('nginx', server_string) - - def test_networked_bad_cert(self): - # We feed a "CA" cert that is unrelated to the server's cert - import ssl - support.requires('network') - with support.transient_internet('self-signed.pythontest.net'): - context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT) - context.load_verify_locations(CERT_localhost) - h = client.HTTPSConnection('self-signed.pythontest.net', 443, context=context) - with self.assertRaises(ssl.SSLError) as exc_info: - h.request('GET', '/') - self.assertEqual(exc_info.exception.reason, 'CERTIFICATE_VERIFY_FAILED') - - def test_local_unknown_cert(self): - # The custom cert isn't known to the default trust bundle - import ssl - server = self.make_server(CERT_localhost) - h = client.HTTPSConnection('localhost', server.port) - with self.assertRaises(ssl.SSLError) as exc_info: - h.request('GET', '/') - self.assertEqual(exc_info.exception.reason, 'CERTIFICATE_VERIFY_FAILED') - - def test_local_good_hostname(self): - # The (valid) cert validates the HTTP hostname - import ssl - server = self.make_server(CERT_localhost) - context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT) - context.load_verify_locations(CERT_localhost) - h = client.HTTPSConnection('localhost', server.port, context=context) - self.addCleanup(h.close) - h.request('GET', '/nonexistent') - resp = h.getresponse() - self.addCleanup(resp.close) - self.assertEqual(resp.status, 404) - - def test_local_bad_hostname(self): - # The (valid) cert doesn't validate the HTTP hostname - import ssl - server = self.make_server(CERT_fakehostname) - context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT) - context.load_verify_locations(CERT_fakehostname) - h = client.HTTPSConnection('localhost', server.port, context=context) - with self.assertRaises(ssl.CertificateError): - h.request('GET', '/') - # Same with explicit check_hostname=True - with support.check_warnings(('', DeprecationWarning)): - h = client.HTTPSConnection('localhost', server.port, - context=context, check_hostname=True) - with self.assertRaises(ssl.CertificateError): - h.request('GET', '/') - # With check_hostname=False, the mismatching is ignored - context.check_hostname = False - with support.check_warnings(('', DeprecationWarning)): - h = client.HTTPSConnection('localhost', server.port, - context=context, check_hostname=False) - h.request('GET', '/nonexistent') - resp = h.getresponse() - resp.close() - h.close() - self.assertEqual(resp.status, 404) - # The context's check_hostname setting is used if one isn't passed to - # HTTPSConnection. - context.check_hostname = False - h = client.HTTPSConnection('localhost', server.port, context=context) - h.request('GET', '/nonexistent') - resp = h.getresponse() - self.assertEqual(resp.status, 404) - resp.close() - h.close() - # Passing check_hostname to HTTPSConnection should override the - # context's setting. - with support.check_warnings(('', DeprecationWarning)): - h = client.HTTPSConnection('localhost', server.port, - context=context, check_hostname=True) - with self.assertRaises(ssl.CertificateError): - h.request('GET', '/') - - @unittest.skipIf(not hasattr(client, 'HTTPSConnection'), - 'http.client.HTTPSConnection not available') - def test_host_port(self): - # Check invalid host_port - - for hp in ("www.python.org:abc", "user:password@www.python.org"): - self.assertRaises(client.InvalidURL, client.HTTPSConnection, hp) - - for hp, h, p in (("[fe80::207:e9ff:fe9b]:8000", - "fe80::207:e9ff:fe9b", 8000), - ("www.python.org:443", "www.python.org", 443), - ("www.python.org:", "www.python.org", 443), - ("www.python.org", "www.python.org", 443), - ("[fe80::207:e9ff:fe9b]", "fe80::207:e9ff:fe9b", 443), - ("[fe80::207:e9ff:fe9b]:", "fe80::207:e9ff:fe9b", - 443)): - c = client.HTTPSConnection(hp) - self.assertEqual(h, c.host) - self.assertEqual(p, c.port) - - def test_tls13_pha(self): - import ssl - if not ssl.HAS_TLSv1_3: - self.skipTest('TLS 1.3 support required') - # just check status of PHA flag - h = client.HTTPSConnection('localhost', 443) - self.assertTrue(h._context.post_handshake_auth) - - context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT) - self.assertFalse(context.post_handshake_auth) - h = client.HTTPSConnection('localhost', 443, context=context) - self.assertIs(h._context, context) - self.assertFalse(h._context.post_handshake_auth) - - with warnings.catch_warnings(): - warnings.filterwarnings('ignore', 'key_file, cert_file and check_hostname are deprecated', - DeprecationWarning) - h = client.HTTPSConnection('localhost', 443, context=context, - cert_file=CERT_localhost) - self.assertTrue(h._context.post_handshake_auth) - - - class RequestBodyTest(TestCase): - """Test cases where a request includes a message body.""" - - def setUp(self): - self.conn = client.HTTPConnection('example.com') - self.conn.sock = self.sock = FakeSocket("") - self.conn.sock = self.sock - - def get_headers_and_fp(self): - f = io.BytesIO(self.sock.data) - f.readline() # read the request line - message = client.parse_headers(f) - return message, f - - def test_list_body(self): - # Note that no content-length is automatically calculated for - # an iterable. The request will fall back to send chunked - # transfer encoding. - cases = ( - ([b'foo', b'bar'], b'3\r\nfoo\r\n3\r\nbar\r\n0\r\n\r\n'), - ((b'foo', b'bar'), b'3\r\nfoo\r\n3\r\nbar\r\n0\r\n\r\n'), - ) - for body, expected in cases: - with self.subTest(body): - self.conn = client.HTTPConnection('example.com') - self.conn.sock = self.sock = FakeSocket('') - - self.conn.request('PUT', '/url', body) - msg, f = self.get_headers_and_fp() - self.assertNotIn('Content-Type', msg) - self.assertNotIn('Content-Length', msg) - self.assertEqual(msg.get('Transfer-Encoding'), 'chunked') - self.assertEqual(expected, f.read()) - - def test_manual_content_length(self): - # Set an incorrect content-length so that we can verify that - # it will not be over-ridden by the library. - self.conn.request("PUT", "/url", "body", - {"Content-Length": "42"}) - message, f = self.get_headers_and_fp() - self.assertEqual("42", message.get("content-length")) - self.assertEqual(4, len(f.read())) - - def test_ascii_body(self): - self.conn.request("PUT", "/url", "body") - message, f = self.get_headers_and_fp() - self.assertEqual("text/plain", message.get_content_type()) - self.assertIsNone(message.get_charset()) - self.assertEqual("4", message.get("content-length")) - self.assertEqual(b'body', f.read()) - - def test_latin1_body(self): - self.conn.request("PUT", "/url", "body\xc1") - message, f = self.get_headers_and_fp() - self.assertEqual("text/plain", message.get_content_type()) - self.assertIsNone(message.get_charset()) - self.assertEqual("5", message.get("content-length")) - self.assertEqual(b'body\xc1', f.read()) - - def test_bytes_body(self): - self.conn.request("PUT", "/url", b"body\xc1") - message, f = self.get_headers_and_fp() - self.assertEqual("text/plain", message.get_content_type()) - self.assertIsNone(message.get_charset()) - self.assertEqual("5", message.get("content-length")) - self.assertEqual(b'body\xc1', f.read()) - - def test_text_file_body(self): - self.addCleanup(support.unlink, support.TESTFN) - with open(support.TESTFN, "w") as f: - f.write("body") - with open(support.TESTFN) as f: - self.conn.request("PUT", "/url", f) - message, f = self.get_headers_and_fp() - self.assertEqual("text/plain", message.get_content_type()) - self.assertIsNone(message.get_charset()) - # No content-length will be determined for files; the body - # will be sent using chunked transfer encoding instead. - self.assertIsNone(message.get("content-length")) - self.assertEqual("chunked", message.get("transfer-encoding")) - self.assertEqual(b'4\r\nbody\r\n0\r\n\r\n', f.read()) - - def test_binary_file_body(self): - self.addCleanup(support.unlink, support.TESTFN) - with open(support.TESTFN, "wb") as f: - f.write(b"body\xc1") - with open(support.TESTFN, "rb") as f: - self.conn.request("PUT", "/url", f) - message, f = self.get_headers_and_fp() - self.assertEqual("text/plain", message.get_content_type()) - self.assertIsNone(message.get_charset()) - self.assertEqual("chunked", message.get("Transfer-Encoding")) - self.assertNotIn("Content-Length", message) - self.assertEqual(b'5\r\nbody\xc1\r\n0\r\n\r\n', f.read()) - - - class HTTPResponseTest(TestCase): - - def setUp(self): - body = "HTTP/1.1 200 Ok\r\nMy-Header: first-value\r\nMy-Header: \ - second-value\r\n\r\nText" - sock = FakeSocket(body) - self.resp = client.HTTPResponse(sock) - self.resp.begin() - - def test_getting_header(self): - header = self.resp.getheader('My-Header') - self.assertEqual(header, 'first-value, second-value') - - header = self.resp.getheader('My-Header', 'some default') - self.assertEqual(header, 'first-value, second-value') - - def test_getting_nonexistent_header_with_string_default(self): - header = self.resp.getheader('No-Such-Header', 'default-value') - self.assertEqual(header, 'default-value') - - def test_getting_nonexistent_header_with_iterable_default(self): - header = self.resp.getheader('No-Such-Header', ['default', 'values']) - self.assertEqual(header, 'default, values') - - header = self.resp.getheader('No-Such-Header', ('default', 'values')) - self.assertEqual(header, 'default, values') - - def test_getting_nonexistent_header_without_default(self): - header = self.resp.getheader('No-Such-Header') - self.assertEqual(header, None) - - def test_getting_header_defaultint(self): - header = self.resp.getheader('No-Such-Header',default=42) - self.assertEqual(header, 42) - - class TunnelTests(TestCase): - def setUp(self): - response_text = ( - 'HTTP/1.0 200 OK\r\n\r\n' # Reply to CONNECT - 'HTTP/1.1 200 OK\r\n' # Reply to HEAD - 'Content-Length: 42\r\n\r\n' - ) - self.host = 'proxy.com' - self.conn = client.HTTPConnection(self.host) - self.conn._create_connection = self._create_connection(response_text) - - def tearDown(self): - self.conn.close() - - def _create_connection(self, response_text): - def create_connection(address, timeout=None, source_address=None): - return FakeSocket(response_text, host=address[0], port=address[1]) - return create_connection - - def test_set_tunnel_host_port_headers(self): - tunnel_host = 'destination.com' - tunnel_port = 8888 - tunnel_headers = {'User-Agent': 'Mozilla/5.0 (compatible, MSIE 11)'} - self.conn.set_tunnel(tunnel_host, port=tunnel_port, - headers=tunnel_headers) - self.conn.request('HEAD', '/', '') - self.assertEqual(self.conn.sock.host, self.host) - self.assertEqual(self.conn.sock.port, client.HTTP_PORT) - self.assertEqual(self.conn._tunnel_host, tunnel_host) - self.assertEqual(self.conn._tunnel_port, tunnel_port) - self.assertEqual(self.conn._tunnel_headers, tunnel_headers) - - def test_disallow_set_tunnel_after_connect(self): - # Once connected, we shouldn't be able to tunnel anymore - self.conn.connect() - self.assertRaises(RuntimeError, self.conn.set_tunnel, - 'destination.com') - - def test_connect_with_tunnel(self): - self.conn.set_tunnel('destination.com') - self.conn.request('HEAD', '/', '') - self.assertEqual(self.conn.sock.host, self.host) - self.assertEqual(self.conn.sock.port, client.HTTP_PORT) - self.assertIn(b'CONNECT destination.com', self.conn.sock.data) - # issue22095 - self.assertNotIn(b'Host: destination.com:None', self.conn.sock.data) - self.assertIn(b'Host: destination.com', self.conn.sock.data) - - # This test should be removed when CONNECT gets the HTTP/1.1 blessing - self.assertNotIn(b'Host: proxy.com', self.conn.sock.data) - - def test_connect_put_request(self): - self.conn.set_tunnel('destination.com') - self.conn.request('PUT', '/', '') - self.assertEqual(self.conn.sock.host, self.host) - self.assertEqual(self.conn.sock.port, client.HTTP_PORT) - self.assertIn(b'CONNECT destination.com', self.conn.sock.data) - self.assertIn(b'Host: destination.com', self.conn.sock.data) - - def test_tunnel_debuglog(self): - expected_header = 'X-Dummy: 1' - response_text = 'HTTP/1.0 200 OK\r\n{}\r\n\r\n'.format(expected_header) - - self.conn.set_debuglevel(1) - self.conn._create_connection = self._create_connection(response_text) - self.conn.set_tunnel('destination.com') - - with support.captured_stdout() as output: - self.conn.request('PUT', '/', '') - lines = output.getvalue().splitlines() - self.assertIn('header: {}'.format(expected_header), lines) - - - if __name__ == '__main__': - unittest.main(verbosity=2) diff --git a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_httpservers.yaml b/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_httpservers.yaml deleted file mode 100644 index 64d85e7a4..000000000 --- a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_httpservers.yaml +++ /dev/null @@ -1,1199 +0,0 @@ -python: | - """Unittests for the various HTTPServer modules. - - Written by Cody A.W. Somerville , - Josip Dzolonga, and Michael Otteneder for the 2007/08 GHOP contest. - """ - - from http.server import BaseHTTPRequestHandler, HTTPServer, \ - SimpleHTTPRequestHandler, CGIHTTPRequestHandler - from http import server, HTTPStatus - - import os - import socket - import sys - import re - import base64 - import ntpath - import shutil - import email.message - import email.utils - import html - import http.client - import urllib.parse - import tempfile - import time - import datetime - import threading - from unittest import mock - from io import BytesIO - - import unittest - from test import support - - - class NoLogRequestHandler: - def log_message(self, *args): - # don't write log messages to stderr - pass - - def read(self, n=None): - return '' - - - class TestServerThread(threading.Thread): - def __init__(self, test_object, request_handler): - threading.Thread.__init__(self) - self.request_handler = request_handler - self.test_object = test_object - - def run(self): - self.server = HTTPServer(('localhost', 0), self.request_handler) - self.test_object.HOST, self.test_object.PORT = self.server.socket.getsockname() - self.test_object.server_started.set() - self.test_object = None - try: - self.server.serve_forever(0.05) - finally: - self.server.server_close() - - def stop(self): - self.server.shutdown() - self.join() - - - class BaseTestCase(unittest.TestCase): - def setUp(self): - self._threads = support.threading_setup() - os.environ = support.EnvironmentVarGuard() - self.server_started = threading.Event() - self.thread = TestServerThread(self, self.request_handler) - self.thread.start() - self.server_started.wait() - - def tearDown(self): - self.thread.stop() - self.thread = None - os.environ.__exit__() - support.threading_cleanup(*self._threads) - - def request(self, uri, method='GET', body=None, headers={}): - self.connection = http.client.HTTPConnection(self.HOST, self.PORT) - self.connection.request(method, uri, body, headers) - return self.connection.getresponse() - - - class BaseHTTPServerTestCase(BaseTestCase): - class request_handler(NoLogRequestHandler, BaseHTTPRequestHandler): - protocol_version = 'HTTP/1.1' - default_request_version = 'HTTP/1.1' - - def do_TEST(self): - self.send_response(HTTPStatus.NO_CONTENT) - self.send_header('Content-Type', 'text/html') - self.send_header('Connection', 'close') - self.end_headers() - - def do_KEEP(self): - self.send_response(HTTPStatus.NO_CONTENT) - self.send_header('Content-Type', 'text/html') - self.send_header('Connection', 'keep-alive') - self.end_headers() - - def do_KEYERROR(self): - self.send_error(999) - - def do_NOTFOUND(self): - self.send_error(HTTPStatus.NOT_FOUND) - - def do_EXPLAINERROR(self): - self.send_error(999, "Short Message", - "This is a long \n explanation") - - def do_CUSTOM(self): - self.send_response(999) - self.send_header('Content-Type', 'text/html') - self.send_header('Connection', 'close') - self.end_headers() - - def do_LATINONEHEADER(self): - self.send_response(999) - self.send_header('X-Special', 'Dängerous Mind') - self.send_header('Connection', 'close') - self.end_headers() - body = self.headers['x-special-incoming'].encode('utf-8') - self.wfile.write(body) - - def do_SEND_ERROR(self): - self.send_error(int(self.path[1:])) - - def do_HEAD(self): - self.send_error(int(self.path[1:])) - - def setUp(self): - BaseTestCase.setUp(self) - self.con = http.client.HTTPConnection(self.HOST, self.PORT) - self.con.connect() - - def test_command(self): - self.con.request('GET', '/') - res = self.con.getresponse() - self.assertEqual(res.status, HTTPStatus.NOT_IMPLEMENTED) - - def test_request_line_trimming(self): - self.con._http_vsn_str = 'HTTP/1.1\n' - self.con.putrequest('XYZBOGUS', '/') - self.con.endheaders() - res = self.con.getresponse() - self.assertEqual(res.status, HTTPStatus.NOT_IMPLEMENTED) - - def test_version_bogus(self): - self.con._http_vsn_str = 'FUBAR' - self.con.putrequest('GET', '/') - self.con.endheaders() - res = self.con.getresponse() - self.assertEqual(res.status, HTTPStatus.BAD_REQUEST) - - def test_version_digits(self): - self.con._http_vsn_str = 'HTTP/9.9.9' - self.con.putrequest('GET', '/') - self.con.endheaders() - res = self.con.getresponse() - self.assertEqual(res.status, HTTPStatus.BAD_REQUEST) - - def test_version_none_get(self): - self.con._http_vsn_str = '' - self.con.putrequest('GET', '/') - self.con.endheaders() - res = self.con.getresponse() - self.assertEqual(res.status, HTTPStatus.NOT_IMPLEMENTED) - - def test_version_none(self): - # Test that a valid method is rejected when not HTTP/1.x - self.con._http_vsn_str = '' - self.con.putrequest('CUSTOM', '/') - self.con.endheaders() - res = self.con.getresponse() - self.assertEqual(res.status, HTTPStatus.BAD_REQUEST) - - def test_version_invalid(self): - self.con._http_vsn = 99 - self.con._http_vsn_str = 'HTTP/9.9' - self.con.putrequest('GET', '/') - self.con.endheaders() - res = self.con.getresponse() - self.assertEqual(res.status, HTTPStatus.HTTP_VERSION_NOT_SUPPORTED) - - def test_send_blank(self): - self.con._http_vsn_str = '' - self.con.putrequest('', '') - self.con.endheaders() - res = self.con.getresponse() - self.assertEqual(res.status, HTTPStatus.BAD_REQUEST) - - def test_header_close(self): - self.con.putrequest('GET', '/') - self.con.putheader('Connection', 'close') - self.con.endheaders() - res = self.con.getresponse() - self.assertEqual(res.status, HTTPStatus.NOT_IMPLEMENTED) - - def test_header_keep_alive(self): - self.con._http_vsn_str = 'HTTP/1.1' - self.con.putrequest('GET', '/') - self.con.putheader('Connection', 'keep-alive') - self.con.endheaders() - res = self.con.getresponse() - self.assertEqual(res.status, HTTPStatus.NOT_IMPLEMENTED) - - def test_handler(self): - self.con.request('TEST', '/') - res = self.con.getresponse() - self.assertEqual(res.status, HTTPStatus.NO_CONTENT) - - def test_return_header_keep_alive(self): - self.con.request('KEEP', '/') - res = self.con.getresponse() - self.assertEqual(res.getheader('Connection'), 'keep-alive') - self.con.request('TEST', '/') - self.addCleanup(self.con.close) - - def test_internal_key_error(self): - self.con.request('KEYERROR', '/') - res = self.con.getresponse() - self.assertEqual(res.status, 999) - - def test_return_custom_status(self): - self.con.request('CUSTOM', '/') - res = self.con.getresponse() - self.assertEqual(res.status, 999) - - def test_return_explain_error(self): - self.con.request('EXPLAINERROR', '/') - res = self.con.getresponse() - self.assertEqual(res.status, 999) - self.assertTrue(int(res.getheader('Content-Length'))) - - def test_latin1_header(self): - self.con.request('LATINONEHEADER', '/', headers={ - 'X-Special-Incoming': 'Ärger mit Unicode' - }) - res = self.con.getresponse() - self.assertEqual(res.getheader('X-Special'), 'Dängerous Mind') - self.assertEqual(res.read(), 'Ärger mit Unicode'.encode('utf-8')) - - def test_error_content_length(self): - # Issue #16088: standard error responses should have a content-length - self.con.request('NOTFOUND', '/') - res = self.con.getresponse() - self.assertEqual(res.status, HTTPStatus.NOT_FOUND) - - data = res.read() - self.assertEqual(int(res.getheader('Content-Length')), len(data)) - - def test_send_error(self): - allow_transfer_encoding_codes = (HTTPStatus.NOT_MODIFIED, - HTTPStatus.RESET_CONTENT) - for code in (HTTPStatus.NO_CONTENT, HTTPStatus.NOT_MODIFIED, - HTTPStatus.PROCESSING, HTTPStatus.RESET_CONTENT, - HTTPStatus.SWITCHING_PROTOCOLS): - self.con.request('SEND_ERROR', '/{}'.format(code)) - res = self.con.getresponse() - self.assertEqual(code, res.status) - self.assertEqual(None, res.getheader('Content-Length')) - self.assertEqual(None, res.getheader('Content-Type')) - if code not in allow_transfer_encoding_codes: - self.assertEqual(None, res.getheader('Transfer-Encoding')) - - data = res.read() - self.assertEqual(b'', data) - - def test_head_via_send_error(self): - allow_transfer_encoding_codes = (HTTPStatus.NOT_MODIFIED, - HTTPStatus.RESET_CONTENT) - for code in (HTTPStatus.OK, HTTPStatus.NO_CONTENT, - HTTPStatus.NOT_MODIFIED, HTTPStatus.RESET_CONTENT, - HTTPStatus.SWITCHING_PROTOCOLS): - self.con.request('HEAD', '/{}'.format(code)) - res = self.con.getresponse() - self.assertEqual(code, res.status) - if code == HTTPStatus.OK: - self.assertTrue(int(res.getheader('Content-Length')) > 0) - self.assertIn('text/html', res.getheader('Content-Type')) - else: - self.assertEqual(None, res.getheader('Content-Length')) - self.assertEqual(None, res.getheader('Content-Type')) - if code not in allow_transfer_encoding_codes: - self.assertEqual(None, res.getheader('Transfer-Encoding')) - - data = res.read() - self.assertEqual(b'', data) - - - class RequestHandlerLoggingTestCase(BaseTestCase): - class request_handler(BaseHTTPRequestHandler): - protocol_version = 'HTTP/1.1' - default_request_version = 'HTTP/1.1' - - def do_GET(self): - self.send_response(HTTPStatus.OK) - self.end_headers() - - def do_ERROR(self): - self.send_error(HTTPStatus.NOT_FOUND, 'File not found') - - def test_get(self): - self.con = http.client.HTTPConnection(self.HOST, self.PORT) - self.con.connect() - - with support.captured_stderr() as err: - self.con.request('GET', '/') - self.con.getresponse() - - self.assertTrue( - err.getvalue().endswith('"GET / HTTP/1.1" 200 -\n')) - - def test_err(self): - self.con = http.client.HTTPConnection(self.HOST, self.PORT) - self.con.connect() - - with support.captured_stderr() as err: - self.con.request('ERROR', '/') - self.con.getresponse() - - lines = err.getvalue().split('\n') - self.assertTrue(lines[0].endswith('code 404, message File not found')) - self.assertTrue(lines[1].endswith('"ERROR / HTTP/1.1" 404 -')) - - - class SimpleHTTPServerTestCase(BaseTestCase): - class request_handler(NoLogRequestHandler, SimpleHTTPRequestHandler): - pass - - def setUp(self): - BaseTestCase.setUp(self) - self.cwd = os.getcwd() - basetempdir = tempfile.gettempdir() - os.chdir(basetempdir) - self.data = b'We are the knights who say Ni!' - self.tempdir = tempfile.mkdtemp(dir=basetempdir) - self.tempdir_name = os.path.basename(self.tempdir) - self.base_url = '/' + self.tempdir_name - tempname = os.path.join(self.tempdir, 'test') - with open(tempname, 'wb') as temp: - temp.write(self.data) - temp.flush() - mtime = os.stat(tempname).st_mtime - # compute last modification datetime for browser cache tests - last_modif = datetime.datetime.fromtimestamp(mtime, - datetime.timezone.utc) - self.last_modif_datetime = last_modif.replace(microsecond=0) - self.last_modif_header = email.utils.formatdate( - last_modif.timestamp(), usegmt=True) - - def tearDown(self): - try: - os.chdir(self.cwd) - try: - shutil.rmtree(self.tempdir) - except: - pass - finally: - BaseTestCase.tearDown(self) - - def check_status_and_reason(self, response, status, data=None): - def close_conn(): - """Don't close reader yet so we can check if there was leftover - buffered input""" - nonlocal reader - reader = response.fp - response.fp = None - reader = None - response._close_conn = close_conn - - body = response.read() - self.assertTrue(response) - self.assertEqual(response.status, status) - self.assertIsNotNone(response.reason) - if data: - self.assertEqual(data, body) - # Ensure the server has not set up a persistent connection, and has - # not sent any extra data - self.assertEqual(response.version, 10) - self.assertEqual(response.msg.get("Connection", "close"), "close") - self.assertEqual(reader.read(30), b'', 'Connection should be closed') - - reader.close() - return body - - @unittest.skipIf(sys.platform == 'darwin', - 'undecodable name cannot always be decoded on macOS') - @unittest.skipIf(sys.platform == 'win32', - 'undecodable name cannot be decoded on win32') - @unittest.skipUnless(support.TESTFN_UNDECODABLE, - 'need support.TESTFN_UNDECODABLE') - def test_undecodable_filename(self): - enc = sys.getfilesystemencoding() - filename = os.fsdecode(support.TESTFN_UNDECODABLE) + '.txt' - with open(os.path.join(self.tempdir, filename), 'wb') as f: - f.write(support.TESTFN_UNDECODABLE) - response = self.request(self.base_url + '/') - if sys.platform == 'darwin': - # On Mac OS the HFS+ filesystem replaces bytes that aren't valid - # UTF-8 into a percent-encoded value. - for name in os.listdir(self.tempdir): - if name != 'test': # Ignore a filename created in setUp(). - filename = name - break - body = self.check_status_and_reason(response, HTTPStatus.OK) - quotedname = urllib.parse.quote(filename, errors='surrogatepass') - self.assertIn(('href="%s"' % quotedname) - .encode(enc, 'surrogateescape'), body) - self.assertIn(('>%s<' % html.escape(filename, quote=False)) - .encode(enc, 'surrogateescape'), body) - response = self.request(self.base_url + '/' + quotedname) - self.check_status_and_reason(response, HTTPStatus.OK, - data=support.TESTFN_UNDECODABLE) - - def test_get(self): - #constructs the path relative to the root directory of the HTTPServer - response = self.request(self.base_url + '/test') - self.check_status_and_reason(response, HTTPStatus.OK, data=self.data) - # check for trailing "/" which should return 404. See Issue17324 - response = self.request(self.base_url + '/test/') - self.check_status_and_reason(response, HTTPStatus.NOT_FOUND) - response = self.request(self.base_url + '/') - self.check_status_and_reason(response, HTTPStatus.OK) - response = self.request(self.base_url) - self.check_status_and_reason(response, HTTPStatus.MOVED_PERMANENTLY) - response = self.request(self.base_url + '/?hi=2') - self.check_status_and_reason(response, HTTPStatus.OK) - response = self.request(self.base_url + '?hi=1') - self.check_status_and_reason(response, HTTPStatus.MOVED_PERMANENTLY) - self.assertEqual(response.getheader("Location"), - self.base_url + "/?hi=1") - response = self.request('/ThisDoesNotExist') - self.check_status_and_reason(response, HTTPStatus.NOT_FOUND) - response = self.request('/' + 'ThisDoesNotExist' + '/') - self.check_status_and_reason(response, HTTPStatus.NOT_FOUND) - - data = b"Dummy index file\r\n" - with open(os.path.join(self.tempdir_name, 'index.html'), 'wb') as f: - f.write(data) - response = self.request(self.base_url + '/') - self.check_status_and_reason(response, HTTPStatus.OK, data) - - # chmod() doesn't work as expected on Windows, and filesystem - # permissions are ignored by root on Unix. - if os.name == 'posix' and os.geteuid() != 0: - os.chmod(self.tempdir, 0) - try: - response = self.request(self.base_url + '/') - self.check_status_and_reason(response, HTTPStatus.NOT_FOUND) - finally: - os.chmod(self.tempdir, 0o755) - - def test_head(self): - response = self.request( - self.base_url + '/test', method='HEAD') - self.check_status_and_reason(response, HTTPStatus.OK) - self.assertEqual(response.getheader('content-length'), - str(len(self.data))) - self.assertEqual(response.getheader('content-type'), - 'application/octet-stream') - - def test_browser_cache(self): - """Check that when a request to /test is sent with the request header - If-Modified-Since set to date of last modification, the server returns - status code 304, not 200 - """ - headers = email.message.Message() - headers['If-Modified-Since'] = self.last_modif_header - response = self.request(self.base_url + '/test', headers=headers) - self.check_status_and_reason(response, HTTPStatus.NOT_MODIFIED) - - # one hour after last modification : must return 304 - new_dt = self.last_modif_datetime + datetime.timedelta(hours=1) - headers = email.message.Message() - headers['If-Modified-Since'] = email.utils.format_datetime(new_dt, - usegmt=True) - response = self.request(self.base_url + '/test', headers=headers) - self.check_status_and_reason(response, HTTPStatus.NOT_MODIFIED) - - def test_browser_cache_file_changed(self): - # with If-Modified-Since earlier than Last-Modified, must return 200 - dt = self.last_modif_datetime - # build datetime object : 365 days before last modification - old_dt = dt - datetime.timedelta(days=365) - headers = email.message.Message() - headers['If-Modified-Since'] = email.utils.format_datetime(old_dt, - usegmt=True) - response = self.request(self.base_url + '/test', headers=headers) - self.check_status_and_reason(response, HTTPStatus.OK) - - def test_browser_cache_with_If_None_Match_header(self): - # if If-None-Match header is present, ignore If-Modified-Since - - headers = email.message.Message() - headers['If-Modified-Since'] = self.last_modif_header - headers['If-None-Match'] = "*" - response = self.request(self.base_url + '/test', headers=headers) - self.check_status_and_reason(response, HTTPStatus.OK) - - def test_invalid_requests(self): - response = self.request('/', method='FOO') - self.check_status_and_reason(response, HTTPStatus.NOT_IMPLEMENTED) - # requests must be case sensitive,so this should fail too - response = self.request('/', method='custom') - self.check_status_and_reason(response, HTTPStatus.NOT_IMPLEMENTED) - response = self.request('/', method='GETs') - self.check_status_and_reason(response, HTTPStatus.NOT_IMPLEMENTED) - - def test_last_modified(self): - """Checks that the datetime returned in Last-Modified response header - is the actual datetime of last modification, rounded to the second - """ - response = self.request(self.base_url + '/test') - self.check_status_and_reason(response, HTTPStatus.OK, data=self.data) - last_modif_header = response.headers['Last-modified'] - self.assertEqual(last_modif_header, self.last_modif_header) - - def test_path_without_leading_slash(self): - response = self.request(self.tempdir_name + '/test') - self.check_status_and_reason(response, HTTPStatus.OK, data=self.data) - response = self.request(self.tempdir_name + '/test/') - self.check_status_and_reason(response, HTTPStatus.NOT_FOUND) - response = self.request(self.tempdir_name + '/') - self.check_status_and_reason(response, HTTPStatus.OK) - response = self.request(self.tempdir_name) - self.check_status_and_reason(response, HTTPStatus.MOVED_PERMANENTLY) - response = self.request(self.tempdir_name + '/?hi=2') - self.check_status_and_reason(response, HTTPStatus.OK) - response = self.request(self.tempdir_name + '?hi=1') - self.check_status_and_reason(response, HTTPStatus.MOVED_PERMANENTLY) - self.assertEqual(response.getheader("Location"), - self.tempdir_name + "/?hi=1") - - def test_html_escape_filename(self): - filename = '.txt' - fullpath = os.path.join(self.tempdir, filename) - - try: - open(fullpath, 'w').close() - except OSError: - raise unittest.SkipTest('Can not create file %s on current file ' - 'system' % filename) - - try: - response = self.request(self.base_url + '/') - body = self.check_status_and_reason(response, HTTPStatus.OK) - enc = response.headers.get_content_charset() - finally: - os.unlink(fullpath) # avoid affecting test_undecodable_filename - - self.assertIsNotNone(enc) - html_text = '>%s<' % html.escape(filename, quote=False) - self.assertIn(html_text.encode(enc), body) - - - cgi_file1 = """\ - #!%s - - print("Content-type: text/html") - print() - print("Hello World") - """ - - cgi_file2 = """\ - #!%s - import cgi - - print("Content-type: text/html") - print() - - form = cgi.FieldStorage() - print("%%s, %%s, %%s" %% (form.getfirst("spam"), form.getfirst("eggs"), - form.getfirst("bacon"))) - """ - - cgi_file4 = """\ - #!%s - import os - - print("Content-type: text/html") - print() - - print(os.environ["%s"]) - """ - - - @unittest.skipIf(hasattr(os, 'geteuid') and os.geteuid() == 0, - "This test can't be run reliably as root (issue #13308).") - class CGIHTTPServerTestCase(BaseTestCase): - class request_handler(NoLogRequestHandler, CGIHTTPRequestHandler): - pass - - linesep = os.linesep.encode('ascii') - - def setUp(self): - BaseTestCase.setUp(self) - self.cwd = os.getcwd() - self.parent_dir = tempfile.mkdtemp() - self.cgi_dir = os.path.join(self.parent_dir, 'cgi-bin') - self.cgi_child_dir = os.path.join(self.cgi_dir, 'child-dir') - os.mkdir(self.cgi_dir) - os.mkdir(self.cgi_child_dir) - self.nocgi_path = None - self.file1_path = None - self.file2_path = None - self.file3_path = None - self.file4_path = None - - # The shebang line should be pure ASCII: use symlink if possible. - # See issue #7668. - self._pythonexe_symlink = None - if support.can_symlink(): - self.pythonexe = os.path.join(self.parent_dir, 'python') - self._pythonexe_symlink = support.PythonSymlink(self.pythonexe).__enter__() - else: - self.pythonexe = sys.executable - - try: - # The python executable path is written as the first line of the - # CGI Python script. The encoding cookie cannot be used, and so the - # path should be encodable to the default script encoding (utf-8) - self.pythonexe.encode('utf-8') - except UnicodeEncodeError: - self.tearDown() - self.skipTest("Python executable path is not encodable to utf-8") - - self.nocgi_path = os.path.join(self.parent_dir, 'nocgi.py') - with open(self.nocgi_path, 'w') as fp: - fp.write(cgi_file1 % self.pythonexe) - os.chmod(self.nocgi_path, 0o777) - - self.file1_path = os.path.join(self.cgi_dir, 'file1.py') - with open(self.file1_path, 'w', encoding='utf-8') as file1: - file1.write(cgi_file1 % self.pythonexe) - os.chmod(self.file1_path, 0o777) - - self.file2_path = os.path.join(self.cgi_dir, 'file2.py') - with open(self.file2_path, 'w', encoding='utf-8') as file2: - file2.write(cgi_file2 % self.pythonexe) - os.chmod(self.file2_path, 0o777) - - self.file3_path = os.path.join(self.cgi_child_dir, 'file3.py') - with open(self.file3_path, 'w', encoding='utf-8') as file3: - file3.write(cgi_file1 % self.pythonexe) - os.chmod(self.file3_path, 0o777) - - self.file4_path = os.path.join(self.cgi_dir, 'file4.py') - with open(self.file4_path, 'w', encoding='utf-8') as file4: - file4.write(cgi_file4 % (self.pythonexe, 'QUERY_STRING')) - os.chmod(self.file4_path, 0o777) - - os.chdir(self.parent_dir) - - def tearDown(self): - try: - os.chdir(self.cwd) - if self._pythonexe_symlink: - self._pythonexe_symlink.__exit__(None, None, None) - if self.nocgi_path: - os.remove(self.nocgi_path) - if self.file1_path: - os.remove(self.file1_path) - if self.file2_path: - os.remove(self.file2_path) - if self.file3_path: - os.remove(self.file3_path) - if self.file4_path: - os.remove(self.file4_path) - os.rmdir(self.cgi_child_dir) - os.rmdir(self.cgi_dir) - os.rmdir(self.parent_dir) - finally: - BaseTestCase.tearDown(self) - - def test_url_collapse_path(self): - # verify tail is the last portion and head is the rest on proper urls - test_vectors = { - '': '//', - '..': IndexError, - '/.//..': IndexError, - '/': '//', - '//': '//', - '/\\': '//\\', - '/.//': '//', - 'cgi-bin/file1.py': '/cgi-bin/file1.py', - '/cgi-bin/file1.py': '/cgi-bin/file1.py', - 'a': '//a', - '/a': '//a', - '//a': '//a', - './a': '//a', - './C:/': '/C:/', - '/a/b': '/a/b', - '/a/b/': '/a/b/', - '/a/b/.': '/a/b/', - '/a/b/c/..': '/a/b/', - '/a/b/c/../d': '/a/b/d', - '/a/b/c/../d/e/../f': '/a/b/d/f', - '/a/b/c/../d/e/../../f': '/a/b/f', - '/a/b/c/../d/e/.././././..//f': '/a/b/f', - '../a/b/c/../d/e/.././././..//f': IndexError, - '/a/b/c/../d/e/../../../f': '/a/f', - '/a/b/c/../d/e/../../../../f': '//f', - '/a/b/c/../d/e/../../../../../f': IndexError, - '/a/b/c/../d/e/../../../../f/..': '//', - '/a/b/c/../d/e/../../../../f/../.': '//', - } - for path, expected in test_vectors.items(): - if isinstance(expected, type) and issubclass(expected, Exception): - self.assertRaises(expected, - server._url_collapse_path, path) - else: - actual = server._url_collapse_path(path) - self.assertEqual(expected, actual, - msg='path = %r\nGot: %r\nWanted: %r' % - (path, actual, expected)) - - def test_headers_and_content(self): - res = self.request('/cgi-bin/file1.py') - self.assertEqual( - (res.read(), res.getheader('Content-type'), res.status), - (b'Hello World' + self.linesep, 'text/html', HTTPStatus.OK)) - - def test_issue19435(self): - res = self.request('///////////nocgi.py/../cgi-bin/nothere.sh') - self.assertEqual(res.status, HTTPStatus.NOT_FOUND) - - def test_post(self): - params = urllib.parse.urlencode( - {'spam' : 1, 'eggs' : 'python', 'bacon' : 123456}) - headers = {'Content-type' : 'application/x-www-form-urlencoded'} - res = self.request('/cgi-bin/file2.py', 'POST', params, headers) - - self.assertEqual(res.read(), b'1, python, 123456' + self.linesep) - - def test_invaliduri(self): - res = self.request('/cgi-bin/invalid') - res.read() - self.assertEqual(res.status, HTTPStatus.NOT_FOUND) - - def test_authorization(self): - headers = {b'Authorization' : b'Basic ' + - base64.b64encode(b'username:pass')} - res = self.request('/cgi-bin/file1.py', 'GET', headers=headers) - self.assertEqual( - (b'Hello World' + self.linesep, 'text/html', HTTPStatus.OK), - (res.read(), res.getheader('Content-type'), res.status)) - - def test_no_leading_slash(self): - # http://bugs.python.org/issue2254 - res = self.request('cgi-bin/file1.py') - self.assertEqual( - (b'Hello World' + self.linesep, 'text/html', HTTPStatus.OK), - (res.read(), res.getheader('Content-type'), res.status)) - - def test_os_environ_is_not_altered(self): - signature = "Test CGI Server" - os.environ['SERVER_SOFTWARE'] = signature - res = self.request('/cgi-bin/file1.py') - self.assertEqual( - (b'Hello World' + self.linesep, 'text/html', HTTPStatus.OK), - (res.read(), res.getheader('Content-type'), res.status)) - self.assertEqual(os.environ['SERVER_SOFTWARE'], signature) - - def test_urlquote_decoding_in_cgi_check(self): - res = self.request('/cgi-bin%2ffile1.py') - self.assertEqual( - (b'Hello World' + self.linesep, 'text/html', HTTPStatus.OK), - (res.read(), res.getheader('Content-type'), res.status)) - - def test_nested_cgi_path_issue21323(self): - res = self.request('/cgi-bin/child-dir/file3.py') - self.assertEqual( - (b'Hello World' + self.linesep, 'text/html', HTTPStatus.OK), - (res.read(), res.getheader('Content-type'), res.status)) - - def test_query_with_multiple_question_mark(self): - res = self.request('/cgi-bin/file4.py?a=b?c=d') - self.assertEqual( - (b'a=b?c=d' + self.linesep, 'text/html', HTTPStatus.OK), - (res.read(), res.getheader('Content-type'), res.status)) - - def test_query_with_continuous_slashes(self): - res = self.request('/cgi-bin/file4.py?k=aa%2F%2Fbb&//q//p//=//a//b//') - self.assertEqual( - (b'k=aa%2F%2Fbb&//q//p//=//a//b//' + self.linesep, - 'text/html', HTTPStatus.OK), - (res.read(), res.getheader('Content-type'), res.status)) - - - class SocketlessRequestHandler(SimpleHTTPRequestHandler): - def __init__(self, *args, **kwargs): - request = mock.Mock() - request.makefile.return_value = BytesIO() - super().__init__(request, None, None) - - self.get_called = False - self.protocol_version = "HTTP/1.1" - - def do_GET(self): - self.get_called = True - self.send_response(HTTPStatus.OK) - self.send_header('Content-Type', 'text/html') - self.end_headers() - self.wfile.write(b'Data\r\n') - - def log_message(self, format, *args): - pass - - class RejectingSocketlessRequestHandler(SocketlessRequestHandler): - def handle_expect_100(self): - self.send_error(HTTPStatus.EXPECTATION_FAILED) - return False - - - class AuditableBytesIO: - - def __init__(self): - self.datas = [] - - def write(self, data): - self.datas.append(data) - - def getData(self): - return b''.join(self.datas) - - @property - def numWrites(self): - return len(self.datas) - - - class BaseHTTPRequestHandlerTestCase(unittest.TestCase): - """Test the functionality of the BaseHTTPServer. - - Test the support for the Expect 100-continue header. - """ - - HTTPResponseMatch = re.compile(b'HTTP/1.[0-9]+ 200 OK') - - def setUp (self): - self.handler = SocketlessRequestHandler() - - def send_typical_request(self, message): - input = BytesIO(message) - output = BytesIO() - self.handler.rfile = input - self.handler.wfile = output - self.handler.handle_one_request() - output.seek(0) - return output.readlines() - - def verify_get_called(self): - self.assertTrue(self.handler.get_called) - - def verify_expected_headers(self, headers): - for fieldName in b'Server: ', b'Date: ', b'Content-Type: ': - self.assertEqual(sum(h.startswith(fieldName) for h in headers), 1) - - def verify_http_server_response(self, response): - match = self.HTTPResponseMatch.search(response) - self.assertIsNotNone(match) - - def test_http_1_1(self): - result = self.send_typical_request(b'GET / HTTP/1.1\r\n\r\n') - self.verify_http_server_response(result[0]) - self.verify_expected_headers(result[1:-1]) - self.verify_get_called() - self.assertEqual(result[-1], b'Data\r\n') - self.assertEqual(self.handler.requestline, 'GET / HTTP/1.1') - self.assertEqual(self.handler.command, 'GET') - self.assertEqual(self.handler.path, '/') - self.assertEqual(self.handler.request_version, 'HTTP/1.1') - self.assertSequenceEqual(self.handler.headers.items(), ()) - - def test_http_1_0(self): - result = self.send_typical_request(b'GET / HTTP/1.0\r\n\r\n') - self.verify_http_server_response(result[0]) - self.verify_expected_headers(result[1:-1]) - self.verify_get_called() - self.assertEqual(result[-1], b'Data\r\n') - self.assertEqual(self.handler.requestline, 'GET / HTTP/1.0') - self.assertEqual(self.handler.command, 'GET') - self.assertEqual(self.handler.path, '/') - self.assertEqual(self.handler.request_version, 'HTTP/1.0') - self.assertSequenceEqual(self.handler.headers.items(), ()) - - def test_http_0_9(self): - result = self.send_typical_request(b'GET / HTTP/0.9\r\n\r\n') - self.assertEqual(len(result), 1) - self.assertEqual(result[0], b'Data\r\n') - self.verify_get_called() - - def test_extra_space(self): - result = self.send_typical_request( - b'GET /spaced out HTTP/1.1\r\n' - b'Host: dummy\r\n' - b'\r\n' - ) - self.assertTrue(result[0].startswith(b'HTTP/1.1 400 ')) - self.verify_expected_headers(result[1:result.index(b'\r\n')]) - self.assertFalse(self.handler.get_called) - - def test_with_continue_1_0(self): - result = self.send_typical_request(b'GET / HTTP/1.0\r\nExpect: 100-continue\r\n\r\n') - self.verify_http_server_response(result[0]) - self.verify_expected_headers(result[1:-1]) - self.verify_get_called() - self.assertEqual(result[-1], b'Data\r\n') - self.assertEqual(self.handler.requestline, 'GET / HTTP/1.0') - self.assertEqual(self.handler.command, 'GET') - self.assertEqual(self.handler.path, '/') - self.assertEqual(self.handler.request_version, 'HTTP/1.0') - headers = (("Expect", "100-continue"),) - self.assertSequenceEqual(self.handler.headers.items(), headers) - - def test_with_continue_1_1(self): - result = self.send_typical_request(b'GET / HTTP/1.1\r\nExpect: 100-continue\r\n\r\n') - self.assertEqual(result[0], b'HTTP/1.1 100 Continue\r\n') - self.assertEqual(result[1], b'\r\n') - self.assertEqual(result[2], b'HTTP/1.1 200 OK\r\n') - self.verify_expected_headers(result[2:-1]) - self.verify_get_called() - self.assertEqual(result[-1], b'Data\r\n') - self.assertEqual(self.handler.requestline, 'GET / HTTP/1.1') - self.assertEqual(self.handler.command, 'GET') - self.assertEqual(self.handler.path, '/') - self.assertEqual(self.handler.request_version, 'HTTP/1.1') - headers = (("Expect", "100-continue"),) - self.assertSequenceEqual(self.handler.headers.items(), headers) - - def test_header_buffering_of_send_error(self): - - input = BytesIO(b'GET / HTTP/1.1\r\n\r\n') - output = AuditableBytesIO() - handler = SocketlessRequestHandler() - handler.rfile = input - handler.wfile = output - handler.request_version = 'HTTP/1.1' - handler.requestline = '' - handler.command = None - - handler.send_error(418) - self.assertEqual(output.numWrites, 2) - - def test_header_buffering_of_send_response_only(self): - - input = BytesIO(b'GET / HTTP/1.1\r\n\r\n') - output = AuditableBytesIO() - handler = SocketlessRequestHandler() - handler.rfile = input - handler.wfile = output - handler.request_version = 'HTTP/1.1' - - handler.send_response_only(418) - self.assertEqual(output.numWrites, 0) - handler.end_headers() - self.assertEqual(output.numWrites, 1) - - def test_header_buffering_of_send_header(self): - - input = BytesIO(b'GET / HTTP/1.1\r\n\r\n') - output = AuditableBytesIO() - handler = SocketlessRequestHandler() - handler.rfile = input - handler.wfile = output - handler.request_version = 'HTTP/1.1' - - handler.send_header('Foo', 'foo') - handler.send_header('bar', 'bar') - self.assertEqual(output.numWrites, 0) - handler.end_headers() - self.assertEqual(output.getData(), b'Foo: foo\r\nbar: bar\r\n\r\n') - self.assertEqual(output.numWrites, 1) - - def test_header_unbuffered_when_continue(self): - - def _readAndReseek(f): - pos = f.tell() - f.seek(0) - data = f.read() - f.seek(pos) - return data - - input = BytesIO(b'GET / HTTP/1.1\r\nExpect: 100-continue\r\n\r\n') - output = BytesIO() - self.handler.rfile = input - self.handler.wfile = output - self.handler.request_version = 'HTTP/1.1' - - self.handler.handle_one_request() - self.assertNotEqual(_readAndReseek(output), b'') - result = _readAndReseek(output).split(b'\r\n') - self.assertEqual(result[0], b'HTTP/1.1 100 Continue') - self.assertEqual(result[1], b'') - self.assertEqual(result[2], b'HTTP/1.1 200 OK') - - def test_with_continue_rejected(self): - usual_handler = self.handler # Save to avoid breaking any subsequent tests. - self.handler = RejectingSocketlessRequestHandler() - result = self.send_typical_request(b'GET / HTTP/1.1\r\nExpect: 100-continue\r\n\r\n') - self.assertEqual(result[0], b'HTTP/1.1 417 Expectation Failed\r\n') - self.verify_expected_headers(result[1:-1]) - # The expect handler should short circuit the usual get method by - # returning false here, so get_called should be false - self.assertFalse(self.handler.get_called) - self.assertEqual(sum(r == b'Connection: close\r\n' for r in result[1:-1]), 1) - self.handler = usual_handler # Restore to avoid breaking any subsequent tests. - - def test_request_length(self): - # Issue #10714: huge request lines are discarded, to avoid Denial - # of Service attacks. - result = self.send_typical_request(b'GET ' + b'x' * 65537) - self.assertEqual(result[0], b'HTTP/1.1 414 Request-URI Too Long\r\n') - self.assertFalse(self.handler.get_called) - self.assertIsInstance(self.handler.requestline, str) - - def test_header_length(self): - # Issue #6791: same for headers - result = self.send_typical_request( - b'GET / HTTP/1.1\r\nX-Foo: bar' + b'r' * 65537 + b'\r\n\r\n') - self.assertEqual(result[0], b'HTTP/1.1 431 Line too long\r\n') - self.assertFalse(self.handler.get_called) - self.assertEqual(self.handler.requestline, 'GET / HTTP/1.1') - - def test_too_many_headers(self): - result = self.send_typical_request( - b'GET / HTTP/1.1\r\n' + b'X-Foo: bar\r\n' * 101 + b'\r\n') - self.assertEqual(result[0], b'HTTP/1.1 431 Too many headers\r\n') - self.assertFalse(self.handler.get_called) - self.assertEqual(self.handler.requestline, 'GET / HTTP/1.1') - - def test_html_escape_on_error(self): - result = self.send_typical_request( - b' / HTTP/1.1') - result = b''.join(result) - text = '' - self.assertIn(html.escape(text, quote=False).encode('ascii'), result) - - def test_close_connection(self): - # handle_one_request() should be repeatedly called until - # it sets close_connection - def handle_one_request(): - self.handler.close_connection = next(close_values) - self.handler.handle_one_request = handle_one_request - - close_values = iter((True,)) - self.handler.handle() - self.assertRaises(StopIteration, next, close_values) - - close_values = iter((False, False, True)) - self.handler.handle() - self.assertRaises(StopIteration, next, close_values) - - def test_date_time_string(self): - now = time.time() - # this is the old code that formats the timestamp - year, month, day, hh, mm, ss, wd, y, z = time.gmtime(now) - expected = "%s, %02d %3s %4d %02d:%02d:%02d GMT" % ( - self.handler.weekdayname[wd], - day, - self.handler.monthname[month], - year, hh, mm, ss - ) - self.assertEqual(self.handler.date_time_string(timestamp=now), expected) - - - class SimpleHTTPRequestHandlerTestCase(unittest.TestCase): - """ Test url parsing """ - def setUp(self): - self.translated = os.getcwd() - self.translated = os.path.join(self.translated, 'filename') - self.handler = SocketlessRequestHandler() - - def test_query_arguments(self): - path = self.handler.translate_path('/filename') - self.assertEqual(path, self.translated) - path = self.handler.translate_path('/filename?foo=bar') - self.assertEqual(path, self.translated) - path = self.handler.translate_path('/filename?a=b&spam=eggs#zot') - self.assertEqual(path, self.translated) - - def test_start_with_double_slash(self): - path = self.handler.translate_path('//filename') - self.assertEqual(path, self.translated) - path = self.handler.translate_path('//filename?foo=bar') - self.assertEqual(path, self.translated) - - def test_windows_colon(self): - with support.swap_attr(server.os, 'path', ntpath): - path = self.handler.translate_path('c:c:c:foo/filename') - path = path.replace(ntpath.sep, os.sep) - self.assertEqual(path, self.translated) - - path = self.handler.translate_path('\\c:../filename') - path = path.replace(ntpath.sep, os.sep) - self.assertEqual(path, self.translated) - - path = self.handler.translate_path('c:\\c:..\\foo/filename') - path = path.replace(ntpath.sep, os.sep) - self.assertEqual(path, self.translated) - - path = self.handler.translate_path('c:c:foo\\c:c:bar/filename') - path = path.replace(ntpath.sep, os.sep) - self.assertEqual(path, self.translated) - - - class MiscTestCase(unittest.TestCase): - def test_all(self): - expected = [] - blacklist = {'executable', 'nobody_uid', 'test'} - for name in dir(server): - if name.startswith('_') or name in blacklist: - continue - module_object = getattr(server, name) - if getattr(module_object, '__module__', None) == 'http.server': - expected.append(name) - self.assertCountEqual(server.__all__, expected) - - - class ScriptTestCase(unittest.TestCase): - - def mock_server_class(self): - return mock.MagicMock( - return_value=mock.MagicMock( - __enter__=mock.MagicMock( - return_value=mock.MagicMock( - socket=mock.MagicMock( - getsockname=lambda: ('', 0), - ), - ), - ), - ), - ) - - @mock.patch('builtins.print') - def test_server_test_unspec(self, _): - mock_server = self.mock_server_class() - server.test(ServerClass=mock_server, bind=None) - self.assertIn( - mock_server.address_family, - (socket.AF_INET6, socket.AF_INET), - ) - - @mock.patch('builtins.print') - def test_server_test_localhost(self, _): - mock_server = self.mock_server_class() - server.test(ServerClass=mock_server, bind="localhost") - self.assertIn( - mock_server.address_family, - (socket.AF_INET6, socket.AF_INET), - ) - - ipv6_addrs = ( - "::", - "2001:0db8:85a3:0000:0000:8a2e:0370:7334", - "::1", - ) - - ipv4_addrs = ( - "0.0.0.0", - "8.8.8.8", - "127.0.0.1", - ) - - @mock.patch('builtins.print') - def test_server_test_ipv6(self, _): - for bind in self.ipv6_addrs: - mock_server = self.mock_server_class() - server.test(ServerClass=mock_server, bind=bind) - self.assertEqual(mock_server.address_family, socket.AF_INET6) - - @mock.patch('builtins.print') - def test_server_test_ipv4(self, _): - for bind in self.ipv4_addrs: - mock_server = self.mock_server_class() - server.test(ServerClass=mock_server, bind=bind) - self.assertEqual(mock_server.address_family, socket.AF_INET) - - - def test_main(verbose=None): - cwd = os.getcwd() - try: - support.run_unittest( - RequestHandlerLoggingTestCase, - BaseHTTPRequestHandlerTestCase, - BaseHTTPServerTestCase, - SimpleHTTPServerTestCase, - CGIHTTPServerTestCase, - SimpleHTTPRequestHandlerTestCase, - MiscTestCase, - ScriptTestCase - ) - finally: - os.chdir(cwd) - - if __name__ == '__main__': - test_main() diff --git a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_imaplib.yaml b/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_imaplib.yaml deleted file mode 100644 index 587631127..000000000 --- a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_imaplib.yaml +++ /dev/null @@ -1,1021 +0,0 @@ -python: | - from test import support - - from contextlib import contextmanager - import imaplib - import os.path - import socketserver - import time - import calendar - import threading - import socket - - from test.support import (reap_threads, verbose, transient_internet, - run_with_tz, run_with_locale, cpython_only, - requires_hashdigest) - import unittest - from unittest import mock - from datetime import datetime, timezone, timedelta - try: - import ssl - except ImportError: - ssl = None - - CERTFILE = os.path.join(os.path.dirname(__file__) or os.curdir, "keycert3.pem") - CAFILE = os.path.join(os.path.dirname(__file__) or os.curdir, "pycacert.pem") - - - class TestImaplib(unittest.TestCase): - - def test_Internaldate2tuple(self): - t0 = calendar.timegm((2000, 1, 1, 0, 0, 0, -1, -1, -1)) - tt = imaplib.Internaldate2tuple( - b'25 (INTERNALDATE "01-Jan-2000 00:00:00 +0000")') - self.assertEqual(time.mktime(tt), t0) - tt = imaplib.Internaldate2tuple( - b'25 (INTERNALDATE "01-Jan-2000 11:30:00 +1130")') - self.assertEqual(time.mktime(tt), t0) - tt = imaplib.Internaldate2tuple( - b'25 (INTERNALDATE "31-Dec-1999 12:30:00 -1130")') - self.assertEqual(time.mktime(tt), t0) - - @run_with_tz('MST+07MDT,M4.1.0,M10.5.0') - def test_Internaldate2tuple_issue10941(self): - self.assertNotEqual(imaplib.Internaldate2tuple( - b'25 (INTERNALDATE "02-Apr-2000 02:30:00 +0000")'), - imaplib.Internaldate2tuple( - b'25 (INTERNALDATE "02-Apr-2000 03:30:00 +0000")')) - - def timevalues(self): - return [2000000000, 2000000000.0, time.localtime(2000000000), - (2033, 5, 18, 5, 33, 20, -1, -1, -1), - (2033, 5, 18, 5, 33, 20, -1, -1, 1), - datetime.fromtimestamp(2000000000, - timezone(timedelta(0, 2 * 60 * 60))), - '"18-May-2033 05:33:20 +0200"'] - - @run_with_locale('LC_ALL', 'de_DE', 'fr_FR') - # DST rules included to work around quirk where the Gnu C library may not - # otherwise restore the previous time zone - @run_with_tz('STD-1DST,M3.2.0,M11.1.0') - def test_Time2Internaldate(self): - expected = '"18-May-2033 05:33:20 +0200"' - - for t in self.timevalues(): - internal = imaplib.Time2Internaldate(t) - self.assertEqual(internal, expected) - - def test_that_Time2Internaldate_returns_a_result(self): - # Without tzset, we can check only that it successfully - # produces a result, not the correctness of the result itself, - # since the result depends on the timezone the machine is in. - for t in self.timevalues(): - imaplib.Time2Internaldate(t) - - def test_imap4_host_default_value(self): - # Check whether the IMAP4_PORT is truly unavailable. - with socket.socket() as s: - try: - s.connect(('', imaplib.IMAP4_PORT)) - self.skipTest( - "Cannot run the test with local IMAP server running.") - except socket.error: - pass - - # This is the exception that should be raised. - expected_errnos = support.get_socket_conn_refused_errs() - with self.assertRaises(OSError) as cm: - imaplib.IMAP4() - self.assertIn(cm.exception.errno, expected_errnos) - - - if ssl: - class SecureTCPServer(socketserver.TCPServer): - - def get_request(self): - newsocket, fromaddr = self.socket.accept() - context = ssl.SSLContext() - context.load_cert_chain(CERTFILE) - connstream = context.wrap_socket(newsocket, server_side=True) - return connstream, fromaddr - - IMAP4_SSL = imaplib.IMAP4_SSL - - else: - - class SecureTCPServer: - pass - - IMAP4_SSL = None - - - class SimpleIMAPHandler(socketserver.StreamRequestHandler): - timeout = 1 - continuation = None - capabilities = '' - - def setup(self): - super().setup() - self.server.logged = None - - def _send(self, message): - if verbose: - print("SENT: %r" % message.strip()) - self.wfile.write(message) - - def _send_line(self, message): - self._send(message + b'\r\n') - - def _send_textline(self, message): - self._send_line(message.encode('ASCII')) - - def _send_tagged(self, tag, code, message): - self._send_textline(' '.join((tag, code, message))) - - def handle(self): - # Send a welcome message. - self._send_textline('* OK IMAP4rev1') - while 1: - # Gather up input until we receive a line terminator or we timeout. - # Accumulate read(1) because it's simpler to handle the differences - # between naked sockets and SSL sockets. - line = b'' - while 1: - try: - part = self.rfile.read(1) - if part == b'': - # Naked sockets return empty strings.. - return - line += part - except OSError: - # ..but SSLSockets raise exceptions. - return - if line.endswith(b'\r\n'): - break - - if verbose: - print('GOT: %r' % line.strip()) - if self.continuation: - try: - self.continuation.send(line) - except StopIteration: - self.continuation = None - continue - splitline = line.decode('ASCII').split() - tag = splitline[0] - cmd = splitline[1] - args = splitline[2:] - - if hasattr(self, 'cmd_' + cmd): - continuation = getattr(self, 'cmd_' + cmd)(tag, args) - if continuation: - self.continuation = continuation - next(continuation) - else: - self._send_tagged(tag, 'BAD', cmd + ' unknown') - - def cmd_CAPABILITY(self, tag, args): - caps = ('IMAP4rev1 ' + self.capabilities - if self.capabilities - else 'IMAP4rev1') - self._send_textline('* CAPABILITY ' + caps) - self._send_tagged(tag, 'OK', 'CAPABILITY completed') - - def cmd_LOGOUT(self, tag, args): - self.server.logged = None - self._send_textline('* BYE IMAP4ref1 Server logging out') - self._send_tagged(tag, 'OK', 'LOGOUT completed') - - def cmd_LOGIN(self, tag, args): - self.server.logged = args[0] - self._send_tagged(tag, 'OK', 'LOGIN completed') - - - class NewIMAPTestsMixin(): - client = None - - def _setup(self, imap_handler, connect=True): - """ - Sets up imap_handler for tests. imap_handler should inherit from either: - - SimpleIMAPHandler - for testing IMAP commands, - - socketserver.StreamRequestHandler - if raw access to stream is needed. - Returns (client, server). - """ - class TestTCPServer(self.server_class): - def handle_error(self, request, client_address): - """ - End request and raise the error if one occurs. - """ - self.close_request(request) - self.server_close() - raise - - self.addCleanup(self._cleanup) - self.server = self.server_class((support.HOST, 0), imap_handler) - self.thread = threading.Thread( - name=self._testMethodName+'-server', - target=self.server.serve_forever, - # Short poll interval to make the test finish quickly. - # Time between requests is short enough that we won't wake - # up spuriously too many times. - kwargs={'poll_interval': 0.01}) - self.thread.daemon = True # In case this function raises. - self.thread.start() - - if connect: - self.client = self.imap_class(*self.server.server_address) - - return self.client, self.server - - def _cleanup(self): - """ - Cleans up the test server. This method should not be called manually, - it is added to the cleanup queue in the _setup method already. - """ - # if logout was called already we'd raise an exception trying to - # shutdown the client once again - if self.client is not None and self.client.state != 'LOGOUT': - self.client.shutdown() - # cleanup the server - self.server.shutdown() - self.server.server_close() - support.join_thread(self.thread, 3.0) - # Explicitly clear the attribute to prevent dangling thread - self.thread = None - - def test_EOF_without_complete_welcome_message(self): - # http://bugs.python.org/issue5949 - class EOFHandler(socketserver.StreamRequestHandler): - def handle(self): - self.wfile.write(b'* OK') - _, server = self._setup(EOFHandler, connect=False) - self.assertRaises(imaplib.IMAP4.abort, self.imap_class, - *server.server_address) - - def test_line_termination(self): - class BadNewlineHandler(SimpleIMAPHandler): - def cmd_CAPABILITY(self, tag, args): - self._send(b'* CAPABILITY IMAP4rev1 AUTH\n') - self._send_tagged(tag, 'OK', 'CAPABILITY completed') - _, server = self._setup(BadNewlineHandler, connect=False) - self.assertRaises(imaplib.IMAP4.abort, self.imap_class, - *server.server_address) - - def test_enable_raises_error_if_not_AUTH(self): - class EnableHandler(SimpleIMAPHandler): - capabilities = 'AUTH ENABLE UTF8=ACCEPT' - client, _ = self._setup(EnableHandler) - self.assertFalse(client.utf8_enabled) - with self.assertRaisesRegex(imaplib.IMAP4.error, 'ENABLE.*NONAUTH'): - client.enable('foo') - self.assertFalse(client.utf8_enabled) - - def test_enable_raises_error_if_no_capability(self): - client, _ = self._setup(SimpleIMAPHandler) - with self.assertRaisesRegex(imaplib.IMAP4.error, - 'does not support ENABLE'): - client.enable('foo') - - def test_enable_UTF8_raises_error_if_not_supported(self): - client, _ = self._setup(SimpleIMAPHandler) - typ, data = client.login('user', 'pass') - self.assertEqual(typ, 'OK') - with self.assertRaisesRegex(imaplib.IMAP4.error, - 'does not support ENABLE'): - client.enable('UTF8=ACCEPT') - - def test_enable_UTF8_True_append(self): - class UTF8AppendServer(SimpleIMAPHandler): - capabilities = 'ENABLE UTF8=ACCEPT' - def cmd_ENABLE(self, tag, args): - self._send_tagged(tag, 'OK', 'ENABLE successful') - def cmd_AUTHENTICATE(self, tag, args): - self._send_textline('+') - self.server.response = yield - self._send_tagged(tag, 'OK', 'FAKEAUTH successful') - def cmd_APPEND(self, tag, args): - self._send_textline('+') - self.server.response = yield - self._send_tagged(tag, 'OK', 'okay') - client, server = self._setup(UTF8AppendServer) - self.assertEqual(client._encoding, 'ascii') - code, _ = client.authenticate('MYAUTH', lambda x: b'fake') - self.assertEqual(code, 'OK') - self.assertEqual(server.response, b'ZmFrZQ==\r\n') # b64 encoded 'fake' - code, _ = client.enable('UTF8=ACCEPT') - self.assertEqual(code, 'OK') - self.assertEqual(client._encoding, 'utf-8') - msg_string = 'Subject: üñí©öðé' - typ, data = client.append(None, None, None, msg_string.encode('utf-8')) - self.assertEqual(typ, 'OK') - self.assertEqual(server.response, - ('UTF8 (%s)\r\n' % msg_string).encode('utf-8')) - - def test_search_disallows_charset_in_utf8_mode(self): - class UTF8Server(SimpleIMAPHandler): - capabilities = 'AUTH ENABLE UTF8=ACCEPT' - def cmd_ENABLE(self, tag, args): - self._send_tagged(tag, 'OK', 'ENABLE successful') - def cmd_AUTHENTICATE(self, tag, args): - self._send_textline('+') - self.server.response = yield - self._send_tagged(tag, 'OK', 'FAKEAUTH successful') - client, _ = self._setup(UTF8Server) - typ, _ = client.authenticate('MYAUTH', lambda x: b'fake') - self.assertEqual(typ, 'OK') - typ, _ = client.enable('UTF8=ACCEPT') - self.assertEqual(typ, 'OK') - self.assertTrue(client.utf8_enabled) - with self.assertRaisesRegex(imaplib.IMAP4.error, 'charset.*UTF8'): - client.search('foo', 'bar') - - def test_bad_auth_name(self): - class MyServer(SimpleIMAPHandler): - def cmd_AUTHENTICATE(self, tag, args): - self._send_tagged(tag, 'NO', - 'unrecognized authentication type {}'.format(args[0])) - client, _ = self._setup(MyServer) - with self.assertRaisesRegex(imaplib.IMAP4.error, - 'unrecognized authentication type METHOD'): - client.authenticate('METHOD', lambda: 1) - - def test_invalid_authentication(self): - class MyServer(SimpleIMAPHandler): - def cmd_AUTHENTICATE(self, tag, args): - self._send_textline('+') - self.response = yield - self._send_tagged(tag, 'NO', '[AUTHENTICATIONFAILED] invalid') - client, _ = self._setup(MyServer) - with self.assertRaisesRegex(imaplib.IMAP4.error, - r'\[AUTHENTICATIONFAILED\] invalid'): - client.authenticate('MYAUTH', lambda x: b'fake') - - def test_valid_authentication_bytes(self): - class MyServer(SimpleIMAPHandler): - def cmd_AUTHENTICATE(self, tag, args): - self._send_textline('+') - self.server.response = yield - self._send_tagged(tag, 'OK', 'FAKEAUTH successful') - client, server = self._setup(MyServer) - code, _ = client.authenticate('MYAUTH', lambda x: b'fake') - self.assertEqual(code, 'OK') - self.assertEqual(server.response, b'ZmFrZQ==\r\n') # b64 encoded 'fake' - - def test_valid_authentication_plain_text(self): - class MyServer(SimpleIMAPHandler): - def cmd_AUTHENTICATE(self, tag, args): - self._send_textline('+') - self.server.response = yield - self._send_tagged(tag, 'OK', 'FAKEAUTH successful') - client, server = self._setup(MyServer) - code, _ = client.authenticate('MYAUTH', lambda x: 'fake') - self.assertEqual(code, 'OK') - self.assertEqual(server.response, b'ZmFrZQ==\r\n') # b64 encoded 'fake' - - @requires_hashdigest('md5') - def test_login_cram_md5_bytes(self): - class AuthHandler(SimpleIMAPHandler): - capabilities = 'LOGINDISABLED AUTH=CRAM-MD5' - def cmd_AUTHENTICATE(self, tag, args): - self._send_textline('+ PDE4OTYuNjk3MTcwOTUyQHBvc3RvZmZpY2Uucm' - 'VzdG9uLm1jaS5uZXQ=') - r = yield - if (r == b'dGltIGYxY2E2YmU0NjRiOWVmYT' - b'FjY2E2ZmZkNmNmMmQ5ZjMy\r\n'): - self._send_tagged(tag, 'OK', 'CRAM-MD5 successful') - else: - self._send_tagged(tag, 'NO', 'No access') - client, _ = self._setup(AuthHandler) - self.assertTrue('AUTH=CRAM-MD5' in client.capabilities) - ret, _ = client.login_cram_md5("tim", b"tanstaaftanstaaf") - self.assertEqual(ret, "OK") - - @requires_hashdigest('md5') - def test_login_cram_md5_plain_text(self): - class AuthHandler(SimpleIMAPHandler): - capabilities = 'LOGINDISABLED AUTH=CRAM-MD5' - def cmd_AUTHENTICATE(self, tag, args): - self._send_textline('+ PDE4OTYuNjk3MTcwOTUyQHBvc3RvZmZpY2Uucm' - 'VzdG9uLm1jaS5uZXQ=') - r = yield - if (r == b'dGltIGYxY2E2YmU0NjRiOWVmYT' - b'FjY2E2ZmZkNmNmMmQ5ZjMy\r\n'): - self._send_tagged(tag, 'OK', 'CRAM-MD5 successful') - else: - self._send_tagged(tag, 'NO', 'No access') - client, _ = self._setup(AuthHandler) - self.assertTrue('AUTH=CRAM-MD5' in client.capabilities) - ret, _ = client.login_cram_md5("tim", "tanstaaftanstaaf") - self.assertEqual(ret, "OK") - - def test_aborted_authentication(self): - class MyServer(SimpleIMAPHandler): - def cmd_AUTHENTICATE(self, tag, args): - self._send_textline('+') - self.response = yield - if self.response == b'*\r\n': - self._send_tagged( - tag, - 'NO', - '[AUTHENTICATIONFAILED] aborted') - else: - self._send_tagged(tag, 'OK', 'MYAUTH successful') - client, _ = self._setup(MyServer) - with self.assertRaisesRegex(imaplib.IMAP4.error, - r'\[AUTHENTICATIONFAILED\] aborted'): - client.authenticate('MYAUTH', lambda x: None) - - @mock.patch('imaplib._MAXLINE', 10) - def test_linetoolong(self): - class TooLongHandler(SimpleIMAPHandler): - def handle(self): - # send response line longer than the limit set in the next line - self.wfile.write(b'* OK ' + 11 * b'x' + b'\r\n') - _, server = self._setup(TooLongHandler, connect=False) - with self.assertRaisesRegex(imaplib.IMAP4.error, - 'got more than 10 bytes'): - self.imap_class(*server.server_address) - - def test_simple_with_statement(self): - _, server = self._setup(SimpleIMAPHandler, connect=False) - with self.imap_class(*server.server_address): - pass - - def test_with_statement(self): - _, server = self._setup(SimpleIMAPHandler, connect=False) - with self.imap_class(*server.server_address) as imap: - imap.login('user', 'pass') - self.assertEqual(server.logged, 'user') - self.assertIsNone(server.logged) - - def test_with_statement_logout(self): - # It is legal to log out explicitly inside the with block - _, server = self._setup(SimpleIMAPHandler, connect=False) - with self.imap_class(*server.server_address) as imap: - imap.login('user', 'pass') - self.assertEqual(server.logged, 'user') - imap.logout() - self.assertIsNone(server.logged) - self.assertIsNone(server.logged) - - # command tests - - def test_login(self): - client, _ = self._setup(SimpleIMAPHandler) - typ, data = client.login('user', 'pass') - self.assertEqual(typ, 'OK') - self.assertEqual(data[0], b'LOGIN completed') - self.assertEqual(client.state, 'AUTH') - - def test_logout(self): - client, _ = self._setup(SimpleIMAPHandler) - typ, data = client.login('user', 'pass') - self.assertEqual(typ, 'OK') - self.assertEqual(data[0], b'LOGIN completed') - typ, data = client.logout() - self.assertEqual(typ, 'BYE', (typ, data)) - self.assertEqual(data[0], b'IMAP4ref1 Server logging out', (typ, data)) - self.assertEqual(client.state, 'LOGOUT') - - def test_lsub(self): - class LsubCmd(SimpleIMAPHandler): - def cmd_LSUB(self, tag, args): - self._send_textline('* LSUB () "." directoryA') - return self._send_tagged(tag, 'OK', 'LSUB completed') - client, _ = self._setup(LsubCmd) - client.login('user', 'pass') - typ, data = client.lsub() - self.assertEqual(typ, 'OK') - self.assertEqual(data[0], b'() "." directoryA') - - - class NewIMAPTests(NewIMAPTestsMixin, unittest.TestCase): - imap_class = imaplib.IMAP4 - server_class = socketserver.TCPServer - - - @unittest.skipUnless(ssl, "SSL not available") - class NewIMAPSSLTests(NewIMAPTestsMixin, unittest.TestCase): - imap_class = IMAP4_SSL - server_class = SecureTCPServer - - def test_ssl_raises(self): - ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT) - self.assertEqual(ssl_context.verify_mode, ssl.CERT_REQUIRED) - self.assertEqual(ssl_context.check_hostname, True) - ssl_context.load_verify_locations(CAFILE) - - with self.assertRaisesRegex(ssl.CertificateError, - "IP address mismatch, certificate is not valid for " - "'127.0.0.1'"): - _, server = self._setup(SimpleIMAPHandler) - client = self.imap_class(*server.server_address, - ssl_context=ssl_context) - client.shutdown() - - def test_ssl_verified(self): - ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT) - ssl_context.load_verify_locations(CAFILE) - - _, server = self._setup(SimpleIMAPHandler) - client = self.imap_class("localhost", server.server_address[1], - ssl_context=ssl_context) - client.shutdown() - - # Mock the private method _connect(), so mark the test as specific - # to CPython stdlib - @cpython_only - def test_certfile_arg_warn(self): - with support.check_warnings(('', DeprecationWarning)): - with mock.patch.object(self.imap_class, 'open'): - with mock.patch.object(self.imap_class, '_connect'): - self.imap_class('localhost', 143, certfile=CERTFILE) - - class ThreadedNetworkedTests(unittest.TestCase): - server_class = socketserver.TCPServer - imap_class = imaplib.IMAP4 - - def make_server(self, addr, hdlr): - - class MyServer(self.server_class): - def handle_error(self, request, client_address): - self.close_request(request) - self.server_close() - raise - - if verbose: - print("creating server") - server = MyServer(addr, hdlr) - self.assertEqual(server.server_address, server.socket.getsockname()) - - if verbose: - print("server created") - print("ADDR =", addr) - print("CLASS =", self.server_class) - print("HDLR =", server.RequestHandlerClass) - - t = threading.Thread( - name='%s serving' % self.server_class, - target=server.serve_forever, - # Short poll interval to make the test finish quickly. - # Time between requests is short enough that we won't wake - # up spuriously too many times. - kwargs={'poll_interval': 0.01}) - t.daemon = True # In case this function raises. - t.start() - if verbose: - print("server running") - return server, t - - def reap_server(self, server, thread): - if verbose: - print("waiting for server") - server.shutdown() - server.server_close() - thread.join() - if verbose: - print("done") - - @contextmanager - def reaped_server(self, hdlr): - server, thread = self.make_server((support.HOST, 0), hdlr) - try: - yield server - finally: - self.reap_server(server, thread) - - @contextmanager - def reaped_pair(self, hdlr): - with self.reaped_server(hdlr) as server: - client = self.imap_class(*server.server_address) - try: - yield server, client - finally: - client.logout() - - @reap_threads - def test_connect(self): - with self.reaped_server(SimpleIMAPHandler) as server: - client = self.imap_class(*server.server_address) - client.shutdown() - - @reap_threads - def test_bracket_flags(self): - - # This violates RFC 3501, which disallows ']' characters in tag names, - # but imaplib has allowed producing such tags forever, other programs - # also produce them (eg: OtherInbox's Organizer app as of 20140716), - # and Gmail, for example, accepts them and produces them. So we - # support them. See issue #21815. - - class BracketFlagHandler(SimpleIMAPHandler): - - def handle(self): - self.flags = ['Answered', 'Flagged', 'Deleted', 'Seen', 'Draft'] - super().handle() - - def cmd_AUTHENTICATE(self, tag, args): - self._send_textline('+') - self.server.response = yield - self._send_tagged(tag, 'OK', 'FAKEAUTH successful') - - def cmd_SELECT(self, tag, args): - flag_msg = ' \\'.join(self.flags) - self._send_line(('* FLAGS (%s)' % flag_msg).encode('ascii')) - self._send_line(b'* 2 EXISTS') - self._send_line(b'* 0 RECENT') - msg = ('* OK [PERMANENTFLAGS %s \\*)] Flags permitted.' - % flag_msg) - self._send_line(msg.encode('ascii')) - self._send_tagged(tag, 'OK', '[READ-WRITE] SELECT completed.') - - def cmd_STORE(self, tag, args): - new_flags = args[2].strip('(').strip(')').split() - self.flags.extend(new_flags) - flags_msg = '(FLAGS (%s))' % ' \\'.join(self.flags) - msg = '* %s FETCH %s' % (args[0], flags_msg) - self._send_line(msg.encode('ascii')) - self._send_tagged(tag, 'OK', 'STORE completed.') - - with self.reaped_pair(BracketFlagHandler) as (server, client): - code, data = client.authenticate('MYAUTH', lambda x: b'fake') - self.assertEqual(code, 'OK') - self.assertEqual(server.response, b'ZmFrZQ==\r\n') - client.select('test') - typ, [data] = client.store(b'1', "+FLAGS", "[test]") - self.assertIn(b'[test]', data) - client.select('test') - typ, [data] = client.response('PERMANENTFLAGS') - self.assertIn(b'[test]', data) - - @reap_threads - def test_issue5949(self): - - class EOFHandler(socketserver.StreamRequestHandler): - def handle(self): - # EOF without sending a complete welcome message. - self.wfile.write(b'* OK') - - with self.reaped_server(EOFHandler) as server: - self.assertRaises(imaplib.IMAP4.abort, - self.imap_class, *server.server_address) - - @reap_threads - def test_line_termination(self): - - class BadNewlineHandler(SimpleIMAPHandler): - - def cmd_CAPABILITY(self, tag, args): - self._send(b'* CAPABILITY IMAP4rev1 AUTH\n') - self._send_tagged(tag, 'OK', 'CAPABILITY completed') - - with self.reaped_server(BadNewlineHandler) as server: - self.assertRaises(imaplib.IMAP4.abort, - self.imap_class, *server.server_address) - - class UTF8Server(SimpleIMAPHandler): - capabilities = 'AUTH ENABLE UTF8=ACCEPT' - - def cmd_ENABLE(self, tag, args): - self._send_tagged(tag, 'OK', 'ENABLE successful') - - def cmd_AUTHENTICATE(self, tag, args): - self._send_textline('+') - self.server.response = yield - self._send_tagged(tag, 'OK', 'FAKEAUTH successful') - - @reap_threads - def test_enable_raises_error_if_not_AUTH(self): - with self.reaped_pair(self.UTF8Server) as (server, client): - self.assertFalse(client.utf8_enabled) - self.assertRaises(imaplib.IMAP4.error, client.enable, 'foo') - self.assertFalse(client.utf8_enabled) - - # XXX Also need a test that enable after SELECT raises an error. - - @reap_threads - def test_enable_raises_error_if_no_capability(self): - class NoEnableServer(self.UTF8Server): - capabilities = 'AUTH' - with self.reaped_pair(NoEnableServer) as (server, client): - self.assertRaises(imaplib.IMAP4.error, client.enable, 'foo') - - @reap_threads - def test_enable_UTF8_raises_error_if_not_supported(self): - class NonUTF8Server(SimpleIMAPHandler): - pass - with self.assertRaises(imaplib.IMAP4.error): - with self.reaped_pair(NonUTF8Server) as (server, client): - typ, data = client.login('user', 'pass') - self.assertEqual(typ, 'OK') - client.enable('UTF8=ACCEPT') - pass - - @reap_threads - def test_enable_UTF8_True_append(self): - - class UTF8AppendServer(self.UTF8Server): - def cmd_APPEND(self, tag, args): - self._send_textline('+') - self.server.response = yield - self._send_tagged(tag, 'OK', 'okay') - - with self.reaped_pair(UTF8AppendServer) as (server, client): - self.assertEqual(client._encoding, 'ascii') - code, _ = client.authenticate('MYAUTH', lambda x: b'fake') - self.assertEqual(code, 'OK') - self.assertEqual(server.response, - b'ZmFrZQ==\r\n') # b64 encoded 'fake' - code, _ = client.enable('UTF8=ACCEPT') - self.assertEqual(code, 'OK') - self.assertEqual(client._encoding, 'utf-8') - msg_string = 'Subject: üñí©öðé' - typ, data = client.append( - None, None, None, msg_string.encode('utf-8')) - self.assertEqual(typ, 'OK') - self.assertEqual( - server.response, - ('UTF8 (%s)\r\n' % msg_string).encode('utf-8') - ) - - # XXX also need a test that makes sure that the Literal and Untagged_status - # regexes uses unicode in UTF8 mode instead of the default ASCII. - - @reap_threads - def test_search_disallows_charset_in_utf8_mode(self): - with self.reaped_pair(self.UTF8Server) as (server, client): - typ, _ = client.authenticate('MYAUTH', lambda x: b'fake') - self.assertEqual(typ, 'OK') - typ, _ = client.enable('UTF8=ACCEPT') - self.assertEqual(typ, 'OK') - self.assertTrue(client.utf8_enabled) - self.assertRaises(imaplib.IMAP4.error, client.search, 'foo', 'bar') - - @reap_threads - def test_bad_auth_name(self): - - class MyServer(SimpleIMAPHandler): - - def cmd_AUTHENTICATE(self, tag, args): - self._send_tagged(tag, 'NO', 'unrecognized authentication ' - 'type {}'.format(args[0])) - - with self.reaped_pair(MyServer) as (server, client): - with self.assertRaises(imaplib.IMAP4.error): - client.authenticate('METHOD', lambda: 1) - - @reap_threads - def test_invalid_authentication(self): - - class MyServer(SimpleIMAPHandler): - - def cmd_AUTHENTICATE(self, tag, args): - self._send_textline('+') - self.response = yield - self._send_tagged(tag, 'NO', '[AUTHENTICATIONFAILED] invalid') - - with self.reaped_pair(MyServer) as (server, client): - with self.assertRaises(imaplib.IMAP4.error): - code, data = client.authenticate('MYAUTH', lambda x: b'fake') - - @reap_threads - def test_valid_authentication(self): - - class MyServer(SimpleIMAPHandler): - - def cmd_AUTHENTICATE(self, tag, args): - self._send_textline('+') - self.server.response = yield - self._send_tagged(tag, 'OK', 'FAKEAUTH successful') - - with self.reaped_pair(MyServer) as (server, client): - code, data = client.authenticate('MYAUTH', lambda x: b'fake') - self.assertEqual(code, 'OK') - self.assertEqual(server.response, - b'ZmFrZQ==\r\n') # b64 encoded 'fake' - - with self.reaped_pair(MyServer) as (server, client): - code, data = client.authenticate('MYAUTH', lambda x: 'fake') - self.assertEqual(code, 'OK') - self.assertEqual(server.response, - b'ZmFrZQ==\r\n') # b64 encoded 'fake' - - @reap_threads - @requires_hashdigest('md5') - def test_login_cram_md5(self): - - class AuthHandler(SimpleIMAPHandler): - - capabilities = 'LOGINDISABLED AUTH=CRAM-MD5' - - def cmd_AUTHENTICATE(self, tag, args): - self._send_textline('+ PDE4OTYuNjk3MTcwOTUyQHBvc3RvZmZpY2Uucm' - 'VzdG9uLm1jaS5uZXQ=') - r = yield - if (r == b'dGltIGYxY2E2YmU0NjRiOWVmYT' - b'FjY2E2ZmZkNmNmMmQ5ZjMy\r\n'): - self._send_tagged(tag, 'OK', 'CRAM-MD5 successful') - else: - self._send_tagged(tag, 'NO', 'No access') - - with self.reaped_pair(AuthHandler) as (server, client): - self.assertTrue('AUTH=CRAM-MD5' in client.capabilities) - ret, data = client.login_cram_md5("tim", "tanstaaftanstaaf") - self.assertEqual(ret, "OK") - - with self.reaped_pair(AuthHandler) as (server, client): - self.assertTrue('AUTH=CRAM-MD5' in client.capabilities) - ret, data = client.login_cram_md5("tim", b"tanstaaftanstaaf") - self.assertEqual(ret, "OK") - - - @reap_threads - def test_aborted_authentication(self): - - class MyServer(SimpleIMAPHandler): - - def cmd_AUTHENTICATE(self, tag, args): - self._send_textline('+') - self.response = yield - - if self.response == b'*\r\n': - self._send_tagged(tag, 'NO', '[AUTHENTICATIONFAILED] aborted') - else: - self._send_tagged(tag, 'OK', 'MYAUTH successful') - - with self.reaped_pair(MyServer) as (server, client): - with self.assertRaises(imaplib.IMAP4.error): - code, data = client.authenticate('MYAUTH', lambda x: None) - - - def test_linetoolong(self): - class TooLongHandler(SimpleIMAPHandler): - def handle(self): - # Send a very long response line - self.wfile.write(b'* OK ' + imaplib._MAXLINE * b'x' + b'\r\n') - - with self.reaped_server(TooLongHandler) as server: - self.assertRaises(imaplib.IMAP4.error, - self.imap_class, *server.server_address) - - @reap_threads - def test_simple_with_statement(self): - # simplest call - with self.reaped_server(SimpleIMAPHandler) as server: - with self.imap_class(*server.server_address): - pass - - @reap_threads - def test_with_statement(self): - with self.reaped_server(SimpleIMAPHandler) as server: - with self.imap_class(*server.server_address) as imap: - imap.login('user', 'pass') - self.assertEqual(server.logged, 'user') - self.assertIsNone(server.logged) - - @reap_threads - def test_with_statement_logout(self): - # what happens if already logout in the block? - with self.reaped_server(SimpleIMAPHandler) as server: - with self.imap_class(*server.server_address) as imap: - imap.login('user', 'pass') - self.assertEqual(server.logged, 'user') - imap.logout() - self.assertIsNone(server.logged) - self.assertIsNone(server.logged) - - - @unittest.skipUnless(ssl, "SSL not available") - class ThreadedNetworkedTestsSSL(ThreadedNetworkedTests): - server_class = SecureTCPServer - imap_class = IMAP4_SSL - - @reap_threads - def test_ssl_verified(self): - ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT) - ssl_context.load_verify_locations(CAFILE) - - with self.assertRaisesRegex( - ssl.CertificateError, - "IP address mismatch, certificate is not valid for " - "'127.0.0.1'"): - with self.reaped_server(SimpleIMAPHandler) as server: - client = self.imap_class(*server.server_address, - ssl_context=ssl_context) - client.shutdown() - - with self.reaped_server(SimpleIMAPHandler) as server: - client = self.imap_class("localhost", server.server_address[1], - ssl_context=ssl_context) - client.shutdown() - - - @unittest.skipUnless( - support.is_resource_enabled('network'), 'network resource disabled') - @unittest.skip('cyrus.andrew.cmu.edu blocks connections') - class RemoteIMAPTest(unittest.TestCase): - host = 'cyrus.andrew.cmu.edu' - port = 143 - username = 'anonymous' - password = 'pass' - imap_class = imaplib.IMAP4 - - def setUp(self): - with transient_internet(self.host): - self.server = self.imap_class(self.host, self.port) - - def tearDown(self): - if self.server is not None: - with transient_internet(self.host): - self.server.logout() - - def test_logincapa(self): - with transient_internet(self.host): - for cap in self.server.capabilities: - self.assertIsInstance(cap, str) - self.assertIn('LOGINDISABLED', self.server.capabilities) - self.assertIn('AUTH=ANONYMOUS', self.server.capabilities) - rs = self.server.login(self.username, self.password) - self.assertEqual(rs[0], 'OK') - - def test_logout(self): - with transient_internet(self.host): - rs = self.server.logout() - self.server = None - self.assertEqual(rs[0], 'BYE', rs) - - - @unittest.skipUnless(ssl, "SSL not available") - @unittest.skipUnless( - support.is_resource_enabled('network'), 'network resource disabled') - @unittest.skip('cyrus.andrew.cmu.edu blocks connections') - class RemoteIMAP_STARTTLSTest(RemoteIMAPTest): - - def setUp(self): - super().setUp() - with transient_internet(self.host): - rs = self.server.starttls() - self.assertEqual(rs[0], 'OK') - - def test_logincapa(self): - for cap in self.server.capabilities: - self.assertIsInstance(cap, str) - self.assertNotIn('LOGINDISABLED', self.server.capabilities) - - - @unittest.skipUnless(ssl, "SSL not available") - @unittest.skip('cyrus.andrew.cmu.edu blocks connections') - class RemoteIMAP_SSLTest(RemoteIMAPTest): - port = 993 - imap_class = IMAP4_SSL - - def setUp(self): - pass - - def tearDown(self): - pass - - def create_ssl_context(self): - ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT) - ssl_context.check_hostname = False - ssl_context.verify_mode = ssl.CERT_NONE - ssl_context.load_cert_chain(CERTFILE) - return ssl_context - - def check_logincapa(self, server): - try: - for cap in server.capabilities: - self.assertIsInstance(cap, str) - self.assertNotIn('LOGINDISABLED', server.capabilities) - self.assertIn('AUTH=PLAIN', server.capabilities) - rs = server.login(self.username, self.password) - self.assertEqual(rs[0], 'OK') - finally: - server.logout() - - def test_logincapa(self): - with transient_internet(self.host): - _server = self.imap_class(self.host, self.port) - self.check_logincapa(_server) - - def test_logout(self): - with transient_internet(self.host): - _server = self.imap_class(self.host, self.port) - rs = _server.logout() - self.assertEqual(rs[0], 'BYE', rs) - - def test_ssl_context_certfile_exclusive(self): - with transient_internet(self.host): - self.assertRaises( - ValueError, self.imap_class, self.host, self.port, - certfile=CERTFILE, ssl_context=self.create_ssl_context()) - - def test_ssl_context_keyfile_exclusive(self): - with transient_internet(self.host): - self.assertRaises( - ValueError, self.imap_class, self.host, self.port, - keyfile=CERTFILE, ssl_context=self.create_ssl_context()) - - - if __name__ == "__main__": - unittest.main() diff --git a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_imghdr.yaml b/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_imghdr.yaml deleted file mode 100644 index ca9ff9f3d..000000000 --- a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_imghdr.yaml +++ /dev/null @@ -1,141 +0,0 @@ -python: | - import imghdr - import io - import os - import pathlib - import unittest - import warnings - from test.support import findfile, TESTFN, unlink - - TEST_FILES = ( - ('python.png', 'png'), - ('python.gif', 'gif'), - ('python.bmp', 'bmp'), - ('python.ppm', 'ppm'), - ('python.pgm', 'pgm'), - ('python.pbm', 'pbm'), - ('python.jpg', 'jpeg'), - ('python.ras', 'rast'), - ('python.sgi', 'rgb'), - ('python.tiff', 'tiff'), - ('python.xbm', 'xbm'), - ('python.webp', 'webp'), - ('python.exr', 'exr'), - ) - - class UnseekableIO(io.FileIO): - def tell(self): - raise io.UnsupportedOperation - - def seek(self, *args, **kwargs): - raise io.UnsupportedOperation - - class TestImghdr(unittest.TestCase): - @classmethod - def setUpClass(cls): - cls.testfile = findfile('python.png', subdir='imghdrdata') - with open(cls.testfile, 'rb') as stream: - cls.testdata = stream.read() - - def tearDown(self): - unlink(TESTFN) - - def test_data(self): - for filename, expected in TEST_FILES: - filename = findfile(filename, subdir='imghdrdata') - self.assertEqual(imghdr.what(filename), expected) - with open(filename, 'rb') as stream: - self.assertEqual(imghdr.what(stream), expected) - with open(filename, 'rb') as stream: - data = stream.read() - self.assertEqual(imghdr.what(None, data), expected) - self.assertEqual(imghdr.what(None, bytearray(data)), expected) - - def test_pathlike_filename(self): - for filename, expected in TEST_FILES: - with self.subTest(filename=filename): - filename = findfile(filename, subdir='imghdrdata') - self.assertEqual(imghdr.what(pathlib.Path(filename)), expected) - - def test_register_test(self): - def test_jumbo(h, file): - if h.startswith(b'eggs'): - return 'ham' - imghdr.tests.append(test_jumbo) - self.addCleanup(imghdr.tests.pop) - self.assertEqual(imghdr.what(None, b'eggs'), 'ham') - - def test_file_pos(self): - with open(TESTFN, 'wb') as stream: - stream.write(b'ababagalamaga') - pos = stream.tell() - stream.write(self.testdata) - with open(TESTFN, 'rb') as stream: - stream.seek(pos) - self.assertEqual(imghdr.what(stream), 'png') - self.assertEqual(stream.tell(), pos) - - def test_bad_args(self): - with self.assertRaises(TypeError): - imghdr.what() - with self.assertRaises(AttributeError): - imghdr.what(None) - with self.assertRaises(TypeError): - imghdr.what(self.testfile, 1) - with self.assertRaises(AttributeError): - imghdr.what(os.fsencode(self.testfile)) - with open(self.testfile, 'rb') as f: - with self.assertRaises(AttributeError): - imghdr.what(f.fileno()) - - def test_invalid_headers(self): - for header in (b'\211PN\r\n', - b'\001\331', - b'\x59\xA6', - b'cutecat', - b'000000JFI', - b'GIF80'): - self.assertIsNone(imghdr.what(None, header)) - - def test_string_data(self): - with warnings.catch_warnings(): - warnings.simplefilter("ignore", BytesWarning) - for filename, _ in TEST_FILES: - filename = findfile(filename, subdir='imghdrdata') - with open(filename, 'rb') as stream: - data = stream.read().decode('latin1') - with self.assertRaises(TypeError): - imghdr.what(io.StringIO(data)) - with self.assertRaises(TypeError): - imghdr.what(None, data) - - def test_missing_file(self): - with self.assertRaises(FileNotFoundError): - imghdr.what('missing') - - def test_closed_file(self): - stream = open(self.testfile, 'rb') - stream.close() - with self.assertRaises(ValueError) as cm: - imghdr.what(stream) - stream = io.BytesIO(self.testdata) - stream.close() - with self.assertRaises(ValueError) as cm: - imghdr.what(stream) - - def test_unseekable(self): - with open(TESTFN, 'wb') as stream: - stream.write(self.testdata) - with UnseekableIO(TESTFN, 'rb') as stream: - with self.assertRaises(io.UnsupportedOperation): - imghdr.what(stream) - - def test_output_stream(self): - with open(TESTFN, 'wb') as stream: - stream.write(self.testdata) - stream.seek(0) - with self.assertRaises(OSError) as cm: - imghdr.what(stream) - - if __name__ == '__main__': - unittest.main() diff --git a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_imp.yaml b/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_imp.yaml deleted file mode 100644 index 7e84e3927..000000000 --- a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_imp.yaml +++ /dev/null @@ -1,459 +0,0 @@ -python: | - import importlib - import importlib.util - import os - import os.path - import py_compile - import sys - from test import support - from test.support import script_helper - import unittest - import warnings - with warnings.catch_warnings(): - warnings.simplefilter('ignore', DeprecationWarning) - import imp - import _imp - - - def requires_load_dynamic(meth): - """Decorator to skip a test if not running under CPython or lacking - imp.load_dynamic().""" - meth = support.cpython_only(meth) - return unittest.skipIf(not hasattr(imp, 'load_dynamic'), - 'imp.load_dynamic() required')(meth) - - - class LockTests(unittest.TestCase): - - """Very basic test of import lock functions.""" - - def verify_lock_state(self, expected): - self.assertEqual(imp.lock_held(), expected, - "expected imp.lock_held() to be %r" % expected) - def testLock(self): - LOOPS = 50 - - # The import lock may already be held, e.g. if the test suite is run - # via "import test.autotest". - lock_held_at_start = imp.lock_held() - self.verify_lock_state(lock_held_at_start) - - for i in range(LOOPS): - imp.acquire_lock() - self.verify_lock_state(True) - - for i in range(LOOPS): - imp.release_lock() - - # The original state should be restored now. - self.verify_lock_state(lock_held_at_start) - - if not lock_held_at_start: - try: - imp.release_lock() - except RuntimeError: - pass - else: - self.fail("release_lock() without lock should raise " - "RuntimeError") - - class ImportTests(unittest.TestCase): - def setUp(self): - mod = importlib.import_module('test.encoded_modules') - self.test_strings = mod.test_strings - self.test_path = mod.__path__ - - def test_import_encoded_module(self): - for modname, encoding, teststr in self.test_strings: - mod = importlib.import_module('test.encoded_modules.' - 'module_' + modname) - self.assertEqual(teststr, mod.test) - - def test_find_module_encoding(self): - for mod, encoding, _ in self.test_strings: - with imp.find_module('module_' + mod, self.test_path)[0] as fd: - self.assertEqual(fd.encoding, encoding) - - path = [os.path.dirname(__file__)] - with self.assertRaises(SyntaxError): - imp.find_module('badsyntax_pep3120', path) - - def test_issue1267(self): - for mod, encoding, _ in self.test_strings: - fp, filename, info = imp.find_module('module_' + mod, - self.test_path) - with fp: - self.assertNotEqual(fp, None) - self.assertEqual(fp.encoding, encoding) - self.assertEqual(fp.tell(), 0) - self.assertEqual(fp.readline(), '# test %s encoding\n' - % encoding) - - fp, filename, info = imp.find_module("tokenize") - with fp: - self.assertNotEqual(fp, None) - self.assertEqual(fp.encoding, "utf-8") - self.assertEqual(fp.tell(), 0) - self.assertEqual(fp.readline(), - '"""Tokenization help for Python programs.\n') - - def test_issue3594(self): - temp_mod_name = 'test_imp_helper' - sys.path.insert(0, '.') - try: - with open(temp_mod_name + '.py', 'w') as file: - file.write("# coding: cp1252\nu = 'test.test_imp'\n") - file, filename, info = imp.find_module(temp_mod_name) - file.close() - self.assertEqual(file.encoding, 'cp1252') - finally: - del sys.path[0] - support.unlink(temp_mod_name + '.py') - support.unlink(temp_mod_name + '.pyc') - - def test_issue5604(self): - # Test cannot cover imp.load_compiled function. - # Martin von Loewis note what shared library cannot have non-ascii - # character because init_xxx function cannot be compiled - # and issue never happens for dynamic modules. - # But sources modified to follow generic way for processing paths. - - # the return encoding could be uppercase or None - fs_encoding = sys.getfilesystemencoding() - - # covers utf-8 and Windows ANSI code pages - # one non-space symbol from every page - # (http://en.wikipedia.org/wiki/Code_page) - known_locales = { - 'utf-8' : b'\xc3\xa4', - 'cp1250' : b'\x8C', - 'cp1251' : b'\xc0', - 'cp1252' : b'\xc0', - 'cp1253' : b'\xc1', - 'cp1254' : b'\xc0', - 'cp1255' : b'\xe0', - 'cp1256' : b'\xe0', - 'cp1257' : b'\xc0', - 'cp1258' : b'\xc0', - } - - if sys.platform == 'darwin': - self.assertEqual(fs_encoding, 'utf-8') - # Mac OS X uses the Normal Form D decomposition - # http://developer.apple.com/mac/library/qa/qa2001/qa1173.html - special_char = b'a\xcc\x88' - else: - special_char = known_locales.get(fs_encoding) - - if not special_char: - self.skipTest("can't run this test with %s as filesystem encoding" - % fs_encoding) - decoded_char = special_char.decode(fs_encoding) - temp_mod_name = 'test_imp_helper_' + decoded_char - test_package_name = 'test_imp_helper_package_' + decoded_char - init_file_name = os.path.join(test_package_name, '__init__.py') - try: - # if the curdir is not in sys.path the test fails when run with - # ./python ./Lib/test/regrtest.py test_imp - sys.path.insert(0, os.curdir) - with open(temp_mod_name + '.py', 'w') as file: - file.write('a = 1\n') - file, filename, info = imp.find_module(temp_mod_name) - with file: - self.assertIsNotNone(file) - self.assertTrue(filename[:-3].endswith(temp_mod_name)) - self.assertEqual(info[0], '.py') - self.assertEqual(info[1], 'r') - self.assertEqual(info[2], imp.PY_SOURCE) - - mod = imp.load_module(temp_mod_name, file, filename, info) - self.assertEqual(mod.a, 1) - - with warnings.catch_warnings(): - warnings.simplefilter('ignore') - mod = imp.load_source(temp_mod_name, temp_mod_name + '.py') - self.assertEqual(mod.a, 1) - - with warnings.catch_warnings(): - warnings.simplefilter('ignore') - if not sys.dont_write_bytecode: - mod = imp.load_compiled( - temp_mod_name, - imp.cache_from_source(temp_mod_name + '.py')) - self.assertEqual(mod.a, 1) - - if not os.path.exists(test_package_name): - os.mkdir(test_package_name) - with open(init_file_name, 'w') as file: - file.write('b = 2\n') - with warnings.catch_warnings(): - warnings.simplefilter('ignore') - package = imp.load_package(test_package_name, test_package_name) - self.assertEqual(package.b, 2) - finally: - del sys.path[0] - for ext in ('.py', '.pyc'): - support.unlink(temp_mod_name + ext) - support.unlink(init_file_name + ext) - support.rmtree(test_package_name) - support.rmtree('__pycache__') - - def test_issue9319(self): - path = os.path.dirname(__file__) - self.assertRaises(SyntaxError, - imp.find_module, "badsyntax_pep3120", [path]) - - def test_load_from_source(self): - # Verify that the imp module can correctly load and find .py files - # XXX (ncoghlan): It would be nice to use support.CleanImport - # here, but that breaks because the os module registers some - # handlers in copy_reg on import. Since CleanImport doesn't - # revert that registration, the module is left in a broken - # state after reversion. Reinitialising the module contents - # and just reverting os.environ to its previous state is an OK - # workaround - orig_path = os.path - orig_getenv = os.getenv - with support.EnvironmentVarGuard(): - x = imp.find_module("os") - self.addCleanup(x[0].close) - new_os = imp.load_module("os", *x) - self.assertIs(os, new_os) - self.assertIs(orig_path, new_os.path) - self.assertIsNot(orig_getenv, new_os.getenv) - - @requires_load_dynamic - def test_issue15828_load_extensions(self): - # Issue 15828 picked up that the adapter between the old imp API - # and importlib couldn't handle C extensions - example = "_heapq" - x = imp.find_module(example) - file_ = x[0] - if file_ is not None: - self.addCleanup(file_.close) - mod = imp.load_module(example, *x) - self.assertEqual(mod.__name__, example) - - @requires_load_dynamic - def test_issue16421_multiple_modules_in_one_dll(self): - # Issue 16421: loading several modules from the same compiled file fails - m = '_testimportmultiple' - fileobj, pathname, description = imp.find_module(m) - fileobj.close() - mod0 = imp.load_dynamic(m, pathname) - mod1 = imp.load_dynamic('_testimportmultiple_foo', pathname) - mod2 = imp.load_dynamic('_testimportmultiple_bar', pathname) - self.assertEqual(mod0.__name__, m) - self.assertEqual(mod1.__name__, '_testimportmultiple_foo') - self.assertEqual(mod2.__name__, '_testimportmultiple_bar') - with self.assertRaises(ImportError): - imp.load_dynamic('nonexistent', pathname) - - @requires_load_dynamic - def test_load_dynamic_ImportError_path(self): - # Issue #1559549 added `name` and `path` attributes to ImportError - # in order to provide better detail. Issue #10854 implemented those - # attributes on import failures of extensions on Windows. - path = 'bogus file path' - name = 'extension' - with self.assertRaises(ImportError) as err: - imp.load_dynamic(name, path) - self.assertIn(path, err.exception.path) - self.assertEqual(name, err.exception.name) - - @requires_load_dynamic - def test_load_module_extension_file_is_None(self): - # When loading an extension module and the file is None, open one - # on the behalf of imp.load_dynamic(). - # Issue #15902 - name = '_testimportmultiple' - found = imp.find_module(name) - if found[0] is not None: - found[0].close() - if found[2][2] != imp.C_EXTENSION: - self.skipTest("found module doesn't appear to be a C extension") - imp.load_module(name, None, *found[1:]) - - @requires_load_dynamic - def test_issue24748_load_module_skips_sys_modules_check(self): - name = 'test.imp_dummy' - try: - del sys.modules[name] - except KeyError: - pass - try: - module = importlib.import_module(name) - spec = importlib.util.find_spec('_testmultiphase') - module = imp.load_dynamic(name, spec.origin) - self.assertEqual(module.__name__, name) - self.assertEqual(module.__spec__.name, name) - self.assertEqual(module.__spec__.origin, spec.origin) - self.assertRaises(AttributeError, getattr, module, 'dummy_name') - self.assertEqual(module.int_const, 1969) - self.assertIs(sys.modules[name], module) - finally: - try: - del sys.modules[name] - except KeyError: - pass - - @unittest.skipIf(sys.dont_write_bytecode, - "test meaningful only when writing bytecode") - def test_bug7732(self): - with support.temp_cwd(): - source = support.TESTFN + '.py' - os.mkdir(source) - self.assertRaisesRegex(ImportError, '^No module', - imp.find_module, support.TESTFN, ["."]) - - def test_multiple_calls_to_get_data(self): - # Issue #18755: make sure multiple calls to get_data() can succeed. - loader = imp._LoadSourceCompatibility('imp', imp.__file__, - open(imp.__file__)) - loader.get_data(imp.__file__) # File should be closed - loader.get_data(imp.__file__) # Will need to create a newly opened file - - def test_load_source(self): - # Create a temporary module since load_source(name) modifies - # sys.modules[name] attributes like __loader___ - modname = f"tmp{__name__}" - mod = type(sys.modules[__name__])(modname) - with support.swap_item(sys.modules, modname, mod): - with self.assertRaisesRegex(ValueError, 'embedded null'): - imp.load_source(modname, __file__ + "\0") - - @support.cpython_only - def test_issue31315(self): - # There shouldn't be an assertion failure in imp.create_dynamic(), - # when spec.name is not a string. - create_dynamic = support.get_attribute(imp, 'create_dynamic') - class BadSpec: - name = None - origin = 'foo' - with self.assertRaises(TypeError): - create_dynamic(BadSpec()) - - def test_issue_35321(self): - # Both _frozen_importlib and _frozen_importlib_external - # should have a spec origin of "frozen" and - # no need to clean up imports in this case. - - import _frozen_importlib_external - self.assertEqual(_frozen_importlib_external.__spec__.origin, "frozen") - - import _frozen_importlib - self.assertEqual(_frozen_importlib.__spec__.origin, "frozen") - - def test_source_hash(self): - self.assertEqual(_imp.source_hash(42, b'hi'), b'\xc6\xe7Z\r\x03:}\xab') - self.assertEqual(_imp.source_hash(43, b'hi'), b'\x85\x9765\xf8\x9a\x8b9') - - def test_pyc_invalidation_mode_from_cmdline(self): - cases = [ - ([], "default"), - (["--check-hash-based-pycs", "default"], "default"), - (["--check-hash-based-pycs", "always"], "always"), - (["--check-hash-based-pycs", "never"], "never"), - ] - for interp_args, expected in cases: - args = interp_args + [ - "-c", - "import _imp; print(_imp.check_hash_based_pycs)", - ] - res = script_helper.assert_python_ok(*args) - self.assertEqual(res.out.strip().decode('utf-8'), expected) - - def test_find_and_load_checked_pyc(self): - # issue 34056 - with support.temp_cwd(): - with open('mymod.py', 'wb') as fp: - fp.write(b'x = 42\n') - py_compile.compile( - 'mymod.py', - doraise=True, - invalidation_mode=py_compile.PycInvalidationMode.CHECKED_HASH, - ) - file, path, description = imp.find_module('mymod', path=['.']) - mod = imp.load_module('mymod', file, path, description) - self.assertEqual(mod.x, 42) - - - class ReloadTests(unittest.TestCase): - - """Very basic tests to make sure that imp.reload() operates just like - reload().""" - - def test_source(self): - # XXX (ncoghlan): It would be nice to use test.support.CleanImport - # here, but that breaks because the os module registers some - # handlers in copy_reg on import. Since CleanImport doesn't - # revert that registration, the module is left in a broken - # state after reversion. Reinitialising the module contents - # and just reverting os.environ to its previous state is an OK - # workaround - with support.EnvironmentVarGuard(): - import os - imp.reload(os) - - def test_extension(self): - with support.CleanImport('time'): - import time - imp.reload(time) - - def test_builtin(self): - with support.CleanImport('marshal'): - import marshal - imp.reload(marshal) - - def test_with_deleted_parent(self): - # see #18681 - from html import parser - html = sys.modules.pop('html') - def cleanup(): - sys.modules['html'] = html - self.addCleanup(cleanup) - with self.assertRaisesRegex(ImportError, 'html'): - imp.reload(parser) - - - class PEP3147Tests(unittest.TestCase): - """Tests of PEP 3147.""" - - tag = imp.get_tag() - - @unittest.skipUnless(sys.implementation.cache_tag is not None, - 'requires sys.implementation.cache_tag not be None') - def test_cache_from_source(self): - # Given the path to a .py file, return the path to its PEP 3147 - # defined .pyc file (i.e. under __pycache__). - path = os.path.join('foo', 'bar', 'baz', 'qux.py') - expect = os.path.join('foo', 'bar', 'baz', '__pycache__', - 'qux.{}.pyc'.format(self.tag)) - self.assertEqual(imp.cache_from_source(path, True), expect) - - @unittest.skipUnless(sys.implementation.cache_tag is not None, - 'requires sys.implementation.cache_tag to not be ' - 'None') - def test_source_from_cache(self): - # Given the path to a PEP 3147 defined .pyc file, return the path to - # its source. This tests the good path. - path = os.path.join('foo', 'bar', 'baz', '__pycache__', - 'qux.{}.pyc'.format(self.tag)) - expect = os.path.join('foo', 'bar', 'baz', 'qux.py') - self.assertEqual(imp.source_from_cache(path), expect) - - - class NullImporterTests(unittest.TestCase): - @unittest.skipIf(support.TESTFN_UNENCODABLE is None, - "Need an undecodeable filename") - def test_unencodeable(self): - name = support.TESTFN_UNENCODABLE - os.mkdir(name) - try: - self.assertRaises(ImportError, imp.NullImporter, name) - finally: - os.rmdir(name) - - - if __name__ == "__main__": - unittest.main() diff --git a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_index.yaml b/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_index.yaml deleted file mode 100644 index ea1e53a66..000000000 --- a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_index.yaml +++ /dev/null @@ -1,276 +0,0 @@ -python: | - import unittest - from test import support - import operator - maxsize = support.MAX_Py_ssize_t - - class newstyle: - def __index__(self): - return self.ind - - class TrapInt(int): - def __index__(self): - return int(self) - - class BaseTestCase(unittest.TestCase): - def setUp(self): - self.o = newstyle() - self.n = newstyle() - - def test_basic(self): - self.o.ind = -2 - self.n.ind = 2 - self.assertEqual(operator.index(self.o), -2) - self.assertEqual(operator.index(self.n), 2) - - def test_slice(self): - self.o.ind = 1 - self.n.ind = 2 - slc = slice(self.o, self.o, self.o) - check_slc = slice(1, 1, 1) - self.assertEqual(slc.indices(self.o), check_slc.indices(1)) - slc = slice(self.n, self.n, self.n) - check_slc = slice(2, 2, 2) - self.assertEqual(slc.indices(self.n), check_slc.indices(2)) - - def test_wrappers(self): - self.o.ind = 4 - self.n.ind = 5 - self.assertEqual(6 .__index__(), 6) - self.assertEqual(-7 .__index__(), -7) - self.assertEqual(self.o.__index__(), 4) - self.assertEqual(self.n.__index__(), 5) - self.assertEqual(True.__index__(), 1) - self.assertEqual(False.__index__(), 0) - - def test_subclasses(self): - r = list(range(10)) - self.assertEqual(r[TrapInt(5):TrapInt(10)], r[5:10]) - self.assertEqual(slice(TrapInt()).indices(0), (0,0,1)) - - def test_error(self): - self.o.ind = 'dumb' - self.n.ind = 'bad' - self.assertRaises(TypeError, operator.index, self.o) - self.assertRaises(TypeError, operator.index, self.n) - self.assertRaises(TypeError, slice(self.o).indices, 0) - self.assertRaises(TypeError, slice(self.n).indices, 0) - - def test_int_subclass_with_index(self): - # __index__ should be used when computing indices, even for int - # subclasses. See issue #17576. - class MyInt(int): - def __index__(self): - return int(str(self)) + 1 - - my_int = MyInt(7) - direct_index = my_int.__index__() - operator_index = operator.index(my_int) - self.assertEqual(direct_index, 8) - self.assertEqual(operator_index, 7) - # Both results should be of exact type int. - self.assertIs(type(direct_index), int) - #self.assertIs(type(operator_index), int) - - def test_index_returns_int_subclass(self): - class BadInt: - def __index__(self): - return True - - class BadInt2(int): - def __index__(self): - return True - - bad_int = BadInt() - with self.assertWarns(DeprecationWarning): - n = operator.index(bad_int) - self.assertEqual(n, 1) - - bad_int = BadInt2() - n = operator.index(bad_int) - self.assertEqual(n, 0) - - - class SeqTestCase: - # This test case isn't run directly. It just defines common tests - # to the different sequence types below - def setUp(self): - self.o = newstyle() - self.n = newstyle() - self.o2 = newstyle() - self.n2 = newstyle() - - def test_index(self): - self.o.ind = -2 - self.n.ind = 2 - self.assertEqual(self.seq[self.n], self.seq[2]) - self.assertEqual(self.seq[self.o], self.seq[-2]) - - def test_slice(self): - self.o.ind = 1 - self.o2.ind = 3 - self.n.ind = 2 - self.n2.ind = 4 - self.assertEqual(self.seq[self.o:self.o2], self.seq[1:3]) - self.assertEqual(self.seq[self.n:self.n2], self.seq[2:4]) - - def test_slice_bug7532(self): - seqlen = len(self.seq) - self.o.ind = int(seqlen * 1.5) - self.n.ind = seqlen + 2 - self.assertEqual(self.seq[self.o:], self.seq[0:0]) - self.assertEqual(self.seq[:self.o], self.seq) - self.assertEqual(self.seq[self.n:], self.seq[0:0]) - self.assertEqual(self.seq[:self.n], self.seq) - self.o2.ind = -seqlen - 2 - self.n2.ind = -int(seqlen * 1.5) - self.assertEqual(self.seq[self.o2:], self.seq) - self.assertEqual(self.seq[:self.o2], self.seq[0:0]) - self.assertEqual(self.seq[self.n2:], self.seq) - self.assertEqual(self.seq[:self.n2], self.seq[0:0]) - - def test_repeat(self): - self.o.ind = 3 - self.n.ind = 2 - self.assertEqual(self.seq * self.o, self.seq * 3) - self.assertEqual(self.seq * self.n, self.seq * 2) - self.assertEqual(self.o * self.seq, self.seq * 3) - self.assertEqual(self.n * self.seq, self.seq * 2) - - def test_wrappers(self): - self.o.ind = 4 - self.n.ind = 5 - self.assertEqual(self.seq.__getitem__(self.o), self.seq[4]) - self.assertEqual(self.seq.__mul__(self.o), self.seq * 4) - self.assertEqual(self.seq.__rmul__(self.o), self.seq * 4) - self.assertEqual(self.seq.__getitem__(self.n), self.seq[5]) - self.assertEqual(self.seq.__mul__(self.n), self.seq * 5) - self.assertEqual(self.seq.__rmul__(self.n), self.seq * 5) - - def test_subclasses(self): - self.assertEqual(self.seq[TrapInt()], self.seq[0]) - - def test_error(self): - self.o.ind = 'dumb' - self.n.ind = 'bad' - indexobj = lambda x, obj: obj.seq[x] - self.assertRaises(TypeError, indexobj, self.o, self) - self.assertRaises(TypeError, indexobj, self.n, self) - sliceobj = lambda x, obj: obj.seq[x:] - self.assertRaises(TypeError, sliceobj, self.o, self) - self.assertRaises(TypeError, sliceobj, self.n, self) - - - class ListTestCase(SeqTestCase, unittest.TestCase): - seq = [0,10,20,30,40,50] - - def test_setdelitem(self): - self.o.ind = -2 - self.n.ind = 2 - lst = list('ab!cdefghi!j') - del lst[self.o] - del lst[self.n] - lst[self.o] = 'X' - lst[self.n] = 'Y' - self.assertEqual(lst, list('abYdefghXj')) - - lst = [5, 6, 7, 8, 9, 10, 11] - lst.__setitem__(self.n, "here") - self.assertEqual(lst, [5, 6, "here", 8, 9, 10, 11]) - lst.__delitem__(self.n) - self.assertEqual(lst, [5, 6, 8, 9, 10, 11]) - - def test_inplace_repeat(self): - self.o.ind = 2 - self.n.ind = 3 - lst = [6, 4] - lst *= self.o - self.assertEqual(lst, [6, 4, 6, 4]) - lst *= self.n - self.assertEqual(lst, [6, 4, 6, 4] * 3) - - lst = [5, 6, 7, 8, 9, 11] - l2 = lst.__imul__(self.n) - self.assertIs(l2, lst) - self.assertEqual(lst, [5, 6, 7, 8, 9, 11] * 3) - - - class NewSeq: - - def __init__(self, iterable): - self._list = list(iterable) - - def __repr__(self): - return repr(self._list) - - def __eq__(self, other): - return self._list == other - - def __len__(self): - return len(self._list) - - def __mul__(self, n): - return self.__class__(self._list*n) - __rmul__ = __mul__ - - def __getitem__(self, index): - return self._list[index] - - - class TupleTestCase(SeqTestCase, unittest.TestCase): - seq = (0,10,20,30,40,50) - - class ByteArrayTestCase(SeqTestCase, unittest.TestCase): - seq = bytearray(b"this is a test") - - class BytesTestCase(SeqTestCase, unittest.TestCase): - seq = b"this is a test" - - class StringTestCase(SeqTestCase, unittest.TestCase): - seq = "this is a test" - - class NewSeqTestCase(SeqTestCase, unittest.TestCase): - seq = NewSeq((0,10,20,30,40,50)) - - - - class RangeTestCase(unittest.TestCase): - - def test_range(self): - n = newstyle() - n.ind = 5 - self.assertEqual(range(1, 20)[n], 6) - self.assertEqual(range(1, 20).__getitem__(n), 6) - - - class OverflowTestCase(unittest.TestCase): - - def setUp(self): - self.pos = 2**100 - self.neg = -self.pos - - def test_large_longs(self): - self.assertEqual(self.pos.__index__(), self.pos) - self.assertEqual(self.neg.__index__(), self.neg) - - def test_getitem(self): - class GetItem: - def __len__(self): - assert False, "__len__ should not be invoked" - def __getitem__(self, key): - return key - x = GetItem() - self.assertEqual(x[self.pos], self.pos) - self.assertEqual(x[self.neg], self.neg) - self.assertEqual(x[self.neg:self.pos].indices(maxsize), - (0, maxsize, 1)) - self.assertEqual(x[self.neg:self.pos:1].indices(maxsize), - (0, maxsize, 1)) - - def test_sequence_repeat(self): - self.assertRaises(OverflowError, lambda: "a" * self.pos) - self.assertRaises(OverflowError, lambda: "a" * self.neg) - - - if __name__ == "__main__": - unittest.main() diff --git a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_int.yaml b/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_int.yaml deleted file mode 100644 index 1913b587a..000000000 --- a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_int.yaml +++ /dev/null @@ -1,576 +0,0 @@ -python: | - import sys - - import unittest - from test import support - from test.test_grammar import (VALID_UNDERSCORE_LITERALS, - INVALID_UNDERSCORE_LITERALS) - - L = [ - ('0', 0), - ('1', 1), - ('9', 9), - ('10', 10), - ('99', 99), - ('100', 100), - ('314', 314), - (' 314', 314), - ('314 ', 314), - (' \t\t 314 \t\t ', 314), - (repr(sys.maxsize), sys.maxsize), - (' 1x', ValueError), - (' 1 ', 1), - (' 1\02 ', ValueError), - ('', ValueError), - (' ', ValueError), - (' \t\t ', ValueError), - ("\u0200", ValueError) - ] - - class IntSubclass(int): - pass - - class IntTestCases(unittest.TestCase): - - def test_basic(self): - self.assertEqual(int(314), 314) - self.assertEqual(int(3.14), 3) - # Check that conversion from float truncates towards zero - self.assertEqual(int(-3.14), -3) - self.assertEqual(int(3.9), 3) - self.assertEqual(int(-3.9), -3) - self.assertEqual(int(3.5), 3) - self.assertEqual(int(-3.5), -3) - self.assertEqual(int("-3"), -3) - self.assertEqual(int(" -3 "), -3) - self.assertEqual(int("\N{EM SPACE}-3\N{EN SPACE}"), -3) - # Different base: - self.assertEqual(int("10",16), 16) - # Test conversion from strings and various anomalies - for s, v in L: - for sign in "", "+", "-": - for prefix in "", " ", "\t", " \t\t ": - ss = prefix + sign + s - vv = v - if sign == "-" and v is not ValueError: - vv = -v - try: - self.assertEqual(int(ss), vv) - except ValueError: - pass - - s = repr(-1-sys.maxsize) - x = int(s) - self.assertEqual(x+1, -sys.maxsize) - self.assertIsInstance(x, int) - # should return int - self.assertEqual(int(s[1:]), sys.maxsize+1) - - # should return int - x = int(1e100) - self.assertIsInstance(x, int) - x = int(-1e100) - self.assertIsInstance(x, int) - - - # SF bug 434186: 0x80000000/2 != 0x80000000>>1. - # Worked by accident in Windows release build, but failed in debug build. - # Failed in all Linux builds. - x = -1-sys.maxsize - self.assertEqual(x >> 1, x//2) - - x = int('1' * 600) - self.assertIsInstance(x, int) - - - self.assertRaises(TypeError, int, 1, 12) - - self.assertEqual(int('0o123', 0), 83) - self.assertEqual(int('0x123', 16), 291) - - # Bug 1679: "0x" is not a valid hex literal - self.assertRaises(ValueError, int, "0x", 16) - self.assertRaises(ValueError, int, "0x", 0) - - self.assertRaises(ValueError, int, "0o", 8) - self.assertRaises(ValueError, int, "0o", 0) - - self.assertRaises(ValueError, int, "0b", 2) - self.assertRaises(ValueError, int, "0b", 0) - - # SF bug 1334662: int(string, base) wrong answers - # Various representations of 2**32 evaluated to 0 - # rather than 2**32 in previous versions - - self.assertEqual(int('100000000000000000000000000000000', 2), 4294967296) - self.assertEqual(int('102002022201221111211', 3), 4294967296) - self.assertEqual(int('10000000000000000', 4), 4294967296) - self.assertEqual(int('32244002423141', 5), 4294967296) - self.assertEqual(int('1550104015504', 6), 4294967296) - self.assertEqual(int('211301422354', 7), 4294967296) - self.assertEqual(int('40000000000', 8), 4294967296) - self.assertEqual(int('12068657454', 9), 4294967296) - self.assertEqual(int('4294967296', 10), 4294967296) - self.assertEqual(int('1904440554', 11), 4294967296) - self.assertEqual(int('9ba461594', 12), 4294967296) - self.assertEqual(int('535a79889', 13), 4294967296) - self.assertEqual(int('2ca5b7464', 14), 4294967296) - self.assertEqual(int('1a20dcd81', 15), 4294967296) - self.assertEqual(int('100000000', 16), 4294967296) - self.assertEqual(int('a7ffda91', 17), 4294967296) - self.assertEqual(int('704he7g4', 18), 4294967296) - self.assertEqual(int('4f5aff66', 19), 4294967296) - self.assertEqual(int('3723ai4g', 20), 4294967296) - self.assertEqual(int('281d55i4', 21), 4294967296) - self.assertEqual(int('1fj8b184', 22), 4294967296) - self.assertEqual(int('1606k7ic', 23), 4294967296) - self.assertEqual(int('mb994ag', 24), 4294967296) - self.assertEqual(int('hek2mgl', 25), 4294967296) - self.assertEqual(int('dnchbnm', 26), 4294967296) - self.assertEqual(int('b28jpdm', 27), 4294967296) - self.assertEqual(int('8pfgih4', 28), 4294967296) - self.assertEqual(int('76beigg', 29), 4294967296) - self.assertEqual(int('5qmcpqg', 30), 4294967296) - self.assertEqual(int('4q0jto4', 31), 4294967296) - self.assertEqual(int('4000000', 32), 4294967296) - self.assertEqual(int('3aokq94', 33), 4294967296) - self.assertEqual(int('2qhxjli', 34), 4294967296) - self.assertEqual(int('2br45qb', 35), 4294967296) - self.assertEqual(int('1z141z4', 36), 4294967296) - - # tests with base 0 - # this fails on 3.0, but in 2.x the old octal syntax is allowed - self.assertEqual(int(' 0o123 ', 0), 83) - self.assertEqual(int(' 0o123 ', 0), 83) - self.assertEqual(int('000', 0), 0) - self.assertEqual(int('0o123', 0), 83) - self.assertEqual(int('0x123', 0), 291) - self.assertEqual(int('0b100', 0), 4) - self.assertEqual(int(' 0O123 ', 0), 83) - self.assertEqual(int(' 0X123 ', 0), 291) - self.assertEqual(int(' 0B100 ', 0), 4) - - # without base still base 10 - self.assertEqual(int('0123'), 123) - self.assertEqual(int('0123', 10), 123) - - # tests with prefix and base != 0 - self.assertEqual(int('0x123', 16), 291) - self.assertEqual(int('0o123', 8), 83) - self.assertEqual(int('0b100', 2), 4) - self.assertEqual(int('0X123', 16), 291) - self.assertEqual(int('0O123', 8), 83) - self.assertEqual(int('0B100', 2), 4) - - # the code has special checks for the first character after the - # type prefix - self.assertRaises(ValueError, int, '0b2', 2) - self.assertRaises(ValueError, int, '0b02', 2) - self.assertRaises(ValueError, int, '0B2', 2) - self.assertRaises(ValueError, int, '0B02', 2) - self.assertRaises(ValueError, int, '0o8', 8) - self.assertRaises(ValueError, int, '0o08', 8) - self.assertRaises(ValueError, int, '0O8', 8) - self.assertRaises(ValueError, int, '0O08', 8) - self.assertRaises(ValueError, int, '0xg', 16) - self.assertRaises(ValueError, int, '0x0g', 16) - self.assertRaises(ValueError, int, '0Xg', 16) - self.assertRaises(ValueError, int, '0X0g', 16) - - # SF bug 1334662: int(string, base) wrong answers - # Checks for proper evaluation of 2**32 + 1 - self.assertEqual(int('100000000000000000000000000000001', 2), 4294967297) - self.assertEqual(int('102002022201221111212', 3), 4294967297) - self.assertEqual(int('10000000000000001', 4), 4294967297) - self.assertEqual(int('32244002423142', 5), 4294967297) - self.assertEqual(int('1550104015505', 6), 4294967297) - self.assertEqual(int('211301422355', 7), 4294967297) - self.assertEqual(int('40000000001', 8), 4294967297) - self.assertEqual(int('12068657455', 9), 4294967297) - self.assertEqual(int('4294967297', 10), 4294967297) - self.assertEqual(int('1904440555', 11), 4294967297) - self.assertEqual(int('9ba461595', 12), 4294967297) - self.assertEqual(int('535a7988a', 13), 4294967297) - self.assertEqual(int('2ca5b7465', 14), 4294967297) - self.assertEqual(int('1a20dcd82', 15), 4294967297) - self.assertEqual(int('100000001', 16), 4294967297) - self.assertEqual(int('a7ffda92', 17), 4294967297) - self.assertEqual(int('704he7g5', 18), 4294967297) - self.assertEqual(int('4f5aff67', 19), 4294967297) - self.assertEqual(int('3723ai4h', 20), 4294967297) - self.assertEqual(int('281d55i5', 21), 4294967297) - self.assertEqual(int('1fj8b185', 22), 4294967297) - self.assertEqual(int('1606k7id', 23), 4294967297) - self.assertEqual(int('mb994ah', 24), 4294967297) - self.assertEqual(int('hek2mgm', 25), 4294967297) - self.assertEqual(int('dnchbnn', 26), 4294967297) - self.assertEqual(int('b28jpdn', 27), 4294967297) - self.assertEqual(int('8pfgih5', 28), 4294967297) - self.assertEqual(int('76beigh', 29), 4294967297) - self.assertEqual(int('5qmcpqh', 30), 4294967297) - self.assertEqual(int('4q0jto5', 31), 4294967297) - self.assertEqual(int('4000001', 32), 4294967297) - self.assertEqual(int('3aokq95', 33), 4294967297) - self.assertEqual(int('2qhxjlj', 34), 4294967297) - self.assertEqual(int('2br45qc', 35), 4294967297) - self.assertEqual(int('1z141z5', 36), 4294967297) - - def test_underscores(self): - for lit in VALID_UNDERSCORE_LITERALS: - if any(ch in lit for ch in '.eEjJ'): - continue - self.assertEqual(int(lit, 0), eval(lit)) - self.assertEqual(int(lit, 0), int(lit.replace('_', ''), 0)) - for lit in INVALID_UNDERSCORE_LITERALS: - if any(ch in lit for ch in '.eEjJ'): - continue - self.assertRaises(ValueError, int, lit, 0) - # Additional test cases with bases != 0, only for the constructor: - self.assertEqual(int("1_00", 3), 9) - self.assertEqual(int("0_100"), 100) # not valid as a literal! - self.assertEqual(int(b"1_00"), 100) # byte underscore - self.assertRaises(ValueError, int, "_100") - self.assertRaises(ValueError, int, "+_100") - self.assertRaises(ValueError, int, "1__00") - self.assertRaises(ValueError, int, "100_") - - @support.cpython_only - def test_small_ints(self): - # Bug #3236: Return small longs from PyLong_FromString - self.assertIs(int('10'), 10) - self.assertIs(int('-1'), -1) - self.assertIs(int(b'10'), 10) - self.assertIs(int(b'-1'), -1) - - def test_no_args(self): - self.assertEqual(int(), 0) - - def test_keyword_args(self): - # Test invoking int() using keyword arguments. - self.assertEqual(int('100', base=2), 4) - with self.assertRaisesRegex(TypeError, 'keyword argument'): - int(x=1.2) - with self.assertRaisesRegex(TypeError, 'keyword argument'): - int(x='100', base=2) - self.assertRaises(TypeError, int, base=10) - self.assertRaises(TypeError, int, base=0) - - def test_int_base_limits(self): - """Testing the supported limits of the int() base parameter.""" - self.assertEqual(int('0', 5), 0) - with self.assertRaises(ValueError): - int('0', 1) - with self.assertRaises(ValueError): - int('0', 37) - with self.assertRaises(ValueError): - int('0', -909) # An old magic value base from Python 2. - with self.assertRaises(ValueError): - int('0', base=0-(2**234)) - with self.assertRaises(ValueError): - int('0', base=2**234) - # Bases 2 through 36 are supported. - for base in range(2,37): - self.assertEqual(int('0', base=base), 0) - - def test_int_base_bad_types(self): - """Not integer types are not valid bases; issue16772.""" - with self.assertRaises(TypeError): - int('0', 5.5) - with self.assertRaises(TypeError): - int('0', 5.0) - - def test_int_base_indexable(self): - class MyIndexable(object): - def __init__(self, value): - self.value = value - def __index__(self): - return self.value - - # Check out of range bases. - for base in 2**100, -2**100, 1, 37: - with self.assertRaises(ValueError): - int('43', base) - - # Check in-range bases. - self.assertEqual(int('101', base=MyIndexable(2)), 5) - self.assertEqual(int('101', base=MyIndexable(10)), 101) - self.assertEqual(int('101', base=MyIndexable(36)), 1 + 36**2) - - def test_non_numeric_input_types(self): - # Test possible non-numeric types for the argument x, including - # subclasses of the explicitly documented accepted types. - class CustomStr(str): pass - class CustomBytes(bytes): pass - class CustomByteArray(bytearray): pass - - factories = [ - bytes, - bytearray, - lambda b: CustomStr(b.decode()), - CustomBytes, - CustomByteArray, - memoryview, - ] - try: - from array import array - except ImportError: - pass - else: - factories.append(lambda b: array('B', b)) - - for f in factories: - x = f(b'100') - with self.subTest(type(x)): - self.assertEqual(int(x), 100) - if isinstance(x, (str, bytes, bytearray)): - self.assertEqual(int(x, 2), 4) - else: - msg = "can't convert non-string" - with self.assertRaisesRegex(TypeError, msg): - int(x, 2) - with self.assertRaisesRegex(ValueError, 'invalid literal'): - int(f(b'A' * 0x10)) - - def test_int_memoryview(self): - self.assertEqual(int(memoryview(b'123')[1:3]), 23) - self.assertEqual(int(memoryview(b'123\x00')[1:3]), 23) - self.assertEqual(int(memoryview(b'123 ')[1:3]), 23) - self.assertEqual(int(memoryview(b'123A')[1:3]), 23) - self.assertEqual(int(memoryview(b'1234')[1:3]), 23) - - def test_string_float(self): - self.assertRaises(ValueError, int, '1.2') - - def test_intconversion(self): - # Test __int__() - class ClassicMissingMethods: - pass - self.assertRaises(TypeError, int, ClassicMissingMethods()) - - class MissingMethods(object): - pass - self.assertRaises(TypeError, int, MissingMethods()) - - class Foo0: - def __int__(self): - return 42 - - self.assertEqual(int(Foo0()), 42) - - class Classic: - pass - for base in (object, Classic): - class IntOverridesTrunc(base): - def __int__(self): - return 42 - def __trunc__(self): - return -12 - self.assertEqual(int(IntOverridesTrunc()), 42) - - class JustTrunc(base): - def __trunc__(self): - return 42 - self.assertEqual(int(JustTrunc()), 42) - - class ExceptionalTrunc(base): - def __trunc__(self): - 1 / 0 - with self.assertRaises(ZeroDivisionError): - int(ExceptionalTrunc()) - - for trunc_result_base in (object, Classic): - class Index(trunc_result_base): - def __index__(self): - return 42 - - class TruncReturnsNonInt(base): - def __trunc__(self): - return Index() - self.assertEqual(int(TruncReturnsNonInt()), 42) - - class Intable(trunc_result_base): - def __int__(self): - return 42 - - class TruncReturnsNonIndex(base): - def __trunc__(self): - return Intable() - self.assertEqual(int(TruncReturnsNonInt()), 42) - - class NonIntegral(trunc_result_base): - def __trunc__(self): - # Check that we avoid infinite recursion. - return NonIntegral() - - class TruncReturnsNonIntegral(base): - def __trunc__(self): - return NonIntegral() - try: - int(TruncReturnsNonIntegral()) - except TypeError as e: - self.assertEqual(str(e), - "__trunc__ returned non-Integral" - " (type NonIntegral)") - else: - self.fail("Failed to raise TypeError with %s" % - ((base, trunc_result_base),)) - - # Regression test for bugs.python.org/issue16060. - class BadInt(trunc_result_base): - def __int__(self): - return 42.0 - - class TruncReturnsBadInt(base): - def __trunc__(self): - return BadInt() - - with self.assertRaises(TypeError): - int(TruncReturnsBadInt()) - - def test_int_subclass_with_index(self): - class MyIndex(int): - def __index__(self): - return 42 - - class BadIndex(int): - def __index__(self): - return 42.0 - - my_int = MyIndex(7) - self.assertEqual(my_int, 7) - self.assertEqual(int(my_int), 7) - - self.assertEqual(int(BadIndex()), 0) - - def test_int_subclass_with_int(self): - class MyInt(int): - def __int__(self): - return 42 - - class BadInt(int): - def __int__(self): - return 42.0 - - my_int = MyInt(7) - self.assertEqual(my_int, 7) - self.assertEqual(int(my_int), 42) - - my_int = BadInt(7) - self.assertEqual(my_int, 7) - self.assertRaises(TypeError, int, my_int) - - def test_int_returns_int_subclass(self): - class BadIndex: - def __index__(self): - return True - - class BadIndex2(int): - def __index__(self): - return True - - class BadInt: - def __int__(self): - return True - - class BadInt2(int): - def __int__(self): - return True - - class TruncReturnsBadIndex: - def __trunc__(self): - return BadIndex() - - class TruncReturnsBadInt: - def __trunc__(self): - return BadInt() - - class TruncReturnsIntSubclass: - def __trunc__(self): - return True - - bad_int = BadIndex() - with self.assertWarns(DeprecationWarning): - n = int(bad_int) - self.assertEqual(n, 1) - self.assertIs(type(n), int) - - bad_int = BadIndex2() - n = int(bad_int) - self.assertEqual(n, 0) - self.assertIs(type(n), int) - - bad_int = BadInt() - with self.assertWarns(DeprecationWarning): - n = int(bad_int) - self.assertEqual(n, 1) - self.assertIs(type(n), int) - - bad_int = BadInt2() - with self.assertWarns(DeprecationWarning): - n = int(bad_int) - self.assertEqual(n, 1) - self.assertIs(type(n), int) - - bad_int = TruncReturnsBadIndex() - with self.assertWarns(DeprecationWarning): - n = int(bad_int) - self.assertEqual(n, 1) - self.assertIs(type(n), int) - - bad_int = TruncReturnsBadInt() - with self.assertWarns(DeprecationWarning): - n = int(bad_int) - self.assertEqual(n, 1) - self.assertIs(type(n), int) - - good_int = TruncReturnsIntSubclass() - n = int(good_int) - self.assertEqual(n, 1) - self.assertIs(type(n), int) - n = IntSubclass(good_int) - self.assertEqual(n, 1) - self.assertIs(type(n), IntSubclass) - - def test_error_message(self): - def check(s, base=None): - with self.assertRaises(ValueError, - msg="int(%r, %r)" % (s, base)) as cm: - if base is None: - int(s) - else: - int(s, base) - self.assertEqual(cm.exception.args[0], - "invalid literal for int() with base %d: %r" % - (10 if base is None else base, s)) - - check('\xbd') - check('123\xbd') - check(' 123 456 ') - - check('123\x00') - # SF bug 1545497: embedded NULs were not detected with explicit base - check('123\x00', 10) - check('123\x00 245', 20) - check('123\x00 245', 16) - check('123\x00245', 20) - check('123\x00245', 16) - # byte string with embedded NUL - check(b'123\x00') - check(b'123\x00', 10) - # non-UTF-8 byte string - check(b'123\xbd') - check(b'123\xbd', 10) - # lone surrogate in Unicode string - check('123\ud800') - check('123\ud800', 10) - - def test_issue31619(self): - self.assertEqual(int('1_0_1_0_1_0_1_0_1_0_1_0_1_0_1_0_1_0_1_0_1_0_1_0_1_0_1_0_1_0_1', 2), - 0b1010101010101010101010101010101) - self.assertEqual(int('1_2_3_4_5_6_7_0_1_2_3', 8), 0o12345670123) - self.assertEqual(int('1_2_3_4_5_6_7_8_9', 16), 0x123456789) - self.assertEqual(int('1_2_3_4_5_6_7', 32), 1144132807) - - - if __name__ == "__main__": - unittest.main() diff --git a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_int_literal.yaml b/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_int_literal.yaml deleted file mode 100644 index 6724d04d3..000000000 --- a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_int_literal.yaml +++ /dev/null @@ -1,144 +0,0 @@ -python: | - """Test correct treatment of hex/oct constants. - - This is complex because of changes due to PEP 237. - """ - - import unittest - - class TestHexOctBin(unittest.TestCase): - - def test_hex_baseline(self): - # A few upper/lowercase tests - self.assertEqual(0x0, 0X0) - self.assertEqual(0x1, 0X1) - self.assertEqual(0x123456789abcdef, 0X123456789abcdef) - # Baseline tests - self.assertEqual(0x0, 0) - self.assertEqual(0x10, 16) - self.assertEqual(0x7fffffff, 2147483647) - self.assertEqual(0x7fffffffffffffff, 9223372036854775807) - # Ditto with a minus sign and parentheses - self.assertEqual(-(0x0), 0) - self.assertEqual(-(0x10), -16) - self.assertEqual(-(0x7fffffff), -2147483647) - self.assertEqual(-(0x7fffffffffffffff), -9223372036854775807) - # Ditto with a minus sign and NO parentheses - self.assertEqual(-0x0, 0) - self.assertEqual(-0x10, -16) - self.assertEqual(-0x7fffffff, -2147483647) - self.assertEqual(-0x7fffffffffffffff, -9223372036854775807) - - def test_hex_unsigned(self): - # Positive constants - self.assertEqual(0x80000000, 2147483648) - self.assertEqual(0xffffffff, 4294967295) - # Ditto with a minus sign and parentheses - self.assertEqual(-(0x80000000), -2147483648) - self.assertEqual(-(0xffffffff), -4294967295) - # Ditto with a minus sign and NO parentheses - # This failed in Python 2.2 through 2.2.2 and in 2.3a1 - self.assertEqual(-0x80000000, -2147483648) - self.assertEqual(-0xffffffff, -4294967295) - - # Positive constants - self.assertEqual(0x8000000000000000, 9223372036854775808) - self.assertEqual(0xffffffffffffffff, 18446744073709551615) - # Ditto with a minus sign and parentheses - self.assertEqual(-(0x8000000000000000), -9223372036854775808) - self.assertEqual(-(0xffffffffffffffff), -18446744073709551615) - # Ditto with a minus sign and NO parentheses - # This failed in Python 2.2 through 2.2.2 and in 2.3a1 - self.assertEqual(-0x8000000000000000, -9223372036854775808) - self.assertEqual(-0xffffffffffffffff, -18446744073709551615) - - def test_oct_baseline(self): - # A few upper/lowercase tests - self.assertEqual(0o0, 0O0) - self.assertEqual(0o1, 0O1) - self.assertEqual(0o1234567, 0O1234567) - # Baseline tests - self.assertEqual(0o0, 0) - self.assertEqual(0o20, 16) - self.assertEqual(0o17777777777, 2147483647) - self.assertEqual(0o777777777777777777777, 9223372036854775807) - # Ditto with a minus sign and parentheses - self.assertEqual(-(0o0), 0) - self.assertEqual(-(0o20), -16) - self.assertEqual(-(0o17777777777), -2147483647) - self.assertEqual(-(0o777777777777777777777), -9223372036854775807) - # Ditto with a minus sign and NO parentheses - self.assertEqual(-0o0, 0) - self.assertEqual(-0o20, -16) - self.assertEqual(-0o17777777777, -2147483647) - self.assertEqual(-0o777777777777777777777, -9223372036854775807) - - def test_oct_unsigned(self): - # Positive constants - self.assertEqual(0o20000000000, 2147483648) - self.assertEqual(0o37777777777, 4294967295) - # Ditto with a minus sign and parentheses - self.assertEqual(-(0o20000000000), -2147483648) - self.assertEqual(-(0o37777777777), -4294967295) - # Ditto with a minus sign and NO parentheses - # This failed in Python 2.2 through 2.2.2 and in 2.3a1 - self.assertEqual(-0o20000000000, -2147483648) - self.assertEqual(-0o37777777777, -4294967295) - - # Positive constants - self.assertEqual(0o1000000000000000000000, 9223372036854775808) - self.assertEqual(0o1777777777777777777777, 18446744073709551615) - # Ditto with a minus sign and parentheses - self.assertEqual(-(0o1000000000000000000000), -9223372036854775808) - self.assertEqual(-(0o1777777777777777777777), -18446744073709551615) - # Ditto with a minus sign and NO parentheses - # This failed in Python 2.2 through 2.2.2 and in 2.3a1 - self.assertEqual(-0o1000000000000000000000, -9223372036854775808) - self.assertEqual(-0o1777777777777777777777, -18446744073709551615) - - def test_bin_baseline(self): - # A few upper/lowercase tests - self.assertEqual(0b0, 0B0) - self.assertEqual(0b1, 0B1) - self.assertEqual(0b10101010101, 0B10101010101) - # Baseline tests - self.assertEqual(0b0, 0) - self.assertEqual(0b10000, 16) - self.assertEqual(0b1111111111111111111111111111111, 2147483647) - self.assertEqual(0b111111111111111111111111111111111111111111111111111111111111111, 9223372036854775807) - # Ditto with a minus sign and parentheses - self.assertEqual(-(0b0), 0) - self.assertEqual(-(0b10000), -16) - self.assertEqual(-(0b1111111111111111111111111111111), -2147483647) - self.assertEqual(-(0b111111111111111111111111111111111111111111111111111111111111111), -9223372036854775807) - # Ditto with a minus sign and NO parentheses - self.assertEqual(-0b0, 0) - self.assertEqual(-0b10000, -16) - self.assertEqual(-0b1111111111111111111111111111111, -2147483647) - self.assertEqual(-0b111111111111111111111111111111111111111111111111111111111111111, -9223372036854775807) - - def test_bin_unsigned(self): - # Positive constants - self.assertEqual(0b10000000000000000000000000000000, 2147483648) - self.assertEqual(0b11111111111111111111111111111111, 4294967295) - # Ditto with a minus sign and parentheses - self.assertEqual(-(0b10000000000000000000000000000000), -2147483648) - self.assertEqual(-(0b11111111111111111111111111111111), -4294967295) - # Ditto with a minus sign and NO parentheses - # This failed in Python 2.2 through 2.2.2 and in 2.3a1 - self.assertEqual(-0b10000000000000000000000000000000, -2147483648) - self.assertEqual(-0b11111111111111111111111111111111, -4294967295) - - # Positive constants - self.assertEqual(0b1000000000000000000000000000000000000000000000000000000000000000, 9223372036854775808) - self.assertEqual(0b1111111111111111111111111111111111111111111111111111111111111111, 18446744073709551615) - # Ditto with a minus sign and parentheses - self.assertEqual(-(0b1000000000000000000000000000000000000000000000000000000000000000), -9223372036854775808) - self.assertEqual(-(0b1111111111111111111111111111111111111111111111111111111111111111), -18446744073709551615) - # Ditto with a minus sign and NO parentheses - # This failed in Python 2.2 through 2.2.2 and in 2.3a1 - self.assertEqual(-0b1000000000000000000000000000000000000000000000000000000000000000, -9223372036854775808) - self.assertEqual(-0b1111111111111111111111111111111111111111111111111111111111111111, -18446744073709551615) - - if __name__ == "__main__": - unittest.main() diff --git a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_io.yaml b/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_io.yaml deleted file mode 100644 index befbb273b..000000000 --- a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_io.yaml +++ /dev/null @@ -1,4505 +0,0 @@ -python: | - """Unit tests for the io module.""" - - # Tests of io are scattered over the test suite: - # * test_bufio - tests file buffering - # * test_memoryio - tests BytesIO and StringIO - # * test_fileio - tests FileIO - # * test_file - tests the file interface - # * test_io - tests everything else in the io module - # * test_univnewlines - tests universal newline support - # * test_largefile - tests operations on a file greater than 2**32 bytes - # (only enabled with -ulargefile) - - ################################################################################ - # ATTENTION TEST WRITERS!!! - ################################################################################ - # When writing tests for io, it's important to test both the C and Python - # implementations. This is usually done by writing a base test that refers to - # the type it is testing as an attribute. Then it provides custom subclasses to - # test both implementations. This file has lots of examples. - ################################################################################ - - import abc - import array - import errno - import locale - import os - import pickle - import random - import signal - import sys - import sysconfig - import threading - import time - import unittest - import warnings - import weakref - from collections import deque, UserList - from itertools import cycle, count - from test import support - from test.support.script_helper import assert_python_ok, run_python_until_end - from test.support import FakePath - - import codecs - import io # C implementation of io - import _pyio as pyio # Python implementation of io - - try: - import ctypes - except ImportError: - def byteslike(*pos, **kw): - return array.array("b", bytes(*pos, **kw)) - else: - def byteslike(*pos, **kw): - """Create a bytes-like object having no string or sequence methods""" - data = bytes(*pos, **kw) - obj = EmptyStruct() - ctypes.resize(obj, len(data)) - memoryview(obj).cast("B")[:] = data - return obj - class EmptyStruct(ctypes.Structure): - pass - - _cflags = sysconfig.get_config_var('CFLAGS') or '' - _config_args = sysconfig.get_config_var('CONFIG_ARGS') or '' - MEMORY_SANITIZER = ( - '-fsanitize=memory' in _cflags or - '--with-memory-sanitizer' in _config_args - ) - - # Does io.IOBase finalizer log the exception if the close() method fails? - # The exception is ignored silently by default in release build. - IOBASE_EMITS_UNRAISABLE = (hasattr(sys, "gettotalrefcount") or sys.flags.dev_mode) - - - def _default_chunk_size(): - """Get the default TextIOWrapper chunk size""" - with open(__file__, "r", encoding="latin-1") as f: - return f._CHUNK_SIZE - - - class MockRawIOWithoutRead: - """A RawIO implementation without read(), so as to exercise the default - RawIO.read() which calls readinto().""" - - def __init__(self, read_stack=()): - self._read_stack = list(read_stack) - self._write_stack = [] - self._reads = 0 - self._extraneous_reads = 0 - - def write(self, b): - self._write_stack.append(bytes(b)) - return len(b) - - def writable(self): - return True - - def fileno(self): - return 42 - - def readable(self): - return True - - def seekable(self): - return True - - def seek(self, pos, whence): - return 0 # wrong but we gotta return something - - def tell(self): - return 0 # same comment as above - - def readinto(self, buf): - self._reads += 1 - max_len = len(buf) - try: - data = self._read_stack[0] - except IndexError: - self._extraneous_reads += 1 - return 0 - if data is None: - del self._read_stack[0] - return None - n = len(data) - if len(data) <= max_len: - del self._read_stack[0] - buf[:n] = data - return n - else: - buf[:] = data[:max_len] - self._read_stack[0] = data[max_len:] - return max_len - - def truncate(self, pos=None): - return pos - - class CMockRawIOWithoutRead(MockRawIOWithoutRead, io.RawIOBase): - pass - - class PyMockRawIOWithoutRead(MockRawIOWithoutRead, pyio.RawIOBase): - pass - - - class MockRawIO(MockRawIOWithoutRead): - - def read(self, n=None): - self._reads += 1 - try: - return self._read_stack.pop(0) - except: - self._extraneous_reads += 1 - return b"" - - class CMockRawIO(MockRawIO, io.RawIOBase): - pass - - class PyMockRawIO(MockRawIO, pyio.RawIOBase): - pass - - - class MisbehavedRawIO(MockRawIO): - def write(self, b): - return super().write(b) * 2 - - def read(self, n=None): - return super().read(n) * 2 - - def seek(self, pos, whence): - return -123 - - def tell(self): - return -456 - - def readinto(self, buf): - super().readinto(buf) - return len(buf) * 5 - - class CMisbehavedRawIO(MisbehavedRawIO, io.RawIOBase): - pass - - class PyMisbehavedRawIO(MisbehavedRawIO, pyio.RawIOBase): - pass - - - class SlowFlushRawIO(MockRawIO): - def __init__(self): - super().__init__() - self.in_flush = threading.Event() - - def flush(self): - self.in_flush.set() - time.sleep(0.25) - - class CSlowFlushRawIO(SlowFlushRawIO, io.RawIOBase): - pass - - class PySlowFlushRawIO(SlowFlushRawIO, pyio.RawIOBase): - pass - - - class CloseFailureIO(MockRawIO): - closed = 0 - - def close(self): - if not self.closed: - self.closed = 1 - raise OSError - - class CCloseFailureIO(CloseFailureIO, io.RawIOBase): - pass - - class PyCloseFailureIO(CloseFailureIO, pyio.RawIOBase): - pass - - - class MockFileIO: - - def __init__(self, data): - self.read_history = [] - super().__init__(data) - - def read(self, n=None): - res = super().read(n) - self.read_history.append(None if res is None else len(res)) - return res - - def readinto(self, b): - res = super().readinto(b) - self.read_history.append(res) - return res - - class CMockFileIO(MockFileIO, io.BytesIO): - pass - - class PyMockFileIO(MockFileIO, pyio.BytesIO): - pass - - - class MockUnseekableIO: - def seekable(self): - return False - - def seek(self, *args): - raise self.UnsupportedOperation("not seekable") - - def tell(self, *args): - raise self.UnsupportedOperation("not seekable") - - def truncate(self, *args): - raise self.UnsupportedOperation("not seekable") - - class CMockUnseekableIO(MockUnseekableIO, io.BytesIO): - UnsupportedOperation = io.UnsupportedOperation - - class PyMockUnseekableIO(MockUnseekableIO, pyio.BytesIO): - UnsupportedOperation = pyio.UnsupportedOperation - - - class MockNonBlockWriterIO: - - def __init__(self): - self._write_stack = [] - self._blocker_char = None - - def pop_written(self): - s = b"".join(self._write_stack) - self._write_stack[:] = [] - return s - - def block_on(self, char): - """Block when a given char is encountered.""" - self._blocker_char = char - - def readable(self): - return True - - def seekable(self): - return True - - def seek(self, pos, whence=0): - # naive implementation, enough for tests - return 0 - - def writable(self): - return True - - def write(self, b): - b = bytes(b) - n = -1 - if self._blocker_char: - try: - n = b.index(self._blocker_char) - except ValueError: - pass - else: - if n > 0: - # write data up to the first blocker - self._write_stack.append(b[:n]) - return n - else: - # cancel blocker and indicate would block - self._blocker_char = None - return None - self._write_stack.append(b) - return len(b) - - class CMockNonBlockWriterIO(MockNonBlockWriterIO, io.RawIOBase): - BlockingIOError = io.BlockingIOError - - class PyMockNonBlockWriterIO(MockNonBlockWriterIO, pyio.RawIOBase): - BlockingIOError = pyio.BlockingIOError - - - class IOTest(unittest.TestCase): - - def setUp(self): - support.unlink(support.TESTFN) - - def tearDown(self): - support.unlink(support.TESTFN) - - def write_ops(self, f): - self.assertEqual(f.write(b"blah."), 5) - f.truncate(0) - self.assertEqual(f.tell(), 5) - f.seek(0) - - self.assertEqual(f.write(b"blah."), 5) - self.assertEqual(f.seek(0), 0) - self.assertEqual(f.write(b"Hello."), 6) - self.assertEqual(f.tell(), 6) - self.assertEqual(f.seek(-1, 1), 5) - self.assertEqual(f.tell(), 5) - buffer = bytearray(b" world\n\n\n") - self.assertEqual(f.write(buffer), 9) - buffer[:] = b"*" * 9 # Overwrite our copy of the data - self.assertEqual(f.seek(0), 0) - self.assertEqual(f.write(b"h"), 1) - self.assertEqual(f.seek(-1, 2), 13) - self.assertEqual(f.tell(), 13) - - self.assertEqual(f.truncate(12), 12) - self.assertEqual(f.tell(), 13) - self.assertRaises(TypeError, f.seek, 0.0) - - def read_ops(self, f, buffered=False): - data = f.read(5) - self.assertEqual(data, b"hello") - data = byteslike(data) - self.assertEqual(f.readinto(data), 5) - self.assertEqual(bytes(data), b" worl") - data = bytearray(5) - self.assertEqual(f.readinto(data), 2) - self.assertEqual(len(data), 5) - self.assertEqual(data[:2], b"d\n") - self.assertEqual(f.seek(0), 0) - self.assertEqual(f.read(20), b"hello world\n") - self.assertEqual(f.read(1), b"") - self.assertEqual(f.readinto(byteslike(b"x")), 0) - self.assertEqual(f.seek(-6, 2), 6) - self.assertEqual(f.read(5), b"world") - self.assertEqual(f.read(0), b"") - self.assertEqual(f.readinto(byteslike()), 0) - self.assertEqual(f.seek(-6, 1), 5) - self.assertEqual(f.read(5), b" worl") - self.assertEqual(f.tell(), 10) - self.assertRaises(TypeError, f.seek, 0.0) - if buffered: - f.seek(0) - self.assertEqual(f.read(), b"hello world\n") - f.seek(6) - self.assertEqual(f.read(), b"world\n") - self.assertEqual(f.read(), b"") - f.seek(0) - data = byteslike(5) - self.assertEqual(f.readinto1(data), 5) - self.assertEqual(bytes(data), b"hello") - - LARGE = 2**31 - - def large_file_ops(self, f): - assert f.readable() - assert f.writable() - try: - self.assertEqual(f.seek(self.LARGE), self.LARGE) - except (OverflowError, ValueError): - self.skipTest("no largefile support") - self.assertEqual(f.tell(), self.LARGE) - self.assertEqual(f.write(b"xxx"), 3) - self.assertEqual(f.tell(), self.LARGE + 3) - self.assertEqual(f.seek(-1, 1), self.LARGE + 2) - self.assertEqual(f.truncate(), self.LARGE + 2) - self.assertEqual(f.tell(), self.LARGE + 2) - self.assertEqual(f.seek(0, 2), self.LARGE + 2) - self.assertEqual(f.truncate(self.LARGE + 1), self.LARGE + 1) - self.assertEqual(f.tell(), self.LARGE + 2) - self.assertEqual(f.seek(0, 2), self.LARGE + 1) - self.assertEqual(f.seek(-1, 2), self.LARGE) - self.assertEqual(f.read(2), b"x") - - def test_invalid_operations(self): - # Try writing on a file opened in read mode and vice-versa. - exc = self.UnsupportedOperation - for mode in ("w", "wb"): - with self.open(support.TESTFN, mode) as fp: - self.assertRaises(exc, fp.read) - self.assertRaises(exc, fp.readline) - with self.open(support.TESTFN, "wb", buffering=0) as fp: - self.assertRaises(exc, fp.read) - self.assertRaises(exc, fp.readline) - with self.open(support.TESTFN, "rb", buffering=0) as fp: - self.assertRaises(exc, fp.write, b"blah") - self.assertRaises(exc, fp.writelines, [b"blah\n"]) - with self.open(support.TESTFN, "rb") as fp: - self.assertRaises(exc, fp.write, b"blah") - self.assertRaises(exc, fp.writelines, [b"blah\n"]) - with self.open(support.TESTFN, "r") as fp: - self.assertRaises(exc, fp.write, "blah") - self.assertRaises(exc, fp.writelines, ["blah\n"]) - # Non-zero seeking from current or end pos - self.assertRaises(exc, fp.seek, 1, self.SEEK_CUR) - self.assertRaises(exc, fp.seek, -1, self.SEEK_END) - - def test_optional_abilities(self): - # Test for OSError when optional APIs are not supported - # The purpose of this test is to try fileno(), reading, writing and - # seeking operations with various objects that indicate they do not - # support these operations. - - def pipe_reader(): - [r, w] = os.pipe() - os.close(w) # So that read() is harmless - return self.FileIO(r, "r") - - def pipe_writer(): - [r, w] = os.pipe() - self.addCleanup(os.close, r) - # Guarantee that we can write into the pipe without blocking - thread = threading.Thread(target=os.read, args=(r, 100)) - thread.start() - self.addCleanup(thread.join) - return self.FileIO(w, "w") - - def buffered_reader(): - return self.BufferedReader(self.MockUnseekableIO()) - - def buffered_writer(): - return self.BufferedWriter(self.MockUnseekableIO()) - - def buffered_random(): - return self.BufferedRandom(self.BytesIO()) - - def buffered_rw_pair(): - return self.BufferedRWPair(self.MockUnseekableIO(), - self.MockUnseekableIO()) - - def text_reader(): - class UnseekableReader(self.MockUnseekableIO): - writable = self.BufferedIOBase.writable - write = self.BufferedIOBase.write - return self.TextIOWrapper(UnseekableReader(), "ascii") - - def text_writer(): - class UnseekableWriter(self.MockUnseekableIO): - readable = self.BufferedIOBase.readable - read = self.BufferedIOBase.read - return self.TextIOWrapper(UnseekableWriter(), "ascii") - - tests = ( - (pipe_reader, "fr"), (pipe_writer, "fw"), - (buffered_reader, "r"), (buffered_writer, "w"), - (buffered_random, "rws"), (buffered_rw_pair, "rw"), - (text_reader, "r"), (text_writer, "w"), - (self.BytesIO, "rws"), (self.StringIO, "rws"), - ) - for [test, abilities] in tests: - with self.subTest(test), test() as obj: - readable = "r" in abilities - self.assertEqual(obj.readable(), readable) - writable = "w" in abilities - self.assertEqual(obj.writable(), writable) - - if isinstance(obj, self.TextIOBase): - data = "3" - elif isinstance(obj, (self.BufferedIOBase, self.RawIOBase)): - data = b"3" - else: - self.fail("Unknown base class") - - if "f" in abilities: - obj.fileno() - else: - self.assertRaises(OSError, obj.fileno) - - if readable: - obj.read(1) - obj.read() - else: - self.assertRaises(OSError, obj.read, 1) - self.assertRaises(OSError, obj.read) - - if writable: - obj.write(data) - else: - self.assertRaises(OSError, obj.write, data) - - if sys.platform.startswith("win") and test in ( - pipe_reader, pipe_writer): - # Pipes seem to appear as seekable on Windows - continue - seekable = "s" in abilities - self.assertEqual(obj.seekable(), seekable) - - if seekable: - obj.tell() - obj.seek(0) - else: - self.assertRaises(OSError, obj.tell) - self.assertRaises(OSError, obj.seek, 0) - - if writable and seekable: - obj.truncate() - obj.truncate(0) - else: - self.assertRaises(OSError, obj.truncate) - self.assertRaises(OSError, obj.truncate, 0) - - def test_open_handles_NUL_chars(self): - fn_with_NUL = 'foo\0bar' - self.assertRaises(ValueError, self.open, fn_with_NUL, 'w') - - bytes_fn = bytes(fn_with_NUL, 'ascii') - with warnings.catch_warnings(): - warnings.simplefilter("ignore", DeprecationWarning) - self.assertRaises(ValueError, self.open, bytes_fn, 'w') - - def test_raw_file_io(self): - with self.open(support.TESTFN, "wb", buffering=0) as f: - self.assertEqual(f.readable(), False) - self.assertEqual(f.writable(), True) - self.assertEqual(f.seekable(), True) - self.write_ops(f) - with self.open(support.TESTFN, "rb", buffering=0) as f: - self.assertEqual(f.readable(), True) - self.assertEqual(f.writable(), False) - self.assertEqual(f.seekable(), True) - self.read_ops(f) - - def test_buffered_file_io(self): - with self.open(support.TESTFN, "wb") as f: - self.assertEqual(f.readable(), False) - self.assertEqual(f.writable(), True) - self.assertEqual(f.seekable(), True) - self.write_ops(f) - with self.open(support.TESTFN, "rb") as f: - self.assertEqual(f.readable(), True) - self.assertEqual(f.writable(), False) - self.assertEqual(f.seekable(), True) - self.read_ops(f, True) - - def test_readline(self): - with self.open(support.TESTFN, "wb") as f: - f.write(b"abc\ndef\nxyzzy\nfoo\x00bar\nanother line") - with self.open(support.TESTFN, "rb") as f: - self.assertEqual(f.readline(), b"abc\n") - self.assertEqual(f.readline(10), b"def\n") - self.assertEqual(f.readline(2), b"xy") - self.assertEqual(f.readline(4), b"zzy\n") - self.assertEqual(f.readline(), b"foo\x00bar\n") - self.assertEqual(f.readline(None), b"another line") - self.assertRaises(TypeError, f.readline, 5.3) - with self.open(support.TESTFN, "r") as f: - self.assertRaises(TypeError, f.readline, 5.3) - - def test_readline_nonsizeable(self): - # Issue #30061 - # Crash when readline() returns an object without __len__ - class R(self.IOBase): - def readline(self): - return None - self.assertRaises((TypeError, StopIteration), next, R()) - - def test_next_nonsizeable(self): - # Issue #30061 - # Crash when __next__() returns an object without __len__ - class R(self.IOBase): - def __next__(self): - return None - self.assertRaises(TypeError, R().readlines, 1) - - def test_raw_bytes_io(self): - f = self.BytesIO() - self.write_ops(f) - data = f.getvalue() - self.assertEqual(data, b"hello world\n") - f = self.BytesIO(data) - self.read_ops(f, True) - - def test_large_file_ops(self): - # On Windows and Mac OSX this test consumes large resources; It takes - # a long time to build the >2 GiB file and takes >2 GiB of disk space - # therefore the resource must be enabled to run this test. - if sys.platform[:3] == 'win' or sys.platform == 'darwin': - support.requires( - 'largefile', - 'test requires %s bytes and a long time to run' % self.LARGE) - with self.open(support.TESTFN, "w+b", 0) as f: - self.large_file_ops(f) - with self.open(support.TESTFN, "w+b") as f: - self.large_file_ops(f) - - def test_with_open(self): - for bufsize in (0, 100): - f = None - with self.open(support.TESTFN, "wb", bufsize) as f: - f.write(b"xxx") - self.assertEqual(f.closed, True) - f = None - try: - with self.open(support.TESTFN, "wb", bufsize) as f: - 1/0 - except ZeroDivisionError: - self.assertEqual(f.closed, True) - else: - self.fail("1/0 didn't raise an exception") - - # issue 5008 - def test_append_mode_tell(self): - with self.open(support.TESTFN, "wb") as f: - f.write(b"xxx") - with self.open(support.TESTFN, "ab", buffering=0) as f: - self.assertEqual(f.tell(), 3) - with self.open(support.TESTFN, "ab") as f: - self.assertEqual(f.tell(), 3) - with self.open(support.TESTFN, "a") as f: - self.assertGreater(f.tell(), 0) - - def test_destructor(self): - record = [] - class MyFileIO(self.FileIO): - def __del__(self): - record.append(1) - try: - f = super().__del__ - except AttributeError: - pass - else: - f() - def close(self): - record.append(2) - super().close() - def flush(self): - record.append(3) - super().flush() - with support.check_warnings(('', ResourceWarning)): - f = MyFileIO(support.TESTFN, "wb") - f.write(b"xxx") - del f - support.gc_collect() - self.assertEqual(record, [1, 2, 3]) - with self.open(support.TESTFN, "rb") as f: - self.assertEqual(f.read(), b"xxx") - - def _check_base_destructor(self, base): - record = [] - class MyIO(base): - def __init__(self): - # This exercises the availability of attributes on object - # destruction. - # (in the C version, close() is called by the tp_dealloc - # function, not by __del__) - self.on_del = 1 - self.on_close = 2 - self.on_flush = 3 - def __del__(self): - record.append(self.on_del) - try: - f = super().__del__ - except AttributeError: - pass - else: - f() - def close(self): - record.append(self.on_close) - super().close() - def flush(self): - record.append(self.on_flush) - super().flush() - f = MyIO() - del f - support.gc_collect() - self.assertEqual(record, [1, 2, 3]) - - def test_IOBase_destructor(self): - self._check_base_destructor(self.IOBase) - - def test_RawIOBase_destructor(self): - self._check_base_destructor(self.RawIOBase) - - def test_BufferedIOBase_destructor(self): - self._check_base_destructor(self.BufferedIOBase) - - def test_TextIOBase_destructor(self): - self._check_base_destructor(self.TextIOBase) - - def test_close_flushes(self): - with self.open(support.TESTFN, "wb") as f: - f.write(b"xxx") - with self.open(support.TESTFN, "rb") as f: - self.assertEqual(f.read(), b"xxx") - - def test_array_writes(self): - a = array.array('i', range(10)) - n = len(a.tobytes()) - def check(f): - with f: - self.assertEqual(f.write(a), n) - f.writelines((a,)) - check(self.BytesIO()) - check(self.FileIO(support.TESTFN, "w")) - check(self.BufferedWriter(self.MockRawIO())) - check(self.BufferedRandom(self.MockRawIO())) - check(self.BufferedRWPair(self.MockRawIO(), self.MockRawIO())) - - def test_closefd(self): - self.assertRaises(ValueError, self.open, support.TESTFN, 'w', - closefd=False) - - def test_read_closed(self): - with self.open(support.TESTFN, "w") as f: - f.write("egg\n") - with self.open(support.TESTFN, "r") as f: - file = self.open(f.fileno(), "r", closefd=False) - self.assertEqual(file.read(), "egg\n") - file.seek(0) - file.close() - self.assertRaises(ValueError, file.read) - with self.open(support.TESTFN, "rb") as f: - file = self.open(f.fileno(), "rb", closefd=False) - self.assertEqual(file.read()[:3], b"egg") - file.close() - self.assertRaises(ValueError, file.readinto, bytearray(1)) - - def test_no_closefd_with_filename(self): - # can't use closefd in combination with a file name - self.assertRaises(ValueError, self.open, support.TESTFN, "r", closefd=False) - - def test_closefd_attr(self): - with self.open(support.TESTFN, "wb") as f: - f.write(b"egg\n") - with self.open(support.TESTFN, "r") as f: - self.assertEqual(f.buffer.raw.closefd, True) - file = self.open(f.fileno(), "r", closefd=False) - self.assertEqual(file.buffer.raw.closefd, False) - - def test_garbage_collection(self): - # FileIO objects are collected, and collecting them flushes - # all data to disk. - with support.check_warnings(('', ResourceWarning)): - f = self.FileIO(support.TESTFN, "wb") - f.write(b"abcxxx") - f.f = f - wr = weakref.ref(f) - del f - support.gc_collect() - self.assertIsNone(wr(), wr) - with self.open(support.TESTFN, "rb") as f: - self.assertEqual(f.read(), b"abcxxx") - - def test_unbounded_file(self): - # Issue #1174606: reading from an unbounded stream such as /dev/zero. - zero = "/dev/zero" - if not os.path.exists(zero): - self.skipTest("{0} does not exist".format(zero)) - if sys.maxsize > 0x7FFFFFFF: - self.skipTest("test can only run in a 32-bit address space") - if support.real_max_memuse < support._2G: - self.skipTest("test requires at least 2 GiB of memory") - with self.open(zero, "rb", buffering=0) as f: - self.assertRaises(OverflowError, f.read) - with self.open(zero, "rb") as f: - self.assertRaises(OverflowError, f.read) - with self.open(zero, "r") as f: - self.assertRaises(OverflowError, f.read) - - def check_flush_error_on_close(self, *args, **kwargs): - # Test that the file is closed despite failed flush - # and that flush() is called before file closed. - f = self.open(*args, **kwargs) - closed = [] - def bad_flush(): - closed[:] = [f.closed] - raise OSError() - f.flush = bad_flush - self.assertRaises(OSError, f.close) # exception not swallowed - self.assertTrue(f.closed) - self.assertTrue(closed) # flush() called - self.assertFalse(closed[0]) # flush() called before file closed - f.flush = lambda: None # break reference loop - - def test_flush_error_on_close(self): - # raw file - # Issue #5700: io.FileIO calls flush() after file closed - self.check_flush_error_on_close(support.TESTFN, 'wb', buffering=0) - fd = os.open(support.TESTFN, os.O_WRONLY|os.O_CREAT) - self.check_flush_error_on_close(fd, 'wb', buffering=0) - fd = os.open(support.TESTFN, os.O_WRONLY|os.O_CREAT) - self.check_flush_error_on_close(fd, 'wb', buffering=0, closefd=False) - os.close(fd) - # buffered io - self.check_flush_error_on_close(support.TESTFN, 'wb') - fd = os.open(support.TESTFN, os.O_WRONLY|os.O_CREAT) - self.check_flush_error_on_close(fd, 'wb') - fd = os.open(support.TESTFN, os.O_WRONLY|os.O_CREAT) - self.check_flush_error_on_close(fd, 'wb', closefd=False) - os.close(fd) - # text io - self.check_flush_error_on_close(support.TESTFN, 'w') - fd = os.open(support.TESTFN, os.O_WRONLY|os.O_CREAT) - self.check_flush_error_on_close(fd, 'w') - fd = os.open(support.TESTFN, os.O_WRONLY|os.O_CREAT) - self.check_flush_error_on_close(fd, 'w', closefd=False) - os.close(fd) - - def test_multi_close(self): - f = self.open(support.TESTFN, "wb", buffering=0) - f.close() - f.close() - f.close() - self.assertRaises(ValueError, f.flush) - - def test_RawIOBase_read(self): - # Exercise the default limited RawIOBase.read(n) implementation (which - # calls readinto() internally). - rawio = self.MockRawIOWithoutRead((b"abc", b"d", None, b"efg", None)) - self.assertEqual(rawio.read(2), b"ab") - self.assertEqual(rawio.read(2), b"c") - self.assertEqual(rawio.read(2), b"d") - self.assertEqual(rawio.read(2), None) - self.assertEqual(rawio.read(2), b"ef") - self.assertEqual(rawio.read(2), b"g") - self.assertEqual(rawio.read(2), None) - self.assertEqual(rawio.read(2), b"") - - def test_types_have_dict(self): - test = ( - self.IOBase(), - self.RawIOBase(), - self.TextIOBase(), - self.StringIO(), - self.BytesIO() - ) - for obj in test: - self.assertTrue(hasattr(obj, "__dict__")) - - def test_opener(self): - with self.open(support.TESTFN, "w") as f: - f.write("egg\n") - fd = os.open(support.TESTFN, os.O_RDONLY) - def opener(path, flags): - return fd - with self.open("non-existent", "r", opener=opener) as f: - self.assertEqual(f.read(), "egg\n") - - def test_bad_opener_negative_1(self): - # Issue #27066. - def badopener(fname, flags): - return -1 - with self.assertRaises(ValueError) as cm: - open('non-existent', 'r', opener=badopener) - self.assertEqual(str(cm.exception), 'opener returned -1') - - def test_bad_opener_other_negative(self): - # Issue #27066. - def badopener(fname, flags): - return -2 - with self.assertRaises(ValueError) as cm: - open('non-existent', 'r', opener=badopener) - self.assertEqual(str(cm.exception), 'opener returned -2') - - def test_fileio_closefd(self): - # Issue #4841 - with self.open(__file__, 'rb') as f1, \ - self.open(__file__, 'rb') as f2: - fileio = self.FileIO(f1.fileno(), closefd=False) - # .__init__() must not close f1 - fileio.__init__(f2.fileno(), closefd=False) - f1.readline() - # .close() must not close f2 - fileio.close() - f2.readline() - - def test_nonbuffered_textio(self): - with support.check_no_resource_warning(self): - with self.assertRaises(ValueError): - self.open(support.TESTFN, 'w', buffering=0) - - def test_invalid_newline(self): - with support.check_no_resource_warning(self): - with self.assertRaises(ValueError): - self.open(support.TESTFN, 'w', newline='invalid') - - def test_buffered_readinto_mixin(self): - # Test the implementation provided by BufferedIOBase - class Stream(self.BufferedIOBase): - def read(self, size): - return b"12345" - read1 = read - stream = Stream() - for method in ("readinto", "readinto1"): - with self.subTest(method): - buffer = byteslike(5) - self.assertEqual(getattr(stream, method)(buffer), 5) - self.assertEqual(bytes(buffer), b"12345") - - def test_fspath_support(self): - def check_path_succeeds(path): - with self.open(path, "w") as f: - f.write("egg\n") - - with self.open(path, "r") as f: - self.assertEqual(f.read(), "egg\n") - - check_path_succeeds(FakePath(support.TESTFN)) - check_path_succeeds(FakePath(os.fsencode(support.TESTFN))) - - with self.open(support.TESTFN, "w") as f: - bad_path = FakePath(f.fileno()) - with self.assertRaises(TypeError): - self.open(bad_path, 'w') - - bad_path = FakePath(None) - with self.assertRaises(TypeError): - self.open(bad_path, 'w') - - bad_path = FakePath(FloatingPointError) - with self.assertRaises(FloatingPointError): - self.open(bad_path, 'w') - - # ensure that refcounting is correct with some error conditions - with self.assertRaisesRegex(ValueError, 'read/write/append mode'): - self.open(FakePath(support.TESTFN), 'rwxa') - - def test_RawIOBase_readall(self): - # Exercise the default unlimited RawIOBase.read() and readall() - # implementations. - rawio = self.MockRawIOWithoutRead((b"abc", b"d", b"efg")) - self.assertEqual(rawio.read(), b"abcdefg") - rawio = self.MockRawIOWithoutRead((b"abc", b"d", b"efg")) - self.assertEqual(rawio.readall(), b"abcdefg") - - def test_BufferedIOBase_readinto(self): - # Exercise the default BufferedIOBase.readinto() and readinto1() - # implementations (which call read() or read1() internally). - class Reader(self.BufferedIOBase): - def __init__(self, avail): - self.avail = avail - def read(self, size): - result = self.avail[:size] - self.avail = self.avail[size:] - return result - def read1(self, size): - """Returns no more than 5 bytes at once""" - return self.read(min(size, 5)) - tests = ( - # (test method, total data available, read buffer size, expected - # read size) - ("readinto", 10, 5, 5), - ("readinto", 10, 6, 6), # More than read1() can return - ("readinto", 5, 6, 5), # Buffer larger than total available - ("readinto", 6, 7, 6), - ("readinto", 10, 0, 0), # Empty buffer - ("readinto1", 10, 5, 5), # Result limited to single read1() call - ("readinto1", 10, 6, 5), # Buffer larger than read1() can return - ("readinto1", 5, 6, 5), # Buffer larger than total available - ("readinto1", 6, 7, 5), - ("readinto1", 10, 0, 0), # Empty buffer - ) - UNUSED_BYTE = 0x81 - for test in tests: - with self.subTest(test): - method, avail, request, result = test - reader = Reader(bytes(range(avail))) - buffer = bytearray((UNUSED_BYTE,) * request) - method = getattr(reader, method) - self.assertEqual(method(buffer), result) - self.assertEqual(len(buffer), request) - self.assertSequenceEqual(buffer[:result], range(result)) - unused = (UNUSED_BYTE,) * (request - result) - self.assertSequenceEqual(buffer[result:], unused) - self.assertEqual(len(reader.avail), avail - result) - - def test_close_assert(self): - class R(self.IOBase): - def __setattr__(self, name, value): - pass - def flush(self): - raise OSError() - f = R() - # This would cause an assertion failure. - self.assertRaises(OSError, f.close) - - # Silence destructor error - R.flush = lambda self: None - - - class CIOTest(IOTest): - - def test_IOBase_finalize(self): - # Issue #12149: segmentation fault on _PyIOBase_finalize when both a - # class which inherits IOBase and an object of this class are caught - # in a reference cycle and close() is already in the method cache. - class MyIO(self.IOBase): - def close(self): - pass - - # create an instance to populate the method cache - MyIO() - obj = MyIO() - obj.obj = obj - wr = weakref.ref(obj) - del MyIO - del obj - support.gc_collect() - self.assertIsNone(wr(), wr) - - class PyIOTest(IOTest): - pass - - - @support.cpython_only - class APIMismatchTest(unittest.TestCase): - - def test_RawIOBase_io_in_pyio_match(self): - """Test that pyio RawIOBase class has all c RawIOBase methods""" - mismatch = support.detect_api_mismatch(pyio.RawIOBase, io.RawIOBase, - ignore=('__weakref__',)) - self.assertEqual(mismatch, set(), msg='Python RawIOBase does not have all C RawIOBase methods') - - def test_RawIOBase_pyio_in_io_match(self): - """Test that c RawIOBase class has all pyio RawIOBase methods""" - mismatch = support.detect_api_mismatch(io.RawIOBase, pyio.RawIOBase) - self.assertEqual(mismatch, set(), msg='C RawIOBase does not have all Python RawIOBase methods') - - - class CommonBufferedTests: - # Tests common to BufferedReader, BufferedWriter and BufferedRandom - - def test_detach(self): - raw = self.MockRawIO() - buf = self.tp(raw) - self.assertIs(buf.detach(), raw) - self.assertRaises(ValueError, buf.detach) - - repr(buf) # Should still work - - def test_fileno(self): - rawio = self.MockRawIO() - bufio = self.tp(rawio) - - self.assertEqual(42, bufio.fileno()) - - def test_invalid_args(self): - rawio = self.MockRawIO() - bufio = self.tp(rawio) - # Invalid whence - self.assertRaises(ValueError, bufio.seek, 0, -1) - self.assertRaises(ValueError, bufio.seek, 0, 9) - - def test_override_destructor(self): - tp = self.tp - record = [] - class MyBufferedIO(tp): - def __del__(self): - record.append(1) - try: - f = super().__del__ - except AttributeError: - pass - else: - f() - def close(self): - record.append(2) - super().close() - def flush(self): - record.append(3) - super().flush() - rawio = self.MockRawIO() - bufio = MyBufferedIO(rawio) - del bufio - support.gc_collect() - self.assertEqual(record, [1, 2, 3]) - - def test_context_manager(self): - # Test usability as a context manager - rawio = self.MockRawIO() - bufio = self.tp(rawio) - def _with(): - with bufio: - pass - _with() - # bufio should now be closed, and using it a second time should raise - # a ValueError. - self.assertRaises(ValueError, _with) - - def test_error_through_destructor(self): - # Test that the exception state is not modified by a destructor, - # even if close() fails. - rawio = self.CloseFailureIO() - with support.catch_unraisable_exception() as cm: - with self.assertRaises(AttributeError): - self.tp(rawio).xyzzy - - if not IOBASE_EMITS_UNRAISABLE: - self.assertIsNone(cm.unraisable) - elif cm.unraisable is not None: - self.assertEqual(cm.unraisable.exc_type, OSError) - - def test_repr(self): - raw = self.MockRawIO() - b = self.tp(raw) - clsname = r"(%s\.)?%s" % (self.tp.__module__, self.tp.__qualname__) - self.assertRegex(repr(b), "<%s>" % clsname) - raw.name = "dummy" - self.assertRegex(repr(b), "<%s name='dummy'>" % clsname) - raw.name = b"dummy" - self.assertRegex(repr(b), "<%s name=b'dummy'>" % clsname) - - def test_recursive_repr(self): - # Issue #25455 - raw = self.MockRawIO() - b = self.tp(raw) - with support.swap_attr(raw, 'name', b): - try: - repr(b) # Should not crash - except RuntimeError: - pass - - def test_flush_error_on_close(self): - # Test that buffered file is closed despite failed flush - # and that flush() is called before file closed. - raw = self.MockRawIO() - closed = [] - def bad_flush(): - closed[:] = [b.closed, raw.closed] - raise OSError() - raw.flush = bad_flush - b = self.tp(raw) - self.assertRaises(OSError, b.close) # exception not swallowed - self.assertTrue(b.closed) - self.assertTrue(raw.closed) - self.assertTrue(closed) # flush() called - self.assertFalse(closed[0]) # flush() called before file closed - self.assertFalse(closed[1]) - raw.flush = lambda: None # break reference loop - - def test_close_error_on_close(self): - raw = self.MockRawIO() - def bad_flush(): - raise OSError('flush') - def bad_close(): - raise OSError('close') - raw.close = bad_close - b = self.tp(raw) - b.flush = bad_flush - with self.assertRaises(OSError) as err: # exception not swallowed - b.close() - self.assertEqual(err.exception.args, ('close',)) - self.assertIsInstance(err.exception.__context__, OSError) - self.assertEqual(err.exception.__context__.args, ('flush',)) - self.assertFalse(b.closed) - - # Silence destructor error - raw.close = lambda: None - b.flush = lambda: None - - def test_nonnormalized_close_error_on_close(self): - # Issue #21677 - raw = self.MockRawIO() - def bad_flush(): - raise non_existing_flush - def bad_close(): - raise non_existing_close - raw.close = bad_close - b = self.tp(raw) - b.flush = bad_flush - with self.assertRaises(NameError) as err: # exception not swallowed - b.close() - self.assertIn('non_existing_close', str(err.exception)) - self.assertIsInstance(err.exception.__context__, NameError) - self.assertIn('non_existing_flush', str(err.exception.__context__)) - self.assertFalse(b.closed) - - # Silence destructor error - b.flush = lambda: None - raw.close = lambda: None - - def test_multi_close(self): - raw = self.MockRawIO() - b = self.tp(raw) - b.close() - b.close() - b.close() - self.assertRaises(ValueError, b.flush) - - def test_unseekable(self): - bufio = self.tp(self.MockUnseekableIO(b"A" * 10)) - self.assertRaises(self.UnsupportedOperation, bufio.tell) - self.assertRaises(self.UnsupportedOperation, bufio.seek, 0) - - def test_readonly_attributes(self): - raw = self.MockRawIO() - buf = self.tp(raw) - x = self.MockRawIO() - with self.assertRaises(AttributeError): - buf.raw = x - - - class SizeofTest: - - @support.cpython_only - def test_sizeof(self): - bufsize1 = 4096 - bufsize2 = 8192 - rawio = self.MockRawIO() - bufio = self.tp(rawio, buffer_size=bufsize1) - size = sys.getsizeof(bufio) - bufsize1 - rawio = self.MockRawIO() - bufio = self.tp(rawio, buffer_size=bufsize2) - self.assertEqual(sys.getsizeof(bufio), size + bufsize2) - - @support.cpython_only - def test_buffer_freeing(self) : - bufsize = 4096 - rawio = self.MockRawIO() - bufio = self.tp(rawio, buffer_size=bufsize) - size = sys.getsizeof(bufio) - bufsize - bufio.close() - self.assertEqual(sys.getsizeof(bufio), size) - - class BufferedReaderTest(unittest.TestCase, CommonBufferedTests): - read_mode = "rb" - - def test_constructor(self): - rawio = self.MockRawIO([b"abc"]) - bufio = self.tp(rawio) - bufio.__init__(rawio) - bufio.__init__(rawio, buffer_size=1024) - bufio.__init__(rawio, buffer_size=16) - self.assertEqual(b"abc", bufio.read()) - self.assertRaises(ValueError, bufio.__init__, rawio, buffer_size=0) - self.assertRaises(ValueError, bufio.__init__, rawio, buffer_size=-16) - self.assertRaises(ValueError, bufio.__init__, rawio, buffer_size=-1) - rawio = self.MockRawIO([b"abc"]) - bufio.__init__(rawio) - self.assertEqual(b"abc", bufio.read()) - - def test_uninitialized(self): - bufio = self.tp.__new__(self.tp) - del bufio - bufio = self.tp.__new__(self.tp) - self.assertRaisesRegex((ValueError, AttributeError), - 'uninitialized|has no attribute', - bufio.read, 0) - bufio.__init__(self.MockRawIO()) - self.assertEqual(bufio.read(0), b'') - - def test_read(self): - for arg in (None, 7): - rawio = self.MockRawIO((b"abc", b"d", b"efg")) - bufio = self.tp(rawio) - self.assertEqual(b"abcdefg", bufio.read(arg)) - # Invalid args - self.assertRaises(ValueError, bufio.read, -2) - - def test_read1(self): - rawio = self.MockRawIO((b"abc", b"d", b"efg")) - bufio = self.tp(rawio) - self.assertEqual(b"a", bufio.read(1)) - self.assertEqual(b"b", bufio.read1(1)) - self.assertEqual(rawio._reads, 1) - self.assertEqual(b"", bufio.read1(0)) - self.assertEqual(b"c", bufio.read1(100)) - self.assertEqual(rawio._reads, 1) - self.assertEqual(b"d", bufio.read1(100)) - self.assertEqual(rawio._reads, 2) - self.assertEqual(b"efg", bufio.read1(100)) - self.assertEqual(rawio._reads, 3) - self.assertEqual(b"", bufio.read1(100)) - self.assertEqual(rawio._reads, 4) - - def test_read1_arbitrary(self): - rawio = self.MockRawIO((b"abc", b"d", b"efg")) - bufio = self.tp(rawio) - self.assertEqual(b"a", bufio.read(1)) - self.assertEqual(b"bc", bufio.read1()) - self.assertEqual(b"d", bufio.read1()) - self.assertEqual(b"efg", bufio.read1(-1)) - self.assertEqual(rawio._reads, 3) - self.assertEqual(b"", bufio.read1()) - self.assertEqual(rawio._reads, 4) - - def test_readinto(self): - rawio = self.MockRawIO((b"abc", b"d", b"efg")) - bufio = self.tp(rawio) - b = bytearray(2) - self.assertEqual(bufio.readinto(b), 2) - self.assertEqual(b, b"ab") - self.assertEqual(bufio.readinto(b), 2) - self.assertEqual(b, b"cd") - self.assertEqual(bufio.readinto(b), 2) - self.assertEqual(b, b"ef") - self.assertEqual(bufio.readinto(b), 1) - self.assertEqual(b, b"gf") - self.assertEqual(bufio.readinto(b), 0) - self.assertEqual(b, b"gf") - rawio = self.MockRawIO((b"abc", None)) - bufio = self.tp(rawio) - self.assertEqual(bufio.readinto(b), 2) - self.assertEqual(b, b"ab") - self.assertEqual(bufio.readinto(b), 1) - self.assertEqual(b, b"cb") - - def test_readinto1(self): - buffer_size = 10 - rawio = self.MockRawIO((b"abc", b"de", b"fgh", b"jkl")) - bufio = self.tp(rawio, buffer_size=buffer_size) - b = bytearray(2) - self.assertEqual(bufio.peek(3), b'abc') - self.assertEqual(rawio._reads, 1) - self.assertEqual(bufio.readinto1(b), 2) - self.assertEqual(b, b"ab") - self.assertEqual(rawio._reads, 1) - self.assertEqual(bufio.readinto1(b), 1) - self.assertEqual(b[:1], b"c") - self.assertEqual(rawio._reads, 1) - self.assertEqual(bufio.readinto1(b), 2) - self.assertEqual(b, b"de") - self.assertEqual(rawio._reads, 2) - b = bytearray(2*buffer_size) - self.assertEqual(bufio.peek(3), b'fgh') - self.assertEqual(rawio._reads, 3) - self.assertEqual(bufio.readinto1(b), 6) - self.assertEqual(b[:6], b"fghjkl") - self.assertEqual(rawio._reads, 4) - - def test_readinto_array(self): - buffer_size = 60 - data = b"a" * 26 - rawio = self.MockRawIO((data,)) - bufio = self.tp(rawio, buffer_size=buffer_size) - - # Create an array with element size > 1 byte - b = array.array('i', b'x' * 32) - assert len(b) != 16 - - # Read into it. We should get as many *bytes* as we can fit into b - # (which is more than the number of elements) - n = bufio.readinto(b) - self.assertGreater(n, len(b)) - - # Check that old contents of b are preserved - bm = memoryview(b).cast('B') - self.assertLess(n, len(bm)) - self.assertEqual(bm[:n], data[:n]) - self.assertEqual(bm[n:], b'x' * (len(bm[n:]))) - - def test_readinto1_array(self): - buffer_size = 60 - data = b"a" * 26 - rawio = self.MockRawIO((data,)) - bufio = self.tp(rawio, buffer_size=buffer_size) - - # Create an array with element size > 1 byte - b = array.array('i', b'x' * 32) - assert len(b) != 16 - - # Read into it. We should get as many *bytes* as we can fit into b - # (which is more than the number of elements) - n = bufio.readinto1(b) - self.assertGreater(n, len(b)) - - # Check that old contents of b are preserved - bm = memoryview(b).cast('B') - self.assertLess(n, len(bm)) - self.assertEqual(bm[:n], data[:n]) - self.assertEqual(bm[n:], b'x' * (len(bm[n:]))) - - def test_readlines(self): - def bufio(): - rawio = self.MockRawIO((b"abc\n", b"d\n", b"ef")) - return self.tp(rawio) - self.assertEqual(bufio().readlines(), [b"abc\n", b"d\n", b"ef"]) - self.assertEqual(bufio().readlines(5), [b"abc\n", b"d\n"]) - self.assertEqual(bufio().readlines(None), [b"abc\n", b"d\n", b"ef"]) - - def test_buffering(self): - data = b"abcdefghi" - dlen = len(data) - - tests = [ - [ 100, [ 3, 1, 4, 8 ], [ dlen, 0 ] ], - [ 100, [ 3, 3, 3], [ dlen ] ], - [ 4, [ 1, 2, 4, 2 ], [ 4, 4, 1 ] ], - ] - - for bufsize, buf_read_sizes, raw_read_sizes in tests: - rawio = self.MockFileIO(data) - bufio = self.tp(rawio, buffer_size=bufsize) - pos = 0 - for nbytes in buf_read_sizes: - self.assertEqual(bufio.read(nbytes), data[pos:pos+nbytes]) - pos += nbytes - # this is mildly implementation-dependent - self.assertEqual(rawio.read_history, raw_read_sizes) - - def test_read_non_blocking(self): - # Inject some None's in there to simulate EWOULDBLOCK - rawio = self.MockRawIO((b"abc", b"d", None, b"efg", None, None, None)) - bufio = self.tp(rawio) - self.assertEqual(b"abcd", bufio.read(6)) - self.assertEqual(b"e", bufio.read(1)) - self.assertEqual(b"fg", bufio.read()) - self.assertEqual(b"", bufio.peek(1)) - self.assertIsNone(bufio.read()) - self.assertEqual(b"", bufio.read()) - - rawio = self.MockRawIO((b"a", None, None)) - self.assertEqual(b"a", rawio.readall()) - self.assertIsNone(rawio.readall()) - - def test_read_past_eof(self): - rawio = self.MockRawIO((b"abc", b"d", b"efg")) - bufio = self.tp(rawio) - - self.assertEqual(b"abcdefg", bufio.read(9000)) - - def test_read_all(self): - rawio = self.MockRawIO((b"abc", b"d", b"efg")) - bufio = self.tp(rawio) - - self.assertEqual(b"abcdefg", bufio.read()) - - @support.requires_resource('cpu') - def test_threads(self): - try: - # Write out many bytes with exactly the same number of 0's, - # 1's... 255's. This will help us check that concurrent reading - # doesn't duplicate or forget contents. - N = 1000 - l = list(range(256)) * N - random.shuffle(l) - s = bytes(bytearray(l)) - with self.open(support.TESTFN, "wb") as f: - f.write(s) - with self.open(support.TESTFN, self.read_mode, buffering=0) as raw: - bufio = self.tp(raw, 8) - errors = [] - results = [] - def f(): - try: - # Intra-buffer read then buffer-flushing read - for n in cycle([1, 19]): - s = bufio.read(n) - if not s: - break - # list.append() is atomic - results.append(s) - except Exception as e: - errors.append(e) - raise - threads = [threading.Thread(target=f) for x in range(20)] - with support.start_threads(threads): - time.sleep(0.02) # yield - self.assertFalse(errors, - "the following exceptions were caught: %r" % errors) - s = b''.join(results) - for i in range(256): - c = bytes(bytearray([i])) - self.assertEqual(s.count(c), N) - finally: - support.unlink(support.TESTFN) - - def test_unseekable(self): - bufio = self.tp(self.MockUnseekableIO(b"A" * 10)) - self.assertRaises(self.UnsupportedOperation, bufio.tell) - self.assertRaises(self.UnsupportedOperation, bufio.seek, 0) - bufio.read(1) - self.assertRaises(self.UnsupportedOperation, bufio.seek, 0) - self.assertRaises(self.UnsupportedOperation, bufio.tell) - - def test_misbehaved_io(self): - rawio = self.MisbehavedRawIO((b"abc", b"d", b"efg")) - bufio = self.tp(rawio) - self.assertRaises(OSError, bufio.seek, 0) - self.assertRaises(OSError, bufio.tell) - - # Silence destructor error - bufio.close = lambda: None - - def test_no_extraneous_read(self): - # Issue #9550; when the raw IO object has satisfied the read request, - # we should not issue any additional reads, otherwise it may block - # (e.g. socket). - bufsize = 16 - for n in (2, bufsize - 1, bufsize, bufsize + 1, bufsize * 2): - rawio = self.MockRawIO([b"x" * n]) - bufio = self.tp(rawio, bufsize) - self.assertEqual(bufio.read(n), b"x" * n) - # Simple case: one raw read is enough to satisfy the request. - self.assertEqual(rawio._extraneous_reads, 0, - "failed for {}: {} != 0".format(n, rawio._extraneous_reads)) - # A more complex case where two raw reads are needed to satisfy - # the request. - rawio = self.MockRawIO([b"x" * (n - 1), b"x"]) - bufio = self.tp(rawio, bufsize) - self.assertEqual(bufio.read(n), b"x" * n) - self.assertEqual(rawio._extraneous_reads, 0, - "failed for {}: {} != 0".format(n, rawio._extraneous_reads)) - - def test_read_on_closed(self): - # Issue #23796 - b = io.BufferedReader(io.BytesIO(b"12")) - b.read(1) - b.close() - self.assertRaises(ValueError, b.peek) - self.assertRaises(ValueError, b.read1, 1) - - - class CBufferedReaderTest(BufferedReaderTest, SizeofTest): - tp = io.BufferedReader - - @unittest.skipIf(MEMORY_SANITIZER, "MSan defaults to crashing " - "instead of returning NULL for malloc failure.") - def test_constructor(self): - BufferedReaderTest.test_constructor(self) - # The allocation can succeed on 32-bit builds, e.g. with more - # than 2 GiB RAM and a 64-bit kernel. - if sys.maxsize > 0x7FFFFFFF: - rawio = self.MockRawIO() - bufio = self.tp(rawio) - self.assertRaises((OverflowError, MemoryError, ValueError), - bufio.__init__, rawio, sys.maxsize) - - def test_initialization(self): - rawio = self.MockRawIO([b"abc"]) - bufio = self.tp(rawio) - self.assertRaises(ValueError, bufio.__init__, rawio, buffer_size=0) - self.assertRaises(ValueError, bufio.read) - self.assertRaises(ValueError, bufio.__init__, rawio, buffer_size=-16) - self.assertRaises(ValueError, bufio.read) - self.assertRaises(ValueError, bufio.__init__, rawio, buffer_size=-1) - self.assertRaises(ValueError, bufio.read) - - def test_misbehaved_io_read(self): - rawio = self.MisbehavedRawIO((b"abc", b"d", b"efg")) - bufio = self.tp(rawio) - # _pyio.BufferedReader seems to implement reading different, so that - # checking this is not so easy. - self.assertRaises(OSError, bufio.read, 10) - - def test_garbage_collection(self): - # C BufferedReader objects are collected. - # The Python version has __del__, so it ends into gc.garbage instead - self.addCleanup(support.unlink, support.TESTFN) - with support.check_warnings(('', ResourceWarning)): - rawio = self.FileIO(support.TESTFN, "w+b") - f = self.tp(rawio) - f.f = f - wr = weakref.ref(f) - del f - support.gc_collect() - self.assertIsNone(wr(), wr) - - def test_args_error(self): - # Issue #17275 - with self.assertRaisesRegex(TypeError, "BufferedReader"): - self.tp(io.BytesIO(), 1024, 1024, 1024) - - - class PyBufferedReaderTest(BufferedReaderTest): - tp = pyio.BufferedReader - - - class BufferedWriterTest(unittest.TestCase, CommonBufferedTests): - write_mode = "wb" - - def test_constructor(self): - rawio = self.MockRawIO() - bufio = self.tp(rawio) - bufio.__init__(rawio) - bufio.__init__(rawio, buffer_size=1024) - bufio.__init__(rawio, buffer_size=16) - self.assertEqual(3, bufio.write(b"abc")) - bufio.flush() - self.assertRaises(ValueError, bufio.__init__, rawio, buffer_size=0) - self.assertRaises(ValueError, bufio.__init__, rawio, buffer_size=-16) - self.assertRaises(ValueError, bufio.__init__, rawio, buffer_size=-1) - bufio.__init__(rawio) - self.assertEqual(3, bufio.write(b"ghi")) - bufio.flush() - self.assertEqual(b"".join(rawio._write_stack), b"abcghi") - - def test_uninitialized(self): - bufio = self.tp.__new__(self.tp) - del bufio - bufio = self.tp.__new__(self.tp) - self.assertRaisesRegex((ValueError, AttributeError), - 'uninitialized|has no attribute', - bufio.write, b'') - bufio.__init__(self.MockRawIO()) - self.assertEqual(bufio.write(b''), 0) - - def test_detach_flush(self): - raw = self.MockRawIO() - buf = self.tp(raw) - buf.write(b"howdy!") - self.assertFalse(raw._write_stack) - buf.detach() - self.assertEqual(raw._write_stack, [b"howdy!"]) - - def test_write(self): - # Write to the buffered IO but don't overflow the buffer. - writer = self.MockRawIO() - bufio = self.tp(writer, 8) - bufio.write(b"abc") - self.assertFalse(writer._write_stack) - buffer = bytearray(b"def") - bufio.write(buffer) - buffer[:] = b"***" # Overwrite our copy of the data - bufio.flush() - self.assertEqual(b"".join(writer._write_stack), b"abcdef") - - def test_write_overflow(self): - writer = self.MockRawIO() - bufio = self.tp(writer, 8) - contents = b"abcdefghijklmnop" - for n in range(0, len(contents), 3): - bufio.write(contents[n:n+3]) - flushed = b"".join(writer._write_stack) - # At least (total - 8) bytes were implicitly flushed, perhaps more - # depending on the implementation. - self.assertTrue(flushed.startswith(contents[:-8]), flushed) - - def check_writes(self, intermediate_func): - # Lots of writes, test the flushed output is as expected. - contents = bytes(range(256)) * 1000 - n = 0 - writer = self.MockRawIO() - bufio = self.tp(writer, 13) - # Generator of write sizes: repeat each N 15 times then proceed to N+1 - def gen_sizes(): - for size in count(1): - for i in range(15): - yield size - sizes = gen_sizes() - while n < len(contents): - size = min(next(sizes), len(contents) - n) - self.assertEqual(bufio.write(contents[n:n+size]), size) - intermediate_func(bufio) - n += size - bufio.flush() - self.assertEqual(contents, b"".join(writer._write_stack)) - - def test_writes(self): - self.check_writes(lambda bufio: None) - - def test_writes_and_flushes(self): - self.check_writes(lambda bufio: bufio.flush()) - - def test_writes_and_seeks(self): - def _seekabs(bufio): - pos = bufio.tell() - bufio.seek(pos + 1, 0) - bufio.seek(pos - 1, 0) - bufio.seek(pos, 0) - self.check_writes(_seekabs) - def _seekrel(bufio): - pos = bufio.seek(0, 1) - bufio.seek(+1, 1) - bufio.seek(-1, 1) - bufio.seek(pos, 0) - self.check_writes(_seekrel) - - def test_writes_and_truncates(self): - self.check_writes(lambda bufio: bufio.truncate(bufio.tell())) - - def test_write_non_blocking(self): - raw = self.MockNonBlockWriterIO() - bufio = self.tp(raw, 8) - - self.assertEqual(bufio.write(b"abcd"), 4) - self.assertEqual(bufio.write(b"efghi"), 5) - # 1 byte will be written, the rest will be buffered - raw.block_on(b"k") - self.assertEqual(bufio.write(b"jklmn"), 5) - - # 8 bytes will be written, 8 will be buffered and the rest will be lost - raw.block_on(b"0") - try: - bufio.write(b"opqrwxyz0123456789") - except self.BlockingIOError as e: - written = e.characters_written - else: - self.fail("BlockingIOError should have been raised") - self.assertEqual(written, 16) - self.assertEqual(raw.pop_written(), - b"abcdefghijklmnopqrwxyz") - - self.assertEqual(bufio.write(b"ABCDEFGHI"), 9) - s = raw.pop_written() - # Previously buffered bytes were flushed - self.assertTrue(s.startswith(b"01234567A"), s) - - def test_write_and_rewind(self): - raw = io.BytesIO() - bufio = self.tp(raw, 4) - self.assertEqual(bufio.write(b"abcdef"), 6) - self.assertEqual(bufio.tell(), 6) - bufio.seek(0, 0) - self.assertEqual(bufio.write(b"XY"), 2) - bufio.seek(6, 0) - self.assertEqual(raw.getvalue(), b"XYcdef") - self.assertEqual(bufio.write(b"123456"), 6) - bufio.flush() - self.assertEqual(raw.getvalue(), b"XYcdef123456") - - def test_flush(self): - writer = self.MockRawIO() - bufio = self.tp(writer, 8) - bufio.write(b"abc") - bufio.flush() - self.assertEqual(b"abc", writer._write_stack[0]) - - def test_writelines(self): - l = [b'ab', b'cd', b'ef'] - writer = self.MockRawIO() - bufio = self.tp(writer, 8) - bufio.writelines(l) - bufio.flush() - self.assertEqual(b''.join(writer._write_stack), b'abcdef') - - def test_writelines_userlist(self): - l = UserList([b'ab', b'cd', b'ef']) - writer = self.MockRawIO() - bufio = self.tp(writer, 8) - bufio.writelines(l) - bufio.flush() - self.assertEqual(b''.join(writer._write_stack), b'abcdef') - - def test_writelines_error(self): - writer = self.MockRawIO() - bufio = self.tp(writer, 8) - self.assertRaises(TypeError, bufio.writelines, [1, 2, 3]) - self.assertRaises(TypeError, bufio.writelines, None) - self.assertRaises(TypeError, bufio.writelines, 'abc') - - def test_destructor(self): - writer = self.MockRawIO() - bufio = self.tp(writer, 8) - bufio.write(b"abc") - del bufio - support.gc_collect() - self.assertEqual(b"abc", writer._write_stack[0]) - - def test_truncate(self): - # Truncate implicitly flushes the buffer. - self.addCleanup(support.unlink, support.TESTFN) - with self.open(support.TESTFN, self.write_mode, buffering=0) as raw: - bufio = self.tp(raw, 8) - bufio.write(b"abcdef") - self.assertEqual(bufio.truncate(3), 3) - self.assertEqual(bufio.tell(), 6) - with self.open(support.TESTFN, "rb", buffering=0) as f: - self.assertEqual(f.read(), b"abc") - - def test_truncate_after_write(self): - # Ensure that truncate preserves the file position after - # writes longer than the buffer size. - # Issue: https://bugs.python.org/issue32228 - self.addCleanup(support.unlink, support.TESTFN) - with self.open(support.TESTFN, "wb") as f: - # Fill with some buffer - f.write(b'\x00' * 10000) - buffer_sizes = [8192, 4096, 200] - for buffer_size in buffer_sizes: - with self.open(support.TESTFN, "r+b", buffering=buffer_size) as f: - f.write(b'\x00' * (buffer_size + 1)) - # After write write_pos and write_end are set to 0 - f.read(1) - # read operation makes sure that pos != raw_pos - f.truncate() - self.assertEqual(f.tell(), buffer_size + 2) - - @support.requires_resource('cpu') - def test_threads(self): - try: - # Write out many bytes from many threads and test they were - # all flushed. - N = 1000 - contents = bytes(range(256)) * N - sizes = cycle([1, 19]) - n = 0 - queue = deque() - while n < len(contents): - size = next(sizes) - queue.append(contents[n:n+size]) - n += size - del contents - # We use a real file object because it allows us to - # exercise situations where the GIL is released before - # writing the buffer to the raw streams. This is in addition - # to concurrency issues due to switching threads in the middle - # of Python code. - with self.open(support.TESTFN, self.write_mode, buffering=0) as raw: - bufio = self.tp(raw, 8) - errors = [] - def f(): - try: - while True: - try: - s = queue.popleft() - except IndexError: - return - bufio.write(s) - except Exception as e: - errors.append(e) - raise - threads = [threading.Thread(target=f) for x in range(20)] - with support.start_threads(threads): - time.sleep(0.02) # yield - self.assertFalse(errors, - "the following exceptions were caught: %r" % errors) - bufio.close() - with self.open(support.TESTFN, "rb") as f: - s = f.read() - for i in range(256): - self.assertEqual(s.count(bytes([i])), N) - finally: - support.unlink(support.TESTFN) - - def test_misbehaved_io(self): - rawio = self.MisbehavedRawIO() - bufio = self.tp(rawio, 5) - self.assertRaises(OSError, bufio.seek, 0) - self.assertRaises(OSError, bufio.tell) - self.assertRaises(OSError, bufio.write, b"abcdef") - - # Silence destructor error - bufio.close = lambda: None - - def test_max_buffer_size_removal(self): - with self.assertRaises(TypeError): - self.tp(self.MockRawIO(), 8, 12) - - def test_write_error_on_close(self): - raw = self.MockRawIO() - def bad_write(b): - raise OSError() - raw.write = bad_write - b = self.tp(raw) - b.write(b'spam') - self.assertRaises(OSError, b.close) # exception not swallowed - self.assertTrue(b.closed) - - def test_slow_close_from_thread(self): - # Issue #31976 - rawio = self.SlowFlushRawIO() - bufio = self.tp(rawio, 8) - t = threading.Thread(target=bufio.close) - t.start() - rawio.in_flush.wait() - self.assertRaises(ValueError, bufio.write, b'spam') - self.assertTrue(bufio.closed) - t.join() - - - - class CBufferedWriterTest(BufferedWriterTest, SizeofTest): - tp = io.BufferedWriter - - @unittest.skipIf(MEMORY_SANITIZER, "MSan defaults to crashing " - "instead of returning NULL for malloc failure.") - def test_constructor(self): - BufferedWriterTest.test_constructor(self) - # The allocation can succeed on 32-bit builds, e.g. with more - # than 2 GiB RAM and a 64-bit kernel. - if sys.maxsize > 0x7FFFFFFF: - rawio = self.MockRawIO() - bufio = self.tp(rawio) - self.assertRaises((OverflowError, MemoryError, ValueError), - bufio.__init__, rawio, sys.maxsize) - - def test_initialization(self): - rawio = self.MockRawIO() - bufio = self.tp(rawio) - self.assertRaises(ValueError, bufio.__init__, rawio, buffer_size=0) - self.assertRaises(ValueError, bufio.write, b"def") - self.assertRaises(ValueError, bufio.__init__, rawio, buffer_size=-16) - self.assertRaises(ValueError, bufio.write, b"def") - self.assertRaises(ValueError, bufio.__init__, rawio, buffer_size=-1) - self.assertRaises(ValueError, bufio.write, b"def") - - def test_garbage_collection(self): - # C BufferedWriter objects are collected, and collecting them flushes - # all data to disk. - # The Python version has __del__, so it ends into gc.garbage instead - self.addCleanup(support.unlink, support.TESTFN) - with support.check_warnings(('', ResourceWarning)): - rawio = self.FileIO(support.TESTFN, "w+b") - f = self.tp(rawio) - f.write(b"123xxx") - f.x = f - wr = weakref.ref(f) - del f - support.gc_collect() - self.assertIsNone(wr(), wr) - with self.open(support.TESTFN, "rb") as f: - self.assertEqual(f.read(), b"123xxx") - - def test_args_error(self): - # Issue #17275 - with self.assertRaisesRegex(TypeError, "BufferedWriter"): - self.tp(io.BytesIO(), 1024, 1024, 1024) - - - class PyBufferedWriterTest(BufferedWriterTest): - tp = pyio.BufferedWriter - - class BufferedRWPairTest(unittest.TestCase): - - def test_constructor(self): - pair = self.tp(self.MockRawIO(), self.MockRawIO()) - self.assertFalse(pair.closed) - - def test_uninitialized(self): - pair = self.tp.__new__(self.tp) - del pair - pair = self.tp.__new__(self.tp) - self.assertRaisesRegex((ValueError, AttributeError), - 'uninitialized|has no attribute', - pair.read, 0) - self.assertRaisesRegex((ValueError, AttributeError), - 'uninitialized|has no attribute', - pair.write, b'') - pair.__init__(self.MockRawIO(), self.MockRawIO()) - self.assertEqual(pair.read(0), b'') - self.assertEqual(pair.write(b''), 0) - - def test_detach(self): - pair = self.tp(self.MockRawIO(), self.MockRawIO()) - self.assertRaises(self.UnsupportedOperation, pair.detach) - - def test_constructor_max_buffer_size_removal(self): - with self.assertRaises(TypeError): - self.tp(self.MockRawIO(), self.MockRawIO(), 8, 12) - - def test_constructor_with_not_readable(self): - class NotReadable(MockRawIO): - def readable(self): - return False - - self.assertRaises(OSError, self.tp, NotReadable(), self.MockRawIO()) - - def test_constructor_with_not_writeable(self): - class NotWriteable(MockRawIO): - def writable(self): - return False - - self.assertRaises(OSError, self.tp, self.MockRawIO(), NotWriteable()) - - def test_read(self): - pair = self.tp(self.BytesIO(b"abcdef"), self.MockRawIO()) - - self.assertEqual(pair.read(3), b"abc") - self.assertEqual(pair.read(1), b"d") - self.assertEqual(pair.read(), b"ef") - pair = self.tp(self.BytesIO(b"abc"), self.MockRawIO()) - self.assertEqual(pair.read(None), b"abc") - - def test_readlines(self): - pair = lambda: self.tp(self.BytesIO(b"abc\ndef\nh"), self.MockRawIO()) - self.assertEqual(pair().readlines(), [b"abc\n", b"def\n", b"h"]) - self.assertEqual(pair().readlines(), [b"abc\n", b"def\n", b"h"]) - self.assertEqual(pair().readlines(5), [b"abc\n", b"def\n"]) - - def test_read1(self): - # .read1() is delegated to the underlying reader object, so this test - # can be shallow. - pair = self.tp(self.BytesIO(b"abcdef"), self.MockRawIO()) - - self.assertEqual(pair.read1(3), b"abc") - self.assertEqual(pair.read1(), b"def") - - def test_readinto(self): - for method in ("readinto", "readinto1"): - with self.subTest(method): - pair = self.tp(self.BytesIO(b"abcdef"), self.MockRawIO()) - - data = byteslike(b'\0' * 5) - self.assertEqual(getattr(pair, method)(data), 5) - self.assertEqual(bytes(data), b"abcde") - - def test_write(self): - w = self.MockRawIO() - pair = self.tp(self.MockRawIO(), w) - - pair.write(b"abc") - pair.flush() - buffer = bytearray(b"def") - pair.write(buffer) - buffer[:] = b"***" # Overwrite our copy of the data - pair.flush() - self.assertEqual(w._write_stack, [b"abc", b"def"]) - - def test_peek(self): - pair = self.tp(self.BytesIO(b"abcdef"), self.MockRawIO()) - - self.assertTrue(pair.peek(3).startswith(b"abc")) - self.assertEqual(pair.read(3), b"abc") - - def test_readable(self): - pair = self.tp(self.MockRawIO(), self.MockRawIO()) - self.assertTrue(pair.readable()) - - def test_writeable(self): - pair = self.tp(self.MockRawIO(), self.MockRawIO()) - self.assertTrue(pair.writable()) - - def test_seekable(self): - # BufferedRWPairs are never seekable, even if their readers and writers - # are. - pair = self.tp(self.MockRawIO(), self.MockRawIO()) - self.assertFalse(pair.seekable()) - - # .flush() is delegated to the underlying writer object and has been - # tested in the test_write method. - - def test_close_and_closed(self): - pair = self.tp(self.MockRawIO(), self.MockRawIO()) - self.assertFalse(pair.closed) - pair.close() - self.assertTrue(pair.closed) - - def test_reader_close_error_on_close(self): - def reader_close(): - reader_non_existing - reader = self.MockRawIO() - reader.close = reader_close - writer = self.MockRawIO() - pair = self.tp(reader, writer) - with self.assertRaises(NameError) as err: - pair.close() - self.assertIn('reader_non_existing', str(err.exception)) - self.assertTrue(pair.closed) - self.assertFalse(reader.closed) - self.assertTrue(writer.closed) - - # Silence destructor error - reader.close = lambda: None - - def test_writer_close_error_on_close(self): - def writer_close(): - writer_non_existing - reader = self.MockRawIO() - writer = self.MockRawIO() - writer.close = writer_close - pair = self.tp(reader, writer) - with self.assertRaises(NameError) as err: - pair.close() - self.assertIn('writer_non_existing', str(err.exception)) - self.assertFalse(pair.closed) - self.assertTrue(reader.closed) - self.assertFalse(writer.closed) - - # Silence destructor error - writer.close = lambda: None - writer = None - - # Ignore BufferedWriter (of the BufferedRWPair) unraisable exception - with support.catch_unraisable_exception(): - # Ignore BufferedRWPair unraisable exception - with support.catch_unraisable_exception(): - pair = None - support.gc_collect() - support.gc_collect() - - def test_reader_writer_close_error_on_close(self): - def reader_close(): - reader_non_existing - def writer_close(): - writer_non_existing - reader = self.MockRawIO() - reader.close = reader_close - writer = self.MockRawIO() - writer.close = writer_close - pair = self.tp(reader, writer) - with self.assertRaises(NameError) as err: - pair.close() - self.assertIn('reader_non_existing', str(err.exception)) - self.assertIsInstance(err.exception.__context__, NameError) - self.assertIn('writer_non_existing', str(err.exception.__context__)) - self.assertFalse(pair.closed) - self.assertFalse(reader.closed) - self.assertFalse(writer.closed) - - # Silence destructor error - reader.close = lambda: None - writer.close = lambda: None - - def test_isatty(self): - class SelectableIsAtty(MockRawIO): - def __init__(self, isatty): - MockRawIO.__init__(self) - self._isatty = isatty - - def isatty(self): - return self._isatty - - pair = self.tp(SelectableIsAtty(False), SelectableIsAtty(False)) - self.assertFalse(pair.isatty()) - - pair = self.tp(SelectableIsAtty(True), SelectableIsAtty(False)) - self.assertTrue(pair.isatty()) - - pair = self.tp(SelectableIsAtty(False), SelectableIsAtty(True)) - self.assertTrue(pair.isatty()) - - pair = self.tp(SelectableIsAtty(True), SelectableIsAtty(True)) - self.assertTrue(pair.isatty()) - - def test_weakref_clearing(self): - brw = self.tp(self.MockRawIO(), self.MockRawIO()) - ref = weakref.ref(brw) - brw = None - ref = None # Shouldn't segfault. - - class CBufferedRWPairTest(BufferedRWPairTest): - tp = io.BufferedRWPair - - class PyBufferedRWPairTest(BufferedRWPairTest): - tp = pyio.BufferedRWPair - - - class BufferedRandomTest(BufferedReaderTest, BufferedWriterTest): - read_mode = "rb+" - write_mode = "wb+" - - def test_constructor(self): - BufferedReaderTest.test_constructor(self) - BufferedWriterTest.test_constructor(self) - - def test_uninitialized(self): - BufferedReaderTest.test_uninitialized(self) - BufferedWriterTest.test_uninitialized(self) - - def test_read_and_write(self): - raw = self.MockRawIO((b"asdf", b"ghjk")) - rw = self.tp(raw, 8) - - self.assertEqual(b"as", rw.read(2)) - rw.write(b"ddd") - rw.write(b"eee") - self.assertFalse(raw._write_stack) # Buffer writes - self.assertEqual(b"ghjk", rw.read()) - self.assertEqual(b"dddeee", raw._write_stack[0]) - - def test_seek_and_tell(self): - raw = self.BytesIO(b"asdfghjkl") - rw = self.tp(raw) - - self.assertEqual(b"as", rw.read(2)) - self.assertEqual(2, rw.tell()) - rw.seek(0, 0) - self.assertEqual(b"asdf", rw.read(4)) - - rw.write(b"123f") - rw.seek(0, 0) - self.assertEqual(b"asdf123fl", rw.read()) - self.assertEqual(9, rw.tell()) - rw.seek(-4, 2) - self.assertEqual(5, rw.tell()) - rw.seek(2, 1) - self.assertEqual(7, rw.tell()) - self.assertEqual(b"fl", rw.read(11)) - rw.flush() - self.assertEqual(b"asdf123fl", raw.getvalue()) - - self.assertRaises(TypeError, rw.seek, 0.0) - - def check_flush_and_read(self, read_func): - raw = self.BytesIO(b"abcdefghi") - bufio = self.tp(raw) - - self.assertEqual(b"ab", read_func(bufio, 2)) - bufio.write(b"12") - self.assertEqual(b"ef", read_func(bufio, 2)) - self.assertEqual(6, bufio.tell()) - bufio.flush() - self.assertEqual(6, bufio.tell()) - self.assertEqual(b"ghi", read_func(bufio)) - raw.seek(0, 0) - raw.write(b"XYZ") - # flush() resets the read buffer - bufio.flush() - bufio.seek(0, 0) - self.assertEqual(b"XYZ", read_func(bufio, 3)) - - def test_flush_and_read(self): - self.check_flush_and_read(lambda bufio, *args: bufio.read(*args)) - - def test_flush_and_readinto(self): - def _readinto(bufio, n=-1): - b = bytearray(n if n >= 0 else 9999) - n = bufio.readinto(b) - return bytes(b[:n]) - self.check_flush_and_read(_readinto) - - def test_flush_and_peek(self): - def _peek(bufio, n=-1): - # This relies on the fact that the buffer can contain the whole - # raw stream, otherwise peek() can return less. - b = bufio.peek(n) - if n != -1: - b = b[:n] - bufio.seek(len(b), 1) - return b - self.check_flush_and_read(_peek) - - def test_flush_and_write(self): - raw = self.BytesIO(b"abcdefghi") - bufio = self.tp(raw) - - bufio.write(b"123") - bufio.flush() - bufio.write(b"45") - bufio.flush() - bufio.seek(0, 0) - self.assertEqual(b"12345fghi", raw.getvalue()) - self.assertEqual(b"12345fghi", bufio.read()) - - def test_threads(self): - BufferedReaderTest.test_threads(self) - BufferedWriterTest.test_threads(self) - - def test_writes_and_peek(self): - def _peek(bufio): - bufio.peek(1) - self.check_writes(_peek) - def _peek(bufio): - pos = bufio.tell() - bufio.seek(-1, 1) - bufio.peek(1) - bufio.seek(pos, 0) - self.check_writes(_peek) - - def test_writes_and_reads(self): - def _read(bufio): - bufio.seek(-1, 1) - bufio.read(1) - self.check_writes(_read) - - def test_writes_and_read1s(self): - def _read1(bufio): - bufio.seek(-1, 1) - bufio.read1(1) - self.check_writes(_read1) - - def test_writes_and_readintos(self): - def _read(bufio): - bufio.seek(-1, 1) - bufio.readinto(bytearray(1)) - self.check_writes(_read) - - def test_write_after_readahead(self): - # Issue #6629: writing after the buffer was filled by readahead should - # first rewind the raw stream. - for overwrite_size in [1, 5]: - raw = self.BytesIO(b"A" * 10) - bufio = self.tp(raw, 4) - # Trigger readahead - self.assertEqual(bufio.read(1), b"A") - self.assertEqual(bufio.tell(), 1) - # Overwriting should rewind the raw stream if it needs so - bufio.write(b"B" * overwrite_size) - self.assertEqual(bufio.tell(), overwrite_size + 1) - # If the write size was smaller than the buffer size, flush() and - # check that rewind happens. - bufio.flush() - self.assertEqual(bufio.tell(), overwrite_size + 1) - s = raw.getvalue() - self.assertEqual(s, - b"A" + b"B" * overwrite_size + b"A" * (9 - overwrite_size)) - - def test_write_rewind_write(self): - # Various combinations of reading / writing / seeking backwards / writing again - def mutate(bufio, pos1, pos2): - assert pos2 >= pos1 - # Fill the buffer - bufio.seek(pos1) - bufio.read(pos2 - pos1) - bufio.write(b'\x02') - # This writes earlier than the previous write, but still inside - # the buffer. - bufio.seek(pos1) - bufio.write(b'\x01') - - b = b"\x80\x81\x82\x83\x84" - for i in range(0, len(b)): - for j in range(i, len(b)): - raw = self.BytesIO(b) - bufio = self.tp(raw, 100) - mutate(bufio, i, j) - bufio.flush() - expected = bytearray(b) - expected[j] = 2 - expected[i] = 1 - self.assertEqual(raw.getvalue(), expected, - "failed result for i=%d, j=%d" % (i, j)) - - def test_truncate_after_read_or_write(self): - raw = self.BytesIO(b"A" * 10) - bufio = self.tp(raw, 100) - self.assertEqual(bufio.read(2), b"AA") # the read buffer gets filled - self.assertEqual(bufio.truncate(), 2) - self.assertEqual(bufio.write(b"BB"), 2) # the write buffer increases - self.assertEqual(bufio.truncate(), 4) - - def test_misbehaved_io(self): - BufferedReaderTest.test_misbehaved_io(self) - BufferedWriterTest.test_misbehaved_io(self) - - def test_interleaved_read_write(self): - # Test for issue #12213 - with self.BytesIO(b'abcdefgh') as raw: - with self.tp(raw, 100) as f: - f.write(b"1") - self.assertEqual(f.read(1), b'b') - f.write(b'2') - self.assertEqual(f.read1(1), b'd') - f.write(b'3') - buf = bytearray(1) - f.readinto(buf) - self.assertEqual(buf, b'f') - f.write(b'4') - self.assertEqual(f.peek(1), b'h') - f.flush() - self.assertEqual(raw.getvalue(), b'1b2d3f4h') - - with self.BytesIO(b'abc') as raw: - with self.tp(raw, 100) as f: - self.assertEqual(f.read(1), b'a') - f.write(b"2") - self.assertEqual(f.read(1), b'c') - f.flush() - self.assertEqual(raw.getvalue(), b'a2c') - - def test_interleaved_readline_write(self): - with self.BytesIO(b'ab\ncdef\ng\n') as raw: - with self.tp(raw) as f: - f.write(b'1') - self.assertEqual(f.readline(), b'b\n') - f.write(b'2') - self.assertEqual(f.readline(), b'def\n') - f.write(b'3') - self.assertEqual(f.readline(), b'\n') - f.flush() - self.assertEqual(raw.getvalue(), b'1b\n2def\n3\n') - - # You can't construct a BufferedRandom over a non-seekable stream. - test_unseekable = None - - - class CBufferedRandomTest(BufferedRandomTest, SizeofTest): - tp = io.BufferedRandom - - @unittest.skipIf(MEMORY_SANITIZER, "MSan defaults to crashing " - "instead of returning NULL for malloc failure.") - def test_constructor(self): - BufferedRandomTest.test_constructor(self) - # The allocation can succeed on 32-bit builds, e.g. with more - # than 2 GiB RAM and a 64-bit kernel. - if sys.maxsize > 0x7FFFFFFF: - rawio = self.MockRawIO() - bufio = self.tp(rawio) - self.assertRaises((OverflowError, MemoryError, ValueError), - bufio.__init__, rawio, sys.maxsize) - - def test_garbage_collection(self): - CBufferedReaderTest.test_garbage_collection(self) - CBufferedWriterTest.test_garbage_collection(self) - - def test_args_error(self): - # Issue #17275 - with self.assertRaisesRegex(TypeError, "BufferedRandom"): - self.tp(io.BytesIO(), 1024, 1024, 1024) - - - class PyBufferedRandomTest(BufferedRandomTest): - tp = pyio.BufferedRandom - - - # To fully exercise seek/tell, the StatefulIncrementalDecoder has these - # properties: - # - A single output character can correspond to many bytes of input. - # - The number of input bytes to complete the character can be - # undetermined until the last input byte is received. - # - The number of input bytes can vary depending on previous input. - # - A single input byte can correspond to many characters of output. - # - The number of output characters can be undetermined until the - # last input byte is received. - # - The number of output characters can vary depending on previous input. - - class StatefulIncrementalDecoder(codecs.IncrementalDecoder): - """ - For testing seek/tell behavior with a stateful, buffering decoder. - - Input is a sequence of words. Words may be fixed-length (length set - by input) or variable-length (period-terminated). In variable-length - mode, extra periods are ignored. Possible words are: - - 'i' followed by a number sets the input length, I (maximum 99). - When I is set to 0, words are space-terminated. - - 'o' followed by a number sets the output length, O (maximum 99). - - Any other word is converted into a word followed by a period on - the output. The output word consists of the input word truncated - or padded out with hyphens to make its length equal to O. If O - is 0, the word is output verbatim without truncating or padding. - I and O are initially set to 1. When I changes, any buffered input is - re-scanned according to the new I. EOF also terminates the last word. - """ - - def __init__(self, errors='strict'): - codecs.IncrementalDecoder.__init__(self, errors) - self.reset() - - def __repr__(self): - return '' % id(self) - - def reset(self): - self.i = 1 - self.o = 1 - self.buffer = bytearray() - - def getstate(self): - i, o = self.i ^ 1, self.o ^ 1 # so that flags = 0 after reset() - return bytes(self.buffer), i*100 + o - - def setstate(self, state): - buffer, io = state - self.buffer = bytearray(buffer) - i, o = divmod(io, 100) - self.i, self.o = i ^ 1, o ^ 1 - - def decode(self, input, final=False): - output = '' - for b in input: - if self.i == 0: # variable-length, terminated with period - if b == ord('.'): - if self.buffer: - output += self.process_word() - else: - self.buffer.append(b) - else: # fixed-length, terminate after self.i bytes - self.buffer.append(b) - if len(self.buffer) == self.i: - output += self.process_word() - if final and self.buffer: # EOF terminates the last word - output += self.process_word() - return output - - def process_word(self): - output = '' - if self.buffer[0] == ord('i'): - self.i = min(99, int(self.buffer[1:] or 0)) # set input length - elif self.buffer[0] == ord('o'): - self.o = min(99, int(self.buffer[1:] or 0)) # set output length - else: - output = self.buffer.decode('ascii') - if len(output) < self.o: - output += '-'*self.o # pad out with hyphens - if self.o: - output = output[:self.o] # truncate to output length - output += '.' - self.buffer = bytearray() - return output - - codecEnabled = False - - @classmethod - def lookupTestDecoder(cls, name): - if cls.codecEnabled and name == 'test_decoder': - latin1 = codecs.lookup('latin-1') - return codecs.CodecInfo( - name='test_decoder', encode=latin1.encode, decode=None, - incrementalencoder=None, - streamreader=None, streamwriter=None, - incrementaldecoder=cls) - - # Register the previous decoder for testing. - # Disabled by default, tests will enable it. - codecs.register(StatefulIncrementalDecoder.lookupTestDecoder) - - - class StatefulIncrementalDecoderTest(unittest.TestCase): - """ - Make sure the StatefulIncrementalDecoder actually works. - """ - - test_cases = [ - # I=1, O=1 (fixed-length input == fixed-length output) - (b'abcd', False, 'a.b.c.d.'), - # I=0, O=0 (variable-length input, variable-length output) - (b'oiabcd', True, 'abcd.'), - # I=0, O=0 (should ignore extra periods) - (b'oi...abcd...', True, 'abcd.'), - # I=0, O=6 (variable-length input, fixed-length output) - (b'i.o6.x.xyz.toolongtofit.', False, 'x-----.xyz---.toolon.'), - # I=2, O=6 (fixed-length input < fixed-length output) - (b'i.i2.o6xyz', True, 'xy----.z-----.'), - # I=6, O=3 (fixed-length input > fixed-length output) - (b'i.o3.i6.abcdefghijklmnop', True, 'abc.ghi.mno.'), - # I=0, then 3; O=29, then 15 (with longer output) - (b'i.o29.a.b.cde.o15.abcdefghijabcdefghij.i3.a.b.c.d.ei00k.l.m', True, - 'a----------------------------.' + - 'b----------------------------.' + - 'cde--------------------------.' + - 'abcdefghijabcde.' + - 'a.b------------.' + - '.c.------------.' + - 'd.e------------.' + - 'k--------------.' + - 'l--------------.' + - 'm--------------.') - ] - - def test_decoder(self): - # Try a few one-shot test cases. - for input, eof, output in self.test_cases: - d = StatefulIncrementalDecoder() - self.assertEqual(d.decode(input, eof), output) - - # Also test an unfinished decode, followed by forcing EOF. - d = StatefulIncrementalDecoder() - self.assertEqual(d.decode(b'oiabcd'), '') - self.assertEqual(d.decode(b'', 1), 'abcd.') - - class TextIOWrapperTest(unittest.TestCase): - - def setUp(self): - self.testdata = b"AAA\r\nBBB\rCCC\r\nDDD\nEEE\r\n" - self.normalized = b"AAA\nBBB\nCCC\nDDD\nEEE\n".decode("ascii") - support.unlink(support.TESTFN) - - def tearDown(self): - support.unlink(support.TESTFN) - - def test_constructor(self): - r = self.BytesIO(b"\xc3\xa9\n\n") - b = self.BufferedReader(r, 1000) - t = self.TextIOWrapper(b) - t.__init__(b, encoding="latin-1", newline="\r\n") - self.assertEqual(t.encoding, "latin-1") - self.assertEqual(t.line_buffering, False) - t.__init__(b, encoding="utf-8", line_buffering=True) - self.assertEqual(t.encoding, "utf-8") - self.assertEqual(t.line_buffering, True) - self.assertEqual("\xe9\n", t.readline()) - self.assertRaises(TypeError, t.__init__, b, newline=42) - self.assertRaises(ValueError, t.__init__, b, newline='xyzzy') - - def test_uninitialized(self): - t = self.TextIOWrapper.__new__(self.TextIOWrapper) - del t - t = self.TextIOWrapper.__new__(self.TextIOWrapper) - self.assertRaises(Exception, repr, t) - self.assertRaisesRegex((ValueError, AttributeError), - 'uninitialized|has no attribute', - t.read, 0) - t.__init__(self.MockRawIO()) - self.assertEqual(t.read(0), '') - - def test_non_text_encoding_codecs_are_rejected(self): - # Ensure the constructor complains if passed a codec that isn't - # marked as a text encoding - # http://bugs.python.org/issue20404 - r = self.BytesIO() - b = self.BufferedWriter(r) - with self.assertRaisesRegex(LookupError, "is not a text encoding"): - self.TextIOWrapper(b, encoding="hex") - - def test_detach(self): - r = self.BytesIO() - b = self.BufferedWriter(r) - t = self.TextIOWrapper(b) - self.assertIs(t.detach(), b) - - t = self.TextIOWrapper(b, encoding="ascii") - t.write("howdy") - self.assertFalse(r.getvalue()) - t.detach() - self.assertEqual(r.getvalue(), b"howdy") - self.assertRaises(ValueError, t.detach) - - # Operations independent of the detached stream should still work - repr(t) - self.assertEqual(t.encoding, "ascii") - self.assertEqual(t.errors, "strict") - self.assertFalse(t.line_buffering) - self.assertFalse(t.write_through) - - def test_repr(self): - raw = self.BytesIO("hello".encode("utf-8")) - b = self.BufferedReader(raw) - t = self.TextIOWrapper(b, encoding="utf-8") - modname = self.TextIOWrapper.__module__ - self.assertRegex(repr(t), - r"<(%s\.)?TextIOWrapper encoding='utf-8'>" % modname) - raw.name = "dummy" - self.assertRegex(repr(t), - r"<(%s\.)?TextIOWrapper name='dummy' encoding='utf-8'>" % modname) - t.mode = "r" - self.assertRegex(repr(t), - r"<(%s\.)?TextIOWrapper name='dummy' mode='r' encoding='utf-8'>" % modname) - raw.name = b"dummy" - self.assertRegex(repr(t), - r"<(%s\.)?TextIOWrapper name=b'dummy' mode='r' encoding='utf-8'>" % modname) - - t.buffer.detach() - repr(t) # Should not raise an exception - - def test_recursive_repr(self): - # Issue #25455 - raw = self.BytesIO() - t = self.TextIOWrapper(raw) - with support.swap_attr(raw, 'name', t): - try: - repr(t) # Should not crash - except RuntimeError: - pass - - def test_line_buffering(self): - r = self.BytesIO() - b = self.BufferedWriter(r, 1000) - t = self.TextIOWrapper(b, newline="\n", line_buffering=True) - t.write("X") - self.assertEqual(r.getvalue(), b"") # No flush happened - t.write("Y\nZ") - self.assertEqual(r.getvalue(), b"XY\nZ") # All got flushed - t.write("A\rB") - self.assertEqual(r.getvalue(), b"XY\nZA\rB") - - def test_reconfigure_line_buffering(self): - r = self.BytesIO() - b = self.BufferedWriter(r, 1000) - t = self.TextIOWrapper(b, newline="\n", line_buffering=False) - t.write("AB\nC") - self.assertEqual(r.getvalue(), b"") - - t.reconfigure(line_buffering=True) # implicit flush - self.assertEqual(r.getvalue(), b"AB\nC") - t.write("DEF\nG") - self.assertEqual(r.getvalue(), b"AB\nCDEF\nG") - t.write("H") - self.assertEqual(r.getvalue(), b"AB\nCDEF\nG") - t.reconfigure(line_buffering=False) # implicit flush - self.assertEqual(r.getvalue(), b"AB\nCDEF\nGH") - t.write("IJ") - self.assertEqual(r.getvalue(), b"AB\nCDEF\nGH") - - # Keeping default value - t.reconfigure() - t.reconfigure(line_buffering=None) - self.assertEqual(t.line_buffering, False) - t.reconfigure(line_buffering=True) - t.reconfigure() - t.reconfigure(line_buffering=None) - self.assertEqual(t.line_buffering, True) - - @unittest.skipIf(sys.flags.utf8_mode, "utf-8 mode is enabled") - def test_default_encoding(self): - old_environ = dict(os.environ) - try: - # try to get a user preferred encoding different than the current - # locale encoding to check that TextIOWrapper() uses the current - # locale encoding and not the user preferred encoding - for key in ('LC_ALL', 'LANG', 'LC_CTYPE'): - if key in os.environ: - del os.environ[key] - - current_locale_encoding = locale.getpreferredencoding(False) - b = self.BytesIO() - t = self.TextIOWrapper(b) - self.assertEqual(t.encoding, current_locale_encoding) - finally: - os.environ.clear() - os.environ.update(old_environ) - - @support.cpython_only - @unittest.skipIf(sys.flags.utf8_mode, "utf-8 mode is enabled") - def test_device_encoding(self): - # Issue 15989 - import _testcapi - b = self.BytesIO() - b.fileno = lambda: _testcapi.INT_MAX + 1 - self.assertRaises(OverflowError, self.TextIOWrapper, b) - b.fileno = lambda: _testcapi.UINT_MAX + 1 - self.assertRaises(OverflowError, self.TextIOWrapper, b) - - def test_encoding(self): - # Check the encoding attribute is always set, and valid - b = self.BytesIO() - t = self.TextIOWrapper(b, encoding="utf-8") - self.assertEqual(t.encoding, "utf-8") - t = self.TextIOWrapper(b) - self.assertIsNotNone(t.encoding) - codecs.lookup(t.encoding) - - def test_encoding_errors_reading(self): - # (1) default - b = self.BytesIO(b"abc\n\xff\n") - t = self.TextIOWrapper(b, encoding="ascii") - self.assertRaises(UnicodeError, t.read) - # (2) explicit strict - b = self.BytesIO(b"abc\n\xff\n") - t = self.TextIOWrapper(b, encoding="ascii", errors="strict") - self.assertRaises(UnicodeError, t.read) - # (3) ignore - b = self.BytesIO(b"abc\n\xff\n") - t = self.TextIOWrapper(b, encoding="ascii", errors="ignore") - self.assertEqual(t.read(), "abc\n\n") - # (4) replace - b = self.BytesIO(b"abc\n\xff\n") - t = self.TextIOWrapper(b, encoding="ascii", errors="replace") - self.assertEqual(t.read(), "abc\n\ufffd\n") - - def test_encoding_errors_writing(self): - # (1) default - b = self.BytesIO() - t = self.TextIOWrapper(b, encoding="ascii") - self.assertRaises(UnicodeError, t.write, "\xff") - # (2) explicit strict - b = self.BytesIO() - t = self.TextIOWrapper(b, encoding="ascii", errors="strict") - self.assertRaises(UnicodeError, t.write, "\xff") - # (3) ignore - b = self.BytesIO() - t = self.TextIOWrapper(b, encoding="ascii", errors="ignore", - newline="\n") - t.write("abc\xffdef\n") - t.flush() - self.assertEqual(b.getvalue(), b"abcdef\n") - # (4) replace - b = self.BytesIO() - t = self.TextIOWrapper(b, encoding="ascii", errors="replace", - newline="\n") - t.write("abc\xffdef\n") - t.flush() - self.assertEqual(b.getvalue(), b"abc?def\n") - - def test_newlines(self): - input_lines = [ "unix\n", "windows\r\n", "os9\r", "last\n", "nonl" ] - - tests = [ - [ None, [ 'unix\n', 'windows\n', 'os9\n', 'last\n', 'nonl' ] ], - [ '', input_lines ], - [ '\n', [ "unix\n", "windows\r\n", "os9\rlast\n", "nonl" ] ], - [ '\r\n', [ "unix\nwindows\r\n", "os9\rlast\nnonl" ] ], - [ '\r', [ "unix\nwindows\r", "\nos9\r", "last\nnonl" ] ], - ] - encodings = ( - 'utf-8', 'latin-1', - 'utf-16', 'utf-16-le', 'utf-16-be', - 'utf-32', 'utf-32-le', 'utf-32-be', - ) - - # Try a range of buffer sizes to test the case where \r is the last - # character in TextIOWrapper._pending_line. - for encoding in encodings: - # XXX: str.encode() should return bytes - data = bytes(''.join(input_lines).encode(encoding)) - for do_reads in (False, True): - for bufsize in range(1, 10): - for newline, exp_lines in tests: - bufio = self.BufferedReader(self.BytesIO(data), bufsize) - textio = self.TextIOWrapper(bufio, newline=newline, - encoding=encoding) - if do_reads: - got_lines = [] - while True: - c2 = textio.read(2) - if c2 == '': - break - self.assertEqual(len(c2), 2) - got_lines.append(c2 + textio.readline()) - else: - got_lines = list(textio) - - for got_line, exp_line in zip(got_lines, exp_lines): - self.assertEqual(got_line, exp_line) - self.assertEqual(len(got_lines), len(exp_lines)) - - def test_newlines_input(self): - testdata = b"AAA\nBB\x00B\nCCC\rDDD\rEEE\r\nFFF\r\nGGG" - normalized = testdata.replace(b"\r\n", b"\n").replace(b"\r", b"\n") - for newline, expected in [ - (None, normalized.decode("ascii").splitlines(keepends=True)), - ("", testdata.decode("ascii").splitlines(keepends=True)), - ("\n", ["AAA\n", "BB\x00B\n", "CCC\rDDD\rEEE\r\n", "FFF\r\n", "GGG"]), - ("\r\n", ["AAA\nBB\x00B\nCCC\rDDD\rEEE\r\n", "FFF\r\n", "GGG"]), - ("\r", ["AAA\nBB\x00B\nCCC\r", "DDD\r", "EEE\r", "\nFFF\r", "\nGGG"]), - ]: - buf = self.BytesIO(testdata) - txt = self.TextIOWrapper(buf, encoding="ascii", newline=newline) - self.assertEqual(txt.readlines(), expected) - txt.seek(0) - self.assertEqual(txt.read(), "".join(expected)) - - def test_newlines_output(self): - testdict = { - "": b"AAA\nBBB\nCCC\nX\rY\r\nZ", - "\n": b"AAA\nBBB\nCCC\nX\rY\r\nZ", - "\r": b"AAA\rBBB\rCCC\rX\rY\r\rZ", - "\r\n": b"AAA\r\nBBB\r\nCCC\r\nX\rY\r\r\nZ", - } - tests = [(None, testdict[os.linesep])] + sorted(testdict.items()) - for newline, expected in tests: - buf = self.BytesIO() - txt = self.TextIOWrapper(buf, encoding="ascii", newline=newline) - txt.write("AAA\nB") - txt.write("BB\nCCC\n") - txt.write("X\rY\r\nZ") - txt.flush() - self.assertEqual(buf.closed, False) - self.assertEqual(buf.getvalue(), expected) - - def test_destructor(self): - l = [] - base = self.BytesIO - class MyBytesIO(base): - def close(self): - l.append(self.getvalue()) - base.close(self) - b = MyBytesIO() - t = self.TextIOWrapper(b, encoding="ascii") - t.write("abc") - del t - support.gc_collect() - self.assertEqual([b"abc"], l) - - def test_override_destructor(self): - record = [] - class MyTextIO(self.TextIOWrapper): - def __del__(self): - record.append(1) - try: - f = super().__del__ - except AttributeError: - pass - else: - f() - def close(self): - record.append(2) - super().close() - def flush(self): - record.append(3) - super().flush() - b = self.BytesIO() - t = MyTextIO(b, encoding="ascii") - del t - support.gc_collect() - self.assertEqual(record, [1, 2, 3]) - - def test_error_through_destructor(self): - # Test that the exception state is not modified by a destructor, - # even if close() fails. - rawio = self.CloseFailureIO() - with support.catch_unraisable_exception() as cm: - with self.assertRaises(AttributeError): - self.TextIOWrapper(rawio).xyzzy - - if not IOBASE_EMITS_UNRAISABLE: - self.assertIsNone(cm.unraisable) - elif cm.unraisable is not None: - self.assertEqual(cm.unraisable.exc_type, OSError) - - # Systematic tests of the text I/O API - - def test_basic_io(self): - for chunksize in (1, 2, 3, 4, 5, 15, 16, 17, 31, 32, 33, 63, 64, 65): - for enc in "ascii", "latin-1", "utf-8" :# , "utf-16-be", "utf-16-le": - f = self.open(support.TESTFN, "w+", encoding=enc) - f._CHUNK_SIZE = chunksize - self.assertEqual(f.write("abc"), 3) - f.close() - f = self.open(support.TESTFN, "r+", encoding=enc) - f._CHUNK_SIZE = chunksize - self.assertEqual(f.tell(), 0) - self.assertEqual(f.read(), "abc") - cookie = f.tell() - self.assertEqual(f.seek(0), 0) - self.assertEqual(f.read(None), "abc") - f.seek(0) - self.assertEqual(f.read(2), "ab") - self.assertEqual(f.read(1), "c") - self.assertEqual(f.read(1), "") - self.assertEqual(f.read(), "") - self.assertEqual(f.tell(), cookie) - self.assertEqual(f.seek(0), 0) - self.assertEqual(f.seek(0, 2), cookie) - self.assertEqual(f.write("def"), 3) - self.assertEqual(f.seek(cookie), cookie) - self.assertEqual(f.read(), "def") - if enc.startswith("utf"): - self.multi_line_test(f, enc) - f.close() - - def multi_line_test(self, f, enc): - f.seek(0) - f.truncate() - sample = "s\xff\u0fff\uffff" - wlines = [] - for size in (0, 1, 2, 3, 4, 5, 30, 31, 32, 33, 62, 63, 64, 65, 1000): - chars = [] - for i in range(size): - chars.append(sample[i % len(sample)]) - line = "".join(chars) + "\n" - wlines.append((f.tell(), line)) - f.write(line) - f.seek(0) - rlines = [] - while True: - pos = f.tell() - line = f.readline() - if not line: - break - rlines.append((pos, line)) - self.assertEqual(rlines, wlines) - - def test_telling(self): - f = self.open(support.TESTFN, "w+", encoding="utf-8") - p0 = f.tell() - f.write("\xff\n") - p1 = f.tell() - f.write("\xff\n") - p2 = f.tell() - f.seek(0) - self.assertEqual(f.tell(), p0) - self.assertEqual(f.readline(), "\xff\n") - self.assertEqual(f.tell(), p1) - self.assertEqual(f.readline(), "\xff\n") - self.assertEqual(f.tell(), p2) - f.seek(0) - for line in f: - self.assertEqual(line, "\xff\n") - self.assertRaises(OSError, f.tell) - self.assertEqual(f.tell(), p2) - f.close() - - def test_seeking(self): - chunk_size = _default_chunk_size() - prefix_size = chunk_size - 2 - u_prefix = "a" * prefix_size - prefix = bytes(u_prefix.encode("utf-8")) - self.assertEqual(len(u_prefix), len(prefix)) - u_suffix = "\u8888\n" - suffix = bytes(u_suffix.encode("utf-8")) - line = prefix + suffix - with self.open(support.TESTFN, "wb") as f: - f.write(line*2) - with self.open(support.TESTFN, "r", encoding="utf-8") as f: - s = f.read(prefix_size) - self.assertEqual(s, str(prefix, "ascii")) - self.assertEqual(f.tell(), prefix_size) - self.assertEqual(f.readline(), u_suffix) - - def test_seeking_too(self): - # Regression test for a specific bug - data = b'\xe0\xbf\xbf\n' - with self.open(support.TESTFN, "wb") as f: - f.write(data) - with self.open(support.TESTFN, "r", encoding="utf-8") as f: - f._CHUNK_SIZE # Just test that it exists - f._CHUNK_SIZE = 2 - f.readline() - f.tell() - - def test_seek_and_tell(self): - #Test seek/tell using the StatefulIncrementalDecoder. - # Make test faster by doing smaller seeks - CHUNK_SIZE = 128 - - def test_seek_and_tell_with_data(data, min_pos=0): - """Tell/seek to various points within a data stream and ensure - that the decoded data returned by read() is consistent.""" - f = self.open(support.TESTFN, 'wb') - f.write(data) - f.close() - f = self.open(support.TESTFN, encoding='test_decoder') - f._CHUNK_SIZE = CHUNK_SIZE - decoded = f.read() - f.close() - - for i in range(min_pos, len(decoded) + 1): # seek positions - for j in [1, 5, len(decoded) - i]: # read lengths - f = self.open(support.TESTFN, encoding='test_decoder') - self.assertEqual(f.read(i), decoded[:i]) - cookie = f.tell() - self.assertEqual(f.read(j), decoded[i:i + j]) - f.seek(cookie) - self.assertEqual(f.read(), decoded[i:]) - f.close() - - # Enable the test decoder. - StatefulIncrementalDecoder.codecEnabled = 1 - - # Run the tests. - try: - # Try each test case. - for input, _, _ in StatefulIncrementalDecoderTest.test_cases: - test_seek_and_tell_with_data(input) - - # Position each test case so that it crosses a chunk boundary. - for input, _, _ in StatefulIncrementalDecoderTest.test_cases: - offset = CHUNK_SIZE - len(input)//2 - prefix = b'.'*offset - # Don't bother seeking into the prefix (takes too long). - min_pos = offset*2 - test_seek_and_tell_with_data(prefix + input, min_pos) - - # Ensure our test decoder won't interfere with subsequent tests. - finally: - StatefulIncrementalDecoder.codecEnabled = 0 - - def test_multibyte_seek_and_tell(self): - f = self.open(support.TESTFN, "w", encoding="euc_jp") - f.write("AB\n\u3046\u3048\n") - f.close() - - f = self.open(support.TESTFN, "r", encoding="euc_jp") - self.assertEqual(f.readline(), "AB\n") - p0 = f.tell() - self.assertEqual(f.readline(), "\u3046\u3048\n") - p1 = f.tell() - f.seek(p0) - self.assertEqual(f.readline(), "\u3046\u3048\n") - self.assertEqual(f.tell(), p1) - f.close() - - def test_seek_with_encoder_state(self): - f = self.open(support.TESTFN, "w", encoding="euc_jis_2004") - f.write("\u00e6\u0300") - p0 = f.tell() - f.write("\u00e6") - f.seek(p0) - f.write("\u0300") - f.close() - - f = self.open(support.TESTFN, "r", encoding="euc_jis_2004") - self.assertEqual(f.readline(), "\u00e6\u0300\u0300") - f.close() - - def test_encoded_writes(self): - data = "1234567890" - tests = ("utf-16", - "utf-16-le", - "utf-16-be", - "utf-32", - "utf-32-le", - "utf-32-be") - for encoding in tests: - buf = self.BytesIO() - f = self.TextIOWrapper(buf, encoding=encoding) - # Check if the BOM is written only once (see issue1753). - f.write(data) - f.write(data) - f.seek(0) - self.assertEqual(f.read(), data * 2) - f.seek(0) - self.assertEqual(f.read(), data * 2) - self.assertEqual(buf.getvalue(), (data * 2).encode(encoding)) - - def test_unreadable(self): - class UnReadable(self.BytesIO): - def readable(self): - return False - txt = self.TextIOWrapper(UnReadable()) - self.assertRaises(OSError, txt.read) - - def test_read_one_by_one(self): - txt = self.TextIOWrapper(self.BytesIO(b"AA\r\nBB")) - reads = "" - while True: - c = txt.read(1) - if not c: - break - reads += c - self.assertEqual(reads, "AA\nBB") - - def test_readlines(self): - txt = self.TextIOWrapper(self.BytesIO(b"AA\nBB\nCC")) - self.assertEqual(txt.readlines(), ["AA\n", "BB\n", "CC"]) - txt.seek(0) - self.assertEqual(txt.readlines(None), ["AA\n", "BB\n", "CC"]) - txt.seek(0) - self.assertEqual(txt.readlines(5), ["AA\n", "BB\n"]) - - # read in amounts equal to TextIOWrapper._CHUNK_SIZE which is 128. - def test_read_by_chunk(self): - # make sure "\r\n" straddles 128 char boundary. - txt = self.TextIOWrapper(self.BytesIO(b"A" * 127 + b"\r\nB")) - reads = "" - while True: - c = txt.read(128) - if not c: - break - reads += c - self.assertEqual(reads, "A"*127+"\nB") - - def test_writelines(self): - l = ['ab', 'cd', 'ef'] - buf = self.BytesIO() - txt = self.TextIOWrapper(buf) - txt.writelines(l) - txt.flush() - self.assertEqual(buf.getvalue(), b'abcdef') - - def test_writelines_userlist(self): - l = UserList(['ab', 'cd', 'ef']) - buf = self.BytesIO() - txt = self.TextIOWrapper(buf) - txt.writelines(l) - txt.flush() - self.assertEqual(buf.getvalue(), b'abcdef') - - def test_writelines_error(self): - txt = self.TextIOWrapper(self.BytesIO()) - self.assertRaises(TypeError, txt.writelines, [1, 2, 3]) - self.assertRaises(TypeError, txt.writelines, None) - self.assertRaises(TypeError, txt.writelines, b'abc') - - def test_issue1395_1(self): - txt = self.TextIOWrapper(self.BytesIO(self.testdata), encoding="ascii") - - # read one char at a time - reads = "" - while True: - c = txt.read(1) - if not c: - break - reads += c - self.assertEqual(reads, self.normalized) - - def test_issue1395_2(self): - txt = self.TextIOWrapper(self.BytesIO(self.testdata), encoding="ascii") - txt._CHUNK_SIZE = 4 - - reads = "" - while True: - c = txt.read(4) - if not c: - break - reads += c - self.assertEqual(reads, self.normalized) - - def test_issue1395_3(self): - txt = self.TextIOWrapper(self.BytesIO(self.testdata), encoding="ascii") - txt._CHUNK_SIZE = 4 - - reads = txt.read(4) - reads += txt.read(4) - reads += txt.readline() - reads += txt.readline() - reads += txt.readline() - self.assertEqual(reads, self.normalized) - - def test_issue1395_4(self): - txt = self.TextIOWrapper(self.BytesIO(self.testdata), encoding="ascii") - txt._CHUNK_SIZE = 4 - - reads = txt.read(4) - reads += txt.read() - self.assertEqual(reads, self.normalized) - - def test_issue1395_5(self): - txt = self.TextIOWrapper(self.BytesIO(self.testdata), encoding="ascii") - txt._CHUNK_SIZE = 4 - - reads = txt.read(4) - pos = txt.tell() - txt.seek(0) - txt.seek(pos) - self.assertEqual(txt.read(4), "BBB\n") - - def test_issue2282(self): - buffer = self.BytesIO(self.testdata) - txt = self.TextIOWrapper(buffer, encoding="ascii") - - self.assertEqual(buffer.seekable(), txt.seekable()) - - def test_append_bom(self): - # The BOM is not written again when appending to a non-empty file - filename = support.TESTFN - for charset in ('utf-8-sig', 'utf-16', 'utf-32'): - with self.open(filename, 'w', encoding=charset) as f: - f.write('aaa') - pos = f.tell() - with self.open(filename, 'rb') as f: - self.assertEqual(f.read(), 'aaa'.encode(charset)) - - with self.open(filename, 'a', encoding=charset) as f: - f.write('xxx') - with self.open(filename, 'rb') as f: - self.assertEqual(f.read(), 'aaaxxx'.encode(charset)) - - def test_seek_bom(self): - # Same test, but when seeking manually - filename = support.TESTFN - for charset in ('utf-8-sig', 'utf-16', 'utf-32'): - with self.open(filename, 'w', encoding=charset) as f: - f.write('aaa') - pos = f.tell() - with self.open(filename, 'r+', encoding=charset) as f: - f.seek(pos) - f.write('zzz') - f.seek(0) - f.write('bbb') - with self.open(filename, 'rb') as f: - self.assertEqual(f.read(), 'bbbzzz'.encode(charset)) - - def test_seek_append_bom(self): - # Same test, but first seek to the start and then to the end - filename = support.TESTFN - for charset in ('utf-8-sig', 'utf-16', 'utf-32'): - with self.open(filename, 'w', encoding=charset) as f: - f.write('aaa') - with self.open(filename, 'a', encoding=charset) as f: - f.seek(0) - f.seek(0, self.SEEK_END) - f.write('xxx') - with self.open(filename, 'rb') as f: - self.assertEqual(f.read(), 'aaaxxx'.encode(charset)) - - def test_errors_property(self): - with self.open(support.TESTFN, "w") as f: - self.assertEqual(f.errors, "strict") - with self.open(support.TESTFN, "w", errors="replace") as f: - self.assertEqual(f.errors, "replace") - - @support.no_tracing - def test_threads_write(self): - # Issue6750: concurrent writes could duplicate data - event = threading.Event() - with self.open(support.TESTFN, "w", buffering=1) as f: - def run(n): - text = "Thread%03d\n" % n - event.wait() - f.write(text) - threads = [threading.Thread(target=run, args=(x,)) - for x in range(20)] - with support.start_threads(threads, event.set): - time.sleep(0.02) - with self.open(support.TESTFN) as f: - content = f.read() - for n in range(20): - self.assertEqual(content.count("Thread%03d\n" % n), 1) - - def test_flush_error_on_close(self): - # Test that text file is closed despite failed flush - # and that flush() is called before file closed. - txt = self.TextIOWrapper(self.BytesIO(self.testdata), encoding="ascii") - closed = [] - def bad_flush(): - closed[:] = [txt.closed, txt.buffer.closed] - raise OSError() - txt.flush = bad_flush - self.assertRaises(OSError, txt.close) # exception not swallowed - self.assertTrue(txt.closed) - self.assertTrue(txt.buffer.closed) - self.assertTrue(closed) # flush() called - self.assertFalse(closed[0]) # flush() called before file closed - self.assertFalse(closed[1]) - txt.flush = lambda: None # break reference loop - - def test_close_error_on_close(self): - buffer = self.BytesIO(self.testdata) - def bad_flush(): - raise OSError('flush') - def bad_close(): - raise OSError('close') - buffer.close = bad_close - txt = self.TextIOWrapper(buffer, encoding="ascii") - txt.flush = bad_flush - with self.assertRaises(OSError) as err: # exception not swallowed - txt.close() - self.assertEqual(err.exception.args, ('close',)) - self.assertIsInstance(err.exception.__context__, OSError) - self.assertEqual(err.exception.__context__.args, ('flush',)) - self.assertFalse(txt.closed) - - # Silence destructor error - buffer.close = lambda: None - txt.flush = lambda: None - - def test_nonnormalized_close_error_on_close(self): - # Issue #21677 - buffer = self.BytesIO(self.testdata) - def bad_flush(): - raise non_existing_flush - def bad_close(): - raise non_existing_close - buffer.close = bad_close - txt = self.TextIOWrapper(buffer, encoding="ascii") - txt.flush = bad_flush - with self.assertRaises(NameError) as err: # exception not swallowed - txt.close() - self.assertIn('non_existing_close', str(err.exception)) - self.assertIsInstance(err.exception.__context__, NameError) - self.assertIn('non_existing_flush', str(err.exception.__context__)) - self.assertFalse(txt.closed) - - # Silence destructor error - buffer.close = lambda: None - txt.flush = lambda: None - - def test_multi_close(self): - txt = self.TextIOWrapper(self.BytesIO(self.testdata), encoding="ascii") - txt.close() - txt.close() - txt.close() - self.assertRaises(ValueError, txt.flush) - - def test_unseekable(self): - txt = self.TextIOWrapper(self.MockUnseekableIO(self.testdata)) - self.assertRaises(self.UnsupportedOperation, txt.tell) - self.assertRaises(self.UnsupportedOperation, txt.seek, 0) - - def test_readonly_attributes(self): - txt = self.TextIOWrapper(self.BytesIO(self.testdata), encoding="ascii") - buf = self.BytesIO(self.testdata) - with self.assertRaises(AttributeError): - txt.buffer = buf - - def test_rawio(self): - # Issue #12591: TextIOWrapper must work with raw I/O objects, so - # that subprocess.Popen() can have the required unbuffered - # semantics with universal_newlines=True. - raw = self.MockRawIO([b'abc', b'def', b'ghi\njkl\nopq\n']) - txt = self.TextIOWrapper(raw, encoding='ascii', newline='\n') - # Reads - self.assertEqual(txt.read(4), 'abcd') - self.assertEqual(txt.readline(), 'efghi\n') - self.assertEqual(list(txt), ['jkl\n', 'opq\n']) - - def test_rawio_write_through(self): - # Issue #12591: with write_through=True, writes don't need a flush - raw = self.MockRawIO([b'abc', b'def', b'ghi\njkl\nopq\n']) - txt = self.TextIOWrapper(raw, encoding='ascii', newline='\n', - write_through=True) - txt.write('1') - txt.write('23\n4') - txt.write('5') - self.assertEqual(b''.join(raw._write_stack), b'123\n45') - - def test_bufio_write_through(self): - # Issue #21396: write_through=True doesn't force a flush() - # on the underlying binary buffered object. - flush_called, write_called = [], [] - class BufferedWriter(self.BufferedWriter): - def flush(self, *args, **kwargs): - flush_called.append(True) - return super().flush(*args, **kwargs) - def write(self, *args, **kwargs): - write_called.append(True) - return super().write(*args, **kwargs) - - rawio = self.BytesIO() - data = b"a" - bufio = BufferedWriter(rawio, len(data)*2) - textio = self.TextIOWrapper(bufio, encoding='ascii', - write_through=True) - # write to the buffered io but don't overflow the buffer - text = data.decode('ascii') - textio.write(text) - - # buffer.flush is not called with write_through=True - self.assertFalse(flush_called) - # buffer.write *is* called with write_through=True - self.assertTrue(write_called) - self.assertEqual(rawio.getvalue(), b"") # no flush - - write_called = [] # reset - textio.write(text * 10) # total content is larger than bufio buffer - self.assertTrue(write_called) - self.assertEqual(rawio.getvalue(), data * 11) # all flushed - - def test_reconfigure_write_through(self): - raw = self.MockRawIO([]) - t = self.TextIOWrapper(raw, encoding='ascii', newline='\n') - t.write('1') - t.reconfigure(write_through=True) # implied flush - self.assertEqual(t.write_through, True) - self.assertEqual(b''.join(raw._write_stack), b'1') - t.write('23') - self.assertEqual(b''.join(raw._write_stack), b'123') - t.reconfigure(write_through=False) - self.assertEqual(t.write_through, False) - t.write('45') - t.flush() - self.assertEqual(b''.join(raw._write_stack), b'12345') - # Keeping default value - t.reconfigure() - t.reconfigure(write_through=None) - self.assertEqual(t.write_through, False) - t.reconfigure(write_through=True) - t.reconfigure() - t.reconfigure(write_through=None) - self.assertEqual(t.write_through, True) - - def test_read_nonbytes(self): - # Issue #17106 - # Crash when underlying read() returns non-bytes - t = self.TextIOWrapper(self.StringIO('a')) - self.assertRaises(TypeError, t.read, 1) - t = self.TextIOWrapper(self.StringIO('a')) - self.assertRaises(TypeError, t.readline) - t = self.TextIOWrapper(self.StringIO('a')) - self.assertRaises(TypeError, t.read) - - def test_illegal_encoder(self): - # Issue 31271: Calling write() while the return value of encoder's - # encode() is invalid shouldn't cause an assertion failure. - rot13 = codecs.lookup("rot13") - with support.swap_attr(rot13, '_is_text_encoding', True): - t = io.TextIOWrapper(io.BytesIO(b'foo'), encoding="rot13") - self.assertRaises(TypeError, t.write, 'bar') - - def test_illegal_decoder(self): - # Issue #17106 - # Bypass the early encoding check added in issue 20404 - def _make_illegal_wrapper(): - quopri = codecs.lookup("quopri") - quopri._is_text_encoding = True - try: - t = self.TextIOWrapper(self.BytesIO(b'aaaaaa'), - newline='\n', encoding="quopri") - finally: - quopri._is_text_encoding = False - return t - # Crash when decoder returns non-string - t = _make_illegal_wrapper() - self.assertRaises(TypeError, t.read, 1) - t = _make_illegal_wrapper() - self.assertRaises(TypeError, t.readline) - t = _make_illegal_wrapper() - self.assertRaises(TypeError, t.read) - - # Issue 31243: calling read() while the return value of decoder's - # getstate() is invalid should neither crash the interpreter nor - # raise a SystemError. - def _make_very_illegal_wrapper(getstate_ret_val): - class BadDecoder: - def getstate(self): - return getstate_ret_val - def _get_bad_decoder(dummy): - return BadDecoder() - quopri = codecs.lookup("quopri") - with support.swap_attr(quopri, 'incrementaldecoder', - _get_bad_decoder): - return _make_illegal_wrapper() - t = _make_very_illegal_wrapper(42) - self.assertRaises(TypeError, t.read, 42) - t = _make_very_illegal_wrapper(()) - self.assertRaises(TypeError, t.read, 42) - t = _make_very_illegal_wrapper((1, 2)) - self.assertRaises(TypeError, t.read, 42) - - def _check_create_at_shutdown(self, **kwargs): - # Issue #20037: creating a TextIOWrapper at shutdown - # shouldn't crash the interpreter. - iomod = self.io.__name__ - code = """if 1: - import codecs - import {iomod} as io - - # Avoid looking up codecs at shutdown - codecs.lookup('utf-8') - - class C: - def __init__(self): - self.buf = io.BytesIO() - def __del__(self): - io.TextIOWrapper(self.buf, **{kwargs}) - print("ok") - c = C() - """.format(iomod=iomod, kwargs=kwargs) - return assert_python_ok("-c", code) - - @support.requires_type_collecting - def test_create_at_shutdown_without_encoding(self): - rc, out, err = self._check_create_at_shutdown() - if err: - # Can error out with a RuntimeError if the module state - # isn't found. - self.assertIn(self.shutdown_error, err.decode()) - else: - self.assertEqual("ok", out.decode().strip()) - - @support.requires_type_collecting - def test_create_at_shutdown_with_encoding(self): - rc, out, err = self._check_create_at_shutdown(encoding='utf-8', - errors='strict') - self.assertFalse(err) - self.assertEqual("ok", out.decode().strip()) - - def test_read_byteslike(self): - r = MemviewBytesIO(b'Just some random string\n') - t = self.TextIOWrapper(r, 'utf-8') - - # TextIOwrapper will not read the full string, because - # we truncate it to a multiple of the native int size - # so that we can construct a more complex memoryview. - bytes_val = _to_memoryview(r.getvalue()).tobytes() - - self.assertEqual(t.read(200), bytes_val.decode('utf-8')) - - def test_issue22849(self): - class F(object): - def readable(self): return True - def writable(self): return True - def seekable(self): return True - - for i in range(10): - try: - self.TextIOWrapper(F(), encoding='utf-8') - except Exception: - pass - - F.tell = lambda x: 0 - t = self.TextIOWrapper(F(), encoding='utf-8') - - def test_reconfigure_encoding_read(self): - # latin1 -> utf8 - # (latin1 can decode utf-8 encoded string) - data = 'abc\xe9\n'.encode('latin1') + 'd\xe9f\n'.encode('utf8') - raw = self.BytesIO(data) - txt = self.TextIOWrapper(raw, encoding='latin1', newline='\n') - self.assertEqual(txt.readline(), 'abc\xe9\n') - with self.assertRaises(self.UnsupportedOperation): - txt.reconfigure(encoding='utf-8') - with self.assertRaises(self.UnsupportedOperation): - txt.reconfigure(newline=None) - - def test_reconfigure_write_fromascii(self): - # ascii has a specific encodefunc in the C implementation, - # but utf-8-sig has not. Make sure that we get rid of the - # cached encodefunc when we switch encoders. - raw = self.BytesIO() - txt = self.TextIOWrapper(raw, encoding='ascii', newline='\n') - txt.write('foo\n') - txt.reconfigure(encoding='utf-8-sig') - txt.write('\xe9\n') - txt.flush() - self.assertEqual(raw.getvalue(), b'foo\n\xc3\xa9\n') - - def test_reconfigure_write(self): - # latin -> utf8 - raw = self.BytesIO() - txt = self.TextIOWrapper(raw, encoding='latin1', newline='\n') - txt.write('abc\xe9\n') - txt.reconfigure(encoding='utf-8') - self.assertEqual(raw.getvalue(), b'abc\xe9\n') - txt.write('d\xe9f\n') - txt.flush() - self.assertEqual(raw.getvalue(), b'abc\xe9\nd\xc3\xa9f\n') - - # ascii -> utf-8-sig: ensure that no BOM is written in the middle of - # the file - raw = self.BytesIO() - txt = self.TextIOWrapper(raw, encoding='ascii', newline='\n') - txt.write('abc\n') - txt.reconfigure(encoding='utf-8-sig') - txt.write('d\xe9f\n') - txt.flush() - self.assertEqual(raw.getvalue(), b'abc\nd\xc3\xa9f\n') - - def test_reconfigure_write_non_seekable(self): - raw = self.BytesIO() - raw.seekable = lambda: False - raw.seek = None - txt = self.TextIOWrapper(raw, encoding='ascii', newline='\n') - txt.write('abc\n') - txt.reconfigure(encoding='utf-8-sig') - txt.write('d\xe9f\n') - txt.flush() - - # If the raw stream is not seekable, there'll be a BOM - self.assertEqual(raw.getvalue(), b'abc\n\xef\xbb\xbfd\xc3\xa9f\n') - - def test_reconfigure_defaults(self): - txt = self.TextIOWrapper(self.BytesIO(), 'ascii', 'replace', '\n') - txt.reconfigure(encoding=None) - self.assertEqual(txt.encoding, 'ascii') - self.assertEqual(txt.errors, 'replace') - txt.write('LF\n') - - txt.reconfigure(newline='\r\n') - self.assertEqual(txt.encoding, 'ascii') - self.assertEqual(txt.errors, 'replace') - - txt.reconfigure(errors='ignore') - self.assertEqual(txt.encoding, 'ascii') - self.assertEqual(txt.errors, 'ignore') - txt.write('CRLF\n') - - txt.reconfigure(encoding='utf-8', newline=None) - self.assertEqual(txt.errors, 'strict') - txt.seek(0) - self.assertEqual(txt.read(), 'LF\nCRLF\n') - - self.assertEqual(txt.detach().getvalue(), b'LF\nCRLF\r\n') - - def test_reconfigure_newline(self): - raw = self.BytesIO(b'CR\rEOF') - txt = self.TextIOWrapper(raw, 'ascii', newline='\n') - txt.reconfigure(newline=None) - self.assertEqual(txt.readline(), 'CR\n') - raw = self.BytesIO(b'CR\rEOF') - txt = self.TextIOWrapper(raw, 'ascii', newline='\n') - txt.reconfigure(newline='') - self.assertEqual(txt.readline(), 'CR\r') - raw = self.BytesIO(b'CR\rLF\nEOF') - txt = self.TextIOWrapper(raw, 'ascii', newline='\r') - txt.reconfigure(newline='\n') - self.assertEqual(txt.readline(), 'CR\rLF\n') - raw = self.BytesIO(b'LF\nCR\rEOF') - txt = self.TextIOWrapper(raw, 'ascii', newline='\n') - txt.reconfigure(newline='\r') - self.assertEqual(txt.readline(), 'LF\nCR\r') - raw = self.BytesIO(b'CR\rCRLF\r\nEOF') - txt = self.TextIOWrapper(raw, 'ascii', newline='\r') - txt.reconfigure(newline='\r\n') - self.assertEqual(txt.readline(), 'CR\rCRLF\r\n') - - txt = self.TextIOWrapper(self.BytesIO(), 'ascii', newline='\r') - txt.reconfigure(newline=None) - txt.write('linesep\n') - txt.reconfigure(newline='') - txt.write('LF\n') - txt.reconfigure(newline='\n') - txt.write('LF\n') - txt.reconfigure(newline='\r') - txt.write('CR\n') - txt.reconfigure(newline='\r\n') - txt.write('CRLF\n') - expected = 'linesep' + os.linesep + 'LF\nLF\nCR\rCRLF\r\n' - self.assertEqual(txt.detach().getvalue().decode('ascii'), expected) - - def test_issue25862(self): - # Assertion failures occurred in tell() after read() and write(). - t = self.TextIOWrapper(self.BytesIO(b'test'), encoding='ascii') - t.read(1) - t.read() - t.tell() - t = self.TextIOWrapper(self.BytesIO(b'test'), encoding='ascii') - t.read(1) - t.write('x') - t.tell() - - - class MemviewBytesIO(io.BytesIO): - '''A BytesIO object whose read method returns memoryviews - rather than bytes''' - - def read1(self, len_): - return _to_memoryview(super().read1(len_)) - - def read(self, len_): - return _to_memoryview(super().read(len_)) - - def _to_memoryview(buf): - '''Convert bytes-object *buf* to a non-trivial memoryview''' - - arr = array.array('i') - idx = len(buf) - len(buf) % arr.itemsize - arr.frombytes(buf[:idx]) - return memoryview(arr) - - - class CTextIOWrapperTest(TextIOWrapperTest): - io = io - shutdown_error = "RuntimeError: could not find io module state" - - def test_initialization(self): - r = self.BytesIO(b"\xc3\xa9\n\n") - b = self.BufferedReader(r, 1000) - t = self.TextIOWrapper(b) - self.assertRaises(ValueError, t.__init__, b, newline='xyzzy') - self.assertRaises(ValueError, t.read) - - t = self.TextIOWrapper.__new__(self.TextIOWrapper) - self.assertRaises(Exception, repr, t) - - def test_garbage_collection(self): - # C TextIOWrapper objects are collected, and collecting them flushes - # all data to disk. - # The Python version has __del__, so it ends in gc.garbage instead. - with support.check_warnings(('', ResourceWarning)): - rawio = io.FileIO(support.TESTFN, "wb") - b = self.BufferedWriter(rawio) - t = self.TextIOWrapper(b, encoding="ascii") - t.write("456def") - t.x = t - wr = weakref.ref(t) - del t - support.gc_collect() - self.assertIsNone(wr(), wr) - with self.open(support.TESTFN, "rb") as f: - self.assertEqual(f.read(), b"456def") - - def test_rwpair_cleared_before_textio(self): - # Issue 13070: TextIOWrapper's finalization would crash when called - # after the reference to the underlying BufferedRWPair's writer got - # cleared by the GC. - for i in range(1000): - b1 = self.BufferedRWPair(self.MockRawIO(), self.MockRawIO()) - t1 = self.TextIOWrapper(b1, encoding="ascii") - b2 = self.BufferedRWPair(self.MockRawIO(), self.MockRawIO()) - t2 = self.TextIOWrapper(b2, encoding="ascii") - # circular references - t1.buddy = t2 - t2.buddy = t1 - support.gc_collect() - - def test_del__CHUNK_SIZE_SystemError(self): - t = self.TextIOWrapper(self.BytesIO(), encoding='ascii') - with self.assertRaises(AttributeError): - del t._CHUNK_SIZE - - def test_internal_buffer_size(self): - # bpo-43260: TextIOWrapper's internal buffer should not store - # data larger than chunk size. - chunk_size = 8192 # default chunk size, updated later - - class MockIO(self.MockRawIO): - def write(self, data): - if len(data) > chunk_size: - raise RuntimeError - return super().write(data) - - buf = MockIO() - t = self.TextIOWrapper(buf, encoding="ascii") - chunk_size = t._CHUNK_SIZE - t.write("abc") - t.write("def") - # default chunk size is 8192 bytes so t don't write data to buf. - self.assertEqual([], buf._write_stack) - - with self.assertRaises(RuntimeError): - t.write("x"*(chunk_size+1)) - - self.assertEqual([b"abcdef"], buf._write_stack) - t.write("ghi") - t.write("x"*chunk_size) - self.assertEqual([b"abcdef", b"ghi", b"x"*chunk_size], buf._write_stack) - - - class PyTextIOWrapperTest(TextIOWrapperTest): - io = pyio - shutdown_error = "LookupError: unknown encoding: ascii" - - - class IncrementalNewlineDecoderTest(unittest.TestCase): - - def check_newline_decoding_utf8(self, decoder): - # UTF-8 specific tests for a newline decoder - def _check_decode(b, s, **kwargs): - # We exercise getstate() / setstate() as well as decode() - state = decoder.getstate() - self.assertEqual(decoder.decode(b, **kwargs), s) - decoder.setstate(state) - self.assertEqual(decoder.decode(b, **kwargs), s) - - _check_decode(b'\xe8\xa2\x88', "\u8888") - - _check_decode(b'\xe8', "") - _check_decode(b'\xa2', "") - _check_decode(b'\x88', "\u8888") - - _check_decode(b'\xe8', "") - _check_decode(b'\xa2', "") - _check_decode(b'\x88', "\u8888") - - _check_decode(b'\xe8', "") - self.assertRaises(UnicodeDecodeError, decoder.decode, b'', final=True) - - decoder.reset() - _check_decode(b'\n', "\n") - _check_decode(b'\r', "") - _check_decode(b'', "\n", final=True) - _check_decode(b'\r', "\n", final=True) - - _check_decode(b'\r', "") - _check_decode(b'a', "\na") - - _check_decode(b'\r\r\n', "\n\n") - _check_decode(b'\r', "") - _check_decode(b'\r', "\n") - _check_decode(b'\na', "\na") - - _check_decode(b'\xe8\xa2\x88\r\n', "\u8888\n") - _check_decode(b'\xe8\xa2\x88', "\u8888") - _check_decode(b'\n', "\n") - _check_decode(b'\xe8\xa2\x88\r', "\u8888") - _check_decode(b'\n', "\n") - - def check_newline_decoding(self, decoder, encoding): - result = [] - if encoding is not None: - encoder = codecs.getincrementalencoder(encoding)() - def _decode_bytewise(s): - # Decode one byte at a time - for b in encoder.encode(s): - result.append(decoder.decode(bytes([b]))) - else: - encoder = None - def _decode_bytewise(s): - # Decode one char at a time - for c in s: - result.append(decoder.decode(c)) - self.assertEqual(decoder.newlines, None) - _decode_bytewise("abc\n\r") - self.assertEqual(decoder.newlines, '\n') - _decode_bytewise("\nabc") - self.assertEqual(decoder.newlines, ('\n', '\r\n')) - _decode_bytewise("abc\r") - self.assertEqual(decoder.newlines, ('\n', '\r\n')) - _decode_bytewise("abc") - self.assertEqual(decoder.newlines, ('\r', '\n', '\r\n')) - _decode_bytewise("abc\r") - self.assertEqual("".join(result), "abc\n\nabcabc\nabcabc") - decoder.reset() - input = "abc" - if encoder is not None: - encoder.reset() - input = encoder.encode(input) - self.assertEqual(decoder.decode(input), "abc") - self.assertEqual(decoder.newlines, None) - - def test_newline_decoder(self): - encodings = ( - # None meaning the IncrementalNewlineDecoder takes unicode input - # rather than bytes input - None, 'utf-8', 'latin-1', - 'utf-16', 'utf-16-le', 'utf-16-be', - 'utf-32', 'utf-32-le', 'utf-32-be', - ) - for enc in encodings: - decoder = enc and codecs.getincrementaldecoder(enc)() - decoder = self.IncrementalNewlineDecoder(decoder, translate=True) - self.check_newline_decoding(decoder, enc) - decoder = codecs.getincrementaldecoder("utf-8")() - decoder = self.IncrementalNewlineDecoder(decoder, translate=True) - self.check_newline_decoding_utf8(decoder) - self.assertRaises(TypeError, decoder.setstate, 42) - - def test_newline_bytes(self): - # Issue 5433: Excessive optimization in IncrementalNewlineDecoder - def _check(dec): - self.assertEqual(dec.newlines, None) - self.assertEqual(dec.decode("\u0D00"), "\u0D00") - self.assertEqual(dec.newlines, None) - self.assertEqual(dec.decode("\u0A00"), "\u0A00") - self.assertEqual(dec.newlines, None) - dec = self.IncrementalNewlineDecoder(None, translate=False) - _check(dec) - dec = self.IncrementalNewlineDecoder(None, translate=True) - _check(dec) - - def test_translate(self): - # issue 35062 - for translate in (-2, -1, 1, 2): - decoder = codecs.getincrementaldecoder("utf-8")() - decoder = self.IncrementalNewlineDecoder(decoder, translate) - self.check_newline_decoding_utf8(decoder) - decoder = codecs.getincrementaldecoder("utf-8")() - decoder = self.IncrementalNewlineDecoder(decoder, translate=0) - self.assertEqual(decoder.decode(b"\r\r\n"), "\r\r\n") - - class CIncrementalNewlineDecoderTest(IncrementalNewlineDecoderTest): - pass - - class PyIncrementalNewlineDecoderTest(IncrementalNewlineDecoderTest): - pass - - - # XXX Tests for open() - - class MiscIOTest(unittest.TestCase): - - def tearDown(self): - support.unlink(support.TESTFN) - - def test___all__(self): - for name in self.io.__all__: - obj = getattr(self.io, name, None) - self.assertIsNotNone(obj, name) - if name in ("open", "open_code"): - continue - elif "error" in name.lower() or name == "UnsupportedOperation": - self.assertTrue(issubclass(obj, Exception), name) - elif not name.startswith("SEEK_"): - self.assertTrue(issubclass(obj, self.IOBase)) - - def test_attributes(self): - f = self.open(support.TESTFN, "wb", buffering=0) - self.assertEqual(f.mode, "wb") - f.close() - - with support.check_warnings(('', DeprecationWarning)): - f = self.open(support.TESTFN, "U") - self.assertEqual(f.name, support.TESTFN) - self.assertEqual(f.buffer.name, support.TESTFN) - self.assertEqual(f.buffer.raw.name, support.TESTFN) - self.assertEqual(f.mode, "U") - self.assertEqual(f.buffer.mode, "rb") - self.assertEqual(f.buffer.raw.mode, "rb") - f.close() - - f = self.open(support.TESTFN, "w+") - self.assertEqual(f.mode, "w+") - self.assertEqual(f.buffer.mode, "rb+") # Does it really matter? - self.assertEqual(f.buffer.raw.mode, "rb+") - - g = self.open(f.fileno(), "wb", closefd=False) - self.assertEqual(g.mode, "wb") - self.assertEqual(g.raw.mode, "wb") - self.assertEqual(g.name, f.fileno()) - self.assertEqual(g.raw.name, f.fileno()) - f.close() - g.close() - - def test_open_pipe_with_append(self): - # bpo-27805: Ignore ESPIPE from lseek() in open(). - r, w = os.pipe() - self.addCleanup(os.close, r) - f = self.open(w, 'a') - self.addCleanup(f.close) - # Check that the file is marked non-seekable. On Windows, however, lseek - # somehow succeeds on pipes. - if sys.platform != 'win32': - self.assertFalse(f.seekable()) - - def test_io_after_close(self): - for kwargs in [ - {"mode": "w"}, - {"mode": "wb"}, - {"mode": "w", "buffering": 1}, - {"mode": "w", "buffering": 2}, - {"mode": "wb", "buffering": 0}, - {"mode": "r"}, - {"mode": "rb"}, - {"mode": "r", "buffering": 1}, - {"mode": "r", "buffering": 2}, - {"mode": "rb", "buffering": 0}, - {"mode": "w+"}, - {"mode": "w+b"}, - {"mode": "w+", "buffering": 1}, - {"mode": "w+", "buffering": 2}, - {"mode": "w+b", "buffering": 0}, - ]: - f = self.open(support.TESTFN, **kwargs) - f.close() - self.assertRaises(ValueError, f.flush) - self.assertRaises(ValueError, f.fileno) - self.assertRaises(ValueError, f.isatty) - self.assertRaises(ValueError, f.__iter__) - if hasattr(f, "peek"): - self.assertRaises(ValueError, f.peek, 1) - self.assertRaises(ValueError, f.read) - if hasattr(f, "read1"): - self.assertRaises(ValueError, f.read1, 1024) - self.assertRaises(ValueError, f.read1) - if hasattr(f, "readall"): - self.assertRaises(ValueError, f.readall) - if hasattr(f, "readinto"): - self.assertRaises(ValueError, f.readinto, bytearray(1024)) - if hasattr(f, "readinto1"): - self.assertRaises(ValueError, f.readinto1, bytearray(1024)) - self.assertRaises(ValueError, f.readline) - self.assertRaises(ValueError, f.readlines) - self.assertRaises(ValueError, f.readlines, 1) - self.assertRaises(ValueError, f.seek, 0) - self.assertRaises(ValueError, f.tell) - self.assertRaises(ValueError, f.truncate) - self.assertRaises(ValueError, f.write, - b"" if "b" in kwargs['mode'] else "") - self.assertRaises(ValueError, f.writelines, []) - self.assertRaises(ValueError, next, f) - - def test_blockingioerror(self): - # Various BlockingIOError issues - class C(str): - pass - c = C("") - b = self.BlockingIOError(1, c) - c.b = b - b.c = c - wr = weakref.ref(c) - del c, b - support.gc_collect() - self.assertIsNone(wr(), wr) - - def test_abcs(self): - # Test the visible base classes are ABCs. - self.assertIsInstance(self.IOBase, abc.ABCMeta) - self.assertIsInstance(self.RawIOBase, abc.ABCMeta) - self.assertIsInstance(self.BufferedIOBase, abc.ABCMeta) - self.assertIsInstance(self.TextIOBase, abc.ABCMeta) - - def _check_abc_inheritance(self, abcmodule): - with self.open(support.TESTFN, "wb", buffering=0) as f: - self.assertIsInstance(f, abcmodule.IOBase) - self.assertIsInstance(f, abcmodule.RawIOBase) - self.assertNotIsInstance(f, abcmodule.BufferedIOBase) - self.assertNotIsInstance(f, abcmodule.TextIOBase) - with self.open(support.TESTFN, "wb") as f: - self.assertIsInstance(f, abcmodule.IOBase) - self.assertNotIsInstance(f, abcmodule.RawIOBase) - self.assertIsInstance(f, abcmodule.BufferedIOBase) - self.assertNotIsInstance(f, abcmodule.TextIOBase) - with self.open(support.TESTFN, "w") as f: - self.assertIsInstance(f, abcmodule.IOBase) - self.assertNotIsInstance(f, abcmodule.RawIOBase) - self.assertNotIsInstance(f, abcmodule.BufferedIOBase) - self.assertIsInstance(f, abcmodule.TextIOBase) - - def test_abc_inheritance(self): - # Test implementations inherit from their respective ABCs - self._check_abc_inheritance(self) - - def test_abc_inheritance_official(self): - # Test implementations inherit from the official ABCs of the - # baseline "io" module. - self._check_abc_inheritance(io) - - def _check_warn_on_dealloc(self, *args, **kwargs): - f = open(*args, **kwargs) - r = repr(f) - with self.assertWarns(ResourceWarning) as cm: - f = None - support.gc_collect() - self.assertIn(r, str(cm.warning.args[0])) - - def test_warn_on_dealloc(self): - self._check_warn_on_dealloc(support.TESTFN, "wb", buffering=0) - self._check_warn_on_dealloc(support.TESTFN, "wb") - self._check_warn_on_dealloc(support.TESTFN, "w") - - def _check_warn_on_dealloc_fd(self, *args, **kwargs): - fds = [] - def cleanup_fds(): - for fd in fds: - try: - os.close(fd) - except OSError as e: - if e.errno != errno.EBADF: - raise - self.addCleanup(cleanup_fds) - r, w = os.pipe() - fds += r, w - self._check_warn_on_dealloc(r, *args, **kwargs) - # When using closefd=False, there's no warning - r, w = os.pipe() - fds += r, w - with support.check_no_resource_warning(self): - open(r, *args, closefd=False, **kwargs) - - def test_warn_on_dealloc_fd(self): - self._check_warn_on_dealloc_fd("rb", buffering=0) - self._check_warn_on_dealloc_fd("rb") - self._check_warn_on_dealloc_fd("r") - - - def test_pickling(self): - # Pickling file objects is forbidden - for kwargs in [ - {"mode": "w"}, - {"mode": "wb"}, - {"mode": "wb", "buffering": 0}, - {"mode": "r"}, - {"mode": "rb"}, - {"mode": "rb", "buffering": 0}, - {"mode": "w+"}, - {"mode": "w+b"}, - {"mode": "w+b", "buffering": 0}, - ]: - for protocol in range(pickle.HIGHEST_PROTOCOL + 1): - with self.open(support.TESTFN, **kwargs) as f: - self.assertRaises(TypeError, pickle.dumps, f, protocol) - - def test_nonblock_pipe_write_bigbuf(self): - self._test_nonblock_pipe_write(16*1024) - - def test_nonblock_pipe_write_smallbuf(self): - self._test_nonblock_pipe_write(1024) - - @unittest.skipUnless(hasattr(os, 'set_blocking'), - 'os.set_blocking() required for this test') - def _test_nonblock_pipe_write(self, bufsize): - sent = [] - received = [] - r, w = os.pipe() - os.set_blocking(r, False) - os.set_blocking(w, False) - - # To exercise all code paths in the C implementation we need - # to play with buffer sizes. For instance, if we choose a - # buffer size less than or equal to _PIPE_BUF (4096 on Linux) - # then we will never get a partial write of the buffer. - rf = self.open(r, mode='rb', closefd=True, buffering=bufsize) - wf = self.open(w, mode='wb', closefd=True, buffering=bufsize) - - with rf, wf: - for N in 9999, 73, 7574: - try: - i = 0 - while True: - msg = bytes([i % 26 + 97]) * N - sent.append(msg) - wf.write(msg) - i += 1 - - except self.BlockingIOError as e: - self.assertEqual(e.args[0], errno.EAGAIN) - self.assertEqual(e.args[2], e.characters_written) - sent[-1] = sent[-1][:e.characters_written] - received.append(rf.read()) - msg = b'BLOCKED' - wf.write(msg) - sent.append(msg) - - while True: - try: - wf.flush() - break - except self.BlockingIOError as e: - self.assertEqual(e.args[0], errno.EAGAIN) - self.assertEqual(e.args[2], e.characters_written) - self.assertEqual(e.characters_written, 0) - received.append(rf.read()) - - received += iter(rf.read, None) - - sent, received = b''.join(sent), b''.join(received) - self.assertEqual(sent, received) - self.assertTrue(wf.closed) - self.assertTrue(rf.closed) - - def test_create_fail(self): - # 'x' mode fails if file is existing - with self.open(support.TESTFN, 'w'): - pass - self.assertRaises(FileExistsError, self.open, support.TESTFN, 'x') - - def test_create_writes(self): - # 'x' mode opens for writing - with self.open(support.TESTFN, 'xb') as f: - f.write(b"spam") - with self.open(support.TESTFN, 'rb') as f: - self.assertEqual(b"spam", f.read()) - - def test_open_allargs(self): - # there used to be a buffer overflow in the parser for rawmode - self.assertRaises(ValueError, self.open, support.TESTFN, 'rwax+') - - - class CMiscIOTest(MiscIOTest): - io = io - - def test_readinto_buffer_overflow(self): - # Issue #18025 - class BadReader(self.io.BufferedIOBase): - def read(self, n=-1): - return b'x' * 10**6 - bufio = BadReader() - b = bytearray(2) - self.assertRaises(ValueError, bufio.readinto, b) - - def check_daemon_threads_shutdown_deadlock(self, stream_name): - # Issue #23309: deadlocks at shutdown should be avoided when a - # daemon thread and the main thread both write to a file. - code = """if 1: - import sys - import time - import threading - from test.support import SuppressCrashReport - - file = sys.{stream_name} - - def run(): - while True: - file.write('.') - file.flush() - - crash = SuppressCrashReport() - crash.__enter__() - # don't call __exit__(): the crash occurs at Python shutdown - - thread = threading.Thread(target=run) - thread.daemon = True - thread.start() - - time.sleep(0.5) - file.write('!') - file.flush() - """.format_map(locals()) - res, _ = run_python_until_end("-c", code) - err = res.err.decode() - if res.rc != 0: - # Failure: should be a fatal error - pattern = (r"Fatal Python error: could not acquire lock " - r"for <(_io\.)?BufferedWriter name='<{stream_name}>'> " - r"at interpreter shutdown, possibly due to " - r"daemon threads".format_map(locals())) - self.assertRegex(err, pattern) - else: - self.assertFalse(err.strip('.!')) - - def test_daemon_threads_shutdown_stdout_deadlock(self): - self.check_daemon_threads_shutdown_deadlock('stdout') - - def test_daemon_threads_shutdown_stderr_deadlock(self): - self.check_daemon_threads_shutdown_deadlock('stderr') - - - class PyMiscIOTest(MiscIOTest): - io = pyio - - - @unittest.skipIf(os.name == 'nt', 'POSIX signals required for this test.') - class SignalsTest(unittest.TestCase): - - def setUp(self): - self.oldalrm = signal.signal(signal.SIGALRM, self.alarm_interrupt) - - def tearDown(self): - signal.signal(signal.SIGALRM, self.oldalrm) - - def alarm_interrupt(self, sig, frame): - 1/0 - - def check_interrupted_write(self, item, bytes, **fdopen_kwargs): - """Check that a partial write, when it gets interrupted, properly - invokes the signal handler, and bubbles up the exception raised - in the latter.""" - read_results = [] - def _read(): - s = os.read(r, 1) - read_results.append(s) - - t = threading.Thread(target=_read) - t.daemon = True - r, w = os.pipe() - fdopen_kwargs["closefd"] = False - large_data = item * (support.PIPE_MAX_SIZE // len(item) + 1) - try: - wio = self.io.open(w, **fdopen_kwargs) - if hasattr(signal, 'pthread_sigmask'): - # create the thread with SIGALRM signal blocked - signal.pthread_sigmask(signal.SIG_BLOCK, [signal.SIGALRM]) - t.start() - signal.pthread_sigmask(signal.SIG_UNBLOCK, [signal.SIGALRM]) - else: - t.start() - - # Fill the pipe enough that the write will be blocking. - # It will be interrupted by the timer armed above. Since the - # other thread has read one byte, the low-level write will - # return with a successful (partial) result rather than an EINTR. - # The buffered IO layer must check for pending signal - # handlers, which in this case will invoke alarm_interrupt(). - signal.alarm(1) - try: - self.assertRaises(ZeroDivisionError, wio.write, large_data) - finally: - signal.alarm(0) - t.join() - # We got one byte, get another one and check that it isn't a - # repeat of the first one. - read_results.append(os.read(r, 1)) - self.assertEqual(read_results, [bytes[0:1], bytes[1:2]]) - finally: - os.close(w) - os.close(r) - # This is deliberate. If we didn't close the file descriptor - # before closing wio, wio would try to flush its internal - # buffer, and block again. - try: - wio.close() - except OSError as e: - if e.errno != errno.EBADF: - raise - - def test_interrupted_write_unbuffered(self): - self.check_interrupted_write(b"xy", b"xy", mode="wb", buffering=0) - - def test_interrupted_write_buffered(self): - self.check_interrupted_write(b"xy", b"xy", mode="wb") - - def test_interrupted_write_text(self): - self.check_interrupted_write("xy", b"xy", mode="w", encoding="ascii") - - @support.no_tracing - def check_reentrant_write(self, data, **fdopen_kwargs): - def on_alarm(*args): - # Will be called reentrantly from the same thread - wio.write(data) - 1/0 - signal.signal(signal.SIGALRM, on_alarm) - r, w = os.pipe() - wio = self.io.open(w, **fdopen_kwargs) - try: - signal.alarm(1) - # Either the reentrant call to wio.write() fails with RuntimeError, - # or the signal handler raises ZeroDivisionError. - with self.assertRaises((ZeroDivisionError, RuntimeError)) as cm: - while 1: - for i in range(100): - wio.write(data) - wio.flush() - # Make sure the buffer doesn't fill up and block further writes - os.read(r, len(data) * 100) - exc = cm.exception - if isinstance(exc, RuntimeError): - self.assertTrue(str(exc).startswith("reentrant call"), str(exc)) - finally: - signal.alarm(0) - wio.close() - os.close(r) - - def test_reentrant_write_buffered(self): - self.check_reentrant_write(b"xy", mode="wb") - - def test_reentrant_write_text(self): - self.check_reentrant_write("xy", mode="w", encoding="ascii") - - def check_interrupted_read_retry(self, decode, **fdopen_kwargs): - """Check that a buffered read, when it gets interrupted (either - returning a partial result or EINTR), properly invokes the signal - handler and retries if the latter returned successfully.""" - r, w = os.pipe() - fdopen_kwargs["closefd"] = False - def alarm_handler(sig, frame): - os.write(w, b"bar") - signal.signal(signal.SIGALRM, alarm_handler) - try: - rio = self.io.open(r, **fdopen_kwargs) - os.write(w, b"foo") - signal.alarm(1) - # Expected behaviour: - # - first raw read() returns partial b"foo" - # - second raw read() returns EINTR - # - third raw read() returns b"bar" - self.assertEqual(decode(rio.read(6)), "foobar") - finally: - signal.alarm(0) - rio.close() - os.close(w) - os.close(r) - - def test_interrupted_read_retry_buffered(self): - self.check_interrupted_read_retry(lambda x: x.decode('latin1'), - mode="rb") - - def test_interrupted_read_retry_text(self): - self.check_interrupted_read_retry(lambda x: x, - mode="r") - - def check_interrupted_write_retry(self, item, **fdopen_kwargs): - """Check that a buffered write, when it gets interrupted (either - returning a partial result or EINTR), properly invokes the signal - handler and retries if the latter returned successfully.""" - select = support.import_module("select") - - # A quantity that exceeds the buffer size of an anonymous pipe's - # write end. - N = support.PIPE_MAX_SIZE - r, w = os.pipe() - fdopen_kwargs["closefd"] = False - - # We need a separate thread to read from the pipe and allow the - # write() to finish. This thread is started after the SIGALRM is - # received (forcing a first EINTR in write()). - read_results = [] - write_finished = False - error = None - def _read(): - try: - while not write_finished: - while r in select.select([r], [], [], 1.0)[0]: - s = os.read(r, 1024) - read_results.append(s) - except BaseException as exc: - nonlocal error - error = exc - t = threading.Thread(target=_read) - t.daemon = True - def alarm1(sig, frame): - signal.signal(signal.SIGALRM, alarm2) - signal.alarm(1) - def alarm2(sig, frame): - t.start() - - large_data = item * N - signal.signal(signal.SIGALRM, alarm1) - try: - wio = self.io.open(w, **fdopen_kwargs) - signal.alarm(1) - # Expected behaviour: - # - first raw write() is partial (because of the limited pipe buffer - # and the first alarm) - # - second raw write() returns EINTR (because of the second alarm) - # - subsequent write()s are successful (either partial or complete) - written = wio.write(large_data) - self.assertEqual(N, written) - - wio.flush() - write_finished = True - t.join() - - self.assertIsNone(error) - self.assertEqual(N, sum(len(x) for x in read_results)) - finally: - signal.alarm(0) - write_finished = True - os.close(w) - os.close(r) - # This is deliberate. If we didn't close the file descriptor - # before closing wio, wio would try to flush its internal - # buffer, and could block (in case of failure). - try: - wio.close() - except OSError as e: - if e.errno != errno.EBADF: - raise - - def test_interrupted_write_retry_buffered(self): - self.check_interrupted_write_retry(b"x", mode="wb") - - def test_interrupted_write_retry_text(self): - self.check_interrupted_write_retry("x", mode="w", encoding="latin1") - - - class CSignalsTest(SignalsTest): - io = io - - class PySignalsTest(SignalsTest): - io = pyio - - # Handling reentrancy issues would slow down _pyio even more, so the - # tests are disabled. - test_reentrant_write_buffered = None - test_reentrant_write_text = None - - - def load_tests(*args): - tests = (CIOTest, PyIOTest, APIMismatchTest, - CBufferedReaderTest, PyBufferedReaderTest, - CBufferedWriterTest, PyBufferedWriterTest, - CBufferedRWPairTest, PyBufferedRWPairTest, - CBufferedRandomTest, PyBufferedRandomTest, - StatefulIncrementalDecoderTest, - CIncrementalNewlineDecoderTest, PyIncrementalNewlineDecoderTest, - CTextIOWrapperTest, PyTextIOWrapperTest, - CMiscIOTest, PyMiscIOTest, - CSignalsTest, PySignalsTest, - ) - - # Put the namespaces of the IO module we are testing and some useful mock - # classes in the __dict__ of each test. - mocks = (MockRawIO, MisbehavedRawIO, MockFileIO, CloseFailureIO, - MockNonBlockWriterIO, MockUnseekableIO, MockRawIOWithoutRead, - SlowFlushRawIO) - all_members = io.__all__ + ["IncrementalNewlineDecoder"] - c_io_ns = {name : getattr(io, name) for name in all_members} - py_io_ns = {name : getattr(pyio, name) for name in all_members} - globs = globals() - c_io_ns.update((x.__name__, globs["C" + x.__name__]) for x in mocks) - py_io_ns.update((x.__name__, globs["Py" + x.__name__]) for x in mocks) - # Avoid turning open into a bound method. - py_io_ns["open"] = pyio.OpenWrapper - for test in tests: - if test.__name__.startswith("C"): - for name, obj in c_io_ns.items(): - setattr(test, name, obj) - elif test.__name__.startswith("Py"): - for name, obj in py_io_ns.items(): - setattr(test, name, obj) - - suite = unittest.TestSuite([unittest.makeSuite(test) for test in tests]) - return suite - - if __name__ == "__main__": - unittest.main() diff --git a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_ipaddress.yaml b/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_ipaddress.yaml deleted file mode 100644 index 20fd8267c..000000000 --- a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_ipaddress.yaml +++ /dev/null @@ -1,2088 +0,0 @@ -python: | - # Copyright 2007 Google Inc. - # Licensed to PSF under a Contributor Agreement. - - """Unittest for ipaddress module.""" - - - import unittest - import re - import contextlib - import functools - import operator - import pickle - import ipaddress - import weakref - from test.support import LARGEST, SMALLEST - - - class BaseTestCase(unittest.TestCase): - # One big change in ipaddress over the original ipaddr module is - # error reporting that tries to assume users *don't know the rules* - # for what constitutes an RFC compliant IP address - - # Ensuring these errors are emitted correctly in all relevant cases - # meant moving to a more systematic test structure that allows the - # test structure to map more directly to the module structure - - # Note that if the constructors are refactored so that addresses with - # multiple problems get classified differently, that's OK - just - # move the affected examples to the newly appropriate test case. - - # There is some duplication between the original relatively ad hoc - # test suite and the new systematic tests. While some redundancy in - # testing is considered preferable to accidentally deleting a valid - # test, the original test suite will likely be reduced over time as - # redundant tests are identified. - - @property - def factory(self): - raise NotImplementedError - - @contextlib.contextmanager - def assertCleanError(self, exc_type, details, *args): - """ - Ensure exception does not display a context by default - - Wraps unittest.TestCase.assertRaisesRegex - """ - if args: - details = details % args - cm = self.assertRaisesRegex(exc_type, details) - with cm as exc: - yield exc - # Ensure we produce clean tracebacks on failure - if exc.exception.__context__ is not None: - self.assertTrue(exc.exception.__suppress_context__) - - def assertAddressError(self, details, *args): - """Ensure a clean AddressValueError""" - return self.assertCleanError(ipaddress.AddressValueError, - details, *args) - - def assertNetmaskError(self, details, *args): - """Ensure a clean NetmaskValueError""" - return self.assertCleanError(ipaddress.NetmaskValueError, - details, *args) - - def assertInstancesEqual(self, lhs, rhs): - """Check constructor arguments produce equivalent instances""" - self.assertEqual(self.factory(lhs), self.factory(rhs)) - - - class CommonTestMixin: - - def test_empty_address(self): - with self.assertAddressError("Address cannot be empty"): - self.factory("") - - def test_floats_rejected(self): - with self.assertAddressError(re.escape(repr("1.0"))): - self.factory(1.0) - - def test_not_an_index_issue15559(self): - # Implementing __index__ makes for a very nasty interaction with the - # bytes constructor. Thus, we disallow implicit use as an integer - self.assertRaises(TypeError, operator.index, self.factory(1)) - self.assertRaises(TypeError, hex, self.factory(1)) - self.assertRaises(TypeError, bytes, self.factory(1)) - - def pickle_test(self, addr): - for proto in range(pickle.HIGHEST_PROTOCOL + 1): - with self.subTest(proto=proto): - x = self.factory(addr) - y = pickle.loads(pickle.dumps(x, proto)) - self.assertEqual(y, x) - - - class CommonTestMixin_v4(CommonTestMixin): - - def test_leading_zeros(self): - self.assertInstancesEqual("000.000.000.000", "0.0.0.0") - self.assertInstancesEqual("192.168.000.001", "192.168.0.1") - self.assertInstancesEqual("016.016.016.016", "16.16.16.16") - self.assertInstancesEqual("001.000.008.016", "1.0.8.16") - - def test_int(self): - self.assertInstancesEqual(0, "0.0.0.0") - self.assertInstancesEqual(3232235521, "192.168.0.1") - - def test_packed(self): - self.assertInstancesEqual(bytes.fromhex("00000000"), "0.0.0.0") - self.assertInstancesEqual(bytes.fromhex("c0a80001"), "192.168.0.1") - - def test_negative_ints_rejected(self): - msg = "-1 (< 0) is not permitted as an IPv4 address" - with self.assertAddressError(re.escape(msg)): - self.factory(-1) - - def test_large_ints_rejected(self): - msg = "%d (>= 2**32) is not permitted as an IPv4 address" - with self.assertAddressError(re.escape(msg % 2**32)): - self.factory(2**32) - - def test_bad_packed_length(self): - def assertBadLength(length): - addr = b'\0' * length - msg = "%r (len %d != 4) is not permitted as an IPv4 address" - with self.assertAddressError(re.escape(msg % (addr, length))): - self.factory(addr) - - assertBadLength(3) - assertBadLength(5) - - - class CommonTestMixin_v6(CommonTestMixin): - - def test_leading_zeros(self): - self.assertInstancesEqual("0000::0000", "::") - self.assertInstancesEqual("000::c0a8:0001", "::c0a8:1") - - def test_int(self): - self.assertInstancesEqual(0, "::") - self.assertInstancesEqual(3232235521, "::c0a8:1") - - def test_packed(self): - addr = b'\0'*12 + bytes.fromhex("00000000") - self.assertInstancesEqual(addr, "::") - addr = b'\0'*12 + bytes.fromhex("c0a80001") - self.assertInstancesEqual(addr, "::c0a8:1") - addr = bytes.fromhex("c0a80001") + b'\0'*12 - self.assertInstancesEqual(addr, "c0a8:1::") - - def test_negative_ints_rejected(self): - msg = "-1 (< 0) is not permitted as an IPv6 address" - with self.assertAddressError(re.escape(msg)): - self.factory(-1) - - def test_large_ints_rejected(self): - msg = "%d (>= 2**128) is not permitted as an IPv6 address" - with self.assertAddressError(re.escape(msg % 2**128)): - self.factory(2**128) - - def test_bad_packed_length(self): - def assertBadLength(length): - addr = b'\0' * length - msg = "%r (len %d != 16) is not permitted as an IPv6 address" - with self.assertAddressError(re.escape(msg % (addr, length))): - self.factory(addr) - self.factory(addr) - - assertBadLength(15) - assertBadLength(17) - - - class AddressTestCase_v4(BaseTestCase, CommonTestMixin_v4): - factory = ipaddress.IPv4Address - - def test_network_passed_as_address(self): - addr = "127.0.0.1/24" - with self.assertAddressError("Unexpected '/' in %r", addr): - ipaddress.IPv4Address(addr) - - def test_bad_address_split(self): - def assertBadSplit(addr): - with self.assertAddressError("Expected 4 octets in %r", addr): - ipaddress.IPv4Address(addr) - - assertBadSplit("127.0.1") - assertBadSplit("42.42.42.42.42") - assertBadSplit("42.42.42") - assertBadSplit("42.42") - assertBadSplit("42") - assertBadSplit("42..42.42.42") - assertBadSplit("42.42.42.42.") - assertBadSplit("42.42.42.42...") - assertBadSplit(".42.42.42.42") - assertBadSplit("...42.42.42.42") - assertBadSplit("016.016.016") - assertBadSplit("016.016") - assertBadSplit("016") - assertBadSplit("000") - assertBadSplit("0x0a.0x0a.0x0a") - assertBadSplit("0x0a.0x0a") - assertBadSplit("0x0a") - assertBadSplit(".") - assertBadSplit("bogus") - assertBadSplit("bogus.com") - assertBadSplit("1000") - assertBadSplit("1000000000000000") - assertBadSplit("192.168.0.1.com") - - def test_empty_octet(self): - def assertBadOctet(addr): - with self.assertAddressError("Empty octet not permitted in %r", - addr): - ipaddress.IPv4Address(addr) - - assertBadOctet("42..42.42") - assertBadOctet("...") - - def test_invalid_characters(self): - def assertBadOctet(addr, octet): - msg = "Only decimal digits permitted in %r in %r" % (octet, addr) - with self.assertAddressError(re.escape(msg)): - ipaddress.IPv4Address(addr) - - assertBadOctet("0x0a.0x0a.0x0a.0x0a", "0x0a") - assertBadOctet("0xa.0x0a.0x0a.0x0a", "0xa") - assertBadOctet("42.42.42.-0", "-0") - assertBadOctet("42.42.42.+0", "+0") - assertBadOctet("42.42.42.-42", "-42") - assertBadOctet("+1.+2.+3.4", "+1") - assertBadOctet("1.2.3.4e0", "4e0") - assertBadOctet("1.2.3.4::", "4::") - assertBadOctet("1.a.2.3", "a") - - def test_octet_length(self): - def assertBadOctet(addr, octet): - msg = "At most 3 characters permitted in %r in %r" - with self.assertAddressError(re.escape(msg % (octet, addr))): - ipaddress.IPv4Address(addr) - - assertBadOctet("0000.000.000.000", "0000") - assertBadOctet("12345.67899.-54321.-98765", "12345") - - def test_octet_limit(self): - def assertBadOctet(addr, octet): - msg = "Octet %d (> 255) not permitted in %r" % (octet, addr) - with self.assertAddressError(re.escape(msg)): - ipaddress.IPv4Address(addr) - - assertBadOctet("257.0.0.0", 257) - assertBadOctet("192.168.0.999", 999) - - def test_pickle(self): - self.pickle_test('192.0.2.1') - - def test_weakref(self): - weakref.ref(self.factory('192.0.2.1')) - - - class AddressTestCase_v6(BaseTestCase, CommonTestMixin_v6): - factory = ipaddress.IPv6Address - - def test_network_passed_as_address(self): - addr = "::1/24" - with self.assertAddressError("Unexpected '/' in %r", addr): - ipaddress.IPv6Address(addr) - - def test_bad_address_split_v6_not_enough_parts(self): - def assertBadSplit(addr): - msg = "At least 3 parts expected in %r" - with self.assertAddressError(msg, addr): - ipaddress.IPv6Address(addr) - - assertBadSplit(":") - assertBadSplit(":1") - assertBadSplit("FEDC:9878") - - def test_bad_address_split_v6_too_many_colons(self): - def assertBadSplit(addr): - msg = "At most 8 colons permitted in %r" - with self.assertAddressError(msg, addr): - ipaddress.IPv6Address(addr) - - assertBadSplit("9:8:7:6:5:4:3::2:1") - assertBadSplit("10:9:8:7:6:5:4:3:2:1") - assertBadSplit("::8:7:6:5:4:3:2:1") - assertBadSplit("8:7:6:5:4:3:2:1::") - # A trailing IPv4 address is two parts - assertBadSplit("10:9:8:7:6:5:4:3:42.42.42.42") - - def test_bad_address_split_v6_too_many_parts(self): - def assertBadSplit(addr): - msg = "Exactly 8 parts expected without '::' in %r" - with self.assertAddressError(msg, addr): - ipaddress.IPv6Address(addr) - - assertBadSplit("3ffe:0:0:0:0:0:0:0:1") - assertBadSplit("9:8:7:6:5:4:3:2:1") - assertBadSplit("7:6:5:4:3:2:1") - # A trailing IPv4 address is two parts - assertBadSplit("9:8:7:6:5:4:3:42.42.42.42") - assertBadSplit("7:6:5:4:3:42.42.42.42") - - def test_bad_address_split_v6_too_many_parts_with_double_colon(self): - def assertBadSplit(addr): - msg = "Expected at most 7 other parts with '::' in %r" - with self.assertAddressError(msg, addr): - ipaddress.IPv6Address(addr) - - assertBadSplit("1:2:3:4::5:6:7:8") - - def test_bad_address_split_v6_repeated_double_colon(self): - def assertBadSplit(addr): - msg = "At most one '::' permitted in %r" - with self.assertAddressError(msg, addr): - ipaddress.IPv6Address(addr) - - assertBadSplit("3ffe::1::1") - assertBadSplit("1::2::3::4:5") - assertBadSplit("2001::db:::1") - assertBadSplit("3ffe::1::") - assertBadSplit("::3ffe::1") - assertBadSplit(":3ffe::1::1") - assertBadSplit("3ffe::1::1:") - assertBadSplit(":3ffe::1::1:") - assertBadSplit(":::") - assertBadSplit('2001:db8:::1') - - def test_bad_address_split_v6_leading_colon(self): - def assertBadSplit(addr): - msg = "Leading ':' only permitted as part of '::' in %r" - with self.assertAddressError(msg, addr): - ipaddress.IPv6Address(addr) - - assertBadSplit(":2001:db8::1") - assertBadSplit(":1:2:3:4:5:6:7") - assertBadSplit(":1:2:3:4:5:6:") - assertBadSplit(":6:5:4:3:2:1::") - - def test_bad_address_split_v6_trailing_colon(self): - def assertBadSplit(addr): - msg = "Trailing ':' only permitted as part of '::' in %r" - with self.assertAddressError(msg, addr): - ipaddress.IPv6Address(addr) - - assertBadSplit("2001:db8::1:") - assertBadSplit("1:2:3:4:5:6:7:") - assertBadSplit("::1.2.3.4:") - assertBadSplit("::7:6:5:4:3:2:") - - def test_bad_v4_part_in(self): - def assertBadAddressPart(addr, v4_error): - with self.assertAddressError("%s in %r", v4_error, addr): - ipaddress.IPv6Address(addr) - - assertBadAddressPart("3ffe::1.net", "Expected 4 octets in '1.net'") - assertBadAddressPart("3ffe::127.0.1", - "Expected 4 octets in '127.0.1'") - assertBadAddressPart("::1.2.3", - "Expected 4 octets in '1.2.3'") - assertBadAddressPart("::1.2.3.4.5", - "Expected 4 octets in '1.2.3.4.5'") - assertBadAddressPart("3ffe::1.1.1.net", - "Only decimal digits permitted in 'net' " - "in '1.1.1.net'") - - def test_invalid_characters(self): - def assertBadPart(addr, part): - msg = "Only hex digits permitted in %r in %r" % (part, addr) - with self.assertAddressError(re.escape(msg)): - ipaddress.IPv6Address(addr) - - assertBadPart("3ffe::goog", "goog") - assertBadPart("3ffe::-0", "-0") - assertBadPart("3ffe::+0", "+0") - assertBadPart("3ffe::-1", "-1") - assertBadPart("1.2.3.4::", "1.2.3.4") - assertBadPart('1234:axy::b', "axy") - - def test_part_length(self): - def assertBadPart(addr, part): - msg = "At most 4 characters permitted in %r in %r" - with self.assertAddressError(msg, part, addr): - ipaddress.IPv6Address(addr) - - assertBadPart("::00000", "00000") - assertBadPart("3ffe::10000", "10000") - assertBadPart("02001:db8::", "02001") - assertBadPart('2001:888888::1', "888888") - - def test_pickle(self): - self.pickle_test('2001:db8::') - - def test_weakref(self): - weakref.ref(self.factory('2001:db8::')) - - - class NetmaskTestMixin_v4(CommonTestMixin_v4): - """Input validation on interfaces and networks is very similar""" - - def test_no_mask(self): - for address in ('1.2.3.4', 0x01020304, b'\x01\x02\x03\x04'): - net = self.factory(address) - self.assertEqual(str(net), '1.2.3.4/32') - self.assertEqual(str(net.netmask), '255.255.255.255') - self.assertEqual(str(net.hostmask), '0.0.0.0') - # IPv4Network has prefixlen, but IPv4Interface doesn't. - # Should we add it to IPv4Interface too? (bpo-36392) - - def test_split_netmask(self): - addr = "1.2.3.4/32/24" - with self.assertAddressError("Only one '/' permitted in %r" % addr): - self.factory(addr) - - def test_address_errors(self): - def assertBadAddress(addr, details): - with self.assertAddressError(details): - self.factory(addr) - - assertBadAddress("/", "Address cannot be empty") - assertBadAddress("/8", "Address cannot be empty") - assertBadAddress("bogus", "Expected 4 octets") - assertBadAddress("google.com", "Expected 4 octets") - assertBadAddress("10/8", "Expected 4 octets") - assertBadAddress("::1.2.3.4", "Only decimal digits") - assertBadAddress("1.2.3.256", re.escape("256 (> 255)")) - - def test_valid_netmask(self): - self.assertEqual(str(self.factory('192.0.2.0/255.255.255.0')), - '192.0.2.0/24') - for i in range(0, 33): - # Generate and re-parse the CIDR format (trivial). - net_str = '0.0.0.0/%d' % i - net = self.factory(net_str) - self.assertEqual(str(net), net_str) - # Generate and re-parse the expanded netmask. - self.assertEqual( - str(self.factory('0.0.0.0/%s' % net.netmask)), net_str) - # Zero prefix is treated as decimal. - self.assertEqual(str(self.factory('0.0.0.0/0%d' % i)), net_str) - # Generate and re-parse the expanded hostmask. The ambiguous - # cases (/0 and /32) are treated as netmasks. - if i in (32, 0): - net_str = '0.0.0.0/%d' % (32 - i) - self.assertEqual( - str(self.factory('0.0.0.0/%s' % net.hostmask)), net_str) - - def test_netmask_errors(self): - def assertBadNetmask(addr, netmask): - msg = "%r is not a valid netmask" % netmask - with self.assertNetmaskError(re.escape(msg)): - self.factory("%s/%s" % (addr, netmask)) - - assertBadNetmask("1.2.3.4", "") - assertBadNetmask("1.2.3.4", "-1") - assertBadNetmask("1.2.3.4", "+1") - assertBadNetmask("1.2.3.4", " 1 ") - assertBadNetmask("1.2.3.4", "0x1") - assertBadNetmask("1.2.3.4", "33") - assertBadNetmask("1.2.3.4", "254.254.255.256") - assertBadNetmask("1.2.3.4", "1.a.2.3") - assertBadNetmask("1.1.1.1", "254.xyz.2.3") - assertBadNetmask("1.1.1.1", "240.255.0.0") - assertBadNetmask("1.1.1.1", "255.254.128.0") - assertBadNetmask("1.1.1.1", "0.1.127.255") - assertBadNetmask("1.1.1.1", "pudding") - assertBadNetmask("1.1.1.1", "::") - - def test_netmask_in_tuple_errors(self): - def assertBadNetmask(addr, netmask): - msg = "%r is not a valid netmask" % netmask - with self.assertNetmaskError(re.escape(msg)): - self.factory((addr, netmask)) - assertBadNetmask("1.1.1.1", -1) - assertBadNetmask("1.1.1.1", 33) - - def test_pickle(self): - self.pickle_test('192.0.2.0/27') - self.pickle_test('192.0.2.0/31') # IPV4LENGTH - 1 - self.pickle_test('192.0.2.0') # IPV4LENGTH - - - class InterfaceTestCase_v4(BaseTestCase, NetmaskTestMixin_v4): - factory = ipaddress.IPv4Interface - - - class NetworkTestCase_v4(BaseTestCase, NetmaskTestMixin_v4): - factory = ipaddress.IPv4Network - - def test_subnet_of(self): - # containee left of container - self.assertFalse( - self.factory('10.0.0.0/30').subnet_of( - self.factory('10.0.1.0/24'))) - # containee inside container - self.assertTrue( - self.factory('10.0.0.0/30').subnet_of( - self.factory('10.0.0.0/24'))) - # containee right of container - self.assertFalse( - self.factory('10.0.0.0/30').subnet_of( - self.factory('10.0.1.0/24'))) - # containee larger than container - self.assertFalse( - self.factory('10.0.1.0/24').subnet_of( - self.factory('10.0.0.0/30'))) - - def test_supernet_of(self): - # containee left of container - self.assertFalse( - self.factory('10.0.0.0/30').supernet_of( - self.factory('10.0.1.0/24'))) - # containee inside container - self.assertFalse( - self.factory('10.0.0.0/30').supernet_of( - self.factory('10.0.0.0/24'))) - # containee right of container - self.assertFalse( - self.factory('10.0.0.0/30').supernet_of( - self.factory('10.0.1.0/24'))) - # containee larger than container - self.assertTrue( - self.factory('10.0.0.0/24').supernet_of( - self.factory('10.0.0.0/30'))) - - def test_subnet_of_mixed_types(self): - with self.assertRaises(TypeError): - ipaddress.IPv4Network('10.0.0.0/30').supernet_of( - ipaddress.IPv6Network('::1/128')) - with self.assertRaises(TypeError): - ipaddress.IPv6Network('::1/128').supernet_of( - ipaddress.IPv4Network('10.0.0.0/30')) - with self.assertRaises(TypeError): - ipaddress.IPv4Network('10.0.0.0/30').subnet_of( - ipaddress.IPv6Network('::1/128')) - with self.assertRaises(TypeError): - ipaddress.IPv6Network('::1/128').subnet_of( - ipaddress.IPv4Network('10.0.0.0/30')) - - - class NetmaskTestMixin_v6(CommonTestMixin_v6): - """Input validation on interfaces and networks is very similar""" - - def test_no_mask(self): - for address in ('::1', 1, b'\x00'*15 + b'\x01'): - net = self.factory(address) - self.assertEqual(str(net), '::1/128') - self.assertEqual(str(net.netmask), 'ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff') - self.assertEqual(str(net.hostmask), '::') - # IPv6Network has prefixlen, but IPv6Interface doesn't. - # Should we add it to IPv4Interface too? (bpo-36392) - - def test_split_netmask(self): - addr = "cafe:cafe::/128/190" - with self.assertAddressError("Only one '/' permitted in %r" % addr): - self.factory(addr) - - def test_address_errors(self): - def assertBadAddress(addr, details): - with self.assertAddressError(details): - self.factory(addr) - - assertBadAddress("/", "Address cannot be empty") - assertBadAddress("/8", "Address cannot be empty") - assertBadAddress("google.com", "At least 3 parts") - assertBadAddress("1.2.3.4", "At least 3 parts") - assertBadAddress("10/8", "At least 3 parts") - assertBadAddress("1234:axy::b", "Only hex digits") - - def test_valid_netmask(self): - # We only support CIDR for IPv6, because expanded netmasks are not - # standard notation. - self.assertEqual(str(self.factory('2001:db8::/32')), '2001:db8::/32') - for i in range(0, 129): - # Generate and re-parse the CIDR format (trivial). - net_str = '::/%d' % i - self.assertEqual(str(self.factory(net_str)), net_str) - # Zero prefix is treated as decimal. - self.assertEqual(str(self.factory('::/0%d' % i)), net_str) - - def test_netmask_errors(self): - def assertBadNetmask(addr, netmask): - msg = "%r is not a valid netmask" % netmask - with self.assertNetmaskError(re.escape(msg)): - self.factory("%s/%s" % (addr, netmask)) - - assertBadNetmask("::1", "") - assertBadNetmask("::1", "::1") - assertBadNetmask("::1", "1::") - assertBadNetmask("::1", "-1") - assertBadNetmask("::1", "+1") - assertBadNetmask("::1", " 1 ") - assertBadNetmask("::1", "0x1") - assertBadNetmask("::1", "129") - assertBadNetmask("::1", "1.2.3.4") - assertBadNetmask("::1", "pudding") - assertBadNetmask("::", "::") - - def test_netmask_in_tuple_errors(self): - def assertBadNetmask(addr, netmask): - msg = "%r is not a valid netmask" % netmask - with self.assertNetmaskError(re.escape(msg)): - self.factory((addr, netmask)) - assertBadNetmask("::1", -1) - assertBadNetmask("::1", 129) - - def test_pickle(self): - self.pickle_test('2001:db8::1000/124') - self.pickle_test('2001:db8::1000/127') # IPV6LENGTH - 1 - self.pickle_test('2001:db8::1000') # IPV6LENGTH - - - class InterfaceTestCase_v6(BaseTestCase, NetmaskTestMixin_v6): - factory = ipaddress.IPv6Interface - - - class NetworkTestCase_v6(BaseTestCase, NetmaskTestMixin_v6): - factory = ipaddress.IPv6Network - - def test_subnet_of(self): - # containee left of container - self.assertFalse( - self.factory('2000:999::/56').subnet_of( - self.factory('2000:aaa::/48'))) - # containee inside container - self.assertTrue( - self.factory('2000:aaa::/56').subnet_of( - self.factory('2000:aaa::/48'))) - # containee right of container - self.assertFalse( - self.factory('2000:bbb::/56').subnet_of( - self.factory('2000:aaa::/48'))) - # containee larger than container - self.assertFalse( - self.factory('2000:aaa::/48').subnet_of( - self.factory('2000:aaa::/56'))) - - def test_supernet_of(self): - # containee left of container - self.assertFalse( - self.factory('2000:999::/56').supernet_of( - self.factory('2000:aaa::/48'))) - # containee inside container - self.assertFalse( - self.factory('2000:aaa::/56').supernet_of( - self.factory('2000:aaa::/48'))) - # containee right of container - self.assertFalse( - self.factory('2000:bbb::/56').supernet_of( - self.factory('2000:aaa::/48'))) - # containee larger than container - self.assertTrue( - self.factory('2000:aaa::/48').supernet_of( - self.factory('2000:aaa::/56'))) - - - class FactoryFunctionErrors(BaseTestCase): - - def assertFactoryError(self, factory, kind): - """Ensure a clean ValueError with the expected message""" - addr = "camelot" - msg = '%r does not appear to be an IPv4 or IPv6 %s' - with self.assertCleanError(ValueError, msg, addr, kind): - factory(addr) - - def test_ip_address(self): - self.assertFactoryError(ipaddress.ip_address, "address") - - def test_ip_interface(self): - self.assertFactoryError(ipaddress.ip_interface, "interface") - - def test_ip_network(self): - self.assertFactoryError(ipaddress.ip_network, "network") - - - class ComparisonTests(unittest.TestCase): - - v4addr = ipaddress.IPv4Address(1) - v4net = ipaddress.IPv4Network(1) - v4intf = ipaddress.IPv4Interface(1) - v6addr = ipaddress.IPv6Address(1) - v6net = ipaddress.IPv6Network(1) - v6intf = ipaddress.IPv6Interface(1) - - v4_addresses = [v4addr, v4intf] - v4_objects = v4_addresses + [v4net] - v6_addresses = [v6addr, v6intf] - v6_objects = v6_addresses + [v6net] - - objects = v4_objects + v6_objects - - v4addr2 = ipaddress.IPv4Address(2) - v4net2 = ipaddress.IPv4Network(2) - v4intf2 = ipaddress.IPv4Interface(2) - v6addr2 = ipaddress.IPv6Address(2) - v6net2 = ipaddress.IPv6Network(2) - v6intf2 = ipaddress.IPv6Interface(2) - - def test_foreign_type_equality(self): - # __eq__ should never raise TypeError directly - other = object() - for obj in self.objects: - self.assertNotEqual(obj, other) - self.assertFalse(obj == other) - self.assertEqual(obj.__eq__(other), NotImplemented) - self.assertEqual(obj.__ne__(other), NotImplemented) - - def test_mixed_type_equality(self): - # Ensure none of the internal objects accidentally - # expose the right set of attributes to become "equal" - for lhs in self.objects: - for rhs in self.objects: - if lhs is rhs: - continue - self.assertNotEqual(lhs, rhs) - - def test_same_type_equality(self): - for obj in self.objects: - self.assertEqual(obj, obj) - self.assertLessEqual(obj, obj) - self.assertGreaterEqual(obj, obj) - - def test_same_type_ordering(self): - for lhs, rhs in ( - (self.v4addr, self.v4addr2), - (self.v4net, self.v4net2), - (self.v4intf, self.v4intf2), - (self.v6addr, self.v6addr2), - (self.v6net, self.v6net2), - (self.v6intf, self.v6intf2), - ): - self.assertNotEqual(lhs, rhs) - self.assertLess(lhs, rhs) - self.assertLessEqual(lhs, rhs) - self.assertGreater(rhs, lhs) - self.assertGreaterEqual(rhs, lhs) - self.assertFalse(lhs > rhs) - self.assertFalse(rhs < lhs) - self.assertFalse(lhs >= rhs) - self.assertFalse(rhs <= lhs) - - def test_containment(self): - for obj in self.v4_addresses: - self.assertIn(obj, self.v4net) - for obj in self.v6_addresses: - self.assertIn(obj, self.v6net) - for obj in self.v4_objects + [self.v6net]: - self.assertNotIn(obj, self.v6net) - for obj in self.v6_objects + [self.v4net]: - self.assertNotIn(obj, self.v4net) - - def test_mixed_type_ordering(self): - for lhs in self.objects: - for rhs in self.objects: - if isinstance(lhs, type(rhs)) or isinstance(rhs, type(lhs)): - continue - self.assertRaises(TypeError, lambda: lhs < rhs) - self.assertRaises(TypeError, lambda: lhs > rhs) - self.assertRaises(TypeError, lambda: lhs <= rhs) - self.assertRaises(TypeError, lambda: lhs >= rhs) - - def test_foreign_type_ordering(self): - other = object() - for obj in self.objects: - with self.assertRaises(TypeError): - obj < other - with self.assertRaises(TypeError): - obj > other - with self.assertRaises(TypeError): - obj <= other - with self.assertRaises(TypeError): - obj >= other - self.assertTrue(obj < LARGEST) - self.assertFalse(obj > LARGEST) - self.assertTrue(obj <= LARGEST) - self.assertFalse(obj >= LARGEST) - self.assertFalse(obj < SMALLEST) - self.assertTrue(obj > SMALLEST) - self.assertFalse(obj <= SMALLEST) - self.assertTrue(obj >= SMALLEST) - - def test_mixed_type_key(self): - # with get_mixed_type_key, you can sort addresses and network. - v4_ordered = [self.v4addr, self.v4net, self.v4intf] - v6_ordered = [self.v6addr, self.v6net, self.v6intf] - self.assertEqual(v4_ordered, - sorted(self.v4_objects, - key=ipaddress.get_mixed_type_key)) - self.assertEqual(v6_ordered, - sorted(self.v6_objects, - key=ipaddress.get_mixed_type_key)) - self.assertEqual(v4_ordered + v6_ordered, - sorted(self.objects, - key=ipaddress.get_mixed_type_key)) - self.assertEqual(NotImplemented, ipaddress.get_mixed_type_key(object)) - - def test_incompatible_versions(self): - # These should always raise TypeError - v4addr = ipaddress.ip_address('1.1.1.1') - v4net = ipaddress.ip_network('1.1.1.1') - v6addr = ipaddress.ip_address('::1') - v6net = ipaddress.ip_network('::1') - - self.assertRaises(TypeError, v4addr.__lt__, v6addr) - self.assertRaises(TypeError, v4addr.__gt__, v6addr) - self.assertRaises(TypeError, v4net.__lt__, v6net) - self.assertRaises(TypeError, v4net.__gt__, v6net) - - self.assertRaises(TypeError, v6addr.__lt__, v4addr) - self.assertRaises(TypeError, v6addr.__gt__, v4addr) - self.assertRaises(TypeError, v6net.__lt__, v4net) - self.assertRaises(TypeError, v6net.__gt__, v4net) - - - class IpaddrUnitTest(unittest.TestCase): - - def setUp(self): - self.ipv4_address = ipaddress.IPv4Address('1.2.3.4') - self.ipv4_interface = ipaddress.IPv4Interface('1.2.3.4/24') - self.ipv4_network = ipaddress.IPv4Network('1.2.3.0/24') - #self.ipv4_hostmask = ipaddress.IPv4Interface('10.0.0.1/0.255.255.255') - self.ipv6_address = ipaddress.IPv6Interface( - '2001:658:22a:cafe:200:0:0:1') - self.ipv6_interface = ipaddress.IPv6Interface( - '2001:658:22a:cafe:200:0:0:1/64') - self.ipv6_network = ipaddress.IPv6Network('2001:658:22a:cafe::/64') - - def testRepr(self): - self.assertEqual("IPv4Interface('1.2.3.4/32')", - repr(ipaddress.IPv4Interface('1.2.3.4'))) - self.assertEqual("IPv6Interface('::1/128')", - repr(ipaddress.IPv6Interface('::1'))) - - # issue #16531: constructing IPv4Network from an (address, mask) tuple - def testIPv4Tuple(self): - # /32 - ip = ipaddress.IPv4Address('192.0.2.1') - net = ipaddress.IPv4Network('192.0.2.1/32') - self.assertEqual(ipaddress.IPv4Network(('192.0.2.1', 32)), net) - self.assertEqual(ipaddress.IPv4Network((ip, 32)), net) - self.assertEqual(ipaddress.IPv4Network((3221225985, 32)), net) - self.assertEqual(ipaddress.IPv4Network(('192.0.2.1', - '255.255.255.255')), net) - self.assertEqual(ipaddress.IPv4Network((ip, - '255.255.255.255')), net) - self.assertEqual(ipaddress.IPv4Network((3221225985, - '255.255.255.255')), net) - # strict=True and host bits set - with self.assertRaises(ValueError): - ipaddress.IPv4Network(('192.0.2.1', 24)) - with self.assertRaises(ValueError): - ipaddress.IPv4Network((ip, 24)) - with self.assertRaises(ValueError): - ipaddress.IPv4Network((3221225985, 24)) - with self.assertRaises(ValueError): - ipaddress.IPv4Network(('192.0.2.1', '255.255.255.0')) - with self.assertRaises(ValueError): - ipaddress.IPv4Network((ip, '255.255.255.0')) - with self.assertRaises(ValueError): - ipaddress.IPv4Network((3221225985, '255.255.255.0')) - # strict=False and host bits set - net = ipaddress.IPv4Network('192.0.2.0/24') - self.assertEqual(ipaddress.IPv4Network(('192.0.2.1', 24), - strict=False), net) - self.assertEqual(ipaddress.IPv4Network((ip, 24), - strict=False), net) - self.assertEqual(ipaddress.IPv4Network((3221225985, 24), - strict=False), net) - self.assertEqual(ipaddress.IPv4Network(('192.0.2.1', - '255.255.255.0'), - strict=False), net) - self.assertEqual(ipaddress.IPv4Network((ip, - '255.255.255.0'), - strict=False), net) - self.assertEqual(ipaddress.IPv4Network((3221225985, - '255.255.255.0'), - strict=False), net) - - # /24 - ip = ipaddress.IPv4Address('192.0.2.0') - net = ipaddress.IPv4Network('192.0.2.0/24') - self.assertEqual(ipaddress.IPv4Network(('192.0.2.0', - '255.255.255.0')), net) - self.assertEqual(ipaddress.IPv4Network((ip, - '255.255.255.0')), net) - self.assertEqual(ipaddress.IPv4Network((3221225984, - '255.255.255.0')), net) - self.assertEqual(ipaddress.IPv4Network(('192.0.2.0', 24)), net) - self.assertEqual(ipaddress.IPv4Network((ip, 24)), net) - self.assertEqual(ipaddress.IPv4Network((3221225984, 24)), net) - - self.assertEqual(ipaddress.IPv4Interface(('192.0.2.1', 24)), - ipaddress.IPv4Interface('192.0.2.1/24')) - self.assertEqual(ipaddress.IPv4Interface((3221225985, 24)), - ipaddress.IPv4Interface('192.0.2.1/24')) - - # issue #16531: constructing IPv6Network from an (address, mask) tuple - def testIPv6Tuple(self): - # /128 - ip = ipaddress.IPv6Address('2001:db8::') - net = ipaddress.IPv6Network('2001:db8::/128') - self.assertEqual(ipaddress.IPv6Network(('2001:db8::', '128')), - net) - self.assertEqual(ipaddress.IPv6Network( - (42540766411282592856903984951653826560, 128)), - net) - self.assertEqual(ipaddress.IPv6Network((ip, '128')), - net) - ip = ipaddress.IPv6Address('2001:db8::') - net = ipaddress.IPv6Network('2001:db8::/96') - self.assertEqual(ipaddress.IPv6Network(('2001:db8::', '96')), - net) - self.assertEqual(ipaddress.IPv6Network( - (42540766411282592856903984951653826560, 96)), - net) - self.assertEqual(ipaddress.IPv6Network((ip, '96')), - net) - - # strict=True and host bits set - ip = ipaddress.IPv6Address('2001:db8::1') - with self.assertRaises(ValueError): - ipaddress.IPv6Network(('2001:db8::1', 96)) - with self.assertRaises(ValueError): - ipaddress.IPv6Network(( - 42540766411282592856903984951653826561, 96)) - with self.assertRaises(ValueError): - ipaddress.IPv6Network((ip, 96)) - # strict=False and host bits set - net = ipaddress.IPv6Network('2001:db8::/96') - self.assertEqual(ipaddress.IPv6Network(('2001:db8::1', 96), - strict=False), - net) - self.assertEqual(ipaddress.IPv6Network( - (42540766411282592856903984951653826561, 96), - strict=False), - net) - self.assertEqual(ipaddress.IPv6Network((ip, 96), strict=False), - net) - - # /96 - self.assertEqual(ipaddress.IPv6Interface(('2001:db8::1', '96')), - ipaddress.IPv6Interface('2001:db8::1/96')) - self.assertEqual(ipaddress.IPv6Interface( - (42540766411282592856903984951653826561, '96')), - ipaddress.IPv6Interface('2001:db8::1/96')) - - # issue57 - def testAddressIntMath(self): - self.assertEqual(ipaddress.IPv4Address('1.1.1.1') + 255, - ipaddress.IPv4Address('1.1.2.0')) - self.assertEqual(ipaddress.IPv4Address('1.1.1.1') - 256, - ipaddress.IPv4Address('1.1.0.1')) - self.assertEqual(ipaddress.IPv6Address('::1') + (2**16 - 2), - ipaddress.IPv6Address('::ffff')) - self.assertEqual(ipaddress.IPv6Address('::ffff') - (2**16 - 2), - ipaddress.IPv6Address('::1')) - - def testInvalidIntToBytes(self): - self.assertRaises(ValueError, ipaddress.v4_int_to_packed, -1) - self.assertRaises(ValueError, ipaddress.v4_int_to_packed, - 2 ** ipaddress.IPV4LENGTH) - self.assertRaises(ValueError, ipaddress.v6_int_to_packed, -1) - self.assertRaises(ValueError, ipaddress.v6_int_to_packed, - 2 ** ipaddress.IPV6LENGTH) - - def testInternals(self): - ip1 = ipaddress.IPv4Address('10.10.10.10') - ip2 = ipaddress.IPv4Address('10.10.10.11') - ip3 = ipaddress.IPv4Address('10.10.10.12') - self.assertEqual(list(ipaddress._find_address_range([ip1])), - [(ip1, ip1)]) - self.assertEqual(list(ipaddress._find_address_range([ip1, ip3])), - [(ip1, ip1), (ip3, ip3)]) - self.assertEqual(list(ipaddress._find_address_range([ip1, ip2, ip3])), - [(ip1, ip3)]) - self.assertEqual(128, ipaddress._count_righthand_zero_bits(0, 128)) - self.assertEqual("IPv4Network('1.2.3.0/24')", repr(self.ipv4_network)) - - def testGetNetwork(self): - self.assertEqual(int(self.ipv4_network.network_address), 16909056) - self.assertEqual(str(self.ipv4_network.network_address), '1.2.3.0') - - self.assertEqual(int(self.ipv6_network.network_address), - 42540616829182469433403647294022090752) - self.assertEqual(str(self.ipv6_network.network_address), - '2001:658:22a:cafe::') - self.assertEqual(str(self.ipv6_network.hostmask), - '::ffff:ffff:ffff:ffff') - - def testIpFromInt(self): - self.assertEqual(self.ipv4_interface._ip, - ipaddress.IPv4Interface(16909060)._ip) - - ipv4 = ipaddress.ip_network('1.2.3.4') - ipv6 = ipaddress.ip_network('2001:658:22a:cafe:200:0:0:1') - self.assertEqual(ipv4, ipaddress.ip_network(int(ipv4.network_address))) - self.assertEqual(ipv6, ipaddress.ip_network(int(ipv6.network_address))) - - v6_int = 42540616829182469433547762482097946625 - self.assertEqual(self.ipv6_interface._ip, - ipaddress.IPv6Interface(v6_int)._ip) - - self.assertEqual(ipaddress.ip_network(self.ipv4_address._ip).version, - 4) - self.assertEqual(ipaddress.ip_network(self.ipv6_address._ip).version, - 6) - - def testIpFromPacked(self): - address = ipaddress.ip_address - self.assertEqual(self.ipv4_interface._ip, - ipaddress.ip_interface(b'\x01\x02\x03\x04')._ip) - self.assertEqual(address('255.254.253.252'), - address(b'\xff\xfe\xfd\xfc')) - self.assertEqual(self.ipv6_interface.ip, - ipaddress.ip_interface( - b'\x20\x01\x06\x58\x02\x2a\xca\xfe' - b'\x02\x00\x00\x00\x00\x00\x00\x01').ip) - self.assertEqual(address('ffff:2:3:4:ffff::'), - address(b'\xff\xff\x00\x02\x00\x03\x00\x04' + - b'\xff\xff' + b'\x00' * 6)) - self.assertEqual(address('::'), - address(b'\x00' * 16)) - - def testGetIp(self): - self.assertEqual(int(self.ipv4_interface.ip), 16909060) - self.assertEqual(str(self.ipv4_interface.ip), '1.2.3.4') - - self.assertEqual(int(self.ipv6_interface.ip), - 42540616829182469433547762482097946625) - self.assertEqual(str(self.ipv6_interface.ip), - '2001:658:22a:cafe:200::1') - - def testGetNetmask(self): - self.assertEqual(int(self.ipv4_network.netmask), 4294967040) - self.assertEqual(str(self.ipv4_network.netmask), '255.255.255.0') - self.assertEqual(int(self.ipv6_network.netmask), - 340282366920938463444927863358058659840) - self.assertEqual(self.ipv6_network.prefixlen, 64) - - def testZeroNetmask(self): - ipv4_zero_netmask = ipaddress.IPv4Interface('1.2.3.4/0') - self.assertEqual(int(ipv4_zero_netmask.network.netmask), 0) - self.assertEqual(ipv4_zero_netmask._prefix_from_prefix_string('0'), 0) - - ipv6_zero_netmask = ipaddress.IPv6Interface('::1/0') - self.assertEqual(int(ipv6_zero_netmask.network.netmask), 0) - self.assertEqual(ipv6_zero_netmask._prefix_from_prefix_string('0'), 0) - - def testIPv4Net(self): - net = ipaddress.IPv4Network('127.0.0.0/0.0.0.255') - self.assertEqual(net.prefixlen, 24) - - def testGetBroadcast(self): - self.assertEqual(int(self.ipv4_network.broadcast_address), 16909311) - self.assertEqual(str(self.ipv4_network.broadcast_address), '1.2.3.255') - - self.assertEqual(int(self.ipv6_network.broadcast_address), - 42540616829182469451850391367731642367) - self.assertEqual(str(self.ipv6_network.broadcast_address), - '2001:658:22a:cafe:ffff:ffff:ffff:ffff') - - def testGetPrefixlen(self): - self.assertEqual(self.ipv4_interface.network.prefixlen, 24) - self.assertEqual(self.ipv6_interface.network.prefixlen, 64) - - def testGetSupernet(self): - self.assertEqual(self.ipv4_network.supernet().prefixlen, 23) - self.assertEqual(str(self.ipv4_network.supernet().network_address), - '1.2.2.0') - self.assertEqual( - ipaddress.IPv4Interface('0.0.0.0/0').network.supernet(), - ipaddress.IPv4Network('0.0.0.0/0')) - - self.assertEqual(self.ipv6_network.supernet().prefixlen, 63) - self.assertEqual(str(self.ipv6_network.supernet().network_address), - '2001:658:22a:cafe::') - self.assertEqual(ipaddress.IPv6Interface('::0/0').network.supernet(), - ipaddress.IPv6Network('::0/0')) - - def testGetSupernet3(self): - self.assertEqual(self.ipv4_network.supernet(3).prefixlen, 21) - self.assertEqual(str(self.ipv4_network.supernet(3).network_address), - '1.2.0.0') - - self.assertEqual(self.ipv6_network.supernet(3).prefixlen, 61) - self.assertEqual(str(self.ipv6_network.supernet(3).network_address), - '2001:658:22a:caf8::') - - def testGetSupernet4(self): - self.assertRaises(ValueError, self.ipv4_network.supernet, - prefixlen_diff=2, new_prefix=1) - self.assertRaises(ValueError, self.ipv4_network.supernet, - new_prefix=25) - self.assertEqual(self.ipv4_network.supernet(prefixlen_diff=2), - self.ipv4_network.supernet(new_prefix=22)) - - self.assertRaises(ValueError, self.ipv6_network.supernet, - prefixlen_diff=2, new_prefix=1) - self.assertRaises(ValueError, self.ipv6_network.supernet, - new_prefix=65) - self.assertEqual(self.ipv6_network.supernet(prefixlen_diff=2), - self.ipv6_network.supernet(new_prefix=62)) - - def testHosts(self): - hosts = list(self.ipv4_network.hosts()) - self.assertEqual(254, len(hosts)) - self.assertEqual(ipaddress.IPv4Address('1.2.3.1'), hosts[0]) - self.assertEqual(ipaddress.IPv4Address('1.2.3.254'), hosts[-1]) - - ipv6_network = ipaddress.IPv6Network('2001:658:22a:cafe::/120') - hosts = list(ipv6_network.hosts()) - self.assertEqual(255, len(hosts)) - self.assertEqual(ipaddress.IPv6Address('2001:658:22a:cafe::1'), hosts[0]) - self.assertEqual(ipaddress.IPv6Address('2001:658:22a:cafe::ff'), hosts[-1]) - - # special case where only 1 bit is left for address - addrs = [ipaddress.IPv4Address('2.0.0.0'), - ipaddress.IPv4Address('2.0.0.1')] - str_args = '2.0.0.0/31' - tpl_args = ('2.0.0.0', 31) - self.assertEqual(addrs, list(ipaddress.ip_network(str_args).hosts())) - self.assertEqual(addrs, list(ipaddress.ip_network(tpl_args).hosts())) - self.assertEqual(list(ipaddress.ip_network(str_args).hosts()), - list(ipaddress.ip_network(tpl_args).hosts())) - - # special case where the network is a /32 - addrs = [ipaddress.IPv4Address('1.2.3.4')] - str_args = '1.2.3.4/32' - tpl_args = ('1.2.3.4', 32) - self.assertEqual(addrs, list(ipaddress.ip_network(str_args).hosts())) - self.assertEqual(addrs, list(ipaddress.ip_network(tpl_args).hosts())) - self.assertEqual(list(ipaddress.ip_network(str_args).hosts()), - list(ipaddress.ip_network(tpl_args).hosts())) - - addrs = [ipaddress.IPv6Address('2001:658:22a:cafe::'), - ipaddress.IPv6Address('2001:658:22a:cafe::1')] - str_args = '2001:658:22a:cafe::/127' - tpl_args = ('2001:658:22a:cafe::', 127) - self.assertEqual(addrs, list(ipaddress.ip_network(str_args).hosts())) - self.assertEqual(addrs, list(ipaddress.ip_network(tpl_args).hosts())) - self.assertEqual(list(ipaddress.ip_network(str_args).hosts()), - list(ipaddress.ip_network(tpl_args).hosts())) - - addrs = [ipaddress.IPv6Address('2001:658:22a:cafe::1'), ] - str_args = '2001:658:22a:cafe::1/128' - tpl_args = ('2001:658:22a:cafe::1', 128) - self.assertEqual(addrs, list(ipaddress.ip_network(str_args).hosts())) - self.assertEqual(addrs, list(ipaddress.ip_network(tpl_args).hosts())) - self.assertEqual(list(ipaddress.ip_network(str_args).hosts()), - list(ipaddress.ip_network(tpl_args).hosts())) - - def testFancySubnetting(self): - self.assertEqual(sorted(self.ipv4_network.subnets(prefixlen_diff=3)), - sorted(self.ipv4_network.subnets(new_prefix=27))) - self.assertRaises(ValueError, list, - self.ipv4_network.subnets(new_prefix=23)) - self.assertRaises(ValueError, list, - self.ipv4_network.subnets(prefixlen_diff=3, - new_prefix=27)) - self.assertEqual(sorted(self.ipv6_network.subnets(prefixlen_diff=4)), - sorted(self.ipv6_network.subnets(new_prefix=68))) - self.assertRaises(ValueError, list, - self.ipv6_network.subnets(new_prefix=63)) - self.assertRaises(ValueError, list, - self.ipv6_network.subnets(prefixlen_diff=4, - new_prefix=68)) - - def testGetSubnets(self): - self.assertEqual(list(self.ipv4_network.subnets())[0].prefixlen, 25) - self.assertEqual(str(list( - self.ipv4_network.subnets())[0].network_address), - '1.2.3.0') - self.assertEqual(str(list( - self.ipv4_network.subnets())[1].network_address), - '1.2.3.128') - - self.assertEqual(list(self.ipv6_network.subnets())[0].prefixlen, 65) - - def testGetSubnetForSingle32(self): - ip = ipaddress.IPv4Network('1.2.3.4/32') - subnets1 = [str(x) for x in ip.subnets()] - subnets2 = [str(x) for x in ip.subnets(2)] - self.assertEqual(subnets1, ['1.2.3.4/32']) - self.assertEqual(subnets1, subnets2) - - def testGetSubnetForSingle128(self): - ip = ipaddress.IPv6Network('::1/128') - subnets1 = [str(x) for x in ip.subnets()] - subnets2 = [str(x) for x in ip.subnets(2)] - self.assertEqual(subnets1, ['::1/128']) - self.assertEqual(subnets1, subnets2) - - def testSubnet2(self): - ips = [str(x) for x in self.ipv4_network.subnets(2)] - self.assertEqual( - ips, - ['1.2.3.0/26', '1.2.3.64/26', '1.2.3.128/26', '1.2.3.192/26']) - - ipsv6 = [str(x) for x in self.ipv6_network.subnets(2)] - self.assertEqual( - ipsv6, - ['2001:658:22a:cafe::/66', - '2001:658:22a:cafe:4000::/66', - '2001:658:22a:cafe:8000::/66', - '2001:658:22a:cafe:c000::/66']) - - def testGetSubnets3(self): - subnets = [str(x) for x in self.ipv4_network.subnets(8)] - self.assertEqual(subnets[:3], - ['1.2.3.0/32', '1.2.3.1/32', '1.2.3.2/32']) - self.assertEqual(subnets[-3:], - ['1.2.3.253/32', '1.2.3.254/32', '1.2.3.255/32']) - self.assertEqual(len(subnets), 256) - - ipv6_network = ipaddress.IPv6Network('2001:658:22a:cafe::/120') - subnets = [str(x) for x in ipv6_network.subnets(8)] - self.assertEqual(subnets[:3], - ['2001:658:22a:cafe::/128', - '2001:658:22a:cafe::1/128', - '2001:658:22a:cafe::2/128']) - self.assertEqual(subnets[-3:], - ['2001:658:22a:cafe::fd/128', - '2001:658:22a:cafe::fe/128', - '2001:658:22a:cafe::ff/128']) - self.assertEqual(len(subnets), 256) - - def testSubnetFailsForLargeCidrDiff(self): - self.assertRaises(ValueError, list, - self.ipv4_interface.network.subnets(9)) - self.assertRaises(ValueError, list, - self.ipv4_network.subnets(9)) - self.assertRaises(ValueError, list, - self.ipv6_interface.network.subnets(65)) - self.assertRaises(ValueError, list, - self.ipv6_network.subnets(65)) - - def testSupernetFailsForLargeCidrDiff(self): - self.assertRaises(ValueError, - self.ipv4_interface.network.supernet, 25) - self.assertRaises(ValueError, - self.ipv6_interface.network.supernet, 65) - - def testSubnetFailsForNegativeCidrDiff(self): - self.assertRaises(ValueError, list, - self.ipv4_interface.network.subnets(-1)) - self.assertRaises(ValueError, list, - self.ipv4_network.subnets(-1)) - self.assertRaises(ValueError, list, - self.ipv6_interface.network.subnets(-1)) - self.assertRaises(ValueError, list, - self.ipv6_network.subnets(-1)) - - def testGetNum_Addresses(self): - self.assertEqual(self.ipv4_network.num_addresses, 256) - self.assertEqual(list(self.ipv4_network.subnets())[0].num_addresses, - 128) - self.assertEqual(self.ipv4_network.supernet().num_addresses, 512) - - self.assertEqual(self.ipv6_network.num_addresses, 18446744073709551616) - self.assertEqual(list(self.ipv6_network.subnets())[0].num_addresses, - 9223372036854775808) - self.assertEqual(self.ipv6_network.supernet().num_addresses, - 36893488147419103232) - - def testContains(self): - self.assertIn(ipaddress.IPv4Interface('1.2.3.128/25'), - self.ipv4_network) - self.assertNotIn(ipaddress.IPv4Interface('1.2.4.1/24'), - self.ipv4_network) - # We can test addresses and string as well. - addr1 = ipaddress.IPv4Address('1.2.3.37') - self.assertIn(addr1, self.ipv4_network) - # issue 61, bad network comparison on like-ip'd network objects - # with identical broadcast addresses. - self.assertFalse(ipaddress.IPv4Network('1.1.0.0/16').__contains__( - ipaddress.IPv4Network('1.0.0.0/15'))) - - def testNth(self): - self.assertEqual(str(self.ipv4_network[5]), '1.2.3.5') - self.assertRaises(IndexError, self.ipv4_network.__getitem__, 256) - - self.assertEqual(str(self.ipv6_network[5]), - '2001:658:22a:cafe::5') - self.assertRaises(IndexError, self.ipv6_network.__getitem__, 1 << 64) - - def testGetitem(self): - # http://code.google.com/p/ipaddr-py/issues/detail?id=15 - addr = ipaddress.IPv4Network('172.31.255.128/255.255.255.240') - self.assertEqual(28, addr.prefixlen) - addr_list = list(addr) - self.assertEqual('172.31.255.128', str(addr_list[0])) - self.assertEqual('172.31.255.128', str(addr[0])) - self.assertEqual('172.31.255.143', str(addr_list[-1])) - self.assertEqual('172.31.255.143', str(addr[-1])) - self.assertEqual(addr_list[-1], addr[-1]) - - def testEqual(self): - self.assertTrue(self.ipv4_interface == - ipaddress.IPv4Interface('1.2.3.4/24')) - self.assertFalse(self.ipv4_interface == - ipaddress.IPv4Interface('1.2.3.4/23')) - self.assertFalse(self.ipv4_interface == - ipaddress.IPv6Interface('::1.2.3.4/24')) - self.assertFalse(self.ipv4_interface == '') - self.assertFalse(self.ipv4_interface == []) - self.assertFalse(self.ipv4_interface == 2) - - self.assertTrue(self.ipv6_interface == - ipaddress.IPv6Interface('2001:658:22a:cafe:200::1/64')) - self.assertFalse(self.ipv6_interface == - ipaddress.IPv6Interface('2001:658:22a:cafe:200::1/63')) - self.assertFalse(self.ipv6_interface == - ipaddress.IPv4Interface('1.2.3.4/23')) - self.assertFalse(self.ipv6_interface == '') - self.assertFalse(self.ipv6_interface == []) - self.assertFalse(self.ipv6_interface == 2) - - def testNotEqual(self): - self.assertFalse(self.ipv4_interface != - ipaddress.IPv4Interface('1.2.3.4/24')) - self.assertTrue(self.ipv4_interface != - ipaddress.IPv4Interface('1.2.3.4/23')) - self.assertTrue(self.ipv4_interface != - ipaddress.IPv6Interface('::1.2.3.4/24')) - self.assertTrue(self.ipv4_interface != '') - self.assertTrue(self.ipv4_interface != []) - self.assertTrue(self.ipv4_interface != 2) - - self.assertTrue(self.ipv4_address != - ipaddress.IPv4Address('1.2.3.5')) - self.assertTrue(self.ipv4_address != '') - self.assertTrue(self.ipv4_address != []) - self.assertTrue(self.ipv4_address != 2) - - self.assertFalse(self.ipv6_interface != - ipaddress.IPv6Interface('2001:658:22a:cafe:200::1/64')) - self.assertTrue(self.ipv6_interface != - ipaddress.IPv6Interface('2001:658:22a:cafe:200::1/63')) - self.assertTrue(self.ipv6_interface != - ipaddress.IPv4Interface('1.2.3.4/23')) - self.assertTrue(self.ipv6_interface != '') - self.assertTrue(self.ipv6_interface != []) - self.assertTrue(self.ipv6_interface != 2) - - self.assertTrue(self.ipv6_address != - ipaddress.IPv4Address('1.2.3.4')) - self.assertTrue(self.ipv6_address != '') - self.assertTrue(self.ipv6_address != []) - self.assertTrue(self.ipv6_address != 2) - - def testSlash32Constructor(self): - self.assertEqual(str(ipaddress.IPv4Interface( - '1.2.3.4/255.255.255.255')), '1.2.3.4/32') - - def testSlash128Constructor(self): - self.assertEqual(str(ipaddress.IPv6Interface('::1/128')), - '::1/128') - - def testSlash0Constructor(self): - self.assertEqual(str(ipaddress.IPv4Interface('1.2.3.4/0.0.0.0')), - '1.2.3.4/0') - - def testCollapsing(self): - # test only IP addresses including some duplicates - ip1 = ipaddress.IPv4Address('1.1.1.0') - ip2 = ipaddress.IPv4Address('1.1.1.1') - ip3 = ipaddress.IPv4Address('1.1.1.2') - ip4 = ipaddress.IPv4Address('1.1.1.3') - ip5 = ipaddress.IPv4Address('1.1.1.4') - ip6 = ipaddress.IPv4Address('1.1.1.0') - # check that addresses are subsumed properly. - collapsed = ipaddress.collapse_addresses( - [ip1, ip2, ip3, ip4, ip5, ip6]) - self.assertEqual(list(collapsed), - [ipaddress.IPv4Network('1.1.1.0/30'), - ipaddress.IPv4Network('1.1.1.4/32')]) - - # test a mix of IP addresses and networks including some duplicates - ip1 = ipaddress.IPv4Address('1.1.1.0') - ip2 = ipaddress.IPv4Address('1.1.1.1') - ip3 = ipaddress.IPv4Address('1.1.1.2') - ip4 = ipaddress.IPv4Address('1.1.1.3') - #ip5 = ipaddress.IPv4Interface('1.1.1.4/30') - #ip6 = ipaddress.IPv4Interface('1.1.1.4/30') - # check that addresses are subsumed properly. - collapsed = ipaddress.collapse_addresses([ip1, ip2, ip3, ip4]) - self.assertEqual(list(collapsed), - [ipaddress.IPv4Network('1.1.1.0/30')]) - - # test only IP networks - ip1 = ipaddress.IPv4Network('1.1.0.0/24') - ip2 = ipaddress.IPv4Network('1.1.1.0/24') - ip3 = ipaddress.IPv4Network('1.1.2.0/24') - ip4 = ipaddress.IPv4Network('1.1.3.0/24') - ip5 = ipaddress.IPv4Network('1.1.4.0/24') - # stored in no particular order b/c we want CollapseAddr to call - # [].sort - ip6 = ipaddress.IPv4Network('1.1.0.0/22') - # check that addresses are subsumed properly. - collapsed = ipaddress.collapse_addresses([ip1, ip2, ip3, ip4, ip5, - ip6]) - self.assertEqual(list(collapsed), - [ipaddress.IPv4Network('1.1.0.0/22'), - ipaddress.IPv4Network('1.1.4.0/24')]) - - # test that two addresses are supernet'ed properly - collapsed = ipaddress.collapse_addresses([ip1, ip2]) - self.assertEqual(list(collapsed), - [ipaddress.IPv4Network('1.1.0.0/23')]) - - # test same IP networks - ip_same1 = ip_same2 = ipaddress.IPv4Network('1.1.1.1/32') - self.assertEqual(list(ipaddress.collapse_addresses( - [ip_same1, ip_same2])), - [ip_same1]) - - # test same IP addresses - ip_same1 = ip_same2 = ipaddress.IPv4Address('1.1.1.1') - self.assertEqual(list(ipaddress.collapse_addresses( - [ip_same1, ip_same2])), - [ipaddress.ip_network('1.1.1.1/32')]) - ip1 = ipaddress.IPv6Network('2001::/100') - ip2 = ipaddress.IPv6Network('2001::/120') - ip3 = ipaddress.IPv6Network('2001::/96') - # test that ipv6 addresses are subsumed properly. - collapsed = ipaddress.collapse_addresses([ip1, ip2, ip3]) - self.assertEqual(list(collapsed), [ip3]) - - # the toejam test - addr_tuples = [ - (ipaddress.ip_address('1.1.1.1'), - ipaddress.ip_address('::1')), - (ipaddress.IPv4Network('1.1.0.0/24'), - ipaddress.IPv6Network('2001::/120')), - (ipaddress.IPv4Network('1.1.0.0/32'), - ipaddress.IPv6Network('2001::/128')), - ] - for ip1, ip2 in addr_tuples: - self.assertRaises(TypeError, ipaddress.collapse_addresses, - [ip1, ip2]) - - def testSummarizing(self): - #ip = ipaddress.ip_address - #ipnet = ipaddress.ip_network - summarize = ipaddress.summarize_address_range - ip1 = ipaddress.ip_address('1.1.1.0') - ip2 = ipaddress.ip_address('1.1.1.255') - - # summarize works only for IPv4 & IPv6 - class IPv7Address(ipaddress.IPv6Address): - @property - def version(self): - return 7 - ip_invalid1 = IPv7Address('::1') - ip_invalid2 = IPv7Address('::1') - self.assertRaises(ValueError, list, - summarize(ip_invalid1, ip_invalid2)) - # test that a summary over ip4 & ip6 fails - self.assertRaises(TypeError, list, - summarize(ip1, ipaddress.IPv6Address('::1'))) - # test a /24 is summarized properly - self.assertEqual(list(summarize(ip1, ip2))[0], - ipaddress.ip_network('1.1.1.0/24')) - # test an IPv4 range that isn't on a network byte boundary - ip2 = ipaddress.ip_address('1.1.1.8') - self.assertEqual(list(summarize(ip1, ip2)), - [ipaddress.ip_network('1.1.1.0/29'), - ipaddress.ip_network('1.1.1.8')]) - # all! - ip1 = ipaddress.IPv4Address(0) - ip2 = ipaddress.IPv4Address(ipaddress.IPv4Address._ALL_ONES) - self.assertEqual([ipaddress.IPv4Network('0.0.0.0/0')], - list(summarize(ip1, ip2))) - - ip1 = ipaddress.ip_address('1::') - ip2 = ipaddress.ip_address('1:ffff:ffff:ffff:ffff:ffff:ffff:ffff') - # test an IPv6 is summarized properly - self.assertEqual(list(summarize(ip1, ip2))[0], - ipaddress.ip_network('1::/16')) - # test an IPv6 range that isn't on a network byte boundary - ip2 = ipaddress.ip_address('2::') - self.assertEqual(list(summarize(ip1, ip2)), - [ipaddress.ip_network('1::/16'), - ipaddress.ip_network('2::/128')]) - - # test exception raised when first is greater than last - self.assertRaises(ValueError, list, - summarize(ipaddress.ip_address('1.1.1.0'), - ipaddress.ip_address('1.1.0.0'))) - # test exception raised when first and last aren't IP addresses - self.assertRaises(TypeError, list, - summarize(ipaddress.ip_network('1.1.1.0'), - ipaddress.ip_network('1.1.0.0'))) - self.assertRaises(TypeError, list, - summarize(ipaddress.ip_network('1.1.1.0'), - ipaddress.ip_network('1.1.0.0'))) - # test exception raised when first and last are not same version - self.assertRaises(TypeError, list, - summarize(ipaddress.ip_address('::'), - ipaddress.ip_network('1.1.0.0'))) - - def testAddressComparison(self): - self.assertTrue(ipaddress.ip_address('1.1.1.1') <= - ipaddress.ip_address('1.1.1.1')) - self.assertTrue(ipaddress.ip_address('1.1.1.1') <= - ipaddress.ip_address('1.1.1.2')) - self.assertTrue(ipaddress.ip_address('::1') <= - ipaddress.ip_address('::1')) - self.assertTrue(ipaddress.ip_address('::1') <= - ipaddress.ip_address('::2')) - - def testInterfaceComparison(self): - self.assertTrue(ipaddress.ip_interface('1.1.1.1/24') == - ipaddress.ip_interface('1.1.1.1/24')) - self.assertTrue(ipaddress.ip_interface('1.1.1.1/16') < - ipaddress.ip_interface('1.1.1.1/24')) - self.assertTrue(ipaddress.ip_interface('1.1.1.1/24') < - ipaddress.ip_interface('1.1.1.2/24')) - self.assertTrue(ipaddress.ip_interface('1.1.1.2/16') < - ipaddress.ip_interface('1.1.1.1/24')) - self.assertTrue(ipaddress.ip_interface('1.1.1.1/24') > - ipaddress.ip_interface('1.1.1.1/16')) - self.assertTrue(ipaddress.ip_interface('1.1.1.2/24') > - ipaddress.ip_interface('1.1.1.1/24')) - self.assertTrue(ipaddress.ip_interface('1.1.1.1/24') > - ipaddress.ip_interface('1.1.1.2/16')) - - self.assertTrue(ipaddress.ip_interface('::1/64') == - ipaddress.ip_interface('::1/64')) - self.assertTrue(ipaddress.ip_interface('::1/64') < - ipaddress.ip_interface('::1/80')) - self.assertTrue(ipaddress.ip_interface('::1/64') < - ipaddress.ip_interface('::2/64')) - self.assertTrue(ipaddress.ip_interface('::2/48') < - ipaddress.ip_interface('::1/64')) - self.assertTrue(ipaddress.ip_interface('::1/80') > - ipaddress.ip_interface('::1/64')) - self.assertTrue(ipaddress.ip_interface('::2/64') > - ipaddress.ip_interface('::1/64')) - self.assertTrue(ipaddress.ip_interface('::1/64') > - ipaddress.ip_interface('::2/48')) - - def testNetworkComparison(self): - # ip1 and ip2 have the same network address - ip1 = ipaddress.IPv4Network('1.1.1.0/24') - ip2 = ipaddress.IPv4Network('1.1.1.0/32') - ip3 = ipaddress.IPv4Network('1.1.2.0/24') - - self.assertTrue(ip1 < ip3) - self.assertTrue(ip3 > ip2) - - self.assertEqual(ip1.compare_networks(ip1), 0) - - # if addresses are the same, sort by netmask - self.assertEqual(ip1.compare_networks(ip2), -1) - self.assertEqual(ip2.compare_networks(ip1), 1) - - self.assertEqual(ip1.compare_networks(ip3), -1) - self.assertEqual(ip3.compare_networks(ip1), 1) - self.assertTrue(ip1._get_networks_key() < ip3._get_networks_key()) - - ip1 = ipaddress.IPv6Network('2001:2000::/96') - ip2 = ipaddress.IPv6Network('2001:2001::/96') - ip3 = ipaddress.IPv6Network('2001:ffff:2000::/96') - - self.assertTrue(ip1 < ip3) - self.assertTrue(ip3 > ip2) - self.assertEqual(ip1.compare_networks(ip3), -1) - self.assertTrue(ip1._get_networks_key() < ip3._get_networks_key()) - - # Test comparing different protocols. - # Should always raise a TypeError. - self.assertRaises(TypeError, - self.ipv4_network.compare_networks, - self.ipv6_network) - ipv6 = ipaddress.IPv6Interface('::/0') - ipv4 = ipaddress.IPv4Interface('0.0.0.0/0') - self.assertRaises(TypeError, ipv4.__lt__, ipv6) - self.assertRaises(TypeError, ipv4.__gt__, ipv6) - self.assertRaises(TypeError, ipv6.__lt__, ipv4) - self.assertRaises(TypeError, ipv6.__gt__, ipv4) - - # Regression test for issue 19. - ip1 = ipaddress.ip_network('10.1.2.128/25') - self.assertFalse(ip1 < ip1) - self.assertFalse(ip1 > ip1) - ip2 = ipaddress.ip_network('10.1.3.0/24') - self.assertTrue(ip1 < ip2) - self.assertFalse(ip2 < ip1) - self.assertFalse(ip1 > ip2) - self.assertTrue(ip2 > ip1) - ip3 = ipaddress.ip_network('10.1.3.0/25') - self.assertTrue(ip2 < ip3) - self.assertFalse(ip3 < ip2) - self.assertFalse(ip2 > ip3) - self.assertTrue(ip3 > ip2) - - # Regression test for issue 28. - ip1 = ipaddress.ip_network('10.10.10.0/31') - ip2 = ipaddress.ip_network('10.10.10.0') - ip3 = ipaddress.ip_network('10.10.10.2/31') - ip4 = ipaddress.ip_network('10.10.10.2') - sorted = [ip1, ip2, ip3, ip4] - unsorted = [ip2, ip4, ip1, ip3] - unsorted.sort() - self.assertEqual(sorted, unsorted) - unsorted = [ip4, ip1, ip3, ip2] - unsorted.sort() - self.assertEqual(sorted, unsorted) - self.assertIs(ip1.__lt__(ipaddress.ip_address('10.10.10.0')), - NotImplemented) - self.assertIs(ip2.__lt__(ipaddress.ip_address('10.10.10.0')), - NotImplemented) - - # <=, >= - self.assertTrue(ipaddress.ip_network('1.1.1.1') <= - ipaddress.ip_network('1.1.1.1')) - self.assertTrue(ipaddress.ip_network('1.1.1.1') <= - ipaddress.ip_network('1.1.1.2')) - self.assertFalse(ipaddress.ip_network('1.1.1.2') <= - ipaddress.ip_network('1.1.1.1')) - self.assertTrue(ipaddress.ip_network('::1') <= - ipaddress.ip_network('::1')) - self.assertTrue(ipaddress.ip_network('::1') <= - ipaddress.ip_network('::2')) - self.assertFalse(ipaddress.ip_network('::2') <= - ipaddress.ip_network('::1')) - - def testStrictNetworks(self): - self.assertRaises(ValueError, ipaddress.ip_network, '192.168.1.1/24') - self.assertRaises(ValueError, ipaddress.ip_network, '::1/120') - - def testOverlaps(self): - other = ipaddress.IPv4Network('1.2.3.0/30') - other2 = ipaddress.IPv4Network('1.2.2.0/24') - other3 = ipaddress.IPv4Network('1.2.2.64/26') - self.assertTrue(self.ipv4_network.overlaps(other)) - self.assertFalse(self.ipv4_network.overlaps(other2)) - self.assertTrue(other2.overlaps(other3)) - - def testEmbeddedIpv4(self): - ipv4_string = '192.168.0.1' - ipv4 = ipaddress.IPv4Interface(ipv4_string) - v4compat_ipv6 = ipaddress.IPv6Interface('::%s' % ipv4_string) - self.assertEqual(int(v4compat_ipv6.ip), int(ipv4.ip)) - v4mapped_ipv6 = ipaddress.IPv6Interface('::ffff:%s' % ipv4_string) - self.assertNotEqual(v4mapped_ipv6.ip, ipv4.ip) - self.assertRaises(ipaddress.AddressValueError, ipaddress.IPv6Interface, - '2001:1.1.1.1:1.1.1.1') - - # Issue 67: IPv6 with embedded IPv4 address not recognized. - def testIPv6AddressTooLarge(self): - # RFC4291 2.5.5.2 - self.assertEqual(ipaddress.ip_address('::FFFF:192.0.2.1'), - ipaddress.ip_address('::FFFF:c000:201')) - # RFC4291 2.2 (part 3) x::d.d.d.d - self.assertEqual(ipaddress.ip_address('FFFF::192.0.2.1'), - ipaddress.ip_address('FFFF::c000:201')) - - def testIPVersion(self): - self.assertEqual(self.ipv4_address.version, 4) - self.assertEqual(self.ipv6_address.version, 6) - - def testMaxPrefixLength(self): - self.assertEqual(self.ipv4_interface.max_prefixlen, 32) - self.assertEqual(self.ipv6_interface.max_prefixlen, 128) - - def testPacked(self): - self.assertEqual(self.ipv4_address.packed, - b'\x01\x02\x03\x04') - self.assertEqual(ipaddress.IPv4Interface('255.254.253.252').packed, - b'\xff\xfe\xfd\xfc') - self.assertEqual(self.ipv6_address.packed, - b'\x20\x01\x06\x58\x02\x2a\xca\xfe' - b'\x02\x00\x00\x00\x00\x00\x00\x01') - self.assertEqual(ipaddress.IPv6Interface('ffff:2:3:4:ffff::').packed, - b'\xff\xff\x00\x02\x00\x03\x00\x04\xff\xff' - + b'\x00' * 6) - self.assertEqual(ipaddress.IPv6Interface('::1:0:0:0:0').packed, - b'\x00' * 6 + b'\x00\x01' + b'\x00' * 8) - - def testIpType(self): - ipv4net = ipaddress.ip_network('1.2.3.4') - ipv4addr = ipaddress.ip_address('1.2.3.4') - ipv6net = ipaddress.ip_network('::1.2.3.4') - ipv6addr = ipaddress.ip_address('::1.2.3.4') - self.assertEqual(ipaddress.IPv4Network, type(ipv4net)) - self.assertEqual(ipaddress.IPv4Address, type(ipv4addr)) - self.assertEqual(ipaddress.IPv6Network, type(ipv6net)) - self.assertEqual(ipaddress.IPv6Address, type(ipv6addr)) - - def testReservedIpv4(self): - # test networks - self.assertEqual(True, ipaddress.ip_interface( - '224.1.1.1/31').is_multicast) - self.assertEqual(False, ipaddress.ip_network('240.0.0.0').is_multicast) - self.assertEqual(True, ipaddress.ip_network('240.0.0.0').is_reserved) - - self.assertEqual(True, ipaddress.ip_interface( - '192.168.1.1/17').is_private) - self.assertEqual(False, ipaddress.ip_network('192.169.0.0').is_private) - self.assertEqual(True, ipaddress.ip_network( - '10.255.255.255').is_private) - self.assertEqual(False, ipaddress.ip_network('11.0.0.0').is_private) - self.assertEqual(False, ipaddress.ip_network('11.0.0.0').is_reserved) - self.assertEqual(True, ipaddress.ip_network( - '172.31.255.255').is_private) - self.assertEqual(False, ipaddress.ip_network('172.32.0.0').is_private) - self.assertEqual(True, - ipaddress.ip_network('169.254.1.0/24').is_link_local) - - self.assertEqual(True, - ipaddress.ip_interface( - '169.254.100.200/24').is_link_local) - self.assertEqual(False, - ipaddress.ip_interface( - '169.255.100.200/24').is_link_local) - - self.assertEqual(True, - ipaddress.ip_network( - '127.100.200.254/32').is_loopback) - self.assertEqual(True, ipaddress.ip_network( - '127.42.0.0/16').is_loopback) - self.assertEqual(False, ipaddress.ip_network('128.0.0.0').is_loopback) - self.assertEqual(False, - ipaddress.ip_network('100.64.0.0/10').is_private) - self.assertEqual(False, ipaddress.ip_network('100.64.0.0/10').is_global) - - self.assertEqual(True, - ipaddress.ip_network('192.0.2.128/25').is_private) - self.assertEqual(True, - ipaddress.ip_network('192.0.3.0/24').is_global) - - # test addresses - self.assertEqual(True, ipaddress.ip_address('0.0.0.0').is_unspecified) - self.assertEqual(True, ipaddress.ip_address('224.1.1.1').is_multicast) - self.assertEqual(False, ipaddress.ip_address('240.0.0.0').is_multicast) - self.assertEqual(True, ipaddress.ip_address('240.0.0.1').is_reserved) - self.assertEqual(False, - ipaddress.ip_address('239.255.255.255').is_reserved) - - self.assertEqual(True, ipaddress.ip_address('192.168.1.1').is_private) - self.assertEqual(False, ipaddress.ip_address('192.169.0.0').is_private) - self.assertEqual(True, ipaddress.ip_address( - '10.255.255.255').is_private) - self.assertEqual(False, ipaddress.ip_address('11.0.0.0').is_private) - self.assertEqual(True, ipaddress.ip_address( - '172.31.255.255').is_private) - self.assertEqual(False, ipaddress.ip_address('172.32.0.0').is_private) - - self.assertEqual(True, - ipaddress.ip_address('169.254.100.200').is_link_local) - self.assertEqual(False, - ipaddress.ip_address('169.255.100.200').is_link_local) - - self.assertTrue(ipaddress.ip_address('192.0.7.1').is_global) - self.assertFalse(ipaddress.ip_address('203.0.113.1').is_global) - - self.assertEqual(True, - ipaddress.ip_address('127.100.200.254').is_loopback) - self.assertEqual(True, ipaddress.ip_address('127.42.0.0').is_loopback) - self.assertEqual(False, ipaddress.ip_address('128.0.0.0').is_loopback) - self.assertEqual(True, ipaddress.ip_network('0.0.0.0').is_unspecified) - - def testReservedIpv6(self): - - self.assertEqual(True, ipaddress.ip_network('ffff::').is_multicast) - self.assertEqual(True, ipaddress.ip_network(2**128 - 1).is_multicast) - self.assertEqual(True, ipaddress.ip_network('ff00::').is_multicast) - self.assertEqual(False, ipaddress.ip_network('fdff::').is_multicast) - - self.assertEqual(True, ipaddress.ip_network('fecf::').is_site_local) - self.assertEqual(True, ipaddress.ip_network( - 'feff:ffff:ffff:ffff::').is_site_local) - self.assertEqual(False, ipaddress.ip_network( - 'fbf:ffff::').is_site_local) - self.assertEqual(False, ipaddress.ip_network('ff00::').is_site_local) - - self.assertEqual(True, ipaddress.ip_network('fc00::').is_private) - self.assertEqual(True, ipaddress.ip_network( - 'fc00:ffff:ffff:ffff::').is_private) - self.assertEqual(False, ipaddress.ip_network('fbff:ffff::').is_private) - self.assertEqual(False, ipaddress.ip_network('fe00::').is_private) - - self.assertEqual(True, ipaddress.ip_network('fea0::').is_link_local) - self.assertEqual(True, ipaddress.ip_network( - 'febf:ffff::').is_link_local) - self.assertEqual(False, ipaddress.ip_network( - 'fe7f:ffff::').is_link_local) - self.assertEqual(False, ipaddress.ip_network('fec0::').is_link_local) - - self.assertEqual(True, ipaddress.ip_interface('0:0::0:01').is_loopback) - self.assertEqual(False, ipaddress.ip_interface('::1/127').is_loopback) - self.assertEqual(False, ipaddress.ip_network('::').is_loopback) - self.assertEqual(False, ipaddress.ip_network('::2').is_loopback) - - self.assertEqual(True, ipaddress.ip_network('0::0').is_unspecified) - self.assertEqual(False, ipaddress.ip_network('::1').is_unspecified) - self.assertEqual(False, ipaddress.ip_network('::/127').is_unspecified) - - self.assertEqual(True, - ipaddress.ip_network('2001::1/128').is_private) - self.assertEqual(True, - ipaddress.ip_network('200::1/128').is_global) - # test addresses - self.assertEqual(True, ipaddress.ip_address('ffff::').is_multicast) - self.assertEqual(True, ipaddress.ip_address(2**128 - 1).is_multicast) - self.assertEqual(True, ipaddress.ip_address('ff00::').is_multicast) - self.assertEqual(False, ipaddress.ip_address('fdff::').is_multicast) - - self.assertEqual(True, ipaddress.ip_address('fecf::').is_site_local) - self.assertEqual(True, ipaddress.ip_address( - 'feff:ffff:ffff:ffff::').is_site_local) - self.assertEqual(False, ipaddress.ip_address( - 'fbf:ffff::').is_site_local) - self.assertEqual(False, ipaddress.ip_address('ff00::').is_site_local) - - self.assertEqual(True, ipaddress.ip_address('fc00::').is_private) - self.assertEqual(True, ipaddress.ip_address( - 'fc00:ffff:ffff:ffff::').is_private) - self.assertEqual(False, ipaddress.ip_address('fbff:ffff::').is_private) - self.assertEqual(False, ipaddress.ip_address('fe00::').is_private) - - self.assertEqual(True, ipaddress.ip_address('fea0::').is_link_local) - self.assertEqual(True, ipaddress.ip_address( - 'febf:ffff::').is_link_local) - self.assertEqual(False, ipaddress.ip_address( - 'fe7f:ffff::').is_link_local) - self.assertEqual(False, ipaddress.ip_address('fec0::').is_link_local) - - self.assertEqual(True, ipaddress.ip_address('0:0::0:01').is_loopback) - self.assertEqual(True, ipaddress.ip_address('::1').is_loopback) - self.assertEqual(False, ipaddress.ip_address('::2').is_loopback) - - self.assertEqual(True, ipaddress.ip_address('0::0').is_unspecified) - self.assertEqual(False, ipaddress.ip_address('::1').is_unspecified) - - # some generic IETF reserved addresses - self.assertEqual(True, ipaddress.ip_address('100::').is_reserved) - self.assertEqual(True, ipaddress.ip_network('4000::1/128').is_reserved) - - def testIpv4Mapped(self): - self.assertEqual( - ipaddress.ip_address('::ffff:192.168.1.1').ipv4_mapped, - ipaddress.ip_address('192.168.1.1')) - self.assertEqual(ipaddress.ip_address('::c0a8:101').ipv4_mapped, None) - self.assertEqual(ipaddress.ip_address('::ffff:c0a8:101').ipv4_mapped, - ipaddress.ip_address('192.168.1.1')) - - def testAddrExclude(self): - addr1 = ipaddress.ip_network('10.1.1.0/24') - addr2 = ipaddress.ip_network('10.1.1.0/26') - addr3 = ipaddress.ip_network('10.2.1.0/24') - addr4 = ipaddress.ip_address('10.1.1.0') - addr5 = ipaddress.ip_network('2001:db8::0/32') - addr6 = ipaddress.ip_network('10.1.1.5/32') - self.assertEqual(sorted(list(addr1.address_exclude(addr2))), - [ipaddress.ip_network('10.1.1.64/26'), - ipaddress.ip_network('10.1.1.128/25')]) - self.assertRaises(ValueError, list, addr1.address_exclude(addr3)) - self.assertRaises(TypeError, list, addr1.address_exclude(addr4)) - self.assertRaises(TypeError, list, addr1.address_exclude(addr5)) - self.assertEqual(list(addr1.address_exclude(addr1)), []) - self.assertEqual(sorted(list(addr1.address_exclude(addr6))), - [ipaddress.ip_network('10.1.1.0/30'), - ipaddress.ip_network('10.1.1.4/32'), - ipaddress.ip_network('10.1.1.6/31'), - ipaddress.ip_network('10.1.1.8/29'), - ipaddress.ip_network('10.1.1.16/28'), - ipaddress.ip_network('10.1.1.32/27'), - ipaddress.ip_network('10.1.1.64/26'), - ipaddress.ip_network('10.1.1.128/25')]) - - def testHash(self): - self.assertEqual(hash(ipaddress.ip_interface('10.1.1.0/24')), - hash(ipaddress.ip_interface('10.1.1.0/24'))) - self.assertEqual(hash(ipaddress.ip_network('10.1.1.0/24')), - hash(ipaddress.ip_network('10.1.1.0/24'))) - self.assertEqual(hash(ipaddress.ip_address('10.1.1.0')), - hash(ipaddress.ip_address('10.1.1.0'))) - # i70 - self.assertEqual(hash(ipaddress.ip_address('1.2.3.4')), - hash(ipaddress.ip_address( - int(ipaddress.ip_address('1.2.3.4')._ip)))) - ip1 = ipaddress.ip_address('10.1.1.0') - ip2 = ipaddress.ip_address('1::') - dummy = {} - dummy[self.ipv4_address] = None - dummy[self.ipv6_address] = None - dummy[ip1] = None - dummy[ip2] = None - self.assertIn(self.ipv4_address, dummy) - self.assertIn(ip2, dummy) - - def testIPBases(self): - net = self.ipv4_network - self.assertEqual('1.2.3.0/24', net.compressed) - net = self.ipv6_network - self.assertRaises(ValueError, net._string_from_ip_int, 2**128 + 1) - - def testIPv6NetworkHelpers(self): - net = self.ipv6_network - self.assertEqual('2001:658:22a:cafe::/64', net.with_prefixlen) - self.assertEqual('2001:658:22a:cafe::/ffff:ffff:ffff:ffff::', - net.with_netmask) - self.assertEqual('2001:658:22a:cafe::/::ffff:ffff:ffff:ffff', - net.with_hostmask) - self.assertEqual('2001:658:22a:cafe::/64', str(net)) - - def testIPv4NetworkHelpers(self): - net = self.ipv4_network - self.assertEqual('1.2.3.0/24', net.with_prefixlen) - self.assertEqual('1.2.3.0/255.255.255.0', net.with_netmask) - self.assertEqual('1.2.3.0/0.0.0.255', net.with_hostmask) - self.assertEqual('1.2.3.0/24', str(net)) - - def testCopyConstructor(self): - addr1 = ipaddress.ip_network('10.1.1.0/24') - addr2 = ipaddress.ip_network(addr1) - addr3 = ipaddress.ip_interface('2001:658:22a:cafe:200::1/64') - addr4 = ipaddress.ip_interface(addr3) - addr5 = ipaddress.IPv4Address('1.1.1.1') - addr6 = ipaddress.IPv6Address('2001:658:22a:cafe:200::1') - - self.assertEqual(addr1, addr2) - self.assertEqual(addr3, addr4) - self.assertEqual(addr5, ipaddress.IPv4Address(addr5)) - self.assertEqual(addr6, ipaddress.IPv6Address(addr6)) - - def testCompressIPv6Address(self): - test_addresses = { - '1:2:3:4:5:6:7:8': '1:2:3:4:5:6:7:8/128', - '2001:0:0:4:0:0:0:8': '2001:0:0:4::8/128', - '2001:0:0:4:5:6:7:8': '2001::4:5:6:7:8/128', - '2001:0:3:4:5:6:7:8': '2001:0:3:4:5:6:7:8/128', - '0:0:3:0:0:0:0:ffff': '0:0:3::ffff/128', - '0:0:0:4:0:0:0:ffff': '::4:0:0:0:ffff/128', - '0:0:0:0:5:0:0:ffff': '::5:0:0:ffff/128', - '1:0:0:4:0:0:7:8': '1::4:0:0:7:8/128', - '0:0:0:0:0:0:0:0': '::/128', - '0:0:0:0:0:0:0:0/0': '::/0', - '0:0:0:0:0:0:0:1': '::1/128', - '2001:0658:022a:cafe:0000:0000:0000:0000/66': - '2001:658:22a:cafe::/66', - '::1.2.3.4': '::102:304/128', - '1:2:3:4:5:ffff:1.2.3.4': '1:2:3:4:5:ffff:102:304/128', - '::7:6:5:4:3:2:1': '0:7:6:5:4:3:2:1/128', - '::7:6:5:4:3:2:0': '0:7:6:5:4:3:2:0/128', - '7:6:5:4:3:2:1::': '7:6:5:4:3:2:1:0/128', - '0:6:5:4:3:2:1::': '0:6:5:4:3:2:1:0/128', - } - for uncompressed, compressed in list(test_addresses.items()): - self.assertEqual(compressed, str(ipaddress.IPv6Interface( - uncompressed))) - - def testExplodeShortHandIpStr(self): - addr1 = ipaddress.IPv6Interface('2001::1') - addr2 = ipaddress.IPv6Address('2001:0:5ef5:79fd:0:59d:a0e5:ba1') - addr3 = ipaddress.IPv6Network('2001::/96') - addr4 = ipaddress.IPv4Address('192.168.178.1') - self.assertEqual('2001:0000:0000:0000:0000:0000:0000:0001/128', - addr1.exploded) - self.assertEqual('0000:0000:0000:0000:0000:0000:0000:0001/128', - ipaddress.IPv6Interface('::1/128').exploded) - # issue 77 - self.assertEqual('2001:0000:5ef5:79fd:0000:059d:a0e5:0ba1', - addr2.exploded) - self.assertEqual('2001:0000:0000:0000:0000:0000:0000:0000/96', - addr3.exploded) - self.assertEqual('192.168.178.1', addr4.exploded) - - def testReversePointer(self): - addr1 = ipaddress.IPv4Address('127.0.0.1') - addr2 = ipaddress.IPv6Address('2001:db8::1') - self.assertEqual('1.0.0.127.in-addr.arpa', addr1.reverse_pointer) - self.assertEqual('1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.' + - 'b.d.0.1.0.0.2.ip6.arpa', - addr2.reverse_pointer) - - def testIntRepresentation(self): - self.assertEqual(16909060, int(self.ipv4_address)) - self.assertEqual(42540616829182469433547762482097946625, - int(self.ipv6_address)) - - def testForceVersion(self): - self.assertEqual(ipaddress.ip_network(1).version, 4) - self.assertEqual(ipaddress.IPv6Network(1).version, 6) - - def testWithStar(self): - self.assertEqual(self.ipv4_interface.with_prefixlen, "1.2.3.4/24") - self.assertEqual(self.ipv4_interface.with_netmask, - "1.2.3.4/255.255.255.0") - self.assertEqual(self.ipv4_interface.with_hostmask, - "1.2.3.4/0.0.0.255") - - self.assertEqual(self.ipv6_interface.with_prefixlen, - '2001:658:22a:cafe:200::1/64') - self.assertEqual(self.ipv6_interface.with_netmask, - '2001:658:22a:cafe:200::1/ffff:ffff:ffff:ffff::') - # this probably don't make much sense, but it's included for - # compatibility with ipv4 - self.assertEqual(self.ipv6_interface.with_hostmask, - '2001:658:22a:cafe:200::1/::ffff:ffff:ffff:ffff') - - def testNetworkElementCaching(self): - # V4 - make sure we're empty - self.assertNotIn('broadcast_address', self.ipv4_network.__dict__) - self.assertNotIn('hostmask', self.ipv4_network.__dict__) - - # V4 - populate and test - self.assertEqual(self.ipv4_network.broadcast_address, - ipaddress.IPv4Address('1.2.3.255')) - self.assertEqual(self.ipv4_network.hostmask, - ipaddress.IPv4Address('0.0.0.255')) - - # V4 - check we're cached - self.assertIn('broadcast_address', self.ipv4_network.__dict__) - self.assertIn('hostmask', self.ipv4_network.__dict__) - - # V6 - make sure we're empty - self.assertNotIn('broadcast_address', self.ipv6_network.__dict__) - self.assertNotIn('hostmask', self.ipv6_network.__dict__) - - # V6 - populate and test - self.assertEqual(self.ipv6_network.network_address, - ipaddress.IPv6Address('2001:658:22a:cafe::')) - self.assertEqual(self.ipv6_interface.network.network_address, - ipaddress.IPv6Address('2001:658:22a:cafe::')) - - self.assertEqual( - self.ipv6_network.broadcast_address, - ipaddress.IPv6Address('2001:658:22a:cafe:ffff:ffff:ffff:ffff')) - self.assertEqual(self.ipv6_network.hostmask, - ipaddress.IPv6Address('::ffff:ffff:ffff:ffff')) - self.assertEqual( - self.ipv6_interface.network.broadcast_address, - ipaddress.IPv6Address('2001:658:22a:cafe:ffff:ffff:ffff:ffff')) - self.assertEqual(self.ipv6_interface.network.hostmask, - ipaddress.IPv6Address('::ffff:ffff:ffff:ffff')) - - # V6 - check we're cached - self.assertIn('broadcast_address', self.ipv6_network.__dict__) - self.assertIn('hostmask', self.ipv6_network.__dict__) - self.assertIn('broadcast_address', self.ipv6_interface.network.__dict__) - self.assertIn('hostmask', self.ipv6_interface.network.__dict__) - - def testTeredo(self): - # stolen from wikipedia - server = ipaddress.IPv4Address('65.54.227.120') - client = ipaddress.IPv4Address('192.0.2.45') - teredo_addr = '2001:0000:4136:e378:8000:63bf:3fff:fdd2' - self.assertEqual((server, client), - ipaddress.ip_address(teredo_addr).teredo) - bad_addr = '2000::4136:e378:8000:63bf:3fff:fdd2' - self.assertFalse(ipaddress.ip_address(bad_addr).teredo) - bad_addr = '2001:0001:4136:e378:8000:63bf:3fff:fdd2' - self.assertFalse(ipaddress.ip_address(bad_addr).teredo) - - # i77 - teredo_addr = ipaddress.IPv6Address('2001:0:5ef5:79fd:0:59d:a0e5:ba1') - self.assertEqual((ipaddress.IPv4Address('94.245.121.253'), - ipaddress.IPv4Address('95.26.244.94')), - teredo_addr.teredo) - - def testsixtofour(self): - sixtofouraddr = ipaddress.ip_address('2002:ac1d:2d64::1') - bad_addr = ipaddress.ip_address('2000:ac1d:2d64::1') - self.assertEqual(ipaddress.IPv4Address('172.29.45.100'), - sixtofouraddr.sixtofour) - self.assertFalse(bad_addr.sixtofour) - - # issue41004 Hash collisions in IPv4Interface and IPv6Interface - def testV4HashIsNotConstant(self): - ipv4_address1 = ipaddress.IPv4Interface("1.2.3.4") - ipv4_address2 = ipaddress.IPv4Interface("2.3.4.5") - self.assertNotEqual(ipv4_address1.__hash__(), ipv4_address2.__hash__()) - - # issue41004 Hash collisions in IPv4Interface and IPv6Interface - def testV6HashIsNotConstant(self): - ipv6_address1 = ipaddress.IPv6Interface("2001:658:22a:cafe:200:0:0:1") - ipv6_address2 = ipaddress.IPv6Interface("2001:658:22a:cafe:200:0:0:2") - self.assertNotEqual(ipv6_address1.__hash__(), ipv6_address2.__hash__()) - - - if __name__ == '__main__': - unittest.main() diff --git a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_isinstance.yaml b/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_isinstance.yaml deleted file mode 100644 index cd23096bb..000000000 --- a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_isinstance.yaml +++ /dev/null @@ -1,296 +0,0 @@ -python: | - # Tests some corner cases with isinstance() and issubclass(). While these - # tests use new style classes and properties, they actually do whitebox - # testing of error conditions uncovered when using extension types. - - import unittest - import sys - - - - class TestIsInstanceExceptions(unittest.TestCase): - # Test to make sure that an AttributeError when accessing the instance's - # class's bases is masked. This was actually a bug in Python 2.2 and - # 2.2.1 where the exception wasn't caught but it also wasn't being cleared - # (leading to an "undetected error" in the debug build). Set up is, - # isinstance(inst, cls) where: - # - # - cls isn't a type, or a tuple - # - cls has a __bases__ attribute - # - inst has a __class__ attribute - # - inst.__class__ as no __bases__ attribute - # - # Sounds complicated, I know, but this mimics a situation where an - # extension type raises an AttributeError when its __bases__ attribute is - # gotten. In that case, isinstance() should return False. - def test_class_has_no_bases(self): - class I(object): - def getclass(self): - # This must return an object that has no __bases__ attribute - return None - __class__ = property(getclass) - - class C(object): - def getbases(self): - return () - __bases__ = property(getbases) - - self.assertEqual(False, isinstance(I(), C())) - - # Like above except that inst.__class__.__bases__ raises an exception - # other than AttributeError - def test_bases_raises_other_than_attribute_error(self): - class E(object): - def getbases(self): - raise RuntimeError - __bases__ = property(getbases) - - class I(object): - def getclass(self): - return E() - __class__ = property(getclass) - - class C(object): - def getbases(self): - return () - __bases__ = property(getbases) - - self.assertRaises(RuntimeError, isinstance, I(), C()) - - # Here's a situation where getattr(cls, '__bases__') raises an exception. - # If that exception is not AttributeError, it should not get masked - def test_dont_mask_non_attribute_error(self): - class I: pass - - class C(object): - def getbases(self): - raise RuntimeError - __bases__ = property(getbases) - - self.assertRaises(RuntimeError, isinstance, I(), C()) - - # Like above, except that getattr(cls, '__bases__') raises an - # AttributeError, which /should/ get masked as a TypeError - def test_mask_attribute_error(self): - class I: pass - - class C(object): - def getbases(self): - raise AttributeError - __bases__ = property(getbases) - - self.assertRaises(TypeError, isinstance, I(), C()) - - # check that we don't mask non AttributeErrors - # see: http://bugs.python.org/issue1574217 - def test_isinstance_dont_mask_non_attribute_error(self): - class C(object): - def getclass(self): - raise RuntimeError - __class__ = property(getclass) - - c = C() - self.assertRaises(RuntimeError, isinstance, c, bool) - - # test another code path - class D: pass - self.assertRaises(RuntimeError, isinstance, c, D) - - - # These tests are similar to above, but tickle certain code paths in - # issubclass() instead of isinstance() -- really PyObject_IsSubclass() - # vs. PyObject_IsInstance(). - class TestIsSubclassExceptions(unittest.TestCase): - def test_dont_mask_non_attribute_error(self): - class C(object): - def getbases(self): - raise RuntimeError - __bases__ = property(getbases) - - class S(C): pass - - self.assertRaises(RuntimeError, issubclass, C(), S()) - - def test_mask_attribute_error(self): - class C(object): - def getbases(self): - raise AttributeError - __bases__ = property(getbases) - - class S(C): pass - - self.assertRaises(TypeError, issubclass, C(), S()) - - # Like above, but test the second branch, where the __bases__ of the - # second arg (the cls arg) is tested. This means the first arg must - # return a valid __bases__, and it's okay for it to be a normal -- - # unrelated by inheritance -- class. - def test_dont_mask_non_attribute_error_in_cls_arg(self): - class B: pass - - class C(object): - def getbases(self): - raise RuntimeError - __bases__ = property(getbases) - - self.assertRaises(RuntimeError, issubclass, B, C()) - - def test_mask_attribute_error_in_cls_arg(self): - class B: pass - - class C(object): - def getbases(self): - raise AttributeError - __bases__ = property(getbases) - - self.assertRaises(TypeError, issubclass, B, C()) - - - - # meta classes for creating abstract classes and instances - class AbstractClass(object): - def __init__(self, bases): - self.bases = bases - - def getbases(self): - return self.bases - __bases__ = property(getbases) - - def __call__(self): - return AbstractInstance(self) - - class AbstractInstance(object): - def __init__(self, klass): - self.klass = klass - - def getclass(self): - return self.klass - __class__ = property(getclass) - - # abstract classes - AbstractSuper = AbstractClass(bases=()) - - AbstractChild = AbstractClass(bases=(AbstractSuper,)) - - # normal classes - class Super: - pass - - class Child(Super): - pass - - class TestIsInstanceIsSubclass(unittest.TestCase): - # Tests to ensure that isinstance and issubclass work on abstract - # classes and instances. Before the 2.2 release, TypeErrors were - # raised when boolean values should have been returned. The bug was - # triggered by mixing 'normal' classes and instances were with - # 'abstract' classes and instances. This case tries to test all - # combinations. - - def test_isinstance_normal(self): - # normal instances - self.assertEqual(True, isinstance(Super(), Super)) - self.assertEqual(False, isinstance(Super(), Child)) - self.assertEqual(False, isinstance(Super(), AbstractSuper)) - self.assertEqual(False, isinstance(Super(), AbstractChild)) - - self.assertEqual(True, isinstance(Child(), Super)) - self.assertEqual(False, isinstance(Child(), AbstractSuper)) - - def test_isinstance_abstract(self): - # abstract instances - self.assertEqual(True, isinstance(AbstractSuper(), AbstractSuper)) - self.assertEqual(False, isinstance(AbstractSuper(), AbstractChild)) - self.assertEqual(False, isinstance(AbstractSuper(), Super)) - self.assertEqual(False, isinstance(AbstractSuper(), Child)) - - self.assertEqual(True, isinstance(AbstractChild(), AbstractChild)) - self.assertEqual(True, isinstance(AbstractChild(), AbstractSuper)) - self.assertEqual(False, isinstance(AbstractChild(), Super)) - self.assertEqual(False, isinstance(AbstractChild(), Child)) - - def test_subclass_normal(self): - # normal classes - self.assertEqual(True, issubclass(Super, Super)) - self.assertEqual(False, issubclass(Super, AbstractSuper)) - self.assertEqual(False, issubclass(Super, Child)) - - self.assertEqual(True, issubclass(Child, Child)) - self.assertEqual(True, issubclass(Child, Super)) - self.assertEqual(False, issubclass(Child, AbstractSuper)) - - def test_subclass_abstract(self): - # abstract classes - self.assertEqual(True, issubclass(AbstractSuper, AbstractSuper)) - self.assertEqual(False, issubclass(AbstractSuper, AbstractChild)) - self.assertEqual(False, issubclass(AbstractSuper, Child)) - - self.assertEqual(True, issubclass(AbstractChild, AbstractChild)) - self.assertEqual(True, issubclass(AbstractChild, AbstractSuper)) - self.assertEqual(False, issubclass(AbstractChild, Super)) - self.assertEqual(False, issubclass(AbstractChild, Child)) - - def test_subclass_tuple(self): - # test with a tuple as the second argument classes - self.assertEqual(True, issubclass(Child, (Child,))) - self.assertEqual(True, issubclass(Child, (Super,))) - self.assertEqual(False, issubclass(Super, (Child,))) - self.assertEqual(True, issubclass(Super, (Child, Super))) - self.assertEqual(False, issubclass(Child, ())) - self.assertEqual(True, issubclass(Super, (Child, (Super,)))) - - self.assertEqual(True, issubclass(int, (int, (float, int)))) - self.assertEqual(True, issubclass(str, (str, (Child, str)))) - - def test_subclass_recursion_limit(self): - # make sure that issubclass raises RecursionError before the C stack is - # blown - self.assertRaises(RecursionError, blowstack, issubclass, str, str) - - def test_isinstance_recursion_limit(self): - # make sure that issubclass raises RecursionError before the C stack is - # blown - self.assertRaises(RecursionError, blowstack, isinstance, '', str) - - def test_issubclass_refcount_handling(self): - # bpo-39382: abstract_issubclass() didn't hold item reference while - # peeking in the bases tuple, in the single inheritance case. - class A: - @property - def __bases__(self): - return (int, ) - - class B: - def __init__(self): - # setting this here increases the chances of exhibiting the bug, - # probably due to memory layout changes. - self.x = 1 - - @property - def __bases__(self): - return (A(), ) - - self.assertEqual(True, issubclass(B(), int)) - - def test_infinite_recursion_in_bases(self): - class X: - @property - def __bases__(self): - return self.__bases__ - - self.assertRaises(RecursionError, issubclass, X(), int) - self.assertRaises(RecursionError, issubclass, int, X()) - self.assertRaises(RecursionError, isinstance, 1, X()) - - - def blowstack(fxn, arg, compare_to): - # Make sure that calling isinstance with a deeply nested tuple for its - # argument will raise RecursionError eventually. - tuple_arg = (compare_to,) - for cnt in range(sys.getrecursionlimit()+5): - tuple_arg = (tuple_arg,) - fxn(arg, tuple_arg) - - - if __name__ == '__main__': - unittest.main() diff --git a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_iter.yaml b/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_iter.yaml deleted file mode 100644 index 3b0b80ad6..000000000 --- a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_iter.yaml +++ /dev/null @@ -1,1024 +0,0 @@ -python: | - # Test iterators. - - import sys - import unittest - from test.support import run_unittest, TESTFN, unlink, cpython_only - from test.support import check_free_after_iterating - import pickle - import collections.abc - - # Test result of triple loop (too big to inline) - TRIPLETS = [(0, 0, 0), (0, 0, 1), (0, 0, 2), - (0, 1, 0), (0, 1, 1), (0, 1, 2), - (0, 2, 0), (0, 2, 1), (0, 2, 2), - - (1, 0, 0), (1, 0, 1), (1, 0, 2), - (1, 1, 0), (1, 1, 1), (1, 1, 2), - (1, 2, 0), (1, 2, 1), (1, 2, 2), - - (2, 0, 0), (2, 0, 1), (2, 0, 2), - (2, 1, 0), (2, 1, 1), (2, 1, 2), - (2, 2, 0), (2, 2, 1), (2, 2, 2)] - - # Helper classes - - class BasicIterClass: - def __init__(self, n): - self.n = n - self.i = 0 - def __next__(self): - res = self.i - if res >= self.n: - raise StopIteration - self.i = res + 1 - return res - def __iter__(self): - return self - - class IteratingSequenceClass: - def __init__(self, n): - self.n = n - def __iter__(self): - return BasicIterClass(self.n) - - class SequenceClass: - def __init__(self, n): - self.n = n - def __getitem__(self, i): - if 0 <= i < self.n: - return i - else: - raise IndexError - - class UnlimitedSequenceClass: - def __getitem__(self, i): - return i - - class DefaultIterClass: - pass - - class NoIterClass: - def __getitem__(self, i): - return i - __iter__ = None - - class BadIterableClass: - def __iter__(self): - raise ZeroDivisionError - - # Main test suite - - class TestCase(unittest.TestCase): - - # Helper to check that an iterator returns a given sequence - def check_iterator(self, it, seq, pickle=True): - if pickle: - self.check_pickle(it, seq) - res = [] - while 1: - try: - val = next(it) - except StopIteration: - break - res.append(val) - self.assertEqual(res, seq) - - # Helper to check that a for loop generates a given sequence - def check_for_loop(self, expr, seq, pickle=True): - if pickle: - self.check_pickle(iter(expr), seq) - res = [] - for val in expr: - res.append(val) - self.assertEqual(res, seq) - - # Helper to check picklability - def check_pickle(self, itorg, seq): - for proto in range(pickle.HIGHEST_PROTOCOL + 1): - d = pickle.dumps(itorg, proto) - it = pickle.loads(d) - # Cannot assert type equality because dict iterators unpickle as list - # iterators. - # self.assertEqual(type(itorg), type(it)) - self.assertTrue(isinstance(it, collections.abc.Iterator)) - self.assertEqual(list(it), seq) - - it = pickle.loads(d) - try: - next(it) - except StopIteration: - continue - d = pickle.dumps(it, proto) - it = pickle.loads(d) - self.assertEqual(list(it), seq[1:]) - - # Test basic use of iter() function - def test_iter_basic(self): - self.check_iterator(iter(range(10)), list(range(10))) - - # Test that iter(iter(x)) is the same as iter(x) - def test_iter_idempotency(self): - seq = list(range(10)) - it = iter(seq) - it2 = iter(it) - self.assertTrue(it is it2) - - # Test that for loops over iterators work - def test_iter_for_loop(self): - self.check_for_loop(iter(range(10)), list(range(10))) - - # Test several independent iterators over the same list - def test_iter_independence(self): - seq = range(3) - res = [] - for i in iter(seq): - for j in iter(seq): - for k in iter(seq): - res.append((i, j, k)) - self.assertEqual(res, TRIPLETS) - - # Test triple list comprehension using iterators - def test_nested_comprehensions_iter(self): - seq = range(3) - res = [(i, j, k) - for i in iter(seq) for j in iter(seq) for k in iter(seq)] - self.assertEqual(res, TRIPLETS) - - # Test triple list comprehension without iterators - def test_nested_comprehensions_for(self): - seq = range(3) - res = [(i, j, k) for i in seq for j in seq for k in seq] - self.assertEqual(res, TRIPLETS) - - # Test a class with __iter__ in a for loop - def test_iter_class_for(self): - self.check_for_loop(IteratingSequenceClass(10), list(range(10))) - - # Test a class with __iter__ with explicit iter() - def test_iter_class_iter(self): - self.check_iterator(iter(IteratingSequenceClass(10)), list(range(10))) - - # Test for loop on a sequence class without __iter__ - def test_seq_class_for(self): - self.check_for_loop(SequenceClass(10), list(range(10))) - - # Test iter() on a sequence class without __iter__ - def test_seq_class_iter(self): - self.check_iterator(iter(SequenceClass(10)), list(range(10))) - - def test_mutating_seq_class_iter_pickle(self): - orig = SequenceClass(5) - for proto in range(pickle.HIGHEST_PROTOCOL + 1): - # initial iterator - itorig = iter(orig) - d = pickle.dumps((itorig, orig), proto) - it, seq = pickle.loads(d) - seq.n = 7 - self.assertIs(type(it), type(itorig)) - self.assertEqual(list(it), list(range(7))) - - # running iterator - next(itorig) - d = pickle.dumps((itorig, orig), proto) - it, seq = pickle.loads(d) - seq.n = 7 - self.assertIs(type(it), type(itorig)) - self.assertEqual(list(it), list(range(1, 7))) - - # empty iterator - for i in range(1, 5): - next(itorig) - d = pickle.dumps((itorig, orig), proto) - it, seq = pickle.loads(d) - seq.n = 7 - self.assertIs(type(it), type(itorig)) - self.assertEqual(list(it), list(range(5, 7))) - - # exhausted iterator - self.assertRaises(StopIteration, next, itorig) - d = pickle.dumps((itorig, orig), proto) - it, seq = pickle.loads(d) - seq.n = 7 - self.assertTrue(isinstance(it, collections.abc.Iterator)) - self.assertEqual(list(it), []) - - def test_mutating_seq_class_exhausted_iter(self): - a = SequenceClass(5) - exhit = iter(a) - empit = iter(a) - for x in exhit: # exhaust the iterator - next(empit) # not exhausted - a.n = 7 - self.assertEqual(list(exhit), []) - self.assertEqual(list(empit), [5, 6]) - self.assertEqual(list(a), [0, 1, 2, 3, 4, 5, 6]) - - # Test a new_style class with __iter__ but no next() method - def test_new_style_iter_class(self): - class IterClass(object): - def __iter__(self): - return self - self.assertRaises(TypeError, iter, IterClass()) - - # Test two-argument iter() with callable instance - def test_iter_callable(self): - class C: - def __init__(self): - self.i = 0 - def __call__(self): - i = self.i - self.i = i + 1 - if i > 100: - raise IndexError # Emergency stop - return i - self.check_iterator(iter(C(), 10), list(range(10)), pickle=False) - - # Test two-argument iter() with function - def test_iter_function(self): - def spam(state=[0]): - i = state[0] - state[0] = i+1 - return i - self.check_iterator(iter(spam, 10), list(range(10)), pickle=False) - - # Test two-argument iter() with function that raises StopIteration - def test_iter_function_stop(self): - def spam(state=[0]): - i = state[0] - if i == 10: - raise StopIteration - state[0] = i+1 - return i - self.check_iterator(iter(spam, 20), list(range(10)), pickle=False) - - # Test exception propagation through function iterator - def test_exception_function(self): - def spam(state=[0]): - i = state[0] - state[0] = i+1 - if i == 10: - raise RuntimeError - return i - res = [] - try: - for x in iter(spam, 20): - res.append(x) - except RuntimeError: - self.assertEqual(res, list(range(10))) - else: - self.fail("should have raised RuntimeError") - - # Test exception propagation through sequence iterator - def test_exception_sequence(self): - class MySequenceClass(SequenceClass): - def __getitem__(self, i): - if i == 10: - raise RuntimeError - return SequenceClass.__getitem__(self, i) - res = [] - try: - for x in MySequenceClass(20): - res.append(x) - except RuntimeError: - self.assertEqual(res, list(range(10))) - else: - self.fail("should have raised RuntimeError") - - # Test for StopIteration from __getitem__ - def test_stop_sequence(self): - class MySequenceClass(SequenceClass): - def __getitem__(self, i): - if i == 10: - raise StopIteration - return SequenceClass.__getitem__(self, i) - self.check_for_loop(MySequenceClass(20), list(range(10)), pickle=False) - - # Test a big range - def test_iter_big_range(self): - self.check_for_loop(iter(range(10000)), list(range(10000))) - - # Test an empty list - def test_iter_empty(self): - self.check_for_loop(iter([]), []) - - # Test a tuple - def test_iter_tuple(self): - self.check_for_loop(iter((0,1,2,3,4,5,6,7,8,9)), list(range(10))) - - # Test a range - def test_iter_range(self): - self.check_for_loop(iter(range(10)), list(range(10))) - - # Test a string - def test_iter_string(self): - self.check_for_loop(iter("abcde"), ["a", "b", "c", "d", "e"]) - - # Test a directory - def test_iter_dict(self): - dict = {} - for i in range(10): - dict[i] = None - self.check_for_loop(dict, list(dict.keys())) - - # Test a file - def test_iter_file(self): - f = open(TESTFN, "w") - try: - for i in range(5): - f.write("%d\n" % i) - finally: - f.close() - f = open(TESTFN, "r") - try: - self.check_for_loop(f, ["0\n", "1\n", "2\n", "3\n", "4\n"], pickle=False) - self.check_for_loop(f, [], pickle=False) - finally: - f.close() - try: - unlink(TESTFN) - except OSError: - pass - - # Test list()'s use of iterators. - def test_builtin_list(self): - self.assertEqual(list(SequenceClass(5)), list(range(5))) - self.assertEqual(list(SequenceClass(0)), []) - self.assertEqual(list(()), []) - - d = {"one": 1, "two": 2, "three": 3} - self.assertEqual(list(d), list(d.keys())) - - self.assertRaises(TypeError, list, list) - self.assertRaises(TypeError, list, 42) - - f = open(TESTFN, "w") - try: - for i in range(5): - f.write("%d\n" % i) - finally: - f.close() - f = open(TESTFN, "r") - try: - self.assertEqual(list(f), ["0\n", "1\n", "2\n", "3\n", "4\n"]) - f.seek(0, 0) - self.assertEqual(list(f), - ["0\n", "1\n", "2\n", "3\n", "4\n"]) - finally: - f.close() - try: - unlink(TESTFN) - except OSError: - pass - - # Test tuples()'s use of iterators. - def test_builtin_tuple(self): - self.assertEqual(tuple(SequenceClass(5)), (0, 1, 2, 3, 4)) - self.assertEqual(tuple(SequenceClass(0)), ()) - self.assertEqual(tuple([]), ()) - self.assertEqual(tuple(()), ()) - self.assertEqual(tuple("abc"), ("a", "b", "c")) - - d = {"one": 1, "two": 2, "three": 3} - self.assertEqual(tuple(d), tuple(d.keys())) - - self.assertRaises(TypeError, tuple, list) - self.assertRaises(TypeError, tuple, 42) - - f = open(TESTFN, "w") - try: - for i in range(5): - f.write("%d\n" % i) - finally: - f.close() - f = open(TESTFN, "r") - try: - self.assertEqual(tuple(f), ("0\n", "1\n", "2\n", "3\n", "4\n")) - f.seek(0, 0) - self.assertEqual(tuple(f), - ("0\n", "1\n", "2\n", "3\n", "4\n")) - finally: - f.close() - try: - unlink(TESTFN) - except OSError: - pass - - # Test filter()'s use of iterators. - def test_builtin_filter(self): - self.assertEqual(list(filter(None, SequenceClass(5))), - list(range(1, 5))) - self.assertEqual(list(filter(None, SequenceClass(0))), []) - self.assertEqual(list(filter(None, ())), []) - self.assertEqual(list(filter(None, "abc")), ["a", "b", "c"]) - - d = {"one": 1, "two": 2, "three": 3} - self.assertEqual(list(filter(None, d)), list(d.keys())) - - self.assertRaises(TypeError, filter, None, list) - self.assertRaises(TypeError, filter, None, 42) - - class Boolean: - def __init__(self, truth): - self.truth = truth - def __bool__(self): - return self.truth - bTrue = Boolean(True) - bFalse = Boolean(False) - - class Seq: - def __init__(self, *args): - self.vals = args - def __iter__(self): - class SeqIter: - def __init__(self, vals): - self.vals = vals - self.i = 0 - def __iter__(self): - return self - def __next__(self): - i = self.i - self.i = i + 1 - if i < len(self.vals): - return self.vals[i] - else: - raise StopIteration - return SeqIter(self.vals) - - seq = Seq(*([bTrue, bFalse] * 25)) - self.assertEqual(list(filter(lambda x: not x, seq)), [bFalse]*25) - self.assertEqual(list(filter(lambda x: not x, iter(seq))), [bFalse]*25) - - # Test max() and min()'s use of iterators. - def test_builtin_max_min(self): - self.assertEqual(max(SequenceClass(5)), 4) - self.assertEqual(min(SequenceClass(5)), 0) - self.assertEqual(max(8, -1), 8) - self.assertEqual(min(8, -1), -1) - - d = {"one": 1, "two": 2, "three": 3} - self.assertEqual(max(d), "two") - self.assertEqual(min(d), "one") - self.assertEqual(max(d.values()), 3) - self.assertEqual(min(iter(d.values())), 1) - - f = open(TESTFN, "w") - try: - f.write("medium line\n") - f.write("xtra large line\n") - f.write("itty-bitty line\n") - finally: - f.close() - f = open(TESTFN, "r") - try: - self.assertEqual(min(f), "itty-bitty line\n") - f.seek(0, 0) - self.assertEqual(max(f), "xtra large line\n") - finally: - f.close() - try: - unlink(TESTFN) - except OSError: - pass - - # Test map()'s use of iterators. - def test_builtin_map(self): - self.assertEqual(list(map(lambda x: x+1, SequenceClass(5))), - list(range(1, 6))) - - d = {"one": 1, "two": 2, "three": 3} - self.assertEqual(list(map(lambda k, d=d: (k, d[k]), d)), - list(d.items())) - dkeys = list(d.keys()) - expected = [(i < len(d) and dkeys[i] or None, - i, - i < len(d) and dkeys[i] or None) - for i in range(3)] - - f = open(TESTFN, "w") - try: - for i in range(10): - f.write("xy" * i + "\n") # line i has len 2*i+1 - finally: - f.close() - f = open(TESTFN, "r") - try: - self.assertEqual(list(map(len, f)), list(range(1, 21, 2))) - finally: - f.close() - try: - unlink(TESTFN) - except OSError: - pass - - # Test zip()'s use of iterators. - def test_builtin_zip(self): - self.assertEqual(list(zip()), []) - self.assertEqual(list(zip(*[])), []) - self.assertEqual(list(zip(*[(1, 2), 'ab'])), [(1, 'a'), (2, 'b')]) - - self.assertRaises(TypeError, zip, None) - self.assertRaises(TypeError, zip, range(10), 42) - self.assertRaises(TypeError, zip, range(10), zip) - - self.assertEqual(list(zip(IteratingSequenceClass(3))), - [(0,), (1,), (2,)]) - self.assertEqual(list(zip(SequenceClass(3))), - [(0,), (1,), (2,)]) - - d = {"one": 1, "two": 2, "three": 3} - self.assertEqual(list(d.items()), list(zip(d, d.values()))) - - # Generate all ints starting at constructor arg. - class IntsFrom: - def __init__(self, start): - self.i = start - - def __iter__(self): - return self - - def __next__(self): - i = self.i - self.i = i+1 - return i - - f = open(TESTFN, "w") - try: - f.write("a\n" "bbb\n" "cc\n") - finally: - f.close() - f = open(TESTFN, "r") - try: - self.assertEqual(list(zip(IntsFrom(0), f, IntsFrom(-100))), - [(0, "a\n", -100), - (1, "bbb\n", -99), - (2, "cc\n", -98)]) - finally: - f.close() - try: - unlink(TESTFN) - except OSError: - pass - - self.assertEqual(list(zip(range(5))), [(i,) for i in range(5)]) - - # Classes that lie about their lengths. - class NoGuessLen5: - def __getitem__(self, i): - if i >= 5: - raise IndexError - return i - - class Guess3Len5(NoGuessLen5): - def __len__(self): - return 3 - - class Guess30Len5(NoGuessLen5): - def __len__(self): - return 30 - - def lzip(*args): - return list(zip(*args)) - - self.assertEqual(len(Guess3Len5()), 3) - self.assertEqual(len(Guess30Len5()), 30) - self.assertEqual(lzip(NoGuessLen5()), lzip(range(5))) - self.assertEqual(lzip(Guess3Len5()), lzip(range(5))) - self.assertEqual(lzip(Guess30Len5()), lzip(range(5))) - - expected = [(i, i) for i in range(5)] - for x in NoGuessLen5(), Guess3Len5(), Guess30Len5(): - for y in NoGuessLen5(), Guess3Len5(), Guess30Len5(): - self.assertEqual(lzip(x, y), expected) - - def test_unicode_join_endcase(self): - - # This class inserts a Unicode object into its argument's natural - # iteration, in the 3rd position. - class OhPhooey: - def __init__(self, seq): - self.it = iter(seq) - self.i = 0 - - def __iter__(self): - return self - - def __next__(self): - i = self.i - self.i = i+1 - if i == 2: - return "fooled you!" - return next(self.it) - - f = open(TESTFN, "w") - try: - f.write("a\n" + "b\n" + "c\n") - finally: - f.close() - - f = open(TESTFN, "r") - # Nasty: string.join(s) can't know whether unicode.join() is needed - # until it's seen all of s's elements. But in this case, f's - # iterator cannot be restarted. So what we're testing here is - # whether string.join() can manage to remember everything it's seen - # and pass that on to unicode.join(). - try: - got = " - ".join(OhPhooey(f)) - self.assertEqual(got, "a\n - b\n - fooled you! - c\n") - finally: - f.close() - try: - unlink(TESTFN) - except OSError: - pass - - # Test iterators with 'x in y' and 'x not in y'. - def test_in_and_not_in(self): - for sc5 in IteratingSequenceClass(5), SequenceClass(5): - for i in range(5): - self.assertIn(i, sc5) - for i in "abc", -1, 5, 42.42, (3, 4), [], {1: 1}, 3-12j, sc5: - self.assertNotIn(i, sc5) - - self.assertRaises(TypeError, lambda: 3 in 12) - self.assertRaises(TypeError, lambda: 3 not in map) - self.assertRaises(ZeroDivisionError, lambda: 3 in BadIterableClass()) - - d = {"one": 1, "two": 2, "three": 3, 1j: 2j} - for k in d: - self.assertIn(k, d) - self.assertNotIn(k, d.values()) - for v in d.values(): - self.assertIn(v, d.values()) - self.assertNotIn(v, d) - for k, v in d.items(): - self.assertIn((k, v), d.items()) - self.assertNotIn((v, k), d.items()) - - f = open(TESTFN, "w") - try: - f.write("a\n" "b\n" "c\n") - finally: - f.close() - f = open(TESTFN, "r") - try: - for chunk in "abc": - f.seek(0, 0) - self.assertNotIn(chunk, f) - f.seek(0, 0) - self.assertIn((chunk + "\n"), f) - finally: - f.close() - try: - unlink(TESTFN) - except OSError: - pass - - # Test iterators with operator.countOf (PySequence_Count). - def test_countOf(self): - from operator import countOf - self.assertEqual(countOf([1,2,2,3,2,5], 2), 3) - self.assertEqual(countOf((1,2,2,3,2,5), 2), 3) - self.assertEqual(countOf("122325", "2"), 3) - self.assertEqual(countOf("122325", "6"), 0) - - self.assertRaises(TypeError, countOf, 42, 1) - self.assertRaises(TypeError, countOf, countOf, countOf) - - d = {"one": 3, "two": 3, "three": 3, 1j: 2j} - for k in d: - self.assertEqual(countOf(d, k), 1) - self.assertEqual(countOf(d.values(), 3), 3) - self.assertEqual(countOf(d.values(), 2j), 1) - self.assertEqual(countOf(d.values(), 1j), 0) - - f = open(TESTFN, "w") - try: - f.write("a\n" "b\n" "c\n" "b\n") - finally: - f.close() - f = open(TESTFN, "r") - try: - for letter, count in ("a", 1), ("b", 2), ("c", 1), ("d", 0): - f.seek(0, 0) - self.assertEqual(countOf(f, letter + "\n"), count) - finally: - f.close() - try: - unlink(TESTFN) - except OSError: - pass - - # Test iterators with operator.indexOf (PySequence_Index). - def test_indexOf(self): - from operator import indexOf - self.assertEqual(indexOf([1,2,2,3,2,5], 1), 0) - self.assertEqual(indexOf((1,2,2,3,2,5), 2), 1) - self.assertEqual(indexOf((1,2,2,3,2,5), 3), 3) - self.assertEqual(indexOf((1,2,2,3,2,5), 5), 5) - self.assertRaises(ValueError, indexOf, (1,2,2,3,2,5), 0) - self.assertRaises(ValueError, indexOf, (1,2,2,3,2,5), 6) - - self.assertEqual(indexOf("122325", "2"), 1) - self.assertEqual(indexOf("122325", "5"), 5) - self.assertRaises(ValueError, indexOf, "122325", "6") - - self.assertRaises(TypeError, indexOf, 42, 1) - self.assertRaises(TypeError, indexOf, indexOf, indexOf) - self.assertRaises(ZeroDivisionError, indexOf, BadIterableClass(), 1) - - f = open(TESTFN, "w") - try: - f.write("a\n" "b\n" "c\n" "d\n" "e\n") - finally: - f.close() - f = open(TESTFN, "r") - try: - fiter = iter(f) - self.assertEqual(indexOf(fiter, "b\n"), 1) - self.assertEqual(indexOf(fiter, "d\n"), 1) - self.assertEqual(indexOf(fiter, "e\n"), 0) - self.assertRaises(ValueError, indexOf, fiter, "a\n") - finally: - f.close() - try: - unlink(TESTFN) - except OSError: - pass - - iclass = IteratingSequenceClass(3) - for i in range(3): - self.assertEqual(indexOf(iclass, i), i) - self.assertRaises(ValueError, indexOf, iclass, -1) - - # Test iterators with file.writelines(). - def test_writelines(self): - f = open(TESTFN, "w") - - try: - self.assertRaises(TypeError, f.writelines, None) - self.assertRaises(TypeError, f.writelines, 42) - - f.writelines(["1\n", "2\n"]) - f.writelines(("3\n", "4\n")) - f.writelines({'5\n': None}) - f.writelines({}) - - # Try a big chunk too. - class Iterator: - def __init__(self, start, finish): - self.start = start - self.finish = finish - self.i = self.start - - def __next__(self): - if self.i >= self.finish: - raise StopIteration - result = str(self.i) + '\n' - self.i += 1 - return result - - def __iter__(self): - return self - - class Whatever: - def __init__(self, start, finish): - self.start = start - self.finish = finish - - def __iter__(self): - return Iterator(self.start, self.finish) - - f.writelines(Whatever(6, 6+2000)) - f.close() - - f = open(TESTFN) - expected = [str(i) + "\n" for i in range(1, 2006)] - self.assertEqual(list(f), expected) - - finally: - f.close() - try: - unlink(TESTFN) - except OSError: - pass - - - # Test iterators on RHS of unpacking assignments. - def test_unpack_iter(self): - a, b = 1, 2 - self.assertEqual((a, b), (1, 2)) - - a, b, c = IteratingSequenceClass(3) - self.assertEqual((a, b, c), (0, 1, 2)) - - try: # too many values - a, b = IteratingSequenceClass(3) - except ValueError: - pass - else: - self.fail("should have raised ValueError") - - try: # not enough values - a, b, c = IteratingSequenceClass(2) - except ValueError: - pass - else: - self.fail("should have raised ValueError") - - try: # not iterable - a, b, c = len - except TypeError: - pass - else: - self.fail("should have raised TypeError") - - a, b, c = {1: 42, 2: 42, 3: 42}.values() - self.assertEqual((a, b, c), (42, 42, 42)) - - f = open(TESTFN, "w") - lines = ("a\n", "bb\n", "ccc\n") - try: - for line in lines: - f.write(line) - finally: - f.close() - f = open(TESTFN, "r") - try: - a, b, c = f - self.assertEqual((a, b, c), lines) - finally: - f.close() - try: - unlink(TESTFN) - except OSError: - pass - - (a, b), (c,) = IteratingSequenceClass(2), {42: 24} - self.assertEqual((a, b, c), (0, 1, 42)) - - - @cpython_only - def test_ref_counting_behavior(self): - class C(object): - count = 0 - def __new__(cls): - cls.count += 1 - return object.__new__(cls) - def __del__(self): - cls = self.__class__ - assert cls.count > 0 - cls.count -= 1 - x = C() - self.assertEqual(C.count, 1) - del x - self.assertEqual(C.count, 0) - l = [C(), C(), C()] - self.assertEqual(C.count, 3) - try: - a, b = iter(l) - except ValueError: - pass - del l - self.assertEqual(C.count, 0) - - - # Make sure StopIteration is a "sink state". - # This tests various things that weren't sink states in Python 2.2.1, - # plus various things that always were fine. - - def test_sinkstate_list(self): - # This used to fail - a = list(range(5)) - b = iter(a) - self.assertEqual(list(b), list(range(5))) - a.extend(range(5, 10)) - self.assertEqual(list(b), []) - - def test_sinkstate_tuple(self): - a = (0, 1, 2, 3, 4) - b = iter(a) - self.assertEqual(list(b), list(range(5))) - self.assertEqual(list(b), []) - - def test_sinkstate_string(self): - a = "abcde" - b = iter(a) - self.assertEqual(list(b), ['a', 'b', 'c', 'd', 'e']) - self.assertEqual(list(b), []) - - def test_sinkstate_sequence(self): - # This used to fail - a = SequenceClass(5) - b = iter(a) - self.assertEqual(list(b), list(range(5))) - a.n = 10 - self.assertEqual(list(b), []) - - def test_sinkstate_callable(self): - # This used to fail - def spam(state=[0]): - i = state[0] - state[0] = i+1 - if i == 10: - raise AssertionError("shouldn't have gotten this far") - return i - b = iter(spam, 5) - self.assertEqual(list(b), list(range(5))) - self.assertEqual(list(b), []) - - def test_sinkstate_dict(self): - # XXX For a more thorough test, see towards the end of: - # http://mail.python.org/pipermail/python-dev/2002-July/026512.html - a = {1:1, 2:2, 0:0, 4:4, 3:3} - for b in iter(a), a.keys(), a.items(), a.values(): - b = iter(a) - self.assertEqual(len(list(b)), 5) - self.assertEqual(list(b), []) - - def test_sinkstate_yield(self): - def gen(): - for i in range(5): - yield i - b = gen() - self.assertEqual(list(b), list(range(5))) - self.assertEqual(list(b), []) - - def test_sinkstate_range(self): - a = range(5) - b = iter(a) - self.assertEqual(list(b), list(range(5))) - self.assertEqual(list(b), []) - - def test_sinkstate_enumerate(self): - a = range(5) - e = enumerate(a) - b = iter(e) - self.assertEqual(list(b), list(zip(range(5), range(5)))) - self.assertEqual(list(b), []) - - def test_3720(self): - # Avoid a crash, when an iterator deletes its next() method. - class BadIterator(object): - def __iter__(self): - return self - def __next__(self): - del BadIterator.__next__ - return 1 - - try: - for i in BadIterator() : - pass - except TypeError: - pass - - def test_extending_list_with_iterator_does_not_segfault(self): - # The code to extend a list with an iterator has a fair - # amount of nontrivial logic in terms of guessing how - # much memory to allocate in advance, "stealing" refs, - # and then shrinking at the end. This is a basic smoke - # test for that scenario. - def gen(): - for i in range(500): - yield i - lst = [0] * 500 - for i in range(240): - lst.pop(0) - lst.extend(gen()) - self.assertEqual(len(lst), 760) - - @cpython_only - def test_iter_overflow(self): - # Test for the issue 22939 - it = iter(UnlimitedSequenceClass()) - # Manually set `it_index` to PY_SSIZE_T_MAX-2 without a loop - it.__setstate__(sys.maxsize - 2) - self.assertEqual(next(it), sys.maxsize - 2) - self.assertEqual(next(it), sys.maxsize - 1) - with self.assertRaises(OverflowError): - next(it) - # Check that Overflow error is always raised - with self.assertRaises(OverflowError): - next(it) - - def test_iter_neg_setstate(self): - it = iter(UnlimitedSequenceClass()) - it.__setstate__(-42) - self.assertEqual(next(it), 0) - self.assertEqual(next(it), 1) - - def test_free_after_iterating(self): - check_free_after_iterating(self, iter, SequenceClass, (0,)) - - def test_error_iter(self): - for typ in (DefaultIterClass, NoIterClass): - self.assertRaises(TypeError, iter, typ()) - self.assertRaises(ZeroDivisionError, iter, BadIterableClass()) - - - def test_main(): - run_unittest(TestCase) - - - if __name__ == "__main__": - test_main() diff --git a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_iterlen.yaml b/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_iterlen.yaml deleted file mode 100644 index fb8e9a5ec..000000000 --- a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_iterlen.yaml +++ /dev/null @@ -1,229 +0,0 @@ -python: | - """ Test Iterator Length Transparency - - Some functions or methods which accept general iterable arguments have - optional, more efficient code paths if they know how many items to expect. - For instance, map(func, iterable), will pre-allocate the exact amount of - space required whenever the iterable can report its length. - - The desired invariant is: len(it)==len(list(it)). - - A complication is that an iterable and iterator can be the same object. To - maintain the invariant, an iterator needs to dynamically update its length. - For instance, an iterable such as range(10) always reports its length as ten, - but it=iter(range(10)) starts at ten, and then goes to nine after next(it). - Having this capability means that map() can ignore the distinction between - map(func, iterable) and map(func, iter(iterable)). - - When the iterable is immutable, the implementation can straight-forwardly - report the original length minus the cumulative number of calls to next(). - This is the case for tuples, range objects, and itertools.repeat(). - - Some containers become temporarily immutable during iteration. This includes - dicts, sets, and collections.deque. Their implementation is equally simple - though they need to permanently set their length to zero whenever there is - an attempt to iterate after a length mutation. - - The situation slightly more involved whenever an object allows length mutation - during iteration. Lists and sequence iterators are dynamically updatable. - So, if a list is extended during iteration, the iterator will continue through - the new items. If it shrinks to a point before the most recent iteration, - then no further items are available and the length is reported at zero. - - Reversed objects can also be wrapped around mutable objects; however, any - appends after the current position are ignored. Any other approach leads - to confusion and possibly returning the same item more than once. - - The iterators not listed above, such as enumerate and the other itertools, - are not length transparent because they have no way to distinguish between - iterables that report static length and iterators whose length changes with - each call (i.e. the difference between enumerate('abc') and - enumerate(iter('abc')). - - """ - - import unittest - from itertools import repeat - from collections import deque - from operator import length_hint - - n = 10 - - - class TestInvariantWithoutMutations: - - def test_invariant(self): - it = self.it - for i in reversed(range(1, n+1)): - self.assertEqual(length_hint(it), i) - next(it) - self.assertEqual(length_hint(it), 0) - self.assertRaises(StopIteration, next, it) - self.assertEqual(length_hint(it), 0) - - class TestTemporarilyImmutable(TestInvariantWithoutMutations): - - def test_immutable_during_iteration(self): - # objects such as deques, sets, and dictionaries enforce - # length immutability during iteration - - it = self.it - self.assertEqual(length_hint(it), n) - next(it) - self.assertEqual(length_hint(it), n-1) - self.mutate() - self.assertRaises(RuntimeError, next, it) - self.assertEqual(length_hint(it), 0) - - ## ------- Concrete Type Tests ------- - - class TestRepeat(TestInvariantWithoutMutations, unittest.TestCase): - - def setUp(self): - self.it = repeat(None, n) - - class TestXrange(TestInvariantWithoutMutations, unittest.TestCase): - - def setUp(self): - self.it = iter(range(n)) - - class TestXrangeCustomReversed(TestInvariantWithoutMutations, unittest.TestCase): - - def setUp(self): - self.it = reversed(range(n)) - - class TestTuple(TestInvariantWithoutMutations, unittest.TestCase): - - def setUp(self): - self.it = iter(tuple(range(n))) - - ## ------- Types that should not be mutated during iteration ------- - - class TestDeque(TestTemporarilyImmutable, unittest.TestCase): - - def setUp(self): - d = deque(range(n)) - self.it = iter(d) - self.mutate = d.pop - - class TestDequeReversed(TestTemporarilyImmutable, unittest.TestCase): - - def setUp(self): - d = deque(range(n)) - self.it = reversed(d) - self.mutate = d.pop - - class TestDictKeys(TestTemporarilyImmutable, unittest.TestCase): - - def setUp(self): - d = dict.fromkeys(range(n)) - self.it = iter(d) - self.mutate = d.popitem - - class TestDictItems(TestTemporarilyImmutable, unittest.TestCase): - - def setUp(self): - d = dict.fromkeys(range(n)) - self.it = iter(d.items()) - self.mutate = d.popitem - - class TestDictValues(TestTemporarilyImmutable, unittest.TestCase): - - def setUp(self): - d = dict.fromkeys(range(n)) - self.it = iter(d.values()) - self.mutate = d.popitem - - class TestSet(TestTemporarilyImmutable, unittest.TestCase): - - def setUp(self): - d = set(range(n)) - self.it = iter(d) - self.mutate = d.pop - - ## ------- Types that can mutate during iteration ------- - - class TestList(TestInvariantWithoutMutations, unittest.TestCase): - - def setUp(self): - self.it = iter(range(n)) - - def test_mutation(self): - d = list(range(n)) - it = iter(d) - next(it) - next(it) - self.assertEqual(length_hint(it), n - 2) - d.append(n) - self.assertEqual(length_hint(it), n - 1) # grow with append - d[1:] = [] - self.assertEqual(length_hint(it), 0) - self.assertEqual(list(it), []) - d.extend(range(20)) - self.assertEqual(length_hint(it), 0) - - - class TestListReversed(TestInvariantWithoutMutations, unittest.TestCase): - - def setUp(self): - self.it = reversed(range(n)) - - def test_mutation(self): - d = list(range(n)) - it = reversed(d) - next(it) - next(it) - self.assertEqual(length_hint(it), n - 2) - d.append(n) - self.assertEqual(length_hint(it), n - 2) # ignore append - d[1:] = [] - self.assertEqual(length_hint(it), 0) - self.assertEqual(list(it), []) # confirm invariant - d.extend(range(20)) - self.assertEqual(length_hint(it), 0) - - ## -- Check to make sure exceptions are not suppressed by __length_hint__() - - - class BadLen(object): - def __iter__(self): - return iter(range(10)) - - def __len__(self): - raise RuntimeError('hello') - - - class BadLengthHint(object): - def __iter__(self): - return iter(range(10)) - - def __length_hint__(self): - raise RuntimeError('hello') - - - class NoneLengthHint(object): - def __iter__(self): - return iter(range(10)) - - def __length_hint__(self): - return NotImplemented - - - class TestLengthHintExceptions(unittest.TestCase): - - def test_issue1242657(self): - self.assertRaises(RuntimeError, list, BadLen()) - self.assertRaises(RuntimeError, list, BadLengthHint()) - self.assertRaises(RuntimeError, [].extend, BadLen()) - self.assertRaises(RuntimeError, [].extend, BadLengthHint()) - b = bytearray(range(10)) - self.assertRaises(RuntimeError, b.extend, BadLen()) - self.assertRaises(RuntimeError, b.extend, BadLengthHint()) - - def test_invalid_hint(self): - # Make sure an invalid result doesn't muck-up the works - self.assertEqual(list(NoneLengthHint()), list(range(10))) - - - if __name__ == "__main__": - unittest.main() diff --git a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_itertools.yaml b/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_itertools.yaml deleted file mode 100644 index c2605e18a..000000000 --- a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_itertools.yaml +++ /dev/null @@ -1,2585 +0,0 @@ -python: | - import unittest - from test import support - from itertools import * - import weakref - from decimal import Decimal - from fractions import Fraction - import operator - import random - import copy - import pickle - from functools import reduce - import sys - import struct - import threading - import gc - - maxsize = support.MAX_Py_ssize_t - minsize = -maxsize-1 - - def lzip(*args): - return list(zip(*args)) - - def onearg(x): - 'Test function of one argument' - return 2*x - - def errfunc(*args): - 'Test function that raises an error' - raise ValueError - - def gen3(): - 'Non-restartable source sequence' - for i in (0, 1, 2): - yield i - - def isEven(x): - 'Test predicate' - return x%2==0 - - def isOdd(x): - 'Test predicate' - return x%2==1 - - def tupleize(*args): - return args - - def irange(n): - for i in range(n): - yield i - - class StopNow: - 'Class emulating an empty iterable.' - def __iter__(self): - return self - def __next__(self): - raise StopIteration - - def take(n, seq): - 'Convenience function for partially consuming a long of infinite iterable' - return list(islice(seq, n)) - - def prod(iterable): - return reduce(operator.mul, iterable, 1) - - def fact(n): - 'Factorial' - return prod(range(1, n+1)) - - # root level methods for pickling ability - def testR(r): - return r[0] - - def testR2(r): - return r[2] - - def underten(x): - return x<10 - - picklecopiers = [lambda s, proto=proto: pickle.loads(pickle.dumps(s, proto)) - for proto in range(pickle.HIGHEST_PROTOCOL + 1)] - - class TestBasicOps(unittest.TestCase): - - def pickletest(self, protocol, it, stop=4, take=1, compare=None): - """Test that an iterator is the same after pickling, also when part-consumed""" - def expand(it, i=0): - # Recursively expand iterables, within sensible bounds - if i > 10: - raise RuntimeError("infinite recursion encountered") - if isinstance(it, str): - return it - try: - l = list(islice(it, stop)) - except TypeError: - return it # can't expand it - return [expand(e, i+1) for e in l] - - # Test the initial copy against the original - dump = pickle.dumps(it, protocol) - i2 = pickle.loads(dump) - self.assertEqual(type(it), type(i2)) - a, b = expand(it), expand(i2) - self.assertEqual(a, b) - if compare: - c = expand(compare) - self.assertEqual(a, c) - - # Take from the copy, and create another copy and compare them. - i3 = pickle.loads(dump) - took = 0 - try: - for i in range(take): - next(i3) - took += 1 - except StopIteration: - pass #in case there is less data than 'take' - dump = pickle.dumps(i3, protocol) - i4 = pickle.loads(dump) - a, b = expand(i3), expand(i4) - self.assertEqual(a, b) - if compare: - c = expand(compare[took:]) - self.assertEqual(a, c); - - def test_accumulate(self): - self.assertEqual(list(accumulate(range(10))), # one positional arg - [0, 1, 3, 6, 10, 15, 21, 28, 36, 45]) - self.assertEqual(list(accumulate(iterable=range(10))), # kw arg - [0, 1, 3, 6, 10, 15, 21, 28, 36, 45]) - for typ in int, complex, Decimal, Fraction: # multiple types - self.assertEqual( - list(accumulate(map(typ, range(10)))), - list(map(typ, [0, 1, 3, 6, 10, 15, 21, 28, 36, 45]))) - self.assertEqual(list(accumulate('abc')), ['a', 'ab', 'abc']) # works with non-numeric - self.assertEqual(list(accumulate([])), []) # empty iterable - self.assertEqual(list(accumulate([7])), [7]) # iterable of length one - self.assertRaises(TypeError, accumulate, range(10), 5, 6) # too many args - self.assertRaises(TypeError, accumulate) # too few args - self.assertRaises(TypeError, accumulate, x=range(10)) # unexpected kwd arg - self.assertRaises(TypeError, list, accumulate([1, []])) # args that don't add - - s = [2, 8, 9, 5, 7, 0, 3, 4, 1, 6] - self.assertEqual(list(accumulate(s, min)), - [2, 2, 2, 2, 2, 0, 0, 0, 0, 0]) - self.assertEqual(list(accumulate(s, max)), - [2, 8, 9, 9, 9, 9, 9, 9, 9, 9]) - self.assertEqual(list(accumulate(s, operator.mul)), - [2, 16, 144, 720, 5040, 0, 0, 0, 0, 0]) - with self.assertRaises(TypeError): - list(accumulate(s, chr)) # unary-operation - for proto in range(pickle.HIGHEST_PROTOCOL + 1): - self.pickletest(proto, accumulate(range(10))) # test pickling - self.pickletest(proto, accumulate(range(10), initial=7)) - self.assertEqual(list(accumulate([10, 5, 1], initial=None)), [10, 15, 16]) - self.assertEqual(list(accumulate([10, 5, 1], initial=100)), [100, 110, 115, 116]) - self.assertEqual(list(accumulate([], initial=100)), [100]) - with self.assertRaises(TypeError): - list(accumulate([10, 20], 100)) - - def test_chain(self): - - def chain2(*iterables): - 'Pure python version in the docs' - for it in iterables: - for element in it: - yield element - - for c in (chain, chain2): - self.assertEqual(list(c('abc', 'def')), list('abcdef')) - self.assertEqual(list(c('abc')), list('abc')) - self.assertEqual(list(c('')), []) - self.assertEqual(take(4, c('abc', 'def')), list('abcd')) - self.assertRaises(TypeError, list,c(2, 3)) - - def test_chain_from_iterable(self): - self.assertEqual(list(chain.from_iterable(['abc', 'def'])), list('abcdef')) - self.assertEqual(list(chain.from_iterable(['abc'])), list('abc')) - self.assertEqual(list(chain.from_iterable([''])), []) - self.assertEqual(take(4, chain.from_iterable(['abc', 'def'])), list('abcd')) - self.assertRaises(TypeError, list, chain.from_iterable([2, 3])) - - def test_chain_reducible(self): - for oper in [copy.deepcopy] + picklecopiers: - it = chain('abc', 'def') - self.assertEqual(list(oper(it)), list('abcdef')) - self.assertEqual(next(it), 'a') - self.assertEqual(list(oper(it)), list('bcdef')) - - self.assertEqual(list(oper(chain(''))), []) - self.assertEqual(take(4, oper(chain('abc', 'def'))), list('abcd')) - self.assertRaises(TypeError, list, oper(chain(2, 3))) - for proto in range(pickle.HIGHEST_PROTOCOL + 1): - self.pickletest(proto, chain('abc', 'def'), compare=list('abcdef')) - - def test_chain_setstate(self): - self.assertRaises(TypeError, chain().__setstate__, ()) - self.assertRaises(TypeError, chain().__setstate__, []) - self.assertRaises(TypeError, chain().__setstate__, 0) - self.assertRaises(TypeError, chain().__setstate__, ([],)) - self.assertRaises(TypeError, chain().__setstate__, (iter([]), [])) - it = chain() - it.__setstate__((iter(['abc', 'def']),)) - self.assertEqual(list(it), ['a', 'b', 'c', 'd', 'e', 'f']) - it = chain() - it.__setstate__((iter(['abc', 'def']), iter(['ghi']))) - self.assertEqual(list(it), ['ghi', 'a', 'b', 'c', 'd', 'e', 'f']) - - def test_combinations(self): - self.assertRaises(TypeError, combinations, 'abc') # missing r argument - self.assertRaises(TypeError, combinations, 'abc', 2, 1) # too many arguments - self.assertRaises(TypeError, combinations, None) # pool is not iterable - self.assertRaises(ValueError, combinations, 'abc', -2) # r is negative - - for op in [lambda a:a] + picklecopiers: - self.assertEqual(list(op(combinations('abc', 32))), []) # r > n - - self.assertEqual(list(op(combinations('ABCD', 2))), - [('A','B'), ('A','C'), ('A','D'), ('B','C'), ('B','D'), ('C','D')]) - testIntermediate = combinations('ABCD', 2) - next(testIntermediate) - self.assertEqual(list(op(testIntermediate)), - [('A','C'), ('A','D'), ('B','C'), ('B','D'), ('C','D')]) - - self.assertEqual(list(op(combinations(range(4), 3))), - [(0,1,2), (0,1,3), (0,2,3), (1,2,3)]) - testIntermediate = combinations(range(4), 3) - next(testIntermediate) - self.assertEqual(list(op(testIntermediate)), - [(0,1,3), (0,2,3), (1,2,3)]) - - - def combinations1(iterable, r): - 'Pure python version shown in the docs' - pool = tuple(iterable) - n = len(pool) - if r > n: - return - indices = list(range(r)) - yield tuple(pool[i] for i in indices) - while 1: - for i in reversed(range(r)): - if indices[i] != i + n - r: - break - else: - return - indices[i] += 1 - for j in range(i+1, r): - indices[j] = indices[j-1] + 1 - yield tuple(pool[i] for i in indices) - - def combinations2(iterable, r): - 'Pure python version shown in the docs' - pool = tuple(iterable) - n = len(pool) - for indices in permutations(range(n), r): - if sorted(indices) == list(indices): - yield tuple(pool[i] for i in indices) - - def combinations3(iterable, r): - 'Pure python version from cwr()' - pool = tuple(iterable) - n = len(pool) - for indices in combinations_with_replacement(range(n), r): - if len(set(indices)) == r: - yield tuple(pool[i] for i in indices) - - for n in range(7): - values = [5*x-12 for x in range(n)] - for r in range(n+2): - result = list(combinations(values, r)) - self.assertEqual(len(result), 0 if r>n else fact(n) / fact(r) / fact(n-r)) # right number of combs - self.assertEqual(len(result), len(set(result))) # no repeats - self.assertEqual(result, sorted(result)) # lexicographic order - for c in result: - self.assertEqual(len(c), r) # r-length combinations - self.assertEqual(len(set(c)), r) # no duplicate elements - self.assertEqual(list(c), sorted(c)) # keep original ordering - self.assertTrue(all(e in values for e in c)) # elements taken from input iterable - self.assertEqual(list(c), - [e for e in values if e in c]) # comb is a subsequence of the input iterable - self.assertEqual(result, list(combinations1(values, r))) # matches first pure python version - self.assertEqual(result, list(combinations2(values, r))) # matches second pure python version - self.assertEqual(result, list(combinations3(values, r))) # matches second pure python version - - for proto in range(pickle.HIGHEST_PROTOCOL + 1): - self.pickletest(proto, combinations(values, r)) # test pickling - - @support.bigaddrspacetest - def test_combinations_overflow(self): - with self.assertRaises((OverflowError, MemoryError)): - combinations("AA", 2**29) - - # Test implementation detail: tuple re-use - @support.impl_detail("tuple reuse is specific to CPython") - def test_combinations_tuple_reuse(self): - self.assertEqual(len(set(map(id, combinations('abcde', 3)))), 1) - self.assertNotEqual(len(set(map(id, list(combinations('abcde', 3))))), 1) - - def test_combinations_with_replacement(self): - cwr = combinations_with_replacement - self.assertRaises(TypeError, cwr, 'abc') # missing r argument - self.assertRaises(TypeError, cwr, 'abc', 2, 1) # too many arguments - self.assertRaises(TypeError, cwr, None) # pool is not iterable - self.assertRaises(ValueError, cwr, 'abc', -2) # r is negative - - for op in [lambda a:a] + picklecopiers: - self.assertEqual(list(op(cwr('ABC', 2))), - [('A','A'), ('A','B'), ('A','C'), ('B','B'), ('B','C'), ('C','C')]) - testIntermediate = cwr('ABC', 2) - next(testIntermediate) - self.assertEqual(list(op(testIntermediate)), - [('A','B'), ('A','C'), ('B','B'), ('B','C'), ('C','C')]) - - - def cwr1(iterable, r): - 'Pure python version shown in the docs' - # number items returned: (n+r-1)! / r! / (n-1)! when n>0 - pool = tuple(iterable) - n = len(pool) - if not n and r: - return - indices = [0] * r - yield tuple(pool[i] for i in indices) - while 1: - for i in reversed(range(r)): - if indices[i] != n - 1: - break - else: - return - indices[i:] = [indices[i] + 1] * (r - i) - yield tuple(pool[i] for i in indices) - - def cwr2(iterable, r): - 'Pure python version shown in the docs' - pool = tuple(iterable) - n = len(pool) - for indices in product(range(n), repeat=r): - if sorted(indices) == list(indices): - yield tuple(pool[i] for i in indices) - - def numcombs(n, r): - if not n: - return 0 if r else 1 - return fact(n+r-1) / fact(r)/ fact(n-1) - - for n in range(7): - values = [5*x-12 for x in range(n)] - for r in range(n+2): - result = list(cwr(values, r)) - - self.assertEqual(len(result), numcombs(n, r)) # right number of combs - self.assertEqual(len(result), len(set(result))) # no repeats - self.assertEqual(result, sorted(result)) # lexicographic order - - regular_combs = list(combinations(values, r)) # compare to combs without replacement - if n == 0 or r <= 1: - self.assertEqual(result, regular_combs) # cases that should be identical - else: - self.assertTrue(set(result) >= set(regular_combs)) # rest should be supersets of regular combs - - for c in result: - self.assertEqual(len(c), r) # r-length combinations - noruns = [k for k,v in groupby(c)] # combo without consecutive repeats - self.assertEqual(len(noruns), len(set(noruns))) # no repeats other than consecutive - self.assertEqual(list(c), sorted(c)) # keep original ordering - self.assertTrue(all(e in values for e in c)) # elements taken from input iterable - self.assertEqual(noruns, - [e for e in values if e in c]) # comb is a subsequence of the input iterable - self.assertEqual(result, list(cwr1(values, r))) # matches first pure python version - self.assertEqual(result, list(cwr2(values, r))) # matches second pure python version - - for proto in range(pickle.HIGHEST_PROTOCOL + 1): - self.pickletest(proto, cwr(values,r)) # test pickling - - @support.bigaddrspacetest - def test_combinations_with_replacement_overflow(self): - with self.assertRaises((OverflowError, MemoryError)): - combinations_with_replacement("AA", 2**30) - - # Test implementation detail: tuple re-use - @support.impl_detail("tuple reuse is specific to CPython") - def test_combinations_with_replacement_tuple_reuse(self): - cwr = combinations_with_replacement - self.assertEqual(len(set(map(id, cwr('abcde', 3)))), 1) - self.assertNotEqual(len(set(map(id, list(cwr('abcde', 3))))), 1) - - def test_permutations(self): - self.assertRaises(TypeError, permutations) # too few arguments - self.assertRaises(TypeError, permutations, 'abc', 2, 1) # too many arguments - self.assertRaises(TypeError, permutations, None) # pool is not iterable - self.assertRaises(ValueError, permutations, 'abc', -2) # r is negative - self.assertEqual(list(permutations('abc', 32)), []) # r > n - self.assertRaises(TypeError, permutations, 'abc', 's') # r is not an int or None - self.assertEqual(list(permutations(range(3), 2)), - [(0,1), (0,2), (1,0), (1,2), (2,0), (2,1)]) - - def permutations1(iterable, r=None): - 'Pure python version shown in the docs' - pool = tuple(iterable) - n = len(pool) - r = n if r is None else r - if r > n: - return - indices = list(range(n)) - cycles = list(range(n-r+1, n+1))[::-1] - yield tuple(pool[i] for i in indices[:r]) - while n: - for i in reversed(range(r)): - cycles[i] -= 1 - if cycles[i] == 0: - indices[i:] = indices[i+1:] + indices[i:i+1] - cycles[i] = n - i - else: - j = cycles[i] - indices[i], indices[-j] = indices[-j], indices[i] - yield tuple(pool[i] for i in indices[:r]) - break - else: - return - - def permutations2(iterable, r=None): - 'Pure python version shown in the docs' - pool = tuple(iterable) - n = len(pool) - r = n if r is None else r - for indices in product(range(n), repeat=r): - if len(set(indices)) == r: - yield tuple(pool[i] for i in indices) - - for n in range(7): - values = [5*x-12 for x in range(n)] - for r in range(n+2): - result = list(permutations(values, r)) - self.assertEqual(len(result), 0 if r>n else fact(n) / fact(n-r)) # right number of perms - self.assertEqual(len(result), len(set(result))) # no repeats - self.assertEqual(result, sorted(result)) # lexicographic order - for p in result: - self.assertEqual(len(p), r) # r-length permutations - self.assertEqual(len(set(p)), r) # no duplicate elements - self.assertTrue(all(e in values for e in p)) # elements taken from input iterable - self.assertEqual(result, list(permutations1(values, r))) # matches first pure python version - self.assertEqual(result, list(permutations2(values, r))) # matches second pure python version - if r == n: - self.assertEqual(result, list(permutations(values, None))) # test r as None - self.assertEqual(result, list(permutations(values))) # test default r - - for proto in range(pickle.HIGHEST_PROTOCOL + 1): - self.pickletest(proto, permutations(values, r)) # test pickling - - @support.bigaddrspacetest - def test_permutations_overflow(self): - with self.assertRaises((OverflowError, MemoryError)): - permutations("A", 2**30) - - @support.impl_detail("tuple reuse is specific to CPython") - def test_permutations_tuple_reuse(self): - self.assertEqual(len(set(map(id, permutations('abcde', 3)))), 1) - self.assertNotEqual(len(set(map(id, list(permutations('abcde', 3))))), 1) - - def test_combinatorics(self): - # Test relationships between product(), permutations(), - # combinations() and combinations_with_replacement(). - - for n in range(6): - s = 'ABCDEFG'[:n] - for r in range(8): - prod = list(product(s, repeat=r)) - cwr = list(combinations_with_replacement(s, r)) - perm = list(permutations(s, r)) - comb = list(combinations(s, r)) - - # Check size - self.assertEqual(len(prod), n**r) - self.assertEqual(len(cwr), (fact(n+r-1) / fact(r)/ fact(n-1)) if n else (not r)) - self.assertEqual(len(perm), 0 if r>n else fact(n) / fact(n-r)) - self.assertEqual(len(comb), 0 if r>n else fact(n) / fact(r) / fact(n-r)) - - # Check lexicographic order without repeated tuples - self.assertEqual(prod, sorted(set(prod))) - self.assertEqual(cwr, sorted(set(cwr))) - self.assertEqual(perm, sorted(set(perm))) - self.assertEqual(comb, sorted(set(comb))) - - # Check interrelationships - self.assertEqual(cwr, [t for t in prod if sorted(t)==list(t)]) # cwr: prods which are sorted - self.assertEqual(perm, [t for t in prod if len(set(t))==r]) # perm: prods with no dups - self.assertEqual(comb, [t for t in perm if sorted(t)==list(t)]) # comb: perms that are sorted - self.assertEqual(comb, [t for t in cwr if len(set(t))==r]) # comb: cwrs without dups - self.assertEqual(comb, list(filter(set(cwr).__contains__, perm))) # comb: perm that is a cwr - self.assertEqual(comb, list(filter(set(perm).__contains__, cwr))) # comb: cwr that is a perm - self.assertEqual(comb, sorted(set(cwr) & set(perm))) # comb: both a cwr and a perm - - def test_compress(self): - self.assertEqual(list(compress(data='ABCDEF', selectors=[1,0,1,0,1,1])), list('ACEF')) - self.assertEqual(list(compress('ABCDEF', [1,0,1,0,1,1])), list('ACEF')) - self.assertEqual(list(compress('ABCDEF', [0,0,0,0,0,0])), list('')) - self.assertEqual(list(compress('ABCDEF', [1,1,1,1,1,1])), list('ABCDEF')) - self.assertEqual(list(compress('ABCDEF', [1,0,1])), list('AC')) - self.assertEqual(list(compress('ABC', [0,1,1,1,1,1])), list('BC')) - n = 10000 - data = chain.from_iterable(repeat(range(6), n)) - selectors = chain.from_iterable(repeat((0, 1))) - self.assertEqual(list(compress(data, selectors)), [1,3,5] * n) - self.assertRaises(TypeError, compress, None, range(6)) # 1st arg not iterable - self.assertRaises(TypeError, compress, range(6), None) # 2nd arg not iterable - self.assertRaises(TypeError, compress, range(6)) # too few args - self.assertRaises(TypeError, compress, range(6), None) # too many args - - # check copy, deepcopy, pickle - for op in [lambda a:copy.copy(a), lambda a:copy.deepcopy(a)] + picklecopiers: - for data, selectors, result1, result2 in [ - ('ABCDEF', [1,0,1,0,1,1], 'ACEF', 'CEF'), - ('ABCDEF', [0,0,0,0,0,0], '', ''), - ('ABCDEF', [1,1,1,1,1,1], 'ABCDEF', 'BCDEF'), - ('ABCDEF', [1,0,1], 'AC', 'C'), - ('ABC', [0,1,1,1,1,1], 'BC', 'C'), - ]: - - self.assertEqual(list(op(compress(data=data, selectors=selectors))), list(result1)) - self.assertEqual(list(op(compress(data, selectors))), list(result1)) - testIntermediate = compress(data, selectors) - if result1: - next(testIntermediate) - self.assertEqual(list(op(testIntermediate)), list(result2)) - - - def test_count(self): - self.assertEqual(lzip('abc',count()), [('a', 0), ('b', 1), ('c', 2)]) - self.assertEqual(lzip('abc',count(3)), [('a', 3), ('b', 4), ('c', 5)]) - self.assertEqual(take(2, lzip('abc',count(3))), [('a', 3), ('b', 4)]) - self.assertEqual(take(2, zip('abc',count(-1))), [('a', -1), ('b', 0)]) - self.assertEqual(take(2, zip('abc',count(-3))), [('a', -3), ('b', -2)]) - self.assertRaises(TypeError, count, 2, 3, 4) - self.assertRaises(TypeError, count, 'a') - self.assertEqual(take(10, count(maxsize-5)), - list(range(maxsize-5, maxsize+5))) - self.assertEqual(take(10, count(-maxsize-5)), - list(range(-maxsize-5, -maxsize+5))) - self.assertEqual(take(3, count(3.25)), [3.25, 4.25, 5.25]) - self.assertEqual(take(3, count(3.25-4j)), [3.25-4j, 4.25-4j, 5.25-4j]) - self.assertEqual(take(3, count(Decimal('1.1'))), - [Decimal('1.1'), Decimal('2.1'), Decimal('3.1')]) - self.assertEqual(take(3, count(Fraction(2, 3))), - [Fraction(2, 3), Fraction(5, 3), Fraction(8, 3)]) - BIGINT = 1<<1000 - self.assertEqual(take(3, count(BIGINT)), [BIGINT, BIGINT+1, BIGINT+2]) - c = count(3) - self.assertEqual(repr(c), 'count(3)') - next(c) - self.assertEqual(repr(c), 'count(4)') - c = count(-9) - self.assertEqual(repr(c), 'count(-9)') - next(c) - self.assertEqual(next(c), -8) - self.assertEqual(repr(count(10.25)), 'count(10.25)') - self.assertEqual(repr(count(10.0)), 'count(10.0)') - self.assertEqual(type(next(count(10.0))), float) - for i in (-sys.maxsize-5, -sys.maxsize+5 ,-10, -1, 0, 10, sys.maxsize-5, sys.maxsize+5): - # Test repr - r1 = repr(count(i)) - r2 = 'count(%r)'.__mod__(i) - self.assertEqual(r1, r2) - - # check copy, deepcopy, pickle - for value in -3, 3, maxsize-5, maxsize+5: - c = count(value) - self.assertEqual(next(copy.copy(c)), value) - self.assertEqual(next(copy.deepcopy(c)), value) - for proto in range(pickle.HIGHEST_PROTOCOL + 1): - self.pickletest(proto, count(value)) - - #check proper internal error handling for large "step' sizes - count(1, maxsize+5); sys.exc_info() - - def test_count_with_stride(self): - self.assertEqual(lzip('abc',count(2,3)), [('a', 2), ('b', 5), ('c', 8)]) - self.assertEqual(lzip('abc',count(start=2,step=3)), - [('a', 2), ('b', 5), ('c', 8)]) - self.assertEqual(lzip('abc',count(step=-1)), - [('a', 0), ('b', -1), ('c', -2)]) - self.assertRaises(TypeError, count, 'a', 'b') - self.assertEqual(lzip('abc',count(2,0)), [('a', 2), ('b', 2), ('c', 2)]) - self.assertEqual(lzip('abc',count(2,1)), [('a', 2), ('b', 3), ('c', 4)]) - self.assertEqual(lzip('abc',count(2,3)), [('a', 2), ('b', 5), ('c', 8)]) - self.assertEqual(take(20, count(maxsize-15, 3)), take(20, range(maxsize-15, maxsize+100, 3))) - self.assertEqual(take(20, count(-maxsize-15, 3)), take(20, range(-maxsize-15,-maxsize+100, 3))) - self.assertEqual(take(3, count(10, maxsize+5)), - list(range(10, 10+3*(maxsize+5), maxsize+5))) - self.assertEqual(take(3, count(2, 1.25)), [2, 3.25, 4.5]) - self.assertEqual(take(3, count(2, 3.25-4j)), [2, 5.25-4j, 8.5-8j]) - self.assertEqual(take(3, count(Decimal('1.1'), Decimal('.1'))), - [Decimal('1.1'), Decimal('1.2'), Decimal('1.3')]) - self.assertEqual(take(3, count(Fraction(2,3), Fraction(1,7))), - [Fraction(2,3), Fraction(17,21), Fraction(20,21)]) - BIGINT = 1<<1000 - self.assertEqual(take(3, count(step=BIGINT)), [0, BIGINT, 2*BIGINT]) - self.assertEqual(repr(take(3, count(10, 2.5))), repr([10, 12.5, 15.0])) - c = count(3, 5) - self.assertEqual(repr(c), 'count(3, 5)') - next(c) - self.assertEqual(repr(c), 'count(8, 5)') - c = count(-9, 0) - self.assertEqual(repr(c), 'count(-9, 0)') - next(c) - self.assertEqual(repr(c), 'count(-9, 0)') - c = count(-9, -3) - self.assertEqual(repr(c), 'count(-9, -3)') - next(c) - self.assertEqual(repr(c), 'count(-12, -3)') - self.assertEqual(repr(c), 'count(-12, -3)') - self.assertEqual(repr(count(10.5, 1.25)), 'count(10.5, 1.25)') - self.assertEqual(repr(count(10.5, 1)), 'count(10.5)') # suppress step=1 when it's an int - self.assertEqual(repr(count(10.5, 1.00)), 'count(10.5, 1.0)') # do show float values lilke 1.0 - self.assertEqual(repr(count(10, 1.00)), 'count(10, 1.0)') - c = count(10, 1.0) - self.assertEqual(type(next(c)), int) - self.assertEqual(type(next(c)), float) - for i in (-sys.maxsize-5, -sys.maxsize+5 ,-10, -1, 0, 10, sys.maxsize-5, sys.maxsize+5): - for j in (-sys.maxsize-5, -sys.maxsize+5 ,-10, -1, 0, 1, 10, sys.maxsize-5, sys.maxsize+5): - # Test repr - r1 = repr(count(i, j)) - if j == 1: - r2 = ('count(%r)' % i) - else: - r2 = ('count(%r, %r)' % (i, j)) - self.assertEqual(r1, r2) - for proto in range(pickle.HIGHEST_PROTOCOL + 1): - self.pickletest(proto, count(i, j)) - - def test_cycle(self): - self.assertEqual(take(10, cycle('abc')), list('abcabcabca')) - self.assertEqual(list(cycle('')), []) - self.assertRaises(TypeError, cycle) - self.assertRaises(TypeError, cycle, 5) - self.assertEqual(list(islice(cycle(gen3()),10)), [0,1,2,0,1,2,0,1,2,0]) - - # check copy, deepcopy, pickle - c = cycle('abc') - self.assertEqual(next(c), 'a') - #simple copy currently not supported, because __reduce__ returns - #an internal iterator - #self.assertEqual(take(10, copy.copy(c)), list('bcabcabcab')) - self.assertEqual(take(10, copy.deepcopy(c)), list('bcabcabcab')) - for proto in range(pickle.HIGHEST_PROTOCOL + 1): - self.assertEqual(take(10, pickle.loads(pickle.dumps(c, proto))), - list('bcabcabcab')) - next(c) - self.assertEqual(take(10, pickle.loads(pickle.dumps(c, proto))), - list('cabcabcabc')) - next(c) - next(c) - for proto in range(pickle.HIGHEST_PROTOCOL + 1): - self.pickletest(proto, cycle('abc')) - - for proto in range(pickle.HIGHEST_PROTOCOL + 1): - # test with partial consumed input iterable - it = iter('abcde') - c = cycle(it) - _ = [next(c) for i in range(2)] # consume 2 of 5 inputs - p = pickle.dumps(c, proto) - d = pickle.loads(p) # rebuild the cycle object - self.assertEqual(take(20, d), list('cdeabcdeabcdeabcdeab')) - - # test with completely consumed input iterable - it = iter('abcde') - c = cycle(it) - _ = [next(c) for i in range(7)] # consume 7 of 5 inputs - p = pickle.dumps(c, proto) - d = pickle.loads(p) # rebuild the cycle object - self.assertEqual(take(20, d), list('cdeabcdeabcdeabcdeab')) - - def test_cycle_setstate(self): - # Verify both modes for restoring state - - # Mode 0 is efficient. It uses an incompletely consumed input - # iterator to build a cycle object and then passes in state with - # a list of previously consumed values. There is no data - # overlap between the two. - c = cycle('defg') - c.__setstate__((list('abc'), 0)) - self.assertEqual(take(20, c), list('defgabcdefgabcdefgab')) - - # Mode 1 is inefficient. It starts with a cycle object built - # from an iterator over the remaining elements in a partial - # cycle and then passes in state with all of the previously - # seen values (this overlaps values included in the iterator). - c = cycle('defg') - c.__setstate__((list('abcdefg'), 1)) - self.assertEqual(take(20, c), list('defgabcdefgabcdefgab')) - - # The first argument to setstate needs to be a tuple - with self.assertRaises(TypeError): - cycle('defg').__setstate__([list('abcdefg'), 0]) - - # The first argument in the setstate tuple must be a list - with self.assertRaises(TypeError): - c = cycle('defg') - c.__setstate__((tuple('defg'), 0)) - take(20, c) - - # The second argument in the setstate tuple must be an int - with self.assertRaises(TypeError): - cycle('defg').__setstate__((list('abcdefg'), 'x')) - - self.assertRaises(TypeError, cycle('').__setstate__, ()) - self.assertRaises(TypeError, cycle('').__setstate__, ([],)) - - def test_groupby(self): - # Check whether it accepts arguments correctly - self.assertEqual([], list(groupby([]))) - self.assertEqual([], list(groupby([], key=id))) - self.assertRaises(TypeError, list, groupby('abc', [])) - self.assertRaises(TypeError, groupby, None) - self.assertRaises(TypeError, groupby, 'abc', lambda x:x, 10) - - # Check normal input - s = [(0, 10, 20), (0, 11,21), (0,12,21), (1,13,21), (1,14,22), - (2,15,22), (3,16,23), (3,17,23)] - dup = [] - for k, g in groupby(s, lambda r:r[0]): - for elem in g: - self.assertEqual(k, elem[0]) - dup.append(elem) - self.assertEqual(s, dup) - - # Check normal pickled - for proto in range(pickle.HIGHEST_PROTOCOL + 1): - dup = [] - for k, g in pickle.loads(pickle.dumps(groupby(s, testR), proto)): - for elem in g: - self.assertEqual(k, elem[0]) - dup.append(elem) - self.assertEqual(s, dup) - - # Check nested case - dup = [] - for k, g in groupby(s, testR): - for ik, ig in groupby(g, testR2): - for elem in ig: - self.assertEqual(k, elem[0]) - self.assertEqual(ik, elem[2]) - dup.append(elem) - self.assertEqual(s, dup) - - # Check nested and pickled - for proto in range(pickle.HIGHEST_PROTOCOL + 1): - dup = [] - for k, g in pickle.loads(pickle.dumps(groupby(s, testR), proto)): - for ik, ig in pickle.loads(pickle.dumps(groupby(g, testR2), proto)): - for elem in ig: - self.assertEqual(k, elem[0]) - self.assertEqual(ik, elem[2]) - dup.append(elem) - self.assertEqual(s, dup) - - - # Check case where inner iterator is not used - keys = [k for k, g in groupby(s, testR)] - expectedkeys = set([r[0] for r in s]) - self.assertEqual(set(keys), expectedkeys) - self.assertEqual(len(keys), len(expectedkeys)) - - # Check case where inner iterator is used after advancing the groupby - # iterator - s = list(zip('AABBBAAAA', range(9))) - it = groupby(s, testR) - _, g1 = next(it) - _, g2 = next(it) - _, g3 = next(it) - self.assertEqual(list(g1), []) - self.assertEqual(list(g2), []) - self.assertEqual(next(g3), ('A', 5)) - list(it) # exhaust the groupby iterator - self.assertEqual(list(g3), []) - - for proto in range(pickle.HIGHEST_PROTOCOL + 1): - it = groupby(s, testR) - _, g = next(it) - next(it) - next(it) - self.assertEqual(list(pickle.loads(pickle.dumps(g, proto))), []) - - # Exercise pipes and filters style - s = 'abracadabra' - # sort s | uniq - r = [k for k, g in groupby(sorted(s))] - self.assertEqual(r, ['a', 'b', 'c', 'd', 'r']) - # sort s | uniq -d - r = [k for k, g in groupby(sorted(s)) if list(islice(g,1,2))] - self.assertEqual(r, ['a', 'b', 'r']) - # sort s | uniq -c - r = [(len(list(g)), k) for k, g in groupby(sorted(s))] - self.assertEqual(r, [(5, 'a'), (2, 'b'), (1, 'c'), (1, 'd'), (2, 'r')]) - # sort s | uniq -c | sort -rn | head -3 - r = sorted([(len(list(g)) , k) for k, g in groupby(sorted(s))], reverse=True)[:3] - self.assertEqual(r, [(5, 'a'), (2, 'r'), (2, 'b')]) - - # iter.__next__ failure - class ExpectedError(Exception): - pass - def delayed_raise(n=0): - for i in range(n): - yield 'yo' - raise ExpectedError - def gulp(iterable, keyp=None, func=list): - return [func(g) for k, g in groupby(iterable, keyp)] - - # iter.__next__ failure on outer object - self.assertRaises(ExpectedError, gulp, delayed_raise(0)) - # iter.__next__ failure on inner object - self.assertRaises(ExpectedError, gulp, delayed_raise(1)) - - # __eq__ failure - class DummyCmp: - def __eq__(self, dst): - raise ExpectedError - s = [DummyCmp(), DummyCmp(), None] - - # __eq__ failure on outer object - self.assertRaises(ExpectedError, gulp, s, func=id) - # __eq__ failure on inner object - self.assertRaises(ExpectedError, gulp, s) - - # keyfunc failure - def keyfunc(obj): - if keyfunc.skip > 0: - keyfunc.skip -= 1 - return obj - else: - raise ExpectedError - - # keyfunc failure on outer object - keyfunc.skip = 0 - self.assertRaises(ExpectedError, gulp, [None], keyfunc) - keyfunc.skip = 1 - self.assertRaises(ExpectedError, gulp, [None, None], keyfunc) - - def test_filter(self): - self.assertEqual(list(filter(isEven, range(6))), [0,2,4]) - self.assertEqual(list(filter(None, [0,1,0,2,0])), [1,2]) - self.assertEqual(list(filter(bool, [0,1,0,2,0])), [1,2]) - self.assertEqual(take(4, filter(isEven, count())), [0,2,4,6]) - self.assertRaises(TypeError, filter) - self.assertRaises(TypeError, filter, lambda x:x) - self.assertRaises(TypeError, filter, lambda x:x, range(6), 7) - self.assertRaises(TypeError, filter, isEven, 3) - self.assertRaises(TypeError, next, filter(range(6), range(6))) - - # check copy, deepcopy, pickle - ans = [0,2,4] - - c = filter(isEven, range(6)) - self.assertEqual(list(copy.copy(c)), ans) - c = filter(isEven, range(6)) - self.assertEqual(list(copy.deepcopy(c)), ans) - for proto in range(pickle.HIGHEST_PROTOCOL + 1): - c = filter(isEven, range(6)) - self.assertEqual(list(pickle.loads(pickle.dumps(c, proto))), ans) - next(c) - self.assertEqual(list(pickle.loads(pickle.dumps(c, proto))), ans[1:]) - for proto in range(pickle.HIGHEST_PROTOCOL + 1): - c = filter(isEven, range(6)) - self.pickletest(proto, c) - - def test_filterfalse(self): - self.assertEqual(list(filterfalse(isEven, range(6))), [1,3,5]) - self.assertEqual(list(filterfalse(None, [0,1,0,2,0])), [0,0,0]) - self.assertEqual(list(filterfalse(bool, [0,1,0,2,0])), [0,0,0]) - self.assertEqual(take(4, filterfalse(isEven, count())), [1,3,5,7]) - self.assertRaises(TypeError, filterfalse) - self.assertRaises(TypeError, filterfalse, lambda x:x) - self.assertRaises(TypeError, filterfalse, lambda x:x, range(6), 7) - self.assertRaises(TypeError, filterfalse, isEven, 3) - self.assertRaises(TypeError, next, filterfalse(range(6), range(6))) - for proto in range(pickle.HIGHEST_PROTOCOL + 1): - self.pickletest(proto, filterfalse(isEven, range(6))) - - def test_zip(self): - # XXX This is rather silly now that builtin zip() calls zip()... - ans = [(x,y) for x, y in zip('abc',count())] - self.assertEqual(ans, [('a', 0), ('b', 1), ('c', 2)]) - self.assertEqual(list(zip('abc', range(6))), lzip('abc', range(6))) - self.assertEqual(list(zip('abcdef', range(3))), lzip('abcdef', range(3))) - self.assertEqual(take(3,zip('abcdef', count())), lzip('abcdef', range(3))) - self.assertEqual(list(zip('abcdef')), lzip('abcdef')) - self.assertEqual(list(zip()), lzip()) - self.assertRaises(TypeError, zip, 3) - self.assertRaises(TypeError, zip, range(3), 3) - self.assertEqual([tuple(list(pair)) for pair in zip('abc', 'def')], - lzip('abc', 'def')) - self.assertEqual([pair for pair in zip('abc', 'def')], - lzip('abc', 'def')) - - @support.impl_detail("tuple reuse is specific to CPython") - def test_zip_tuple_reuse(self): - ids = list(map(id, zip('abc', 'def'))) - self.assertEqual(min(ids), max(ids)) - ids = list(map(id, list(zip('abc', 'def')))) - self.assertEqual(len(dict.fromkeys(ids)), len(ids)) - - # check copy, deepcopy, pickle - ans = [(x,y) for x, y in copy.copy(zip('abc',count()))] - self.assertEqual(ans, [('a', 0), ('b', 1), ('c', 2)]) - - ans = [(x,y) for x, y in copy.deepcopy(zip('abc',count()))] - self.assertEqual(ans, [('a', 0), ('b', 1), ('c', 2)]) - - for proto in range(pickle.HIGHEST_PROTOCOL + 1): - ans = [(x,y) for x, y in pickle.loads(pickle.dumps(zip('abc',count()), proto))] - self.assertEqual(ans, [('a', 0), ('b', 1), ('c', 2)]) - - for proto in range(pickle.HIGHEST_PROTOCOL + 1): - testIntermediate = zip('abc',count()) - next(testIntermediate) - ans = [(x,y) for x, y in pickle.loads(pickle.dumps(testIntermediate, proto))] - self.assertEqual(ans, [('b', 1), ('c', 2)]) - - for proto in range(pickle.HIGHEST_PROTOCOL + 1): - self.pickletest(proto, zip('abc', count())) - - def test_ziplongest(self): - for args in [ - ['abc', range(6)], - [range(6), 'abc'], - [range(1000), range(2000,2100), range(3000,3050)], - [range(1000), range(0), range(3000,3050), range(1200), range(1500)], - [range(1000), range(0), range(3000,3050), range(1200), range(1500), range(0)], - ]: - target = [tuple([arg[i] if i < len(arg) else None for arg in args]) - for i in range(max(map(len, args)))] - self.assertEqual(list(zip_longest(*args)), target) - self.assertEqual(list(zip_longest(*args, **{})), target) - target = [tuple((e is None and 'X' or e) for e in t) for t in target] # Replace None fills with 'X' - self.assertEqual(list(zip_longest(*args, **dict(fillvalue='X'))), target) - - self.assertEqual(take(3,zip_longest('abcdef', count())), list(zip('abcdef', range(3)))) # take 3 from infinite input - - self.assertEqual(list(zip_longest()), list(zip())) - self.assertEqual(list(zip_longest([])), list(zip([]))) - self.assertEqual(list(zip_longest('abcdef')), list(zip('abcdef'))) - - self.assertEqual(list(zip_longest('abc', 'defg', **{})), - list(zip(list('abc')+[None], 'defg'))) # empty keyword dict - self.assertRaises(TypeError, zip_longest, 3) - self.assertRaises(TypeError, zip_longest, range(3), 3) - - for stmt in [ - "zip_longest('abc', fv=1)", - "zip_longest('abc', fillvalue=1, bogus_keyword=None)", - ]: - try: - eval(stmt, globals(), locals()) - except TypeError: - pass - else: - self.fail('Did not raise Type in: ' + stmt) - - self.assertEqual([tuple(list(pair)) for pair in zip_longest('abc', 'def')], - list(zip('abc', 'def'))) - self.assertEqual([pair for pair in zip_longest('abc', 'def')], - list(zip('abc', 'def'))) - - @support.impl_detail("tuple reuse is specific to CPython") - def test_zip_longest_tuple_reuse(self): - ids = list(map(id, zip_longest('abc', 'def'))) - self.assertEqual(min(ids), max(ids)) - ids = list(map(id, list(zip_longest('abc', 'def')))) - self.assertEqual(len(dict.fromkeys(ids)), len(ids)) - - def test_zip_longest_pickling(self): - for proto in range(pickle.HIGHEST_PROTOCOL + 1): - self.pickletest(proto, zip_longest("abc", "def")) - self.pickletest(proto, zip_longest("abc", "defgh")) - self.pickletest(proto, zip_longest("abc", "defgh", fillvalue=1)) - self.pickletest(proto, zip_longest("", "defgh")) - - def test_zip_longest_bad_iterable(self): - exception = TypeError() - - class BadIterable: - def __iter__(self): - raise exception - - with self.assertRaises(TypeError) as cm: - zip_longest(BadIterable()) - - self.assertIs(cm.exception, exception) - - def test_bug_7244(self): - - class Repeater: - # this class is similar to itertools.repeat - def __init__(self, o, t, e): - self.o = o - self.t = int(t) - self.e = e - def __iter__(self): # its iterator is itself - return self - def __next__(self): - if self.t > 0: - self.t -= 1 - return self.o - else: - raise self.e - - # Formerly this code in would fail in debug mode - # with Undetected Error and Stop Iteration - r1 = Repeater(1, 3, StopIteration) - r2 = Repeater(2, 4, StopIteration) - def run(r1, r2): - result = [] - for i, j in zip_longest(r1, r2, fillvalue=0): - with support.captured_output('stdout'): - print((i, j)) - result.append((i, j)) - return result - self.assertEqual(run(r1, r2), [(1,2), (1,2), (1,2), (0,2)]) - - # Formerly, the RuntimeError would be lost - # and StopIteration would stop as expected - r1 = Repeater(1, 3, RuntimeError) - r2 = Repeater(2, 4, StopIteration) - it = zip_longest(r1, r2, fillvalue=0) - self.assertEqual(next(it), (1, 2)) - self.assertEqual(next(it), (1, 2)) - self.assertEqual(next(it), (1, 2)) - self.assertRaises(RuntimeError, next, it) - - def test_product(self): - for args, result in [ - ([], [()]), # zero iterables - (['ab'], [('a',), ('b',)]), # one iterable - ([range(2), range(3)], [(0,0), (0,1), (0,2), (1,0), (1,1), (1,2)]), # two iterables - ([range(0), range(2), range(3)], []), # first iterable with zero length - ([range(2), range(0), range(3)], []), # middle iterable with zero length - ([range(2), range(3), range(0)], []), # last iterable with zero length - ]: - self.assertEqual(list(product(*args)), result) - for r in range(4): - self.assertEqual(list(product(*(args*r))), - list(product(*args, **dict(repeat=r)))) - self.assertEqual(len(list(product(*[range(7)]*6))), 7**6) - self.assertRaises(TypeError, product, range(6), None) - - def product1(*args, **kwds): - pools = list(map(tuple, args)) * kwds.get('repeat', 1) - n = len(pools) - if n == 0: - yield () - return - if any(len(pool) == 0 for pool in pools): - return - indices = [0] * n - yield tuple(pool[i] for pool, i in zip(pools, indices)) - while 1: - for i in reversed(range(n)): # right to left - if indices[i] == len(pools[i]) - 1: - continue - indices[i] += 1 - for j in range(i+1, n): - indices[j] = 0 - yield tuple(pool[i] for pool, i in zip(pools, indices)) - break - else: - return - - def product2(*args, **kwds): - 'Pure python version used in docs' - pools = list(map(tuple, args)) * kwds.get('repeat', 1) - result = [[]] - for pool in pools: - result = [x+[y] for x in result for y in pool] - for prod in result: - yield tuple(prod) - - argtypes = ['', 'abc', '', range(0), range(4), dict(a=1, b=2, c=3), - set('abcdefg'), range(11), tuple(range(13))] - for i in range(100): - args = [random.choice(argtypes) for j in range(random.randrange(5))] - expected_len = prod(map(len, args)) - self.assertEqual(len(list(product(*args))), expected_len) - self.assertEqual(list(product(*args)), list(product1(*args))) - self.assertEqual(list(product(*args)), list(product2(*args))) - args = map(iter, args) - self.assertEqual(len(list(product(*args))), expected_len) - - @support.bigaddrspacetest - def test_product_overflow(self): - with self.assertRaises((OverflowError, MemoryError)): - product(*(['ab']*2**5), repeat=2**25) - - @support.impl_detail("tuple reuse is specific to CPython") - def test_product_tuple_reuse(self): - self.assertEqual(len(set(map(id, product('abc', 'def')))), 1) - self.assertNotEqual(len(set(map(id, list(product('abc', 'def'))))), 1) - - def test_product_pickling(self): - # check copy, deepcopy, pickle - for args, result in [ - ([], [()]), # zero iterables - (['ab'], [('a',), ('b',)]), # one iterable - ([range(2), range(3)], [(0,0), (0,1), (0,2), (1,0), (1,1), (1,2)]), # two iterables - ([range(0), range(2), range(3)], []), # first iterable with zero length - ([range(2), range(0), range(3)], []), # middle iterable with zero length - ([range(2), range(3), range(0)], []), # last iterable with zero length - ]: - self.assertEqual(list(copy.copy(product(*args))), result) - self.assertEqual(list(copy.deepcopy(product(*args))), result) - for proto in range(pickle.HIGHEST_PROTOCOL + 1): - self.pickletest(proto, product(*args)) - - def test_product_issue_25021(self): - # test that indices are properly clamped to the length of the tuples - p = product((1, 2),(3,)) - p.__setstate__((0, 0x1000)) # will access tuple element 1 if not clamped - self.assertEqual(next(p), (2, 3)) - # test that empty tuple in the list will result in an immediate StopIteration - p = product((1, 2), (), (3,)) - p.__setstate__((0, 0, 0x1000)) # will access tuple element 1 if not clamped - self.assertRaises(StopIteration, next, p) - - def test_repeat(self): - self.assertEqual(list(repeat(object='a', times=3)), ['a', 'a', 'a']) - self.assertEqual(lzip(range(3),repeat('a')), - [(0, 'a'), (1, 'a'), (2, 'a')]) - self.assertEqual(list(repeat('a', 3)), ['a', 'a', 'a']) - self.assertEqual(take(3, repeat('a')), ['a', 'a', 'a']) - self.assertEqual(list(repeat('a', 0)), []) - self.assertEqual(list(repeat('a', -3)), []) - self.assertRaises(TypeError, repeat) - self.assertRaises(TypeError, repeat, None, 3, 4) - self.assertRaises(TypeError, repeat, None, 'a') - r = repeat(1+0j) - self.assertEqual(repr(r), 'repeat((1+0j))') - r = repeat(1+0j, 5) - self.assertEqual(repr(r), 'repeat((1+0j), 5)') - list(r) - self.assertEqual(repr(r), 'repeat((1+0j), 0)') - - # check copy, deepcopy, pickle - c = repeat(object='a', times=10) - self.assertEqual(next(c), 'a') - self.assertEqual(take(2, copy.copy(c)), list('a' * 2)) - self.assertEqual(take(2, copy.deepcopy(c)), list('a' * 2)) - for proto in range(pickle.HIGHEST_PROTOCOL + 1): - self.pickletest(proto, repeat(object='a', times=10)) - - def test_repeat_with_negative_times(self): - self.assertEqual(repr(repeat('a', -1)), "repeat('a', 0)") - self.assertEqual(repr(repeat('a', -2)), "repeat('a', 0)") - self.assertEqual(repr(repeat('a', times=-1)), "repeat('a', 0)") - self.assertEqual(repr(repeat('a', times=-2)), "repeat('a', 0)") - - def test_map(self): - self.assertEqual(list(map(operator.pow, range(3), range(1,7))), - [0**1, 1**2, 2**3]) - self.assertEqual(list(map(tupleize, 'abc', range(5))), - [('a',0),('b',1),('c',2)]) - self.assertEqual(list(map(tupleize, 'abc', count())), - [('a',0),('b',1),('c',2)]) - self.assertEqual(take(2,map(tupleize, 'abc', count())), - [('a',0),('b',1)]) - self.assertEqual(list(map(operator.pow, [])), []) - self.assertRaises(TypeError, map) - self.assertRaises(TypeError, list, map(None, range(3), range(3))) - self.assertRaises(TypeError, map, operator.neg) - self.assertRaises(TypeError, next, map(10, range(5))) - self.assertRaises(ValueError, next, map(errfunc, [4], [5])) - self.assertRaises(TypeError, next, map(onearg, [4], [5])) - - # check copy, deepcopy, pickle - ans = [('a',0),('b',1),('c',2)] - - c = map(tupleize, 'abc', count()) - self.assertEqual(list(copy.copy(c)), ans) - - c = map(tupleize, 'abc', count()) - self.assertEqual(list(copy.deepcopy(c)), ans) - - for proto in range(pickle.HIGHEST_PROTOCOL + 1): - c = map(tupleize, 'abc', count()) - self.pickletest(proto, c) - - def test_starmap(self): - self.assertEqual(list(starmap(operator.pow, zip(range(3), range(1,7)))), - [0**1, 1**2, 2**3]) - self.assertEqual(take(3, starmap(operator.pow, zip(count(), count(1)))), - [0**1, 1**2, 2**3]) - self.assertEqual(list(starmap(operator.pow, [])), []) - self.assertEqual(list(starmap(operator.pow, [iter([4,5])])), [4**5]) - self.assertRaises(TypeError, list, starmap(operator.pow, [None])) - self.assertRaises(TypeError, starmap) - self.assertRaises(TypeError, starmap, operator.pow, [(4,5)], 'extra') - self.assertRaises(TypeError, next, starmap(10, [(4,5)])) - self.assertRaises(ValueError, next, starmap(errfunc, [(4,5)])) - self.assertRaises(TypeError, next, starmap(onearg, [(4,5)])) - - # check copy, deepcopy, pickle - ans = [0**1, 1**2, 2**3] - - c = starmap(operator.pow, zip(range(3), range(1,7))) - self.assertEqual(list(copy.copy(c)), ans) - - c = starmap(operator.pow, zip(range(3), range(1,7))) - self.assertEqual(list(copy.deepcopy(c)), ans) - - for proto in range(pickle.HIGHEST_PROTOCOL + 1): - c = starmap(operator.pow, zip(range(3), range(1,7))) - self.pickletest(proto, c) - - def test_islice(self): - for args in [ # islice(args) should agree with range(args) - (10, 20, 3), - (10, 3, 20), - (10, 20), - (10, 10), - (10, 3), - (20,) - ]: - self.assertEqual(list(islice(range(100), *args)), - list(range(*args))) - - for args, tgtargs in [ # Stop when seqn is exhausted - ((10, 110, 3), ((10, 100, 3))), - ((10, 110), ((10, 100))), - ((110,), (100,)) - ]: - self.assertEqual(list(islice(range(100), *args)), - list(range(*tgtargs))) - - # Test stop=None - self.assertEqual(list(islice(range(10), None)), list(range(10))) - self.assertEqual(list(islice(range(10), None, None)), list(range(10))) - self.assertEqual(list(islice(range(10), None, None, None)), list(range(10))) - self.assertEqual(list(islice(range(10), 2, None)), list(range(2, 10))) - self.assertEqual(list(islice(range(10), 1, None, 2)), list(range(1, 10, 2))) - - # Test number of items consumed SF #1171417 - it = iter(range(10)) - self.assertEqual(list(islice(it, 3)), list(range(3))) - self.assertEqual(list(it), list(range(3, 10))) - - it = iter(range(10)) - self.assertEqual(list(islice(it, 3, 3)), []) - self.assertEqual(list(it), list(range(3, 10))) - - # Test invalid arguments - ra = range(10) - self.assertRaises(TypeError, islice, ra) - self.assertRaises(TypeError, islice, ra, 1, 2, 3, 4) - self.assertRaises(ValueError, islice, ra, -5, 10, 1) - self.assertRaises(ValueError, islice, ra, 1, -5, -1) - self.assertRaises(ValueError, islice, ra, 1, 10, -1) - self.assertRaises(ValueError, islice, ra, 1, 10, 0) - self.assertRaises(ValueError, islice, ra, 'a') - self.assertRaises(ValueError, islice, ra, 'a', 1) - self.assertRaises(ValueError, islice, ra, 1, 'a') - self.assertRaises(ValueError, islice, ra, 'a', 1, 1) - self.assertRaises(ValueError, islice, ra, 1, 'a', 1) - self.assertEqual(len(list(islice(count(), 1, 10, maxsize))), 1) - - # Issue #10323: Less islice in a predictable state - c = count() - self.assertEqual(list(islice(c, 1, 3, 50)), [1]) - self.assertEqual(next(c), 3) - - # check copy, deepcopy, pickle - for args in [ # islice(args) should agree with range(args) - (10, 20, 3), - (10, 3, 20), - (10, 20), - (10, 3), - (20,) - ]: - self.assertEqual(list(copy.copy(islice(range(100), *args))), - list(range(*args))) - self.assertEqual(list(copy.deepcopy(islice(range(100), *args))), - list(range(*args))) - for proto in range(pickle.HIGHEST_PROTOCOL + 1): - self.pickletest(proto, islice(range(100), *args)) - - # Issue #21321: check source iterator is not referenced - # from islice() after the latter has been exhausted - it = (x for x in (1, 2)) - wr = weakref.ref(it) - it = islice(it, 1) - self.assertIsNotNone(wr()) - list(it) # exhaust the iterator - support.gc_collect() - self.assertIsNone(wr()) - - # Issue #30537: islice can accept integer-like objects as - # arguments - class IntLike(object): - def __init__(self, val): - self.val = val - def __index__(self): - return self.val - self.assertEqual(list(islice(range(100), IntLike(10))), list(range(10))) - self.assertEqual(list(islice(range(100), IntLike(10), IntLike(50))), - list(range(10, 50))) - self.assertEqual(list(islice(range(100), IntLike(10), IntLike(50), IntLike(5))), - list(range(10,50,5))) - - def test_takewhile(self): - data = [1, 3, 5, 20, 2, 4, 6, 8] - self.assertEqual(list(takewhile(underten, data)), [1, 3, 5]) - self.assertEqual(list(takewhile(underten, [])), []) - self.assertRaises(TypeError, takewhile) - self.assertRaises(TypeError, takewhile, operator.pow) - self.assertRaises(TypeError, takewhile, operator.pow, [(4,5)], 'extra') - self.assertRaises(TypeError, next, takewhile(10, [(4,5)])) - self.assertRaises(ValueError, next, takewhile(errfunc, [(4,5)])) - t = takewhile(bool, [1, 1, 1, 0, 0, 0]) - self.assertEqual(list(t), [1, 1, 1]) - self.assertRaises(StopIteration, next, t) - - # check copy, deepcopy, pickle - self.assertEqual(list(copy.copy(takewhile(underten, data))), [1, 3, 5]) - self.assertEqual(list(copy.deepcopy(takewhile(underten, data))), - [1, 3, 5]) - for proto in range(pickle.HIGHEST_PROTOCOL + 1): - self.pickletest(proto, takewhile(underten, data)) - - def test_dropwhile(self): - data = [1, 3, 5, 20, 2, 4, 6, 8] - self.assertEqual(list(dropwhile(underten, data)), [20, 2, 4, 6, 8]) - self.assertEqual(list(dropwhile(underten, [])), []) - self.assertRaises(TypeError, dropwhile) - self.assertRaises(TypeError, dropwhile, operator.pow) - self.assertRaises(TypeError, dropwhile, operator.pow, [(4,5)], 'extra') - self.assertRaises(TypeError, next, dropwhile(10, [(4,5)])) - self.assertRaises(ValueError, next, dropwhile(errfunc, [(4,5)])) - - # check copy, deepcopy, pickle - self.assertEqual(list(copy.copy(dropwhile(underten, data))), [20, 2, 4, 6, 8]) - self.assertEqual(list(copy.deepcopy(dropwhile(underten, data))), - [20, 2, 4, 6, 8]) - for proto in range(pickle.HIGHEST_PROTOCOL + 1): - self.pickletest(proto, dropwhile(underten, data)) - - def test_tee(self): - n = 200 - - a, b = tee([]) # test empty iterator - self.assertEqual(list(a), []) - self.assertEqual(list(b), []) - - a, b = tee(irange(n)) # test 100% interleaved - self.assertEqual(lzip(a,b), lzip(range(n), range(n))) - - a, b = tee(irange(n)) # test 0% interleaved - self.assertEqual(list(a), list(range(n))) - self.assertEqual(list(b), list(range(n))) - - a, b = tee(irange(n)) # test dealloc of leading iterator - for i in range(100): - self.assertEqual(next(a), i) - del a - self.assertEqual(list(b), list(range(n))) - - a, b = tee(irange(n)) # test dealloc of trailing iterator - for i in range(100): - self.assertEqual(next(a), i) - del b - self.assertEqual(list(a), list(range(100, n))) - - for j in range(5): # test randomly interleaved - order = [0]*n + [1]*n - random.shuffle(order) - lists = ([], []) - its = tee(irange(n)) - for i in order: - value = next(its[i]) - lists[i].append(value) - self.assertEqual(lists[0], list(range(n))) - self.assertEqual(lists[1], list(range(n))) - - # test argument format checking - self.assertRaises(TypeError, tee) - self.assertRaises(TypeError, tee, 3) - self.assertRaises(TypeError, tee, [1,2], 'x') - self.assertRaises(TypeError, tee, [1,2], 3, 'x') - - # tee object should be instantiable - a, b = tee('abc') - c = type(a)('def') - self.assertEqual(list(c), list('def')) - - # test long-lagged and multi-way split - a, b, c = tee(range(2000), 3) - for i in range(100): - self.assertEqual(next(a), i) - self.assertEqual(list(b), list(range(2000))) - self.assertEqual([next(c), next(c)], list(range(2))) - self.assertEqual(list(a), list(range(100,2000))) - self.assertEqual(list(c), list(range(2,2000))) - - # test values of n - self.assertRaises(TypeError, tee, 'abc', 'invalid') - self.assertRaises(ValueError, tee, [], -1) - for n in range(5): - result = tee('abc', n) - self.assertEqual(type(result), tuple) - self.assertEqual(len(result), n) - self.assertEqual([list(x) for x in result], [list('abc')]*n) - - # tee pass-through to copyable iterator - a, b = tee('abc') - c, d = tee(a) - self.assertTrue(a is c) - - # test tee_new - t1, t2 = tee('abc') - tnew = type(t1) - self.assertRaises(TypeError, tnew) - self.assertRaises(TypeError, tnew, 10) - t3 = tnew(t1) - self.assertTrue(list(t1) == list(t2) == list(t3) == list('abc')) - - # test that tee objects are weak referencable - a, b = tee(range(10)) - p = weakref.proxy(a) - self.assertEqual(getattr(p, '__class__'), type(b)) - del a - self.assertRaises(ReferenceError, getattr, p, '__class__') - - ans = list('abc') - long_ans = list(range(10000)) - - # check copy - a, b = tee('abc') - self.assertEqual(list(copy.copy(a)), ans) - self.assertEqual(list(copy.copy(b)), ans) - a, b = tee(list(range(10000))) - self.assertEqual(list(copy.copy(a)), long_ans) - self.assertEqual(list(copy.copy(b)), long_ans) - - # check partially consumed copy - a, b = tee('abc') - take(2, a) - take(1, b) - self.assertEqual(list(copy.copy(a)), ans[2:]) - self.assertEqual(list(copy.copy(b)), ans[1:]) - self.assertEqual(list(a), ans[2:]) - self.assertEqual(list(b), ans[1:]) - a, b = tee(range(10000)) - take(100, a) - take(60, b) - self.assertEqual(list(copy.copy(a)), long_ans[100:]) - self.assertEqual(list(copy.copy(b)), long_ans[60:]) - self.assertEqual(list(a), long_ans[100:]) - self.assertEqual(list(b), long_ans[60:]) - - # check deepcopy - a, b = tee('abc') - self.assertEqual(list(copy.deepcopy(a)), ans) - self.assertEqual(list(copy.deepcopy(b)), ans) - self.assertEqual(list(a), ans) - self.assertEqual(list(b), ans) - a, b = tee(range(10000)) - self.assertEqual(list(copy.deepcopy(a)), long_ans) - self.assertEqual(list(copy.deepcopy(b)), long_ans) - self.assertEqual(list(a), long_ans) - self.assertEqual(list(b), long_ans) - - # check partially consumed deepcopy - a, b = tee('abc') - take(2, a) - take(1, b) - self.assertEqual(list(copy.deepcopy(a)), ans[2:]) - self.assertEqual(list(copy.deepcopy(b)), ans[1:]) - self.assertEqual(list(a), ans[2:]) - self.assertEqual(list(b), ans[1:]) - a, b = tee(range(10000)) - take(100, a) - take(60, b) - self.assertEqual(list(copy.deepcopy(a)), long_ans[100:]) - self.assertEqual(list(copy.deepcopy(b)), long_ans[60:]) - self.assertEqual(list(a), long_ans[100:]) - self.assertEqual(list(b), long_ans[60:]) - - # check pickle - for proto in range(pickle.HIGHEST_PROTOCOL + 1): - self.pickletest(proto, iter(tee('abc'))) - a, b = tee('abc') - self.pickletest(proto, a, compare=ans) - self.pickletest(proto, b, compare=ans) - - # Issue 13454: Crash when deleting backward iterator from tee() - def test_tee_del_backward(self): - forward, backward = tee(repeat(None, 20000000)) - try: - any(forward) # exhaust the iterator - del backward - except: - del forward, backward - raise - - def test_tee_reenter(self): - class I: - first = True - def __iter__(self): - return self - def __next__(self): - first = self.first - self.first = False - if first: - return next(b) - - a, b = tee(I()) - with self.assertRaisesRegex(RuntimeError, "tee"): - next(a) - - def test_tee_concurrent(self): - start = threading.Event() - finish = threading.Event() - class I: - def __iter__(self): - return self - def __next__(self): - start.set() - finish.wait() - - a, b = tee(I()) - thread = threading.Thread(target=next, args=[a]) - thread.start() - try: - start.wait() - with self.assertRaisesRegex(RuntimeError, "tee"): - next(b) - finally: - finish.set() - thread.join() - - def test_StopIteration(self): - self.assertRaises(StopIteration, next, zip()) - - for f in (chain, cycle, zip, groupby): - self.assertRaises(StopIteration, next, f([])) - self.assertRaises(StopIteration, next, f(StopNow())) - - self.assertRaises(StopIteration, next, islice([], None)) - self.assertRaises(StopIteration, next, islice(StopNow(), None)) - - p, q = tee([]) - self.assertRaises(StopIteration, next, p) - self.assertRaises(StopIteration, next, q) - p, q = tee(StopNow()) - self.assertRaises(StopIteration, next, p) - self.assertRaises(StopIteration, next, q) - - self.assertRaises(StopIteration, next, repeat(None, 0)) - - for f in (filter, filterfalse, map, takewhile, dropwhile, starmap): - self.assertRaises(StopIteration, next, f(lambda x:x, [])) - self.assertRaises(StopIteration, next, f(lambda x:x, StopNow())) - - @support.cpython_only - def test_combinations_result_gc(self): - # bpo-42536: combinations's tuple-reuse speed trick breaks the GC's - # assumptions about what can be untracked. Make sure we re-track result - # tuples whenever we reuse them. - it = combinations([None, []], 1) - next(it) - gc.collect() - # That GC collection probably untracked the recycled internal result - # tuple, which has the value (None,). Make sure it's re-tracked when - # it's mutated and returned from __next__: - self.assertTrue(gc.is_tracked(next(it))) - - @support.cpython_only - def test_combinations_with_replacement_result_gc(self): - # Ditto for combinations_with_replacement. - it = combinations_with_replacement([None, []], 1) - next(it) - gc.collect() - self.assertTrue(gc.is_tracked(next(it))) - - @support.cpython_only - def test_permutations_result_gc(self): - # Ditto for permutations. - it = permutations([None, []], 1) - next(it) - gc.collect() - self.assertTrue(gc.is_tracked(next(it))) - - @support.cpython_only - def test_product_result_gc(self): - # Ditto for product. - it = product([None, []]) - next(it) - gc.collect() - self.assertTrue(gc.is_tracked(next(it))) - - @support.cpython_only - def test_zip_longest_result_gc(self): - # Ditto for zip_longest. - it = zip_longest([[]]) - gc.collect() - self.assertTrue(gc.is_tracked(next(it))) - - - class TestExamples(unittest.TestCase): - - def test_accumulate(self): - self.assertEqual(list(accumulate([1,2,3,4,5])), [1, 3, 6, 10, 15]) - - def test_accumulate_reducible(self): - # check copy, deepcopy, pickle - data = [1, 2, 3, 4, 5] - accumulated = [1, 3, 6, 10, 15] - - for proto in range(pickle.HIGHEST_PROTOCOL + 1): - it = accumulate(data) - self.assertEqual(list(pickle.loads(pickle.dumps(it, proto))), accumulated[:]) - self.assertEqual(next(it), 1) - self.assertEqual(list(pickle.loads(pickle.dumps(it, proto))), accumulated[1:]) - it = accumulate(data) - self.assertEqual(next(it), 1) - self.assertEqual(list(copy.deepcopy(it)), accumulated[1:]) - self.assertEqual(list(copy.copy(it)), accumulated[1:]) - - def test_accumulate_reducible_none(self): - # Issue #25718: total is None - it = accumulate([None, None, None], operator.is_) - self.assertEqual(next(it), None) - for proto in range(pickle.HIGHEST_PROTOCOL + 1): - it_copy = pickle.loads(pickle.dumps(it, proto)) - self.assertEqual(list(it_copy), [True, False]) - self.assertEqual(list(copy.deepcopy(it)), [True, False]) - self.assertEqual(list(copy.copy(it)), [True, False]) - - def test_chain(self): - self.assertEqual(''.join(chain('ABC', 'DEF')), 'ABCDEF') - - def test_chain_from_iterable(self): - self.assertEqual(''.join(chain.from_iterable(['ABC', 'DEF'])), 'ABCDEF') - - def test_combinations(self): - self.assertEqual(list(combinations('ABCD', 2)), - [('A','B'), ('A','C'), ('A','D'), ('B','C'), ('B','D'), ('C','D')]) - self.assertEqual(list(combinations(range(4), 3)), - [(0,1,2), (0,1,3), (0,2,3), (1,2,3)]) - - def test_combinations_with_replacement(self): - self.assertEqual(list(combinations_with_replacement('ABC', 2)), - [('A','A'), ('A','B'), ('A','C'), ('B','B'), ('B','C'), ('C','C')]) - - def test_compress(self): - self.assertEqual(list(compress('ABCDEF', [1,0,1,0,1,1])), list('ACEF')) - - def test_count(self): - self.assertEqual(list(islice(count(10), 5)), [10, 11, 12, 13, 14]) - - def test_cycle(self): - self.assertEqual(list(islice(cycle('ABCD'), 12)), list('ABCDABCDABCD')) - - def test_dropwhile(self): - self.assertEqual(list(dropwhile(lambda x: x<5, [1,4,6,4,1])), [6,4,1]) - - def test_groupby(self): - self.assertEqual([k for k, g in groupby('AAAABBBCCDAABBB')], - list('ABCDAB')) - self.assertEqual([(list(g)) for k, g in groupby('AAAABBBCCD')], - [list('AAAA'), list('BBB'), list('CC'), list('D')]) - - def test_filter(self): - self.assertEqual(list(filter(lambda x: x%2, range(10))), [1,3,5,7,9]) - - def test_filterfalse(self): - self.assertEqual(list(filterfalse(lambda x: x%2, range(10))), [0,2,4,6,8]) - - def test_map(self): - self.assertEqual(list(map(pow, (2,3,10), (5,2,3))), [32, 9, 1000]) - - def test_islice(self): - self.assertEqual(list(islice('ABCDEFG', 2)), list('AB')) - self.assertEqual(list(islice('ABCDEFG', 2, 4)), list('CD')) - self.assertEqual(list(islice('ABCDEFG', 2, None)), list('CDEFG')) - self.assertEqual(list(islice('ABCDEFG', 0, None, 2)), list('ACEG')) - - def test_zip(self): - self.assertEqual(list(zip('ABCD', 'xy')), [('A', 'x'), ('B', 'y')]) - - def test_zip_longest(self): - self.assertEqual(list(zip_longest('ABCD', 'xy', fillvalue='-')), - [('A', 'x'), ('B', 'y'), ('C', '-'), ('D', '-')]) - - def test_permutations(self): - self.assertEqual(list(permutations('ABCD', 2)), - list(map(tuple, 'AB AC AD BA BC BD CA CB CD DA DB DC'.split()))) - self.assertEqual(list(permutations(range(3))), - [(0,1,2), (0,2,1), (1,0,2), (1,2,0), (2,0,1), (2,1,0)]) - - def test_product(self): - self.assertEqual(list(product('ABCD', 'xy')), - list(map(tuple, 'Ax Ay Bx By Cx Cy Dx Dy'.split()))) - self.assertEqual(list(product(range(2), repeat=3)), - [(0,0,0), (0,0,1), (0,1,0), (0,1,1), - (1,0,0), (1,0,1), (1,1,0), (1,1,1)]) - - def test_repeat(self): - self.assertEqual(list(repeat(10, 3)), [10, 10, 10]) - - def test_stapmap(self): - self.assertEqual(list(starmap(pow, [(2,5), (3,2), (10,3)])), - [32, 9, 1000]) - - def test_takewhile(self): - self.assertEqual(list(takewhile(lambda x: x<5, [1,4,6,4,1])), [1,4]) - - - class TestPurePythonRoughEquivalents(unittest.TestCase): - - @staticmethod - def islice(iterable, *args): - s = slice(*args) - start, stop, step = s.start or 0, s.stop or sys.maxsize, s.step or 1 - it = iter(range(start, stop, step)) - try: - nexti = next(it) - except StopIteration: - # Consume *iterable* up to the *start* position. - for i, element in zip(range(start), iterable): - pass - return - try: - for i, element in enumerate(iterable): - if i == nexti: - yield element - nexti = next(it) - except StopIteration: - # Consume to *stop*. - for i, element in zip(range(i + 1, stop), iterable): - pass - - def test_islice_recipe(self): - self.assertEqual(list(self.islice('ABCDEFG', 2)), list('AB')) - self.assertEqual(list(self.islice('ABCDEFG', 2, 4)), list('CD')) - self.assertEqual(list(self.islice('ABCDEFG', 2, None)), list('CDEFG')) - self.assertEqual(list(self.islice('ABCDEFG', 0, None, 2)), list('ACEG')) - # Test items consumed. - it = iter(range(10)) - self.assertEqual(list(self.islice(it, 3)), list(range(3))) - self.assertEqual(list(it), list(range(3, 10))) - it = iter(range(10)) - self.assertEqual(list(self.islice(it, 3, 3)), []) - self.assertEqual(list(it), list(range(3, 10))) - # Test that slice finishes in predictable state. - c = count() - self.assertEqual(list(self.islice(c, 1, 3, 50)), [1]) - self.assertEqual(next(c), 3) - - - class TestGC(unittest.TestCase): - - def makecycle(self, iterator, container): - container.append(iterator) - next(iterator) - del container, iterator - - def test_accumulate(self): - a = [] - self.makecycle(accumulate([1,2,a,3]), a) - - def test_chain(self): - a = [] - self.makecycle(chain(a), a) - - def test_chain_from_iterable(self): - a = [] - self.makecycle(chain.from_iterable([a]), a) - - def test_combinations(self): - a = [] - self.makecycle(combinations([1,2,a,3], 3), a) - - def test_combinations_with_replacement(self): - a = [] - self.makecycle(combinations_with_replacement([1,2,a,3], 3), a) - - def test_compress(self): - a = [] - self.makecycle(compress('ABCDEF', [1,0,1,0,1,0]), a) - - def test_count(self): - a = [] - Int = type('Int', (int,), dict(x=a)) - self.makecycle(count(Int(0), Int(1)), a) - - def test_cycle(self): - a = [] - self.makecycle(cycle([a]*2), a) - - def test_dropwhile(self): - a = [] - self.makecycle(dropwhile(bool, [0, a, a]), a) - - def test_groupby(self): - a = [] - self.makecycle(groupby([a]*2, lambda x:x), a) - - def test_issue2246(self): - # Issue 2246 -- the _grouper iterator was not included in GC - n = 10 - keyfunc = lambda x: x - for i, j in groupby(range(n), key=keyfunc): - keyfunc.__dict__.setdefault('x',[]).append(j) - - def test_filter(self): - a = [] - self.makecycle(filter(lambda x:True, [a]*2), a) - - def test_filterfalse(self): - a = [] - self.makecycle(filterfalse(lambda x:False, a), a) - - def test_zip(self): - a = [] - self.makecycle(zip([a]*2, [a]*3), a) - - def test_zip_longest(self): - a = [] - self.makecycle(zip_longest([a]*2, [a]*3), a) - b = [a, None] - self.makecycle(zip_longest([a]*2, [a]*3, fillvalue=b), a) - - def test_map(self): - a = [] - self.makecycle(map(lambda x:x, [a]*2), a) - - def test_islice(self): - a = [] - self.makecycle(islice([a]*2, None), a) - - def test_permutations(self): - a = [] - self.makecycle(permutations([1,2,a,3], 3), a) - - def test_product(self): - a = [] - self.makecycle(product([1,2,a,3], repeat=3), a) - - def test_repeat(self): - a = [] - self.makecycle(repeat(a), a) - - def test_starmap(self): - a = [] - self.makecycle(starmap(lambda *t: t, [(a,a)]*2), a) - - def test_takewhile(self): - a = [] - self.makecycle(takewhile(bool, [1, 0, a, a]), a) - - def R(seqn): - 'Regular generator' - for i in seqn: - yield i - - class G: - 'Sequence using __getitem__' - def __init__(self, seqn): - self.seqn = seqn - def __getitem__(self, i): - return self.seqn[i] - - class I: - 'Sequence using iterator protocol' - def __init__(self, seqn): - self.seqn = seqn - self.i = 0 - def __iter__(self): - return self - def __next__(self): - if self.i >= len(self.seqn): raise StopIteration - v = self.seqn[self.i] - self.i += 1 - return v - - class Ig: - 'Sequence using iterator protocol defined with a generator' - def __init__(self, seqn): - self.seqn = seqn - self.i = 0 - def __iter__(self): - for val in self.seqn: - yield val - - class X: - 'Missing __getitem__ and __iter__' - def __init__(self, seqn): - self.seqn = seqn - self.i = 0 - def __next__(self): - if self.i >= len(self.seqn): raise StopIteration - v = self.seqn[self.i] - self.i += 1 - return v - - class N: - 'Iterator missing __next__()' - def __init__(self, seqn): - self.seqn = seqn - self.i = 0 - def __iter__(self): - return self - - class E: - 'Test propagation of exceptions' - def __init__(self, seqn): - self.seqn = seqn - self.i = 0 - def __iter__(self): - return self - def __next__(self): - 3 // 0 - - class S: - 'Test immediate stop' - def __init__(self, seqn): - pass - def __iter__(self): - return self - def __next__(self): - raise StopIteration - - def L(seqn): - 'Test multiple tiers of iterators' - return chain(map(lambda x:x, R(Ig(G(seqn))))) - - - class TestVariousIteratorArgs(unittest.TestCase): - - def test_accumulate(self): - s = [1,2,3,4,5] - r = [1,3,6,10,15] - n = len(s) - for g in (G, I, Ig, L, R): - self.assertEqual(list(accumulate(g(s))), r) - self.assertEqual(list(accumulate(S(s))), []) - self.assertRaises(TypeError, accumulate, X(s)) - self.assertRaises(TypeError, accumulate, N(s)) - self.assertRaises(ZeroDivisionError, list, accumulate(E(s))) - - def test_chain(self): - for s in ("123", "", range(1000), ('do', 1.2), range(2000,2200,5)): - for g in (G, I, Ig, S, L, R): - self.assertEqual(list(chain(g(s))), list(g(s))) - self.assertEqual(list(chain(g(s), g(s))), list(g(s))+list(g(s))) - self.assertRaises(TypeError, list, chain(X(s))) - self.assertRaises(TypeError, list, chain(N(s))) - self.assertRaises(ZeroDivisionError, list, chain(E(s))) - - def test_compress(self): - for s in ("123", "", range(1000), ('do', 1.2), range(2000,2200,5)): - n = len(s) - for g in (G, I, Ig, S, L, R): - self.assertEqual(list(compress(g(s), repeat(1))), list(g(s))) - self.assertRaises(TypeError, compress, X(s), repeat(1)) - self.assertRaises(TypeError, compress, N(s), repeat(1)) - self.assertRaises(ZeroDivisionError, list, compress(E(s), repeat(1))) - - def test_product(self): - for s in ("123", "", range(1000), ('do', 1.2), range(2000,2200,5)): - self.assertRaises(TypeError, product, X(s)) - self.assertRaises(TypeError, product, N(s)) - self.assertRaises(ZeroDivisionError, product, E(s)) - - def test_cycle(self): - for s in ("123", "", range(1000), ('do', 1.2), range(2000,2200,5)): - for g in (G, I, Ig, S, L, R): - tgtlen = len(s) * 3 - expected = list(g(s))*3 - actual = list(islice(cycle(g(s)), tgtlen)) - self.assertEqual(actual, expected) - self.assertRaises(TypeError, cycle, X(s)) - self.assertRaises(TypeError, cycle, N(s)) - self.assertRaises(ZeroDivisionError, list, cycle(E(s))) - - def test_groupby(self): - for s in (range(10), range(0), range(1000), (7,11), range(2000,2200,5)): - for g in (G, I, Ig, S, L, R): - self.assertEqual([k for k, sb in groupby(g(s))], list(g(s))) - self.assertRaises(TypeError, groupby, X(s)) - self.assertRaises(TypeError, groupby, N(s)) - self.assertRaises(ZeroDivisionError, list, groupby(E(s))) - - def test_filter(self): - for s in (range(10), range(0), range(1000), (7,11), range(2000,2200,5)): - for g in (G, I, Ig, S, L, R): - self.assertEqual(list(filter(isEven, g(s))), - [x for x in g(s) if isEven(x)]) - self.assertRaises(TypeError, filter, isEven, X(s)) - self.assertRaises(TypeError, filter, isEven, N(s)) - self.assertRaises(ZeroDivisionError, list, filter(isEven, E(s))) - - def test_filterfalse(self): - for s in (range(10), range(0), range(1000), (7,11), range(2000,2200,5)): - for g in (G, I, Ig, S, L, R): - self.assertEqual(list(filterfalse(isEven, g(s))), - [x for x in g(s) if isOdd(x)]) - self.assertRaises(TypeError, filterfalse, isEven, X(s)) - self.assertRaises(TypeError, filterfalse, isEven, N(s)) - self.assertRaises(ZeroDivisionError, list, filterfalse(isEven, E(s))) - - def test_zip(self): - for s in ("123", "", range(1000), ('do', 1.2), range(2000,2200,5)): - for g in (G, I, Ig, S, L, R): - self.assertEqual(list(zip(g(s))), lzip(g(s))) - self.assertEqual(list(zip(g(s), g(s))), lzip(g(s), g(s))) - self.assertRaises(TypeError, zip, X(s)) - self.assertRaises(TypeError, zip, N(s)) - self.assertRaises(ZeroDivisionError, list, zip(E(s))) - - def test_ziplongest(self): - for s in ("123", "", range(1000), ('do', 1.2), range(2000,2200,5)): - for g in (G, I, Ig, S, L, R): - self.assertEqual(list(zip_longest(g(s))), list(zip(g(s)))) - self.assertEqual(list(zip_longest(g(s), g(s))), list(zip(g(s), g(s)))) - self.assertRaises(TypeError, zip_longest, X(s)) - self.assertRaises(TypeError, zip_longest, N(s)) - self.assertRaises(ZeroDivisionError, list, zip_longest(E(s))) - - def test_map(self): - for s in (range(10), range(0), range(100), (7,11), range(20,50,5)): - for g in (G, I, Ig, S, L, R): - self.assertEqual(list(map(onearg, g(s))), - [onearg(x) for x in g(s)]) - self.assertEqual(list(map(operator.pow, g(s), g(s))), - [x**x for x in g(s)]) - self.assertRaises(TypeError, map, onearg, X(s)) - self.assertRaises(TypeError, map, onearg, N(s)) - self.assertRaises(ZeroDivisionError, list, map(onearg, E(s))) - - def test_islice(self): - for s in ("12345", "", range(1000), ('do', 1.2), range(2000,2200,5)): - for g in (G, I, Ig, S, L, R): - self.assertEqual(list(islice(g(s),1,None,2)), list(g(s))[1::2]) - self.assertRaises(TypeError, islice, X(s), 10) - self.assertRaises(TypeError, islice, N(s), 10) - self.assertRaises(ZeroDivisionError, list, islice(E(s), 10)) - - def test_starmap(self): - for s in (range(10), range(0), range(100), (7,11), range(20,50,5)): - for g in (G, I, Ig, S, L, R): - ss = lzip(s, s) - self.assertEqual(list(starmap(operator.pow, g(ss))), - [x**x for x in g(s)]) - self.assertRaises(TypeError, starmap, operator.pow, X(ss)) - self.assertRaises(TypeError, starmap, operator.pow, N(ss)) - self.assertRaises(ZeroDivisionError, list, starmap(operator.pow, E(ss))) - - def test_takewhile(self): - for s in (range(10), range(0), range(1000), (7,11), range(2000,2200,5)): - for g in (G, I, Ig, S, L, R): - tgt = [] - for elem in g(s): - if not isEven(elem): break - tgt.append(elem) - self.assertEqual(list(takewhile(isEven, g(s))), tgt) - self.assertRaises(TypeError, takewhile, isEven, X(s)) - self.assertRaises(TypeError, takewhile, isEven, N(s)) - self.assertRaises(ZeroDivisionError, list, takewhile(isEven, E(s))) - - def test_dropwhile(self): - for s in (range(10), range(0), range(1000), (7,11), range(2000,2200,5)): - for g in (G, I, Ig, S, L, R): - tgt = [] - for elem in g(s): - if not tgt and isOdd(elem): continue - tgt.append(elem) - self.assertEqual(list(dropwhile(isOdd, g(s))), tgt) - self.assertRaises(TypeError, dropwhile, isOdd, X(s)) - self.assertRaises(TypeError, dropwhile, isOdd, N(s)) - self.assertRaises(ZeroDivisionError, list, dropwhile(isOdd, E(s))) - - def test_tee(self): - for s in ("123", "", range(1000), ('do', 1.2), range(2000,2200,5)): - for g in (G, I, Ig, S, L, R): - it1, it2 = tee(g(s)) - self.assertEqual(list(it1), list(g(s))) - self.assertEqual(list(it2), list(g(s))) - self.assertRaises(TypeError, tee, X(s)) - self.assertRaises(TypeError, tee, N(s)) - self.assertRaises(ZeroDivisionError, list, tee(E(s))[0]) - - class LengthTransparency(unittest.TestCase): - - def test_repeat(self): - self.assertEqual(operator.length_hint(repeat(None, 50)), 50) - self.assertEqual(operator.length_hint(repeat(None, 0)), 0) - self.assertEqual(operator.length_hint(repeat(None), 12), 12) - - def test_repeat_with_negative_times(self): - self.assertEqual(operator.length_hint(repeat(None, -1)), 0) - self.assertEqual(operator.length_hint(repeat(None, -2)), 0) - self.assertEqual(operator.length_hint(repeat(None, times=-1)), 0) - self.assertEqual(operator.length_hint(repeat(None, times=-2)), 0) - - class RegressionTests(unittest.TestCase): - - def test_sf_793826(self): - # Fix Armin Rigo's successful efforts to wreak havoc - - def mutatingtuple(tuple1, f, tuple2): - # this builds a tuple t which is a copy of tuple1, - # then calls f(t), then mutates t to be equal to tuple2 - # (needs len(tuple1) == len(tuple2)). - def g(value, first=[1]): - if first: - del first[:] - f(next(z)) - return value - items = list(tuple2) - items[1:1] = list(tuple1) - gen = map(g, items) - z = zip(*[gen]*len(tuple1)) - next(z) - - def f(t): - global T - T = t - first[:] = list(T) - - first = [] - mutatingtuple((1,2,3), f, (4,5,6)) - second = list(T) - self.assertEqual(first, second) - - - def test_sf_950057(self): - # Make sure that chain() and cycle() catch exceptions immediately - # rather than when shifting between input sources - - def gen1(): - hist.append(0) - yield 1 - hist.append(1) - raise AssertionError - hist.append(2) - - def gen2(x): - hist.append(3) - yield 2 - hist.append(4) - - hist = [] - self.assertRaises(AssertionError, list, chain(gen1(), gen2(False))) - self.assertEqual(hist, [0,1]) - - hist = [] - self.assertRaises(AssertionError, list, chain(gen1(), gen2(True))) - self.assertEqual(hist, [0,1]) - - hist = [] - self.assertRaises(AssertionError, list, cycle(gen1())) - self.assertEqual(hist, [0,1]) - - @support.skip_if_pgo_task - def test_long_chain_of_empty_iterables(self): - # Make sure itertools.chain doesn't run into recursion limits when - # dealing with long chains of empty iterables. Even with a high - # number this would probably only fail in Py_DEBUG mode. - it = chain.from_iterable(() for unused in range(10000000)) - with self.assertRaises(StopIteration): - next(it) - - def test_issue30347_1(self): - def f(n): - if n == 5: - list(b) - return n != 6 - for (k, b) in groupby(range(10), f): - list(b) # shouldn't crash - - def test_issue30347_2(self): - class K: - def __init__(self, v): - pass - def __eq__(self, other): - nonlocal i - i += 1 - if i == 1: - next(g, None) - return True - i = 0 - g = next(groupby(range(10), K))[1] - for j in range(2): - next(g, None) # shouldn't crash - - - class SubclassWithKwargsTest(unittest.TestCase): - def test_keywords_in_subclass(self): - # count is not subclassable... - for cls in (repeat, zip, filter, filterfalse, chain, map, - starmap, islice, takewhile, dropwhile, cycle, compress): - class Subclass(cls): - def __init__(self, newarg=None, *args): - cls.__init__(self, *args) - try: - Subclass(newarg=1) - except TypeError as err: - # we expect type errors because of wrong argument count - self.assertNotIn("keyword arguments", err.args[0]) - - @support.cpython_only - class SizeofTest(unittest.TestCase): - def setUp(self): - self.ssize_t = struct.calcsize('n') - - check_sizeof = support.check_sizeof - - def test_product_sizeof(self): - basesize = support.calcobjsize('3Pi') - check = self.check_sizeof - check(product('ab', '12'), basesize + 2 * self.ssize_t) - check(product(*(('abc',) * 10)), basesize + 10 * self.ssize_t) - - def test_combinations_sizeof(self): - basesize = support.calcobjsize('3Pni') - check = self.check_sizeof - check(combinations('abcd', 3), basesize + 3 * self.ssize_t) - check(combinations(range(10), 4), basesize + 4 * self.ssize_t) - - def test_combinations_with_replacement_sizeof(self): - cwr = combinations_with_replacement - basesize = support.calcobjsize('3Pni') - check = self.check_sizeof - check(cwr('abcd', 3), basesize + 3 * self.ssize_t) - check(cwr(range(10), 4), basesize + 4 * self.ssize_t) - - def test_permutations_sizeof(self): - basesize = support.calcobjsize('4Pni') - check = self.check_sizeof - check(permutations('abcd'), - basesize + 4 * self.ssize_t + 4 * self.ssize_t) - check(permutations('abcd', 3), - basesize + 4 * self.ssize_t + 3 * self.ssize_t) - check(permutations('abcde', 3), - basesize + 5 * self.ssize_t + 3 * self.ssize_t) - check(permutations(range(10), 4), - basesize + 10 * self.ssize_t + 4 * self.ssize_t) - - - libreftest = """ Doctest for examples in the library reference: libitertools.tex - - - >>> amounts = [120.15, 764.05, 823.14] - >>> for checknum, amount in zip(count(1200), amounts): - ... print('Check %d is for $%.2f' % (checknum, amount)) - ... - Check 1200 is for $120.15 - Check 1201 is for $764.05 - Check 1202 is for $823.14 - - >>> import operator - >>> for cube in map(operator.pow, range(1,4), repeat(3)): - ... print(cube) - ... - 1 - 8 - 27 - - >>> reportlines = ['EuroPython', 'Roster', '', 'alex', '', 'laura', '', 'martin', '', 'walter', '', 'samuele'] - >>> for name in islice(reportlines, 3, None, 2): - ... print(name.title()) - ... - Alex - Laura - Martin - Walter - Samuele - - >>> from operator import itemgetter - >>> d = dict(a=1, b=2, c=1, d=2, e=1, f=2, g=3) - >>> di = sorted(sorted(d.items()), key=itemgetter(1)) - >>> for k, g in groupby(di, itemgetter(1)): - ... print(k, list(map(itemgetter(0), g))) - ... - 1 ['a', 'c', 'e'] - 2 ['b', 'd', 'f'] - 3 ['g'] - - # Find runs of consecutive numbers using groupby. The key to the solution - # is differencing with a range so that consecutive numbers all appear in - # same group. - >>> data = [ 1, 4,5,6, 10, 15,16,17,18, 22, 25,26,27,28] - >>> for k, g in groupby(enumerate(data), lambda t:t[0]-t[1]): - ... print(list(map(operator.itemgetter(1), g))) - ... - [1] - [4, 5, 6] - [10] - [15, 16, 17, 18] - [22] - [25, 26, 27, 28] - - >>> def take(n, iterable): - ... "Return first n items of the iterable as a list" - ... return list(islice(iterable, n)) - - >>> def prepend(value, iterator): - ... "Prepend a single value in front of an iterator" - ... # prepend(1, [2, 3, 4]) -> 1 2 3 4 - ... return chain([value], iterator) - - >>> def enumerate(iterable, start=0): - ... return zip(count(start), iterable) - - >>> def tabulate(function, start=0): - ... "Return function(0), function(1), ..." - ... return map(function, count(start)) - - >>> import collections - >>> def consume(iterator, n=None): - ... "Advance the iterator n-steps ahead. If n is None, consume entirely." - ... # Use functions that consume iterators at C speed. - ... if n is None: - ... # feed the entire iterator into a zero-length deque - ... collections.deque(iterator, maxlen=0) - ... else: - ... # advance to the empty slice starting at position n - ... next(islice(iterator, n, n), None) - - >>> def nth(iterable, n, default=None): - ... "Returns the nth item or a default value" - ... return next(islice(iterable, n, None), default) - - >>> def all_equal(iterable): - ... "Returns True if all the elements are equal to each other" - ... g = groupby(iterable) - ... return next(g, True) and not next(g, False) - - >>> def quantify(iterable, pred=bool): - ... "Count how many times the predicate is true" - ... return sum(map(pred, iterable)) - - >>> def padnone(iterable): - ... "Returns the sequence elements and then returns None indefinitely" - ... return chain(iterable, repeat(None)) - - >>> def ncycles(iterable, n): - ... "Returns the sequence elements n times" - ... return chain(*repeat(iterable, n)) - - >>> def dotproduct(vec1, vec2): - ... return sum(map(operator.mul, vec1, vec2)) - - >>> def flatten(listOfLists): - ... return list(chain.from_iterable(listOfLists)) - - >>> def repeatfunc(func, times=None, *args): - ... "Repeat calls to func with specified arguments." - ... " Example: repeatfunc(random.random)" - ... if times is None: - ... return starmap(func, repeat(args)) - ... else: - ... return starmap(func, repeat(args, times)) - - >>> def pairwise(iterable): - ... "s -> (s0,s1), (s1,s2), (s2, s3), ..." - ... a, b = tee(iterable) - ... try: - ... next(b) - ... except StopIteration: - ... pass - ... return zip(a, b) - - >>> def grouper(n, iterable, fillvalue=None): - ... "grouper(3, 'ABCDEFG', 'x') --> ABC DEF Gxx" - ... args = [iter(iterable)] * n - ... return zip_longest(*args, fillvalue=fillvalue) - - >>> def roundrobin(*iterables): - ... "roundrobin('ABC', 'D', 'EF') --> A D E B F C" - ... # Recipe credited to George Sakkis - ... pending = len(iterables) - ... nexts = cycle(iter(it).__next__ for it in iterables) - ... while pending: - ... try: - ... for next in nexts: - ... yield next() - ... except StopIteration: - ... pending -= 1 - ... nexts = cycle(islice(nexts, pending)) - - >>> def powerset(iterable): - ... "powerset([1,2,3]) --> () (1,) (2,) (3,) (1,2) (1,3) (2,3) (1,2,3)" - ... s = list(iterable) - ... return chain.from_iterable(combinations(s, r) for r in range(len(s)+1)) - - >>> def unique_everseen(iterable, key=None): - ... "List unique elements, preserving order. Remember all elements ever seen." - ... # unique_everseen('AAAABBBCCDAABBB') --> A B C D - ... # unique_everseen('ABBCcAD', str.lower) --> A B C D - ... seen = set() - ... seen_add = seen.add - ... if key is None: - ... for element in iterable: - ... if element not in seen: - ... seen_add(element) - ... yield element - ... else: - ... for element in iterable: - ... k = key(element) - ... if k not in seen: - ... seen_add(k) - ... yield element - - >>> def unique_justseen(iterable, key=None): - ... "List unique elements, preserving order. Remember only the element just seen." - ... # unique_justseen('AAAABBBCCDAABBB') --> A B C D A B - ... # unique_justseen('ABBCcAD', str.lower) --> A B C A D - ... return map(next, map(itemgetter(1), groupby(iterable, key))) - - >>> def first_true(iterable, default=False, pred=None): - ... '''Returns the first true value in the iterable. - ... - ... If no true value is found, returns *default* - ... - ... If *pred* is not None, returns the first item - ... for which pred(item) is true. - ... - ... ''' - ... # first_true([a,b,c], x) --> a or b or c or x - ... # first_true([a,b], x, f) --> a if f(a) else b if f(b) else x - ... return next(filter(pred, iterable), default) - - >>> def nth_combination(iterable, r, index): - ... 'Equivalent to list(combinations(iterable, r))[index]' - ... pool = tuple(iterable) - ... n = len(pool) - ... if r < 0 or r > n: - ... raise ValueError - ... c = 1 - ... k = min(r, n-r) - ... for i in range(1, k+1): - ... c = c * (n - k + i) // i - ... if index < 0: - ... index += c - ... if index < 0 or index >= c: - ... raise IndexError - ... result = [] - ... while r: - ... c, n, r = c*r//n, n-1, r-1 - ... while index >= c: - ... index -= c - ... c, n = c*(n-r)//n, n-1 - ... result.append(pool[-1-n]) - ... return tuple(result) - - - This is not part of the examples but it tests to make sure the definitions - perform as purported. - - >>> take(10, count()) - [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] - - >>> list(prepend(1, [2, 3, 4])) - [1, 2, 3, 4] - - >>> list(enumerate('abc')) - [(0, 'a'), (1, 'b'), (2, 'c')] - - >>> list(islice(tabulate(lambda x: 2*x), 4)) - [0, 2, 4, 6] - - >>> it = iter(range(10)) - >>> consume(it, 3) - >>> next(it) - 3 - >>> consume(it) - >>> next(it, 'Done') - 'Done' - - >>> nth('abcde', 3) - 'd' - - >>> nth('abcde', 9) is None - True - - >>> [all_equal(s) for s in ('', 'A', 'AAAA', 'AAAB', 'AAABA')] - [True, True, True, False, False] - - >>> quantify(range(99), lambda x: x%2==0) - 50 - - >>> a = [[1, 2, 3], [4, 5, 6]] - >>> flatten(a) - [1, 2, 3, 4, 5, 6] - - >>> list(repeatfunc(pow, 5, 2, 3)) - [8, 8, 8, 8, 8] - - >>> import random - >>> take(5, map(int, repeatfunc(random.random))) - [0, 0, 0, 0, 0] - - >>> list(pairwise('abcd')) - [('a', 'b'), ('b', 'c'), ('c', 'd')] - - >>> list(pairwise([])) - [] - - >>> list(pairwise('a')) - [] - - >>> list(islice(padnone('abc'), 0, 6)) - ['a', 'b', 'c', None, None, None] - - >>> list(ncycles('abc', 3)) - ['a', 'b', 'c', 'a', 'b', 'c', 'a', 'b', 'c'] - - >>> dotproduct([1,2,3], [4,5,6]) - 32 - - >>> list(grouper(3, 'abcdefg', 'x')) - [('a', 'b', 'c'), ('d', 'e', 'f'), ('g', 'x', 'x')] - - >>> list(roundrobin('abc', 'd', 'ef')) - ['a', 'd', 'e', 'b', 'f', 'c'] - - >>> list(powerset([1,2,3])) - [(), (1,), (2,), (3,), (1, 2), (1, 3), (2, 3), (1, 2, 3)] - - >>> all(len(list(powerset(range(n)))) == 2**n for n in range(18)) - True - - >>> list(powerset('abcde')) == sorted(sorted(set(powerset('abcde'))), key=len) - True - - >>> list(unique_everseen('AAAABBBCCDAABBB')) - ['A', 'B', 'C', 'D'] - - >>> list(unique_everseen('ABBCcAD', str.lower)) - ['A', 'B', 'C', 'D'] - - >>> list(unique_justseen('AAAABBBCCDAABBB')) - ['A', 'B', 'C', 'D', 'A', 'B'] - - >>> list(unique_justseen('ABBCcAD', str.lower)) - ['A', 'B', 'C', 'A', 'D'] - - >>> first_true('ABC0DEF1', '9', str.isdigit) - '0' - - >>> population = 'ABCDEFGH' - >>> for r in range(len(population) + 1): - ... seq = list(combinations(population, r)) - ... for i in range(len(seq)): - ... assert nth_combination(population, r, i) == seq[i] - ... for i in range(-len(seq), 0): - ... assert nth_combination(population, r, i) == seq[i] - - - """ - - __test__ = {'libreftest' : libreftest} - - def test_main(verbose=None): - test_classes = (TestBasicOps, TestVariousIteratorArgs, TestGC, - RegressionTests, LengthTransparency, - SubclassWithKwargsTest, TestExamples, - TestPurePythonRoughEquivalents, - SizeofTest) - support.run_unittest(*test_classes) - - # verify reference counting - if verbose and hasattr(sys, "gettotalrefcount"): - import gc - counts = [None] * 5 - for i in range(len(counts)): - support.run_unittest(*test_classes) - gc.collect() - counts[i] = sys.gettotalrefcount() - print(counts) - - # doctest the examples in the library reference - support.run_doctest(sys.modules[__name__], verbose) - - if __name__ == "__main__": - test_main(verbose=True) diff --git a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_keyword.yaml b/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_keyword.yaml deleted file mode 100644 index 1be97f0fc..000000000 --- a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_keyword.yaml +++ /dev/null @@ -1,38 +0,0 @@ -python: | - import keyword - import unittest - - - class Test_iskeyword(unittest.TestCase): - def test_true_is_a_keyword(self): - self.assertTrue(keyword.iskeyword('True')) - - def test_uppercase_true_is_not_a_keyword(self): - self.assertFalse(keyword.iskeyword('TRUE')) - - def test_none_value_is_not_a_keyword(self): - self.assertFalse(keyword.iskeyword(None)) - - # This is probably an accident of the current implementation, but should be - # preserved for backward compatibility. - def test_changing_the_kwlist_does_not_affect_iskeyword(self): - oldlist = keyword.kwlist - self.addCleanup(setattr, keyword, 'kwlist', oldlist) - keyword.kwlist = ['its', 'all', 'eggs', 'beans', 'and', 'a', 'slice'] - self.assertFalse(keyword.iskeyword('eggs')) - - def test_all_keywords_fail_to_be_used_as_names(self): - for key in keyword.kwlist: - with self.assertRaises(SyntaxError): - exec(f"{key} = 42") - - def test_async_and_await_are_keywords(self): - self.assertIn("async", keyword.kwlist) - self.assertIn("await", keyword.kwlist) - - def test_keywords_are_sorted(self): - self.assertListEqual(sorted(keyword.kwlist), keyword.kwlist) - - - if __name__ == "__main__": - unittest.main() diff --git a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_keywordonlyarg.yaml b/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_keywordonlyarg.yaml deleted file mode 100644 index fb04d7d26..000000000 --- a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_keywordonlyarg.yaml +++ /dev/null @@ -1,178 +0,0 @@ -python: | - """Unit tests for the keyword only argument specified in PEP 3102.""" - - __author__ = "Jiwon Seo" - __email__ = "seojiwon at gmail dot com" - - import unittest - - def posonly_sum(pos_arg1, *arg, **kwarg): - return pos_arg1 + sum(arg) + sum(kwarg.values()) - def keywordonly_sum(*, k1=0, k2): - return k1 + k2 - def keywordonly_nodefaults_sum(*, k1, k2): - return k1 + k2 - def keywordonly_and_kwarg_sum(*, k1, k2, **kwarg): - return k1 + k2 + sum(kwarg.values()) - def mixedargs_sum(a, b=0, *arg, k1, k2=0): - return a + b + k1 + k2 + sum(arg) - def mixedargs_sum2(a, b=0, *arg, k1, k2=0, **kwargs): - return a + b + k1 + k2 + sum(arg) + sum(kwargs.values()) - - def sortnum(*nums, reverse=False): - return sorted(list(nums), reverse=reverse) - - def sortwords(*words, reverse=False, **kwargs): - return sorted(list(words), reverse=reverse) - - class Foo: - def __init__(self, *, k1, k2=0): - self.k1 = k1 - self.k2 = k2 - def set(self, p1, *, k1, k2): - self.k1 = k1 - self.k2 = k2 - def sum(self): - return self.k1 + self.k2 - - class KeywordOnlyArgTestCase(unittest.TestCase): - def assertRaisesSyntaxError(self, codestr): - def shouldRaiseSyntaxError(s): - compile(s, "", "single") - self.assertRaises(SyntaxError, shouldRaiseSyntaxError, codestr) - - def testSyntaxErrorForFunctionDefinition(self): - self.assertRaisesSyntaxError("def f(p, *):\n pass\n") - self.assertRaisesSyntaxError("def f(p1, *, p1=100):\n pass\n") - self.assertRaisesSyntaxError("def f(p1, *k1, k1=100):\n pass\n") - self.assertRaisesSyntaxError("def f(p1, *, k1, k1=100):\n pass\n") - self.assertRaisesSyntaxError("def f(p1, *, **k1):\n pass\n") - self.assertRaisesSyntaxError("def f(p1, *, k1, **k1):\n pass\n") - self.assertRaisesSyntaxError("def f(p1, *, None, **k1):\n pass\n") - self.assertRaisesSyntaxError("def f(p, *, (k1, k2), **kw):\n pass\n") - - def testSyntaxForManyArguments(self): - # more than 255 positional arguments, should compile ok - fundef = "def f(%s):\n pass\n" % ', '.join('i%d' % i for i in range(300)) - compile(fundef, "", "single") - # more than 255 keyword-only arguments, should compile ok - fundef = "def f(*, %s):\n pass\n" % ', '.join('i%d' % i for i in range(300)) - compile(fundef, "", "single") - - def testTooManyPositionalErrorMessage(self): - def f(a, b=None, *, c=None): - pass - with self.assertRaises(TypeError) as exc: - f(1, 2, 3) - expected = "f() takes from 1 to 2 positional arguments but 3 were given" - self.assertEqual(str(exc.exception), expected) - - def testSyntaxErrorForFunctionCall(self): - self.assertRaisesSyntaxError("f(p, k=1, p2)") - self.assertRaisesSyntaxError("f(p, k1=50, *(1,2), k1=100)") - - def testRaiseErrorFuncallWithUnexpectedKeywordArgument(self): - self.assertRaises(TypeError, keywordonly_sum, ()) - self.assertRaises(TypeError, keywordonly_nodefaults_sum, ()) - self.assertRaises(TypeError, Foo, ()) - try: - keywordonly_sum(k2=100, non_existing_arg=200) - self.fail("should raise TypeError") - except TypeError: - pass - try: - keywordonly_nodefaults_sum(k2=2) - self.fail("should raise TypeError") - except TypeError: - pass - - def testFunctionCall(self): - self.assertEqual(1, posonly_sum(1)) - self.assertEqual(1+2, posonly_sum(1,**{"2":2})) - self.assertEqual(1+2+3, posonly_sum(1,*(2,3))) - self.assertEqual(1+2+3+4, posonly_sum(1,*(2,3),**{"4":4})) - - self.assertEqual(1, keywordonly_sum(k2=1)) - self.assertEqual(1+2, keywordonly_sum(k1=1, k2=2)) - - self.assertEqual(1+2, keywordonly_and_kwarg_sum(k1=1, k2=2)) - self.assertEqual(1+2+3, keywordonly_and_kwarg_sum(k1=1, k2=2, k3=3)) - self.assertEqual(1+2+3+4, - keywordonly_and_kwarg_sum(k1=1, k2=2, - **{"a":3,"b":4})) - - self.assertEqual(1+2, mixedargs_sum(1, k1=2)) - self.assertEqual(1+2+3, mixedargs_sum(1, 2, k1=3)) - self.assertEqual(1+2+3+4, mixedargs_sum(1, 2, k1=3, k2=4)) - self.assertEqual(1+2+3+4+5, mixedargs_sum(1, 2, 3, k1=4, k2=5)) - - self.assertEqual(1+2, mixedargs_sum2(1, k1=2)) - self.assertEqual(1+2+3, mixedargs_sum2(1, 2, k1=3)) - self.assertEqual(1+2+3+4, mixedargs_sum2(1, 2, k1=3, k2=4)) - self.assertEqual(1+2+3+4+5, mixedargs_sum2(1, 2, 3, k1=4, k2=5)) - self.assertEqual(1+2+3+4+5+6, - mixedargs_sum2(1, 2, 3, k1=4, k2=5, k3=6)) - self.assertEqual(1+2+3+4+5+6, - mixedargs_sum2(1, 2, 3, k1=4, **{'k2':5, 'k3':6})) - - self.assertEqual(1, Foo(k1=1).sum()) - self.assertEqual(1+2, Foo(k1=1,k2=2).sum()) - - self.assertEqual([1,2,3], sortnum(3,2,1)) - self.assertEqual([3,2,1], sortnum(1,2,3, reverse=True)) - - self.assertEqual(['a','b','c'], sortwords('a','c','b')) - self.assertEqual(['c','b','a'], sortwords('a','c','b', reverse=True)) - self.assertEqual(['c','b','a'], - sortwords('a','c','b', reverse=True, ignore='ignore')) - - def testKwDefaults(self): - def foo(p1,p2=0, *, k1, k2=0): - return p1 + p2 + k1 + k2 - - self.assertEqual(2, foo.__code__.co_kwonlyargcount) - self.assertEqual({"k2":0}, foo.__kwdefaults__) - foo.__kwdefaults__ = {"k1":0} - try: - foo(1,k1=10) - self.fail("__kwdefaults__ is not properly changed") - except TypeError: - pass - - def test_kwonly_methods(self): - class Example: - def f(self, *, k1=1, k2=2): - return k1, k2 - - self.assertEqual(Example().f(k1=1, k2=2), (1, 2)) - self.assertEqual(Example.f(Example(), k1=1, k2=2), (1, 2)) - self.assertRaises(TypeError, Example.f, k1=1, k2=2) - - def test_issue13343(self): - # The Python compiler must scan all symbols of a function to - # determine their scope: global, local, cell... - # This was not done for the default values of keyword - # arguments in a lambda definition, and the following line - # used to fail with a SystemError. - lambda *, k1=unittest: None - - def test_mangling(self): - class X: - def f(self, *, __a=42): - return __a - self.assertEqual(X().f(), 42) - - def test_default_evaluation_order(self): - # See issue 16967 - a = 42 - with self.assertRaises(NameError) as err: - def f(v=a, x=b, *, y=c, z=d): - pass - self.assertEqual(str(err.exception), "name 'b' is not defined") - with self.assertRaises(NameError) as err: - f = lambda v=a, x=b, *, y=c, z=d: None - self.assertEqual(str(err.exception), "name 'b' is not defined") - - - if __name__ == "__main__": - unittest.main() diff --git a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_largefile.yaml b/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_largefile.yaml deleted file mode 100644 index ae403e799..000000000 --- a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_largefile.yaml +++ /dev/null @@ -1,190 +0,0 @@ -python: | - """Test largefile support on system where this makes sense. - """ - - import os - import stat - import sys - import unittest - from test.support import TESTFN, requires, unlink, bigmemtest - import io # C implementation of io - import _pyio as pyio # Python implementation of io - - # size of file to create (>2 GiB; 2 GiB == 2,147,483,648 bytes) - size = 2_500_000_000 - - class LargeFileTest: - """Test that each file function works as expected for large - (i.e. > 2 GiB) files. - """ - - def setUp(self): - if os.path.exists(TESTFN): - mode = 'r+b' - else: - mode = 'w+b' - - with self.open(TESTFN, mode) as f: - current_size = os.fstat(f.fileno())[stat.ST_SIZE] - if current_size == size+1: - return - - if current_size == 0: - f.write(b'z') - - f.seek(0) - f.seek(size) - f.write(b'a') - f.flush() - self.assertEqual(os.fstat(f.fileno())[stat.ST_SIZE], size+1) - - @classmethod - def tearDownClass(cls): - with cls.open(TESTFN, 'wb'): - pass - if not os.stat(TESTFN)[stat.ST_SIZE] == 0: - raise cls.failureException('File was not truncated by opening ' - 'with mode "wb"') - - # _pyio.FileIO.readall() uses a temporary bytearray then casted to bytes, - # so memuse=2 is needed - @bigmemtest(size=size, memuse=2, dry_run=False) - def test_large_read(self, _size): - # bpo-24658: Test that a read greater than 2GB does not fail. - with self.open(TESTFN, "rb") as f: - self.assertEqual(len(f.read()), size + 1) - self.assertEqual(f.tell(), size + 1) - - def test_osstat(self): - self.assertEqual(os.stat(TESTFN)[stat.ST_SIZE], size+1) - - def test_seek_read(self): - with self.open(TESTFN, 'rb') as f: - self.assertEqual(f.tell(), 0) - self.assertEqual(f.read(1), b'z') - self.assertEqual(f.tell(), 1) - f.seek(0) - self.assertEqual(f.tell(), 0) - f.seek(0, 0) - self.assertEqual(f.tell(), 0) - f.seek(42) - self.assertEqual(f.tell(), 42) - f.seek(42, 0) - self.assertEqual(f.tell(), 42) - f.seek(42, 1) - self.assertEqual(f.tell(), 84) - f.seek(0, 1) - self.assertEqual(f.tell(), 84) - f.seek(0, 2) # seek from the end - self.assertEqual(f.tell(), size + 1 + 0) - f.seek(-10, 2) - self.assertEqual(f.tell(), size + 1 - 10) - f.seek(-size-1, 2) - self.assertEqual(f.tell(), 0) - f.seek(size) - self.assertEqual(f.tell(), size) - # the 'a' that was written at the end of file above - self.assertEqual(f.read(1), b'a') - f.seek(-size-1, 1) - self.assertEqual(f.read(1), b'z') - self.assertEqual(f.tell(), 1) - - def test_lseek(self): - with self.open(TESTFN, 'rb') as f: - self.assertEqual(os.lseek(f.fileno(), 0, 0), 0) - self.assertEqual(os.lseek(f.fileno(), 42, 0), 42) - self.assertEqual(os.lseek(f.fileno(), 42, 1), 84) - self.assertEqual(os.lseek(f.fileno(), 0, 1), 84) - self.assertEqual(os.lseek(f.fileno(), 0, 2), size+1+0) - self.assertEqual(os.lseek(f.fileno(), -10, 2), size+1-10) - self.assertEqual(os.lseek(f.fileno(), -size-1, 2), 0) - self.assertEqual(os.lseek(f.fileno(), size, 0), size) - # the 'a' that was written at the end of file above - self.assertEqual(f.read(1), b'a') - - def test_truncate(self): - with self.open(TESTFN, 'r+b') as f: - if not hasattr(f, 'truncate'): - raise unittest.SkipTest("open().truncate() not available " - "on this system") - f.seek(0, 2) - # else we've lost track of the true size - self.assertEqual(f.tell(), size+1) - # Cut it back via seek + truncate with no argument. - newsize = size - 10 - f.seek(newsize) - f.truncate() - self.assertEqual(f.tell(), newsize) # else pointer moved - f.seek(0, 2) - self.assertEqual(f.tell(), newsize) # else wasn't truncated - # Ensure that truncate(smaller than true size) shrinks - # the file. - newsize -= 1 - f.seek(42) - f.truncate(newsize) - self.assertEqual(f.tell(), 42) - f.seek(0, 2) - self.assertEqual(f.tell(), newsize) - # XXX truncate(larger than true size) is ill-defined - # across platform; cut it waaaaay back - f.seek(0) - f.truncate(1) - self.assertEqual(f.tell(), 0) # else pointer moved - f.seek(0) - self.assertEqual(len(f.read()), 1) # else wasn't truncated - - def test_seekable(self): - # Issue #5016; seekable() can return False when the current position - # is negative when truncated to an int. - for pos in (2**31-1, 2**31, 2**31+1): - with self.open(TESTFN, 'rb') as f: - f.seek(pos) - self.assertTrue(f.seekable()) - - def setUpModule(): - try: - import signal - # The default handler for SIGXFSZ is to abort the process. - # By ignoring it, system calls exceeding the file size resource - # limit will raise OSError instead of crashing the interpreter. - signal.signal(signal.SIGXFSZ, signal.SIG_IGN) - except (ImportError, AttributeError): - pass - - # On Windows and Mac OSX this test consumes large resources; It - # takes a long time to build the >2 GiB file and takes >2 GiB of disk - # space therefore the resource must be enabled to run this test. - # If not, nothing after this line stanza will be executed. - if sys.platform[:3] == 'win' or sys.platform == 'darwin': - requires('largefile', - 'test requires %s bytes and a long time to run' % str(size)) - else: - # Only run if the current filesystem supports large files. - # (Skip this test on Windows, since we now always support - # large files.) - f = open(TESTFN, 'wb', buffering=0) - try: - # 2**31 == 2147483648 - f.seek(2147483649) - # Seeking is not enough of a test: you must write and flush, too! - f.write(b'x') - f.flush() - except (OSError, OverflowError): - raise unittest.SkipTest("filesystem does not have " - "largefile support") - finally: - f.close() - unlink(TESTFN) - - - class CLargeFileTest(LargeFileTest, unittest.TestCase): - open = staticmethod(io.open) - - class PyLargeFileTest(LargeFileTest, unittest.TestCase): - open = staticmethod(pyio.open) - - def tearDownModule(): - unlink(TESTFN) - - if __name__ == '__main__': - unittest.main() diff --git a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_lib2to3.yaml b/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_lib2to3.yaml deleted file mode 100644 index 6abd7c678..000000000 --- a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_lib2to3.yaml +++ /dev/null @@ -1,6 +0,0 @@ -python: | - from lib2to3.tests import load_tests - import unittest - - if __name__ == '__main__': - unittest.main() diff --git a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_linecache.yaml b/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_linecache.yaml deleted file mode 100644 index 5ffeee84d..000000000 --- a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_linecache.yaml +++ /dev/null @@ -1,243 +0,0 @@ -python: | - """ Tests for the linecache module """ - - import linecache - import unittest - import os.path - import tempfile - import tokenize - from test import support - - - FILENAME = linecache.__file__ - NONEXISTENT_FILENAME = FILENAME + '.missing' - INVALID_NAME = '!@$)(!@#_1' - EMPTY = '' - TEST_PATH = os.path.dirname(__file__) - MODULES = "linecache abc".split() - MODULE_PATH = os.path.dirname(FILENAME) - - SOURCE_1 = ''' - " Docstring " - - def function(): - return result - - ''' - - SOURCE_2 = ''' - def f(): - return 1 + 1 - - a = f() - - ''' - - SOURCE_3 = ''' - def f(): - return 3''' # No ending newline - - - class TempFile: - - def setUp(self): - super().setUp() - with tempfile.NamedTemporaryFile(delete=False) as fp: - self.file_name = fp.name - fp.write(self.file_byte_string) - self.addCleanup(support.unlink, self.file_name) - - - class GetLineTestsGoodData(TempFile): - # file_list = ['list\n', 'of\n', 'good\n', 'strings\n'] - - def setUp(self): - self.file_byte_string = ''.join(self.file_list).encode('utf-8') - super().setUp() - - def test_getline(self): - with tokenize.open(self.file_name) as fp: - for index, line in enumerate(fp): - if not line.endswith('\n'): - line += '\n' - - cached_line = linecache.getline(self.file_name, index + 1) - self.assertEqual(line, cached_line) - - def test_getlines(self): - lines = linecache.getlines(self.file_name) - self.assertEqual(lines, self.file_list) - - - class GetLineTestsBadData(TempFile): - # file_byte_string = b'Bad data goes here' - - def test_getline(self): - self.assertRaises((SyntaxError, UnicodeDecodeError), - linecache.getline, self.file_name, 1) - - def test_getlines(self): - self.assertRaises((SyntaxError, UnicodeDecodeError), - linecache.getlines, self.file_name) - - - class EmptyFile(GetLineTestsGoodData, unittest.TestCase): - file_list = [] - - - class SingleEmptyLine(GetLineTestsGoodData, unittest.TestCase): - file_list = ['\n'] - - - class GoodUnicode(GetLineTestsGoodData, unittest.TestCase): - file_list = ['á\n', 'b\n', 'abcdef\n', 'ááááá\n'] - - - class BadUnicode(GetLineTestsBadData, unittest.TestCase): - file_byte_string = b'\x80abc' - - - class LineCacheTests(unittest.TestCase): - - def test_getline(self): - getline = linecache.getline - - # Bad values for line number should return an empty string - self.assertEqual(getline(FILENAME, 2**15), EMPTY) - self.assertEqual(getline(FILENAME, -1), EMPTY) - - # Float values currently raise TypeError, should it? - self.assertRaises(TypeError, getline, FILENAME, 1.1) - - # Bad filenames should return an empty string - self.assertEqual(getline(EMPTY, 1), EMPTY) - self.assertEqual(getline(INVALID_NAME, 1), EMPTY) - - # Check module loading - for entry in MODULES: - filename = os.path.join(MODULE_PATH, entry) + '.py' - with open(filename) as file: - for index, line in enumerate(file): - self.assertEqual(line, getline(filename, index + 1)) - - # Check that bogus data isn't returned (issue #1309567) - empty = linecache.getlines('a/b/c/__init__.py') - self.assertEqual(empty, []) - - def test_no_ending_newline(self): - self.addCleanup(support.unlink, support.TESTFN) - with open(support.TESTFN, "w") as fp: - fp.write(SOURCE_3) - lines = linecache.getlines(support.TESTFN) - self.assertEqual(lines, ["\n", "def f():\n", " return 3\n"]) - - def test_clearcache(self): - cached = [] - for entry in MODULES: - filename = os.path.join(MODULE_PATH, entry) + '.py' - cached.append(filename) - linecache.getline(filename, 1) - - # Are all files cached? - self.assertNotEqual(cached, []) - cached_empty = [fn for fn in cached if fn not in linecache.cache] - self.assertEqual(cached_empty, []) - - # Can we clear the cache? - linecache.clearcache() - cached_empty = [fn for fn in cached if fn in linecache.cache] - self.assertEqual(cached_empty, []) - - def test_checkcache(self): - getline = linecache.getline - # Create a source file and cache its contents - source_name = support.TESTFN + '.py' - self.addCleanup(support.unlink, source_name) - with open(source_name, 'w') as source: - source.write(SOURCE_1) - getline(source_name, 1) - - # Keep a copy of the old contents - source_list = [] - with open(source_name) as source: - for index, line in enumerate(source): - self.assertEqual(line, getline(source_name, index + 1)) - source_list.append(line) - - with open(source_name, 'w') as source: - source.write(SOURCE_2) - - # Try to update a bogus cache entry - linecache.checkcache('dummy') - - # Check that the cache matches the old contents - for index, line in enumerate(source_list): - self.assertEqual(line, getline(source_name, index + 1)) - - # Update the cache and check whether it matches the new source file - linecache.checkcache(source_name) - with open(source_name) as source: - for index, line in enumerate(source): - self.assertEqual(line, getline(source_name, index + 1)) - source_list.append(line) - - def test_lazycache_no_globals(self): - lines = linecache.getlines(FILENAME) - linecache.clearcache() - self.assertEqual(False, linecache.lazycache(FILENAME, None)) - self.assertEqual(lines, linecache.getlines(FILENAME)) - - def test_lazycache_smoke(self): - lines = linecache.getlines(NONEXISTENT_FILENAME, globals()) - linecache.clearcache() - self.assertEqual( - True, linecache.lazycache(NONEXISTENT_FILENAME, globals())) - self.assertEqual(1, len(linecache.cache[NONEXISTENT_FILENAME])) - # Note here that we're looking up a nonexistent filename with no - # globals: this would error if the lazy value wasn't resolved. - self.assertEqual(lines, linecache.getlines(NONEXISTENT_FILENAME)) - - def test_lazycache_provide_after_failed_lookup(self): - linecache.clearcache() - lines = linecache.getlines(NONEXISTENT_FILENAME, globals()) - linecache.clearcache() - linecache.getlines(NONEXISTENT_FILENAME) - linecache.lazycache(NONEXISTENT_FILENAME, globals()) - self.assertEqual(lines, linecache.updatecache(NONEXISTENT_FILENAME)) - - def test_lazycache_check(self): - linecache.clearcache() - linecache.lazycache(NONEXISTENT_FILENAME, globals()) - linecache.checkcache() - - def test_lazycache_bad_filename(self): - linecache.clearcache() - self.assertEqual(False, linecache.lazycache('', globals())) - self.assertEqual(False, linecache.lazycache('', globals())) - - def test_lazycache_already_cached(self): - linecache.clearcache() - lines = linecache.getlines(NONEXISTENT_FILENAME, globals()) - self.assertEqual( - False, - linecache.lazycache(NONEXISTENT_FILENAME, globals())) - self.assertEqual(4, len(linecache.cache[NONEXISTENT_FILENAME])) - - def test_memoryerror(self): - lines = linecache.getlines(FILENAME) - self.assertTrue(lines) - def raise_memoryerror(*args, **kwargs): - raise MemoryError - with support.swap_attr(linecache, 'updatecache', raise_memoryerror): - lines2 = linecache.getlines(FILENAME) - self.assertEqual(lines2, lines) - - linecache.clearcache() - with support.swap_attr(linecache, 'updatecache', raise_memoryerror): - lines3 = linecache.getlines(FILENAME) - self.assertEqual(lines3, []) - self.assertEqual(linecache.getlines(FILENAME), lines) - - - if __name__ == "__main__": - unittest.main() diff --git a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_list.yaml b/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_list.yaml deleted file mode 100644 index 8d77dfa6c..000000000 --- a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_list.yaml +++ /dev/null @@ -1,229 +0,0 @@ -python: | - import sys - from test import list_tests - from test.support import cpython_only - import pickle - import unittest - - class ListTest(list_tests.CommonTest): - type2test = list - - def test_basic(self): - self.assertEqual(list([]), []) - l0_3 = [0, 1, 2, 3] - l0_3_bis = list(l0_3) - self.assertEqual(l0_3, l0_3_bis) - self.assertTrue(l0_3 is not l0_3_bis) - self.assertEqual(list(()), []) - self.assertEqual(list((0, 1, 2, 3)), [0, 1, 2, 3]) - self.assertEqual(list(''), []) - self.assertEqual(list('spam'), ['s', 'p', 'a', 'm']) - self.assertEqual(list(x for x in range(10) if x % 2), - [1, 3, 5, 7, 9]) - - if sys.maxsize == 0x7fffffff: - # This test can currently only work on 32-bit machines. - # XXX If/when PySequence_Length() returns a ssize_t, it should be - # XXX re-enabled. - # Verify clearing of bug #556025. - # This assumes that the max data size (sys.maxint) == max - # address size this also assumes that the address size is at - # least 4 bytes with 8 byte addresses, the bug is not well - # tested - # - # Note: This test is expected to SEGV under Cygwin 1.3.12 or - # earlier due to a newlib bug. See the following mailing list - # thread for the details: - - # http://sources.redhat.com/ml/newlib/2002/msg00369.html - self.assertRaises(MemoryError, list, range(sys.maxsize // 2)) - - # This code used to segfault in Py2.4a3 - x = [] - x.extend(-y for y in x) - self.assertEqual(x, []) - - def test_keyword_args(self): - with self.assertRaisesRegex(TypeError, 'keyword argument'): - list(sequence=[]) - - def test_truth(self): - super().test_truth() - self.assertTrue(not []) - self.assertTrue([42]) - - def test_identity(self): - self.assertTrue([] is not []) - - def test_len(self): - super().test_len() - self.assertEqual(len([]), 0) - self.assertEqual(len([0]), 1) - self.assertEqual(len([0, 1, 2]), 3) - - def test_overflow(self): - lst = [4, 5, 6, 7] - n = int((sys.maxsize*2+2) // len(lst)) - def mul(a, b): return a * b - def imul(a, b): a *= b - self.assertRaises((MemoryError, OverflowError), mul, lst, n) - self.assertRaises((MemoryError, OverflowError), imul, lst, n) - - def test_repr_large(self): - # Check the repr of large list objects - def check(n): - l = [0] * n - s = repr(l) - self.assertEqual(s, - '[' + ', '.join(['0'] * n) + ']') - check(10) # check our checking code - check(1000000) - - def test_iterator_pickle(self): - orig = self.type2test([4, 5, 6, 7]) - data = [10, 11, 12, 13, 14, 15] - for proto in range(pickle.HIGHEST_PROTOCOL + 1): - # initial iterator - itorig = iter(orig) - d = pickle.dumps((itorig, orig), proto) - it, a = pickle.loads(d) - a[:] = data - self.assertEqual(type(it), type(itorig)) - self.assertEqual(list(it), data) - - # running iterator - next(itorig) - d = pickle.dumps((itorig, orig), proto) - it, a = pickle.loads(d) - a[:] = data - self.assertEqual(type(it), type(itorig)) - self.assertEqual(list(it), data[1:]) - - # empty iterator - for i in range(1, len(orig)): - next(itorig) - d = pickle.dumps((itorig, orig), proto) - it, a = pickle.loads(d) - a[:] = data - self.assertEqual(type(it), type(itorig)) - self.assertEqual(list(it), data[len(orig):]) - - # exhausted iterator - self.assertRaises(StopIteration, next, itorig) - d = pickle.dumps((itorig, orig), proto) - it, a = pickle.loads(d) - a[:] = data - self.assertEqual(list(it), []) - - def test_reversed_pickle(self): - orig = self.type2test([4, 5, 6, 7]) - data = [10, 11, 12, 13, 14, 15] - for proto in range(pickle.HIGHEST_PROTOCOL + 1): - # initial iterator - itorig = reversed(orig) - d = pickle.dumps((itorig, orig), proto) - it, a = pickle.loads(d) - a[:] = data - self.assertEqual(type(it), type(itorig)) - self.assertEqual(list(it), data[len(orig)-1::-1]) - - # running iterator - next(itorig) - d = pickle.dumps((itorig, orig), proto) - it, a = pickle.loads(d) - a[:] = data - self.assertEqual(type(it), type(itorig)) - self.assertEqual(list(it), data[len(orig)-2::-1]) - - # empty iterator - for i in range(1, len(orig)): - next(itorig) - d = pickle.dumps((itorig, orig), proto) - it, a = pickle.loads(d) - a[:] = data - self.assertEqual(type(it), type(itorig)) - self.assertEqual(list(it), []) - - # exhausted iterator - self.assertRaises(StopIteration, next, itorig) - d = pickle.dumps((itorig, orig), proto) - it, a = pickle.loads(d) - a[:] = data - self.assertEqual(list(it), []) - - def test_no_comdat_folding(self): - # Issue 8847: In the PGO build, the MSVC linker's COMDAT folding - # optimization causes failures in code that relies on distinct - # function addresses. - class L(list): pass - with self.assertRaises(TypeError): - (3,) + L([1,2]) - - def test_equal_operator_modifying_operand(self): - # test fix for seg fault reported in bpo-38588 part 2. - class X: - def __eq__(self,other) : - list2.clear() - return NotImplemented - - class Y: - def __eq__(self, other): - list1.clear() - return NotImplemented - - class Z: - def __eq__(self, other): - list3.clear() - return NotImplemented - - list1 = [X()] - list2 = [Y()] - self.assertTrue(list1 == list2) - - list3 = [Z()] - list4 = [1] - self.assertFalse(list3 == list4) - - @cpython_only - def test_preallocation(self): - iterable = [0] * 10 - iter_size = sys.getsizeof(iterable) - - self.assertEqual(iter_size, sys.getsizeof(list([0] * 10))) - self.assertEqual(iter_size, sys.getsizeof(list(range(10)))) - - def test_count_index_remove_crashes(self): - # bpo-38610: The count(), index(), and remove() methods were not - # holding strong references to list elements while calling - # PyObject_RichCompareBool(). - class X: - def __eq__(self, other): - lst.clear() - return NotImplemented - - lst = [X()] - with self.assertRaises(ValueError): - lst.index(lst) - - class L(list): - def __eq__(self, other): - str(other) - return NotImplemented - - lst = L([X()]) - lst.count(lst) - - lst = L([X()]) - with self.assertRaises(ValueError): - lst.remove(lst) - - # bpo-39453: list.__contains__ was not holding strong references - # to list elements while calling PyObject_RichCompareBool(). - lst = [X(), X()] - 3 in lst - lst = [X(), X()] - X() in lst - - - if __name__ == "__main__": - unittest.main() diff --git a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_listcomps.yaml b/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_listcomps.yaml deleted file mode 100644 index cd2685454..000000000 --- a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_listcomps.yaml +++ /dev/null @@ -1,149 +0,0 @@ -python: | - doctests = """ - ########### Tests borrowed from or inspired by test_genexps.py ############ - - Test simple loop with conditional - - >>> sum([i*i for i in range(100) if i&1 == 1]) - 166650 - - Test simple nesting - - >>> [(i,j) for i in range(3) for j in range(4)] - [(0, 0), (0, 1), (0, 2), (0, 3), (1, 0), (1, 1), (1, 2), (1, 3), (2, 0), (2, 1), (2, 2), (2, 3)] - - Test nesting with the inner expression dependent on the outer - - >>> [(i,j) for i in range(4) for j in range(i)] - [(1, 0), (2, 0), (2, 1), (3, 0), (3, 1), (3, 2)] - - Make sure the induction variable is not exposed - - >>> i = 20 - >>> sum([i*i for i in range(100)]) - 328350 - - >>> i - 20 - - Verify that syntax error's are raised for listcomps used as lvalues - - >>> [y for y in (1,2)] = 10 # doctest: +IGNORE_EXCEPTION_DETAIL - Traceback (most recent call last): - ... - SyntaxError: ... - - >>> [y for y in (1,2)] += 10 # doctest: +IGNORE_EXCEPTION_DETAIL - Traceback (most recent call last): - ... - SyntaxError: ... - - - ########### Tests borrowed from or inspired by test_generators.py ############ - - Make a nested list comprehension that acts like range() - - >>> def frange(n): - ... return [i for i in range(n)] - >>> frange(10) - [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] - - Same again, only as a lambda expression instead of a function definition - - >>> lrange = lambda n: [i for i in range(n)] - >>> lrange(10) - [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] - - Generators can call other generators: - - >>> def grange(n): - ... for x in [i for i in range(n)]: - ... yield x - >>> list(grange(5)) - [0, 1, 2, 3, 4] - - - Make sure that None is a valid return value - - >>> [None for i in range(10)] - [None, None, None, None, None, None, None, None, None, None] - - ########### Tests for various scoping corner cases ############ - - Return lambdas that use the iteration variable as a default argument - - >>> items = [(lambda i=i: i) for i in range(5)] - >>> [x() for x in items] - [0, 1, 2, 3, 4] - - Same again, only this time as a closure variable - - >>> items = [(lambda: i) for i in range(5)] - >>> [x() for x in items] - [4, 4, 4, 4, 4] - - Another way to test that the iteration variable is local to the list comp - - >>> items = [(lambda: i) for i in range(5)] - >>> i = 20 - >>> [x() for x in items] - [4, 4, 4, 4, 4] - - And confirm that a closure can jump over the list comp scope - - >>> items = [(lambda: y) for i in range(5)] - >>> y = 2 - >>> [x() for x in items] - [2, 2, 2, 2, 2] - - We also repeat each of the above scoping tests inside a function - - >>> def test_func(): - ... items = [(lambda i=i: i) for i in range(5)] - ... return [x() for x in items] - >>> test_func() - [0, 1, 2, 3, 4] - - >>> def test_func(): - ... items = [(lambda: i) for i in range(5)] - ... return [x() for x in items] - >>> test_func() - [4, 4, 4, 4, 4] - - >>> def test_func(): - ... items = [(lambda: i) for i in range(5)] - ... i = 20 - ... return [x() for x in items] - >>> test_func() - [4, 4, 4, 4, 4] - - >>> def test_func(): - ... items = [(lambda: y) for i in range(5)] - ... y = 2 - ... return [x() for x in items] - >>> test_func() - [2, 2, 2, 2, 2] - - """ - - - __test__ = {'doctests' : doctests} - - def test_main(verbose=None): - import sys - from test import support - from test import test_listcomps - support.run_doctest(test_listcomps, verbose) - - # verify reference counting - if verbose and hasattr(sys, "gettotalrefcount"): - import gc - counts = [None] * 5 - for i in range(len(counts)): - support.run_doctest(test_listcomps, verbose) - gc.collect() - counts[i] = sys.gettotalrefcount() - print(counts) - - if __name__ == "__main__": - test_main(verbose=True) diff --git a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_locale.yaml b/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_locale.yaml deleted file mode 100644 index e7b90014c..000000000 --- a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_locale.yaml +++ /dev/null @@ -1,641 +0,0 @@ -python: | - from test.support import verbose, is_android, check_warnings - import unittest - import locale - import sys - import codecs - - - class BaseLocalizedTest(unittest.TestCase): - # - # Base class for tests using a real locale - # - - @classmethod - def setUpClass(cls): - if sys.platform == 'darwin': - import os - tlocs = ("en_US.UTF-8", "en_US.ISO8859-1", "en_US") - if int(os.uname().release.split('.')[0]) < 10: - # The locale test work fine on OSX 10.6, I (ronaldoussoren) - # haven't had time yet to verify if tests work on OSX 10.5 - # (10.4 is known to be bad) - raise unittest.SkipTest("Locale support on MacOSX is minimal") - elif sys.platform.startswith("win"): - tlocs = ("En", "English") - else: - tlocs = ("en_US.UTF-8", "en_US.ISO8859-1", - "en_US.US-ASCII", "en_US") - try: - oldlocale = locale.setlocale(locale.LC_NUMERIC) - for tloc in tlocs: - try: - locale.setlocale(locale.LC_NUMERIC, tloc) - except locale.Error: - continue - break - else: - raise unittest.SkipTest("Test locale not supported " - "(tried %s)" % (', '.join(tlocs))) - cls.enUS_locale = tloc - finally: - locale.setlocale(locale.LC_NUMERIC, oldlocale) - - def setUp(self): - oldlocale = locale.setlocale(self.locale_type) - self.addCleanup(locale.setlocale, self.locale_type, oldlocale) - locale.setlocale(self.locale_type, self.enUS_locale) - if verbose: - print("testing with %r..." % self.enUS_locale, end=' ', flush=True) - - - class BaseCookedTest(unittest.TestCase): - # - # Base class for tests using cooked localeconv() values - # - - def setUp(self): - locale._override_localeconv = self.cooked_values - - def tearDown(self): - locale._override_localeconv = {} - - class CCookedTest(BaseCookedTest): - # A cooked "C" locale - - cooked_values = { - 'currency_symbol': '', - 'decimal_point': '.', - 'frac_digits': 127, - 'grouping': [], - 'int_curr_symbol': '', - 'int_frac_digits': 127, - 'mon_decimal_point': '', - 'mon_grouping': [], - 'mon_thousands_sep': '', - 'n_cs_precedes': 127, - 'n_sep_by_space': 127, - 'n_sign_posn': 127, - 'negative_sign': '', - 'p_cs_precedes': 127, - 'p_sep_by_space': 127, - 'p_sign_posn': 127, - 'positive_sign': '', - 'thousands_sep': '' - } - - class EnUSCookedTest(BaseCookedTest): - # A cooked "en_US" locale - - cooked_values = { - 'currency_symbol': '$', - 'decimal_point': '.', - 'frac_digits': 2, - 'grouping': [3, 3, 0], - 'int_curr_symbol': 'USD ', - 'int_frac_digits': 2, - 'mon_decimal_point': '.', - 'mon_grouping': [3, 3, 0], - 'mon_thousands_sep': ',', - 'n_cs_precedes': 1, - 'n_sep_by_space': 0, - 'n_sign_posn': 1, - 'negative_sign': '-', - 'p_cs_precedes': 1, - 'p_sep_by_space': 0, - 'p_sign_posn': 1, - 'positive_sign': '', - 'thousands_sep': ',' - } - - - class FrFRCookedTest(BaseCookedTest): - # A cooked "fr_FR" locale with a space character as decimal separator - # and a non-ASCII currency symbol. - - cooked_values = { - 'currency_symbol': '\u20ac', - 'decimal_point': ',', - 'frac_digits': 2, - 'grouping': [3, 3, 0], - 'int_curr_symbol': 'EUR ', - 'int_frac_digits': 2, - 'mon_decimal_point': ',', - 'mon_grouping': [3, 3, 0], - 'mon_thousands_sep': ' ', - 'n_cs_precedes': 0, - 'n_sep_by_space': 1, - 'n_sign_posn': 1, - 'negative_sign': '-', - 'p_cs_precedes': 0, - 'p_sep_by_space': 1, - 'p_sign_posn': 1, - 'positive_sign': '', - 'thousands_sep': ' ' - } - - - class BaseFormattingTest(object): - # - # Utility functions for formatting tests - # - - def _test_formatfunc(self, format, value, out, func, **format_opts): - self.assertEqual( - func(format, value, **format_opts), out) - - def _test_format(self, format, value, out, **format_opts): - with check_warnings(('', DeprecationWarning)): - self._test_formatfunc(format, value, out, - func=locale.format, **format_opts) - - def _test_format_string(self, format, value, out, **format_opts): - self._test_formatfunc(format, value, out, - func=locale.format_string, **format_opts) - - def _test_currency(self, value, out, **format_opts): - self.assertEqual(locale.currency(value, **format_opts), out) - - - class EnUSNumberFormatting(BaseFormattingTest): - # XXX there is a grouping + padding bug when the thousands separator - # is empty but the grouping array contains values (e.g. Solaris 10) - - def setUp(self): - self.sep = locale.localeconv()['thousands_sep'] - - def test_grouping(self): - self._test_format("%f", 1024, grouping=1, out='1%s024.000000' % self.sep) - self._test_format("%f", 102, grouping=1, out='102.000000') - self._test_format("%f", -42, grouping=1, out='-42.000000') - self._test_format("%+f", -42, grouping=1, out='-42.000000') - - def test_grouping_and_padding(self): - self._test_format("%20.f", -42, grouping=1, out='-42'.rjust(20)) - if self.sep: - self._test_format("%+10.f", -4200, grouping=1, - out=('-4%s200' % self.sep).rjust(10)) - self._test_format("%-10.f", -4200, grouping=1, - out=('-4%s200' % self.sep).ljust(10)) - - def test_integer_grouping(self): - self._test_format("%d", 4200, grouping=True, out='4%s200' % self.sep) - self._test_format("%+d", 4200, grouping=True, out='+4%s200' % self.sep) - self._test_format("%+d", -4200, grouping=True, out='-4%s200' % self.sep) - - def test_integer_grouping_and_padding(self): - self._test_format("%10d", 4200, grouping=True, - out=('4%s200' % self.sep).rjust(10)) - self._test_format("%-10d", -4200, grouping=True, - out=('-4%s200' % self.sep).ljust(10)) - - def test_simple(self): - self._test_format("%f", 1024, grouping=0, out='1024.000000') - self._test_format("%f", 102, grouping=0, out='102.000000') - self._test_format("%f", -42, grouping=0, out='-42.000000') - self._test_format("%+f", -42, grouping=0, out='-42.000000') - - def test_padding(self): - self._test_format("%20.f", -42, grouping=0, out='-42'.rjust(20)) - self._test_format("%+10.f", -4200, grouping=0, out='-4200'.rjust(10)) - self._test_format("%-10.f", 4200, grouping=0, out='4200'.ljust(10)) - - def test_format_deprecation(self): - with self.assertWarns(DeprecationWarning): - locale.format("%-10.f", 4200, grouping=True) - - def test_complex_formatting(self): - # Spaces in formatting string - self._test_format_string("One million is %i", 1000000, grouping=1, - out='One million is 1%s000%s000' % (self.sep, self.sep)) - self._test_format_string("One million is %i", 1000000, grouping=1, - out='One million is 1%s000%s000' % (self.sep, self.sep)) - # Dots in formatting string - self._test_format_string(".%f.", 1000.0, out='.1000.000000.') - # Padding - if self.sep: - self._test_format_string("--> %10.2f", 4200, grouping=1, - out='--> ' + ('4%s200.00' % self.sep).rjust(10)) - # Asterisk formats - self._test_format_string("%10.*f", (2, 1000), grouping=0, - out='1000.00'.rjust(10)) - if self.sep: - self._test_format_string("%*.*f", (10, 2, 1000), grouping=1, - out=('1%s000.00' % self.sep).rjust(10)) - # Test more-in-one - if self.sep: - self._test_format_string("int %i float %.2f str %s", - (1000, 1000.0, 'str'), grouping=1, - out='int 1%s000 float 1%s000.00 str str' % - (self.sep, self.sep)) - - - class TestFormatPatternArg(unittest.TestCase): - # Test handling of pattern argument of format - - def test_onlyOnePattern(self): - with check_warnings(('', DeprecationWarning)): - # Issue 2522: accept exactly one % pattern, and no extra chars. - self.assertRaises(ValueError, locale.format, "%f\n", 'foo') - self.assertRaises(ValueError, locale.format, "%f\r", 'foo') - self.assertRaises(ValueError, locale.format, "%f\r\n", 'foo') - self.assertRaises(ValueError, locale.format, " %f", 'foo') - self.assertRaises(ValueError, locale.format, "%fg", 'foo') - self.assertRaises(ValueError, locale.format, "%^g", 'foo') - self.assertRaises(ValueError, locale.format, "%f%%", 'foo') - - - class TestLocaleFormatString(unittest.TestCase): - """General tests on locale.format_string""" - - def test_percent_escape(self): - self.assertEqual(locale.format_string('%f%%', 1.0), '%f%%' % 1.0) - self.assertEqual(locale.format_string('%d %f%%d', (1, 1.0)), - '%d %f%%d' % (1, 1.0)) - self.assertEqual(locale.format_string('%(foo)s %%d', {'foo': 'bar'}), - ('%(foo)s %%d' % {'foo': 'bar'})) - - def test_mapping(self): - self.assertEqual(locale.format_string('%(foo)s bing.', {'foo': 'bar'}), - ('%(foo)s bing.' % {'foo': 'bar'})) - self.assertEqual(locale.format_string('%(foo)s', {'foo': 'bar'}), - ('%(foo)s' % {'foo': 'bar'})) - - - - class TestNumberFormatting(BaseLocalizedTest, EnUSNumberFormatting): - # Test number formatting with a real English locale. - - locale_type = locale.LC_NUMERIC - - def setUp(self): - BaseLocalizedTest.setUp(self) - EnUSNumberFormatting.setUp(self) - - - class TestEnUSNumberFormatting(EnUSCookedTest, EnUSNumberFormatting): - # Test number formatting with a cooked "en_US" locale. - - def setUp(self): - EnUSCookedTest.setUp(self) - EnUSNumberFormatting.setUp(self) - - def test_currency(self): - self._test_currency(50000, "$50000.00") - self._test_currency(50000, "$50,000.00", grouping=True) - self._test_currency(50000, "USD 50,000.00", - grouping=True, international=True) - - - class TestCNumberFormatting(CCookedTest, BaseFormattingTest): - # Test number formatting with a cooked "C" locale. - - def test_grouping(self): - self._test_format("%.2f", 12345.67, grouping=True, out='12345.67') - - def test_grouping_and_padding(self): - self._test_format("%9.2f", 12345.67, grouping=True, out=' 12345.67') - - - class TestFrFRNumberFormatting(FrFRCookedTest, BaseFormattingTest): - # Test number formatting with a cooked "fr_FR" locale. - - def test_decimal_point(self): - self._test_format("%.2f", 12345.67, out='12345,67') - - def test_grouping(self): - self._test_format("%.2f", 345.67, grouping=True, out='345,67') - self._test_format("%.2f", 12345.67, grouping=True, out='12 345,67') - - def test_grouping_and_padding(self): - self._test_format("%6.2f", 345.67, grouping=True, out='345,67') - self._test_format("%7.2f", 345.67, grouping=True, out=' 345,67') - self._test_format("%8.2f", 12345.67, grouping=True, out='12 345,67') - self._test_format("%9.2f", 12345.67, grouping=True, out='12 345,67') - self._test_format("%10.2f", 12345.67, grouping=True, out=' 12 345,67') - self._test_format("%-6.2f", 345.67, grouping=True, out='345,67') - self._test_format("%-7.2f", 345.67, grouping=True, out='345,67 ') - self._test_format("%-8.2f", 12345.67, grouping=True, out='12 345,67') - self._test_format("%-9.2f", 12345.67, grouping=True, out='12 345,67') - self._test_format("%-10.2f", 12345.67, grouping=True, out='12 345,67 ') - - def test_integer_grouping(self): - self._test_format("%d", 200, grouping=True, out='200') - self._test_format("%d", 4200, grouping=True, out='4 200') - - def test_integer_grouping_and_padding(self): - self._test_format("%4d", 4200, grouping=True, out='4 200') - self._test_format("%5d", 4200, grouping=True, out='4 200') - self._test_format("%10d", 4200, grouping=True, out='4 200'.rjust(10)) - self._test_format("%-4d", 4200, grouping=True, out='4 200') - self._test_format("%-5d", 4200, grouping=True, out='4 200') - self._test_format("%-10d", 4200, grouping=True, out='4 200'.ljust(10)) - - def test_currency(self): - euro = '\u20ac' - self._test_currency(50000, "50000,00 " + euro) - self._test_currency(50000, "50 000,00 " + euro, grouping=True) - # XXX is the trailing space a bug? - self._test_currency(50000, "50 000,00 EUR ", - grouping=True, international=True) - - - class TestCollation(unittest.TestCase): - # Test string collation functions - - def test_strcoll(self): - self.assertLess(locale.strcoll('a', 'b'), 0) - self.assertEqual(locale.strcoll('a', 'a'), 0) - self.assertGreater(locale.strcoll('b', 'a'), 0) - # embedded null character - self.assertRaises(ValueError, locale.strcoll, 'a\0', 'a') - self.assertRaises(ValueError, locale.strcoll, 'a', 'a\0') - - def test_strxfrm(self): - self.assertLess(locale.strxfrm('a'), locale.strxfrm('b')) - # embedded null character - self.assertRaises(ValueError, locale.strxfrm, 'a\0') - - - class TestEnUSCollation(BaseLocalizedTest, TestCollation): - # Test string collation functions with a real English locale - - locale_type = locale.LC_ALL - - def setUp(self): - enc = codecs.lookup(locale.getpreferredencoding(False) or 'ascii').name - if enc not in ('utf-8', 'iso8859-1', 'cp1252'): - raise unittest.SkipTest('encoding not suitable') - if enc != 'iso8859-1' and (sys.platform == 'darwin' or is_android or - sys.platform.startswith('freebsd')): - raise unittest.SkipTest('wcscoll/wcsxfrm have known bugs') - BaseLocalizedTest.setUp(self) - - @unittest.skipIf(sys.platform.startswith('aix'), - 'bpo-29972: broken test on AIX') - def test_strcoll_with_diacritic(self): - self.assertLess(locale.strcoll('à', 'b'), 0) - - @unittest.skipIf(sys.platform.startswith('aix'), - 'bpo-29972: broken test on AIX') - def test_strxfrm_with_diacritic(self): - self.assertLess(locale.strxfrm('à'), locale.strxfrm('b')) - - - class NormalizeTest(unittest.TestCase): - def check(self, localename, expected): - self.assertEqual(locale.normalize(localename), expected, msg=localename) - - def test_locale_alias(self): - for localename, alias in locale.locale_alias.items(): - with self.subTest(locale=(localename, alias)): - self.check(localename, alias) - - def test_empty(self): - self.check('', '') - - def test_c(self): - self.check('c', 'C') - self.check('posix', 'C') - - def test_english(self): - self.check('en', 'en_US.ISO8859-1') - self.check('EN', 'en_US.ISO8859-1') - self.check('en.iso88591', 'en_US.ISO8859-1') - self.check('en_US', 'en_US.ISO8859-1') - self.check('en_us', 'en_US.ISO8859-1') - self.check('en_GB', 'en_GB.ISO8859-1') - self.check('en_US.UTF-8', 'en_US.UTF-8') - self.check('en_US.utf8', 'en_US.UTF-8') - self.check('en_US:UTF-8', 'en_US.UTF-8') - self.check('en_US.ISO8859-1', 'en_US.ISO8859-1') - self.check('en_US.US-ASCII', 'en_US.ISO8859-1') - self.check('en_US.88591', 'en_US.ISO8859-1') - self.check('en_US.885915', 'en_US.ISO8859-15') - self.check('english', 'en_EN.ISO8859-1') - self.check('english_uk.ascii', 'en_GB.ISO8859-1') - - def test_hyphenated_encoding(self): - self.check('az_AZ.iso88599e', 'az_AZ.ISO8859-9E') - self.check('az_AZ.ISO8859-9E', 'az_AZ.ISO8859-9E') - self.check('tt_RU.koi8c', 'tt_RU.KOI8-C') - self.check('tt_RU.KOI8-C', 'tt_RU.KOI8-C') - self.check('lo_LA.cp1133', 'lo_LA.IBM-CP1133') - self.check('lo_LA.ibmcp1133', 'lo_LA.IBM-CP1133') - self.check('lo_LA.IBM-CP1133', 'lo_LA.IBM-CP1133') - self.check('uk_ua.microsoftcp1251', 'uk_UA.CP1251') - self.check('uk_ua.microsoft-cp1251', 'uk_UA.CP1251') - self.check('ka_ge.georgianacademy', 'ka_GE.GEORGIAN-ACADEMY') - self.check('ka_GE.GEORGIAN-ACADEMY', 'ka_GE.GEORGIAN-ACADEMY') - self.check('cs_CZ.iso88592', 'cs_CZ.ISO8859-2') - self.check('cs_CZ.ISO8859-2', 'cs_CZ.ISO8859-2') - - def test_euro_modifier(self): - self.check('de_DE@euro', 'de_DE.ISO8859-15') - self.check('en_US.ISO8859-15@euro', 'en_US.ISO8859-15') - self.check('de_DE.utf8@euro', 'de_DE.UTF-8') - - def test_latin_modifier(self): - self.check('be_BY.UTF-8@latin', 'be_BY.UTF-8@latin') - self.check('sr_RS.UTF-8@latin', 'sr_RS.UTF-8@latin') - self.check('sr_RS.UTF-8@latn', 'sr_RS.UTF-8@latin') - - def test_valencia_modifier(self): - self.check('ca_ES.UTF-8@valencia', 'ca_ES.UTF-8@valencia') - self.check('ca_ES@valencia', 'ca_ES.UTF-8@valencia') - self.check('ca@valencia', 'ca_ES.ISO8859-1@valencia') - - def test_devanagari_modifier(self): - self.check('ks_IN.UTF-8@devanagari', 'ks_IN.UTF-8@devanagari') - self.check('ks_IN@devanagari', 'ks_IN.UTF-8@devanagari') - self.check('ks@devanagari', 'ks_IN.UTF-8@devanagari') - self.check('ks_IN.UTF-8', 'ks_IN.UTF-8') - self.check('ks_IN', 'ks_IN.UTF-8') - self.check('ks', 'ks_IN.UTF-8') - self.check('sd_IN.UTF-8@devanagari', 'sd_IN.UTF-8@devanagari') - self.check('sd_IN@devanagari', 'sd_IN.UTF-8@devanagari') - self.check('sd@devanagari', 'sd_IN.UTF-8@devanagari') - self.check('sd_IN.UTF-8', 'sd_IN.UTF-8') - self.check('sd_IN', 'sd_IN.UTF-8') - self.check('sd', 'sd_IN.UTF-8') - - def test_euc_encoding(self): - self.check('ja_jp.euc', 'ja_JP.eucJP') - self.check('ja_jp.eucjp', 'ja_JP.eucJP') - self.check('ko_kr.euc', 'ko_KR.eucKR') - self.check('ko_kr.euckr', 'ko_KR.eucKR') - self.check('zh_cn.euc', 'zh_CN.eucCN') - self.check('zh_tw.euc', 'zh_TW.eucTW') - self.check('zh_tw.euctw', 'zh_TW.eucTW') - - def test_japanese(self): - self.check('ja', 'ja_JP.eucJP') - self.check('ja.jis', 'ja_JP.JIS7') - self.check('ja.sjis', 'ja_JP.SJIS') - self.check('ja_jp', 'ja_JP.eucJP') - self.check('ja_jp.ajec', 'ja_JP.eucJP') - self.check('ja_jp.euc', 'ja_JP.eucJP') - self.check('ja_jp.eucjp', 'ja_JP.eucJP') - self.check('ja_jp.iso-2022-jp', 'ja_JP.JIS7') - self.check('ja_jp.iso2022jp', 'ja_JP.JIS7') - self.check('ja_jp.jis', 'ja_JP.JIS7') - self.check('ja_jp.jis7', 'ja_JP.JIS7') - self.check('ja_jp.mscode', 'ja_JP.SJIS') - self.check('ja_jp.pck', 'ja_JP.SJIS') - self.check('ja_jp.sjis', 'ja_JP.SJIS') - self.check('ja_jp.ujis', 'ja_JP.eucJP') - self.check('ja_jp.utf8', 'ja_JP.UTF-8') - self.check('japan', 'ja_JP.eucJP') - self.check('japanese', 'ja_JP.eucJP') - self.check('japanese-euc', 'ja_JP.eucJP') - self.check('japanese.euc', 'ja_JP.eucJP') - self.check('japanese.sjis', 'ja_JP.SJIS') - self.check('jp_jp', 'ja_JP.eucJP') - - - class TestMiscellaneous(unittest.TestCase): - def test_defaults_UTF8(self): - # Issue #18378: on (at least) macOS setting LC_CTYPE to "UTF-8" is - # valid. Futhermore LC_CTYPE=UTF is used by the UTF-8 locale coercing - # during interpreter startup (on macOS). - import _locale - import os - - self.assertEqual(locale._parse_localename('UTF-8'), (None, 'UTF-8')) - - if hasattr(_locale, '_getdefaultlocale'): - orig_getlocale = _locale._getdefaultlocale - del _locale._getdefaultlocale - else: - orig_getlocale = None - - orig_env = {} - try: - for key in ('LC_ALL', 'LC_CTYPE', 'LANG', 'LANGUAGE'): - if key in os.environ: - orig_env[key] = os.environ[key] - del os.environ[key] - - os.environ['LC_CTYPE'] = 'UTF-8' - - self.assertEqual(locale.getdefaultlocale(), (None, 'UTF-8')) - - finally: - for k in orig_env: - os.environ[k] = orig_env[k] - - if 'LC_CTYPE' not in orig_env: - del os.environ['LC_CTYPE'] - - if orig_getlocale is not None: - _locale._getdefaultlocale = orig_getlocale - - def test_getpreferredencoding(self): - # Invoke getpreferredencoding to make sure it does not cause exceptions. - enc = locale.getpreferredencoding() - if enc: - # If encoding non-empty, make sure it is valid - codecs.lookup(enc) - - def test_strcoll_3303(self): - # test crasher from bug #3303 - self.assertRaises(TypeError, locale.strcoll, "a", None) - self.assertRaises(TypeError, locale.strcoll, b"a", None) - - def test_setlocale_category(self): - locale.setlocale(locale.LC_ALL) - locale.setlocale(locale.LC_TIME) - locale.setlocale(locale.LC_CTYPE) - locale.setlocale(locale.LC_COLLATE) - locale.setlocale(locale.LC_MONETARY) - locale.setlocale(locale.LC_NUMERIC) - - # crasher from bug #7419 - self.assertRaises(locale.Error, locale.setlocale, 12345) - - def test_getsetlocale_issue1813(self): - # Issue #1813: setting and getting the locale under a Turkish locale - oldlocale = locale.setlocale(locale.LC_CTYPE) - self.addCleanup(locale.setlocale, locale.LC_CTYPE, oldlocale) - try: - locale.setlocale(locale.LC_CTYPE, 'tr_TR') - except locale.Error: - # Unsupported locale on this system - self.skipTest('test needs Turkish locale') - loc = locale.getlocale(locale.LC_CTYPE) - if verbose: - print('testing with %a' % (loc,), end=' ', flush=True) - try: - locale.setlocale(locale.LC_CTYPE, loc) - except locale.Error as exc: - # bpo-37945: setlocale(LC_CTYPE) fails with getlocale(LC_CTYPE) - # and the tr_TR locale on Windows. getlocale() builds a locale - # which is not recognize by setlocale(). - self.skipTest(f"setlocale(LC_CTYPE, {loc!r}) failed: {exc!r}") - self.assertEqual(loc, locale.getlocale(locale.LC_CTYPE)) - - def test_invalid_locale_format_in_localetuple(self): - with self.assertRaises(TypeError): - locale.setlocale(locale.LC_ALL, b'fi_FI') - - def test_invalid_iterable_in_localetuple(self): - with self.assertRaises(TypeError): - locale.setlocale(locale.LC_ALL, (b'not', b'valid')) - - - class BaseDelocalizeTest(BaseLocalizedTest): - - def _test_delocalize(self, value, out): - self.assertEqual(locale.delocalize(value), out) - - def _test_atof(self, value, out): - self.assertEqual(locale.atof(value), out) - - def _test_atoi(self, value, out): - self.assertEqual(locale.atoi(value), out) - - - class TestEnUSDelocalize(EnUSCookedTest, BaseDelocalizeTest): - - def test_delocalize(self): - self._test_delocalize('50000.00', '50000.00') - self._test_delocalize('50,000.00', '50000.00') - - def test_atof(self): - self._test_atof('50000.00', 50000.) - self._test_atof('50,000.00', 50000.) - - def test_atoi(self): - self._test_atoi('50000', 50000) - self._test_atoi('50,000', 50000) - - - class TestCDelocalizeTest(CCookedTest, BaseDelocalizeTest): - - def test_delocalize(self): - self._test_delocalize('50000.00', '50000.00') - - def test_atof(self): - self._test_atof('50000.00', 50000.) - - def test_atoi(self): - self._test_atoi('50000', 50000) - - - class TestfrFRDelocalizeTest(FrFRCookedTest, BaseDelocalizeTest): - - def test_delocalize(self): - self._test_delocalize('50000,00', '50000.00') - self._test_delocalize('50 000,00', '50000.00') - - def test_atof(self): - self._test_atof('50000,00', 50000.) - self._test_atof('50 000,00', 50000.) - - def test_atoi(self): - self._test_atoi('50000', 50000) - self._test_atoi('50 000', 50000) - - - if __name__ == '__main__': - unittest.main() diff --git a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_logging.yaml b/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_logging.yaml deleted file mode 100644 index 26fa35c5a..000000000 --- a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_logging.yaml +++ /dev/null @@ -1,5238 +0,0 @@ -python: | - # Copyright 2001-2017 by Vinay Sajip. All Rights Reserved. - # - # Permission to use, copy, modify, and distribute this software and its - # documentation for any purpose and without fee is hereby granted, - # provided that the above copyright notice appear in all copies and that - # both that copyright notice and this permission notice appear in - # supporting documentation, and that the name of Vinay Sajip - # not be used in advertising or publicity pertaining to distribution - # of the software without specific, written prior permission. - # VINAY SAJIP DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING - # ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL - # VINAY SAJIP BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR - # ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - # IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT - # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - """Test harness for the logging module. Run all tests. - - Copyright (C) 2001-2017 Vinay Sajip. All Rights Reserved. - """ - - import logging - import logging.handlers - import logging.config - - import codecs - import configparser - import copy - import datetime - import pathlib - import pickle - import io - import gc - import json - import os - import queue - import random - import re - import signal - import socket - import struct - import sys - import tempfile - from test.support.script_helper import assert_python_ok, assert_python_failure - from test import support - import textwrap - import threading - import time - import unittest - import warnings - import weakref - - import asyncore - from http.server import HTTPServer, BaseHTTPRequestHandler - import smtpd - from urllib.parse import urlparse, parse_qs - from socketserver import (ThreadingUDPServer, DatagramRequestHandler, - ThreadingTCPServer, StreamRequestHandler) - - try: - import win32evtlog, win32evtlogutil, pywintypes - except ImportError: - win32evtlog = win32evtlogutil = pywintypes = None - - try: - import zlib - except ImportError: - pass - - class BaseTest(unittest.TestCase): - - """Base class for logging tests.""" - - log_format = "%(name)s -> %(levelname)s: %(message)s" - expected_log_pat = r"^([\w.]+) -> (\w+): (\d+)$" - message_num = 0 - - def setUp(self): - """Setup the default logging stream to an internal StringIO instance, - so that we can examine log output as we want.""" - self._threading_key = support.threading_setup() - - logger_dict = logging.getLogger().manager.loggerDict - logging._acquireLock() - try: - self.saved_handlers = logging._handlers.copy() - self.saved_handler_list = logging._handlerList[:] - self.saved_loggers = saved_loggers = logger_dict.copy() - self.saved_name_to_level = logging._nameToLevel.copy() - self.saved_level_to_name = logging._levelToName.copy() - self.logger_states = logger_states = {} - for name in saved_loggers: - logger_states[name] = getattr(saved_loggers[name], - 'disabled', None) - finally: - logging._releaseLock() - - # Set two unused loggers - self.logger1 = logging.getLogger("\xab\xd7\xbb") - self.logger2 = logging.getLogger("\u013f\u00d6\u0047") - - self.root_logger = logging.getLogger("") - self.original_logging_level = self.root_logger.getEffectiveLevel() - - self.stream = io.StringIO() - self.root_logger.setLevel(logging.DEBUG) - self.root_hdlr = logging.StreamHandler(self.stream) - self.root_formatter = logging.Formatter(self.log_format) - self.root_hdlr.setFormatter(self.root_formatter) - if self.logger1.hasHandlers(): - hlist = self.logger1.handlers + self.root_logger.handlers - raise AssertionError('Unexpected handlers: %s' % hlist) - if self.logger2.hasHandlers(): - hlist = self.logger2.handlers + self.root_logger.handlers - raise AssertionError('Unexpected handlers: %s' % hlist) - self.root_logger.addHandler(self.root_hdlr) - self.assertTrue(self.logger1.hasHandlers()) - self.assertTrue(self.logger2.hasHandlers()) - - def tearDown(self): - """Remove our logging stream, and restore the original logging - level.""" - self.stream.close() - self.root_logger.removeHandler(self.root_hdlr) - while self.root_logger.handlers: - h = self.root_logger.handlers[0] - self.root_logger.removeHandler(h) - h.close() - self.root_logger.setLevel(self.original_logging_level) - logging._acquireLock() - try: - logging._levelToName.clear() - logging._levelToName.update(self.saved_level_to_name) - logging._nameToLevel.clear() - logging._nameToLevel.update(self.saved_name_to_level) - logging._handlers.clear() - logging._handlers.update(self.saved_handlers) - logging._handlerList[:] = self.saved_handler_list - manager = logging.getLogger().manager - manager.disable = 0 - loggerDict = manager.loggerDict - loggerDict.clear() - loggerDict.update(self.saved_loggers) - logger_states = self.logger_states - for name in self.logger_states: - if logger_states[name] is not None: - self.saved_loggers[name].disabled = logger_states[name] - finally: - logging._releaseLock() - - self.doCleanups() - support.threading_cleanup(*self._threading_key) - - def assert_log_lines(self, expected_values, stream=None, pat=None): - """Match the collected log lines against the regular expression - self.expected_log_pat, and compare the extracted group values to - the expected_values list of tuples.""" - stream = stream or self.stream - pat = re.compile(pat or self.expected_log_pat) - actual_lines = stream.getvalue().splitlines() - self.assertEqual(len(actual_lines), len(expected_values)) - for actual, expected in zip(actual_lines, expected_values): - match = pat.search(actual) - if not match: - self.fail("Log line does not match expected pattern:\n" + - actual) - self.assertEqual(tuple(match.groups()), expected) - s = stream.read() - if s: - self.fail("Remaining output at end of log stream:\n" + s) - - def next_message(self): - """Generate a message consisting solely of an auto-incrementing - integer.""" - self.message_num += 1 - return "%d" % self.message_num - - - class BuiltinLevelsTest(BaseTest): - """Test builtin levels and their inheritance.""" - - def test_flat(self): - # Logging levels in a flat logger namespace. - m = self.next_message - - ERR = logging.getLogger("ERR") - ERR.setLevel(logging.ERROR) - INF = logging.LoggerAdapter(logging.getLogger("INF"), {}) - INF.setLevel(logging.INFO) - DEB = logging.getLogger("DEB") - DEB.setLevel(logging.DEBUG) - - # These should log. - ERR.log(logging.CRITICAL, m()) - ERR.error(m()) - - INF.log(logging.CRITICAL, m()) - INF.error(m()) - INF.warning(m()) - INF.info(m()) - - DEB.log(logging.CRITICAL, m()) - DEB.error(m()) - DEB.warning(m()) - DEB.info(m()) - DEB.debug(m()) - - # These should not log. - ERR.warning(m()) - ERR.info(m()) - ERR.debug(m()) - - INF.debug(m()) - - self.assert_log_lines([ - ('ERR', 'CRITICAL', '1'), - ('ERR', 'ERROR', '2'), - ('INF', 'CRITICAL', '3'), - ('INF', 'ERROR', '4'), - ('INF', 'WARNING', '5'), - ('INF', 'INFO', '6'), - ('DEB', 'CRITICAL', '7'), - ('DEB', 'ERROR', '8'), - ('DEB', 'WARNING', '9'), - ('DEB', 'INFO', '10'), - ('DEB', 'DEBUG', '11'), - ]) - - def test_nested_explicit(self): - # Logging levels in a nested namespace, all explicitly set. - m = self.next_message - - INF = logging.getLogger("INF") - INF.setLevel(logging.INFO) - INF_ERR = logging.getLogger("INF.ERR") - INF_ERR.setLevel(logging.ERROR) - - # These should log. - INF_ERR.log(logging.CRITICAL, m()) - INF_ERR.error(m()) - - # These should not log. - INF_ERR.warning(m()) - INF_ERR.info(m()) - INF_ERR.debug(m()) - - self.assert_log_lines([ - ('INF.ERR', 'CRITICAL', '1'), - ('INF.ERR', 'ERROR', '2'), - ]) - - def test_nested_inherited(self): - # Logging levels in a nested namespace, inherited from parent loggers. - m = self.next_message - - INF = logging.getLogger("INF") - INF.setLevel(logging.INFO) - INF_ERR = logging.getLogger("INF.ERR") - INF_ERR.setLevel(logging.ERROR) - INF_UNDEF = logging.getLogger("INF.UNDEF") - INF_ERR_UNDEF = logging.getLogger("INF.ERR.UNDEF") - UNDEF = logging.getLogger("UNDEF") - - # These should log. - INF_UNDEF.log(logging.CRITICAL, m()) - INF_UNDEF.error(m()) - INF_UNDEF.warning(m()) - INF_UNDEF.info(m()) - INF_ERR_UNDEF.log(logging.CRITICAL, m()) - INF_ERR_UNDEF.error(m()) - - # These should not log. - INF_UNDEF.debug(m()) - INF_ERR_UNDEF.warning(m()) - INF_ERR_UNDEF.info(m()) - INF_ERR_UNDEF.debug(m()) - - self.assert_log_lines([ - ('INF.UNDEF', 'CRITICAL', '1'), - ('INF.UNDEF', 'ERROR', '2'), - ('INF.UNDEF', 'WARNING', '3'), - ('INF.UNDEF', 'INFO', '4'), - ('INF.ERR.UNDEF', 'CRITICAL', '5'), - ('INF.ERR.UNDEF', 'ERROR', '6'), - ]) - - def test_nested_with_virtual_parent(self): - # Logging levels when some parent does not exist yet. - m = self.next_message - - INF = logging.getLogger("INF") - GRANDCHILD = logging.getLogger("INF.BADPARENT.UNDEF") - CHILD = logging.getLogger("INF.BADPARENT") - INF.setLevel(logging.INFO) - - # These should log. - GRANDCHILD.log(logging.FATAL, m()) - GRANDCHILD.info(m()) - CHILD.log(logging.FATAL, m()) - CHILD.info(m()) - - # These should not log. - GRANDCHILD.debug(m()) - CHILD.debug(m()) - - self.assert_log_lines([ - ('INF.BADPARENT.UNDEF', 'CRITICAL', '1'), - ('INF.BADPARENT.UNDEF', 'INFO', '2'), - ('INF.BADPARENT', 'CRITICAL', '3'), - ('INF.BADPARENT', 'INFO', '4'), - ]) - - def test_regression_22386(self): - """See issue #22386 for more information.""" - self.assertEqual(logging.getLevelName('INFO'), logging.INFO) - self.assertEqual(logging.getLevelName(logging.INFO), 'INFO') - - def test_issue27935(self): - fatal = logging.getLevelName('FATAL') - self.assertEqual(fatal, logging.FATAL) - - def test_regression_29220(self): - """See issue #29220 for more information.""" - logging.addLevelName(logging.INFO, '') - self.addCleanup(logging.addLevelName, logging.INFO, 'INFO') - self.assertEqual(logging.getLevelName(logging.INFO), '') - self.assertEqual(logging.getLevelName(logging.NOTSET), 'NOTSET') - self.assertEqual(logging.getLevelName('NOTSET'), logging.NOTSET) - - class BasicFilterTest(BaseTest): - - """Test the bundled Filter class.""" - - def test_filter(self): - # Only messages satisfying the specified criteria pass through the - # filter. - filter_ = logging.Filter("spam.eggs") - handler = self.root_logger.handlers[0] - try: - handler.addFilter(filter_) - spam = logging.getLogger("spam") - spam_eggs = logging.getLogger("spam.eggs") - spam_eggs_fish = logging.getLogger("spam.eggs.fish") - spam_bakedbeans = logging.getLogger("spam.bakedbeans") - - spam.info(self.next_message()) - spam_eggs.info(self.next_message()) # Good. - spam_eggs_fish.info(self.next_message()) # Good. - spam_bakedbeans.info(self.next_message()) - - self.assert_log_lines([ - ('spam.eggs', 'INFO', '2'), - ('spam.eggs.fish', 'INFO', '3'), - ]) - finally: - handler.removeFilter(filter_) - - def test_callable_filter(self): - # Only messages satisfying the specified criteria pass through the - # filter. - - def filterfunc(record): - parts = record.name.split('.') - prefix = '.'.join(parts[:2]) - return prefix == 'spam.eggs' - - handler = self.root_logger.handlers[0] - try: - handler.addFilter(filterfunc) - spam = logging.getLogger("spam") - spam_eggs = logging.getLogger("spam.eggs") - spam_eggs_fish = logging.getLogger("spam.eggs.fish") - spam_bakedbeans = logging.getLogger("spam.bakedbeans") - - spam.info(self.next_message()) - spam_eggs.info(self.next_message()) # Good. - spam_eggs_fish.info(self.next_message()) # Good. - spam_bakedbeans.info(self.next_message()) - - self.assert_log_lines([ - ('spam.eggs', 'INFO', '2'), - ('spam.eggs.fish', 'INFO', '3'), - ]) - finally: - handler.removeFilter(filterfunc) - - def test_empty_filter(self): - f = logging.Filter() - r = logging.makeLogRecord({'name': 'spam.eggs'}) - self.assertTrue(f.filter(r)) - - # - # First, we define our levels. There can be as many as you want - the only - # limitations are that they should be integers, the lowest should be > 0 and - # larger values mean less information being logged. If you need specific - # level values which do not fit into these limitations, you can use a - # mapping dictionary to convert between your application levels and the - # logging system. - # - SILENT = 120 - TACITURN = 119 - TERSE = 118 - EFFUSIVE = 117 - SOCIABLE = 116 - VERBOSE = 115 - TALKATIVE = 114 - GARRULOUS = 113 - CHATTERBOX = 112 - BORING = 111 - - LEVEL_RANGE = range(BORING, SILENT + 1) - - # - # Next, we define names for our levels. You don't need to do this - in which - # case the system will use "Level n" to denote the text for the level. - # - my_logging_levels = { - SILENT : 'Silent', - TACITURN : 'Taciturn', - TERSE : 'Terse', - EFFUSIVE : 'Effusive', - SOCIABLE : 'Sociable', - VERBOSE : 'Verbose', - TALKATIVE : 'Talkative', - GARRULOUS : 'Garrulous', - CHATTERBOX : 'Chatterbox', - BORING : 'Boring', - } - - class GarrulousFilter(logging.Filter): - - """A filter which blocks garrulous messages.""" - - def filter(self, record): - return record.levelno != GARRULOUS - - class VerySpecificFilter(logging.Filter): - - """A filter which blocks sociable and taciturn messages.""" - - def filter(self, record): - return record.levelno not in [SOCIABLE, TACITURN] - - - class CustomLevelsAndFiltersTest(BaseTest): - - """Test various filtering possibilities with custom logging levels.""" - - # Skip the logger name group. - expected_log_pat = r"^[\w.]+ -> (\w+): (\d+)$" - - def setUp(self): - BaseTest.setUp(self) - for k, v in my_logging_levels.items(): - logging.addLevelName(k, v) - - def log_at_all_levels(self, logger): - for lvl in LEVEL_RANGE: - logger.log(lvl, self.next_message()) - - def test_logger_filter(self): - # Filter at logger level. - self.root_logger.setLevel(VERBOSE) - # Levels >= 'Verbose' are good. - self.log_at_all_levels(self.root_logger) - self.assert_log_lines([ - ('Verbose', '5'), - ('Sociable', '6'), - ('Effusive', '7'), - ('Terse', '8'), - ('Taciturn', '9'), - ('Silent', '10'), - ]) - - def test_handler_filter(self): - # Filter at handler level. - self.root_logger.handlers[0].setLevel(SOCIABLE) - try: - # Levels >= 'Sociable' are good. - self.log_at_all_levels(self.root_logger) - self.assert_log_lines([ - ('Sociable', '6'), - ('Effusive', '7'), - ('Terse', '8'), - ('Taciturn', '9'), - ('Silent', '10'), - ]) - finally: - self.root_logger.handlers[0].setLevel(logging.NOTSET) - - def test_specific_filters(self): - # Set a specific filter object on the handler, and then add another - # filter object on the logger itself. - handler = self.root_logger.handlers[0] - specific_filter = None - garr = GarrulousFilter() - handler.addFilter(garr) - try: - self.log_at_all_levels(self.root_logger) - first_lines = [ - # Notice how 'Garrulous' is missing - ('Boring', '1'), - ('Chatterbox', '2'), - ('Talkative', '4'), - ('Verbose', '5'), - ('Sociable', '6'), - ('Effusive', '7'), - ('Terse', '8'), - ('Taciturn', '9'), - ('Silent', '10'), - ] - self.assert_log_lines(first_lines) - - specific_filter = VerySpecificFilter() - self.root_logger.addFilter(specific_filter) - self.log_at_all_levels(self.root_logger) - self.assert_log_lines(first_lines + [ - # Not only 'Garrulous' is still missing, but also 'Sociable' - # and 'Taciturn' - ('Boring', '11'), - ('Chatterbox', '12'), - ('Talkative', '14'), - ('Verbose', '15'), - ('Effusive', '17'), - ('Terse', '18'), - ('Silent', '20'), - ]) - finally: - if specific_filter: - self.root_logger.removeFilter(specific_filter) - handler.removeFilter(garr) - - - class HandlerTest(BaseTest): - def test_name(self): - h = logging.Handler() - h.name = 'generic' - self.assertEqual(h.name, 'generic') - h.name = 'anothergeneric' - self.assertEqual(h.name, 'anothergeneric') - self.assertRaises(NotImplementedError, h.emit, None) - - def test_builtin_handlers(self): - # We can't actually *use* too many handlers in the tests, - # but we can try instantiating them with various options - if sys.platform in ('linux', 'darwin'): - for existing in (True, False): - fd, fn = tempfile.mkstemp() - os.close(fd) - if not existing: - os.unlink(fn) - h = logging.handlers.WatchedFileHandler(fn, delay=True) - if existing: - dev, ino = h.dev, h.ino - self.assertEqual(dev, -1) - self.assertEqual(ino, -1) - r = logging.makeLogRecord({'msg': 'Test'}) - h.handle(r) - # Now remove the file. - os.unlink(fn) - self.assertFalse(os.path.exists(fn)) - # The next call should recreate the file. - h.handle(r) - self.assertTrue(os.path.exists(fn)) - else: - self.assertEqual(h.dev, -1) - self.assertEqual(h.ino, -1) - h.close() - if existing: - os.unlink(fn) - if sys.platform == 'darwin': - sockname = '/var/run/syslog' - else: - sockname = '/dev/log' - try: - h = logging.handlers.SysLogHandler(sockname) - self.assertEqual(h.facility, h.LOG_USER) - self.assertTrue(h.unixsocket) - h.close() - except OSError: # syslogd might not be available - pass - for method in ('GET', 'POST', 'PUT'): - if method == 'PUT': - self.assertRaises(ValueError, logging.handlers.HTTPHandler, - 'localhost', '/log', method) - else: - h = logging.handlers.HTTPHandler('localhost', '/log', method) - h.close() - h = logging.handlers.BufferingHandler(0) - r = logging.makeLogRecord({}) - self.assertTrue(h.shouldFlush(r)) - h.close() - h = logging.handlers.BufferingHandler(1) - self.assertFalse(h.shouldFlush(r)) - h.close() - - def test_path_objects(self): - """ - Test that Path objects are accepted as filename arguments to handlers. - - See Issue #27493. - """ - fd, fn = tempfile.mkstemp() - os.close(fd) - os.unlink(fn) - pfn = pathlib.Path(fn) - cases = ( - (logging.FileHandler, (pfn, 'w')), - (logging.handlers.RotatingFileHandler, (pfn, 'a')), - (logging.handlers.TimedRotatingFileHandler, (pfn, 'h')), - ) - if sys.platform in ('linux', 'darwin'): - cases += ((logging.handlers.WatchedFileHandler, (pfn, 'w')),) - for cls, args in cases: - h = cls(*args) - self.assertTrue(os.path.exists(fn)) - h.close() - os.unlink(fn) - - @unittest.skipIf(os.name == 'nt', 'WatchedFileHandler not appropriate for Windows.') - def test_race(self): - # Issue #14632 refers. - def remove_loop(fname, tries): - for _ in range(tries): - try: - os.unlink(fname) - self.deletion_time = time.time() - except OSError: - pass - time.sleep(0.004 * random.randint(0, 4)) - - del_count = 500 - log_count = 500 - - self.handle_time = None - self.deletion_time = None - - for delay in (False, True): - fd, fn = tempfile.mkstemp('.log', 'test_logging-3-') - os.close(fd) - remover = threading.Thread(target=remove_loop, args=(fn, del_count)) - remover.daemon = True - remover.start() - h = logging.handlers.WatchedFileHandler(fn, delay=delay) - f = logging.Formatter('%(asctime)s: %(levelname)s: %(message)s') - h.setFormatter(f) - try: - for _ in range(log_count): - time.sleep(0.005) - r = logging.makeLogRecord({'msg': 'testing' }) - try: - self.handle_time = time.time() - h.handle(r) - except Exception: - print('Deleted at %s, ' - 'opened at %s' % (self.deletion_time, - self.handle_time)) - raise - finally: - remover.join() - h.close() - if os.path.exists(fn): - os.unlink(fn) - - # The implementation relies on os.register_at_fork existing, but we test - # based on os.fork existing because that is what users and this test use. - # This helps ensure that when fork exists (the important concept) that the - # register_at_fork mechanism is also present and used. - @unittest.skipIf(not hasattr(os, 'fork'), 'Test requires os.fork().') - def test_post_fork_child_no_deadlock(self): - """Ensure child logging locks are not held; bpo-6721 & bpo-36533.""" - class _OurHandler(logging.Handler): - def __init__(self): - super().__init__() - self.sub_handler = logging.StreamHandler( - stream=open('/dev/null', 'wt')) - - def emit(self, record): - self.sub_handler.acquire() - try: - self.sub_handler.emit(record) - finally: - self.sub_handler.release() - - self.assertEqual(len(logging._handlers), 0) - refed_h = _OurHandler() - self.addCleanup(refed_h.sub_handler.stream.close) - refed_h.name = 'because we need at least one for this test' - self.assertGreater(len(logging._handlers), 0) - self.assertGreater(len(logging._at_fork_reinit_lock_weakset), 1) - test_logger = logging.getLogger('test_post_fork_child_no_deadlock') - test_logger.addHandler(refed_h) - test_logger.setLevel(logging.DEBUG) - - locks_held__ready_to_fork = threading.Event() - fork_happened__release_locks_and_end_thread = threading.Event() - - def lock_holder_thread_fn(): - logging._acquireLock() - try: - refed_h.acquire() - try: - # Tell the main thread to do the fork. - locks_held__ready_to_fork.set() - - # If the deadlock bug exists, the fork will happen - # without dealing with the locks we hold, deadlocking - # the child. - - # Wait for a successful fork or an unreasonable amount of - # time before releasing our locks. To avoid a timing based - # test we'd need communication from os.fork() as to when it - # has actually happened. Given this is a regression test - # for a fixed issue, potentially less reliably detecting - # regression via timing is acceptable for simplicity. - # The test will always take at least this long. :( - fork_happened__release_locks_and_end_thread.wait(0.5) - finally: - refed_h.release() - finally: - logging._releaseLock() - - lock_holder_thread = threading.Thread( - target=lock_holder_thread_fn, - name='test_post_fork_child_no_deadlock lock holder') - lock_holder_thread.start() - - locks_held__ready_to_fork.wait() - pid = os.fork() - if pid == 0: # Child. - try: - test_logger.info(r'Child process did not deadlock. \o/') - finally: - os._exit(0) - else: # Parent. - test_logger.info(r'Parent process returned from fork. \o/') - fork_happened__release_locks_and_end_thread.set() - lock_holder_thread.join() - start_time = time.monotonic() - while True: - test_logger.debug('Waiting for child process.') - waited_pid, status = os.waitpid(pid, os.WNOHANG) - if waited_pid == pid: - break # child process exited. - if time.monotonic() - start_time > 7: - break # so long? implies child deadlock. - time.sleep(0.05) - test_logger.debug('Done waiting.') - if waited_pid != pid: - os.kill(pid, signal.SIGKILL) - waited_pid, status = os.waitpid(pid, 0) - self.fail("child process deadlocked.") - self.assertEqual(status, 0, msg="child process error") - - - class BadStream(object): - def write(self, data): - raise RuntimeError('deliberate mistake') - - class TestStreamHandler(logging.StreamHandler): - def handleError(self, record): - self.error_record = record - - class StreamWithIntName(object): - level = logging.NOTSET - name = 2 - - class StreamHandlerTest(BaseTest): - def test_error_handling(self): - h = TestStreamHandler(BadStream()) - r = logging.makeLogRecord({}) - old_raise = logging.raiseExceptions - - try: - h.handle(r) - self.assertIs(h.error_record, r) - - h = logging.StreamHandler(BadStream()) - with support.captured_stderr() as stderr: - h.handle(r) - msg = '\nRuntimeError: deliberate mistake\n' - self.assertIn(msg, stderr.getvalue()) - - logging.raiseExceptions = False - with support.captured_stderr() as stderr: - h.handle(r) - self.assertEqual('', stderr.getvalue()) - finally: - logging.raiseExceptions = old_raise - - def test_stream_setting(self): - """ - Test setting the handler's stream - """ - h = logging.StreamHandler() - stream = io.StringIO() - old = h.setStream(stream) - self.assertIs(old, sys.stderr) - actual = h.setStream(old) - self.assertIs(actual, stream) - # test that setting to existing value returns None - actual = h.setStream(old) - self.assertIsNone(actual) - - def test_can_represent_stream_with_int_name(self): - h = logging.StreamHandler(StreamWithIntName()) - self.assertEqual(repr(h), '') - - # -- The following section could be moved into a server_helper.py module - # -- if it proves to be of wider utility than just test_logging - - class TestSMTPServer(smtpd.SMTPServer): - """ - This class implements a test SMTP server. - - :param addr: A (host, port) tuple which the server listens on. - You can specify a port value of zero: the server's - *port* attribute will hold the actual port number - used, which can be used in client connections. - :param handler: A callable which will be called to process - incoming messages. The handler will be passed - the client address tuple, who the message is from, - a list of recipients and the message data. - :param poll_interval: The interval, in seconds, used in the underlying - :func:`select` or :func:`poll` call by - :func:`asyncore.loop`. - :param sockmap: A dictionary which will be used to hold - :class:`asyncore.dispatcher` instances used by - :func:`asyncore.loop`. This avoids changing the - :mod:`asyncore` module's global state. - """ - - def __init__(self, addr, handler, poll_interval, sockmap): - smtpd.SMTPServer.__init__(self, addr, None, map=sockmap, - decode_data=True) - self.port = self.socket.getsockname()[1] - self._handler = handler - self._thread = None - self._quit = False - self.poll_interval = poll_interval - - def process_message(self, peer, mailfrom, rcpttos, data): - """ - Delegates to the handler passed in to the server's constructor. - - Typically, this will be a test case method. - :param peer: The client (host, port) tuple. - :param mailfrom: The address of the sender. - :param rcpttos: The addresses of the recipients. - :param data: The message. - """ - self._handler(peer, mailfrom, rcpttos, data) - - def start(self): - """ - Start the server running on a separate daemon thread. - """ - self._thread = t = threading.Thread(target=self.serve_forever, - args=(self.poll_interval,)) - t.setDaemon(True) - t.start() - - def serve_forever(self, poll_interval): - """ - Run the :mod:`asyncore` loop until normal termination - conditions arise. - :param poll_interval: The interval, in seconds, used in the underlying - :func:`select` or :func:`poll` call by - :func:`asyncore.loop`. - """ - while not self._quit: - asyncore.loop(poll_interval, map=self._map, count=1) - - def stop(self, timeout=None): - """ - Stop the thread by closing the server instance. - Wait for the server thread to terminate. - - :param timeout: How long to wait for the server thread - to terminate. - """ - self._quit = True - support.join_thread(self._thread, timeout) - self._thread = None - self.close() - asyncore.close_all(map=self._map, ignore_all=True) - - - class ControlMixin(object): - """ - This mixin is used to start a server on a separate thread, and - shut it down programmatically. Request handling is simplified - instead - of needing to derive a suitable RequestHandler subclass, you just - provide a callable which will be passed each received request to be - processed. - - :param handler: A handler callable which will be called with a - single parameter - the request - in order to - process the request. This handler is called on the - server thread, effectively meaning that requests are - processed serially. While not quite Web scale ;-), - this should be fine for testing applications. - :param poll_interval: The polling interval in seconds. - """ - def __init__(self, handler, poll_interval): - self._thread = None - self.poll_interval = poll_interval - self._handler = handler - self.ready = threading.Event() - - def start(self): - """ - Create a daemon thread to run the server, and start it. - """ - self._thread = t = threading.Thread(target=self.serve_forever, - args=(self.poll_interval,)) - t.setDaemon(True) - t.start() - - def serve_forever(self, poll_interval): - """ - Run the server. Set the ready flag before entering the - service loop. - """ - self.ready.set() - super(ControlMixin, self).serve_forever(poll_interval) - - def stop(self, timeout=None): - """ - Tell the server thread to stop, and wait for it to do so. - - :param timeout: How long to wait for the server thread - to terminate. - """ - self.shutdown() - if self._thread is not None: - support.join_thread(self._thread, timeout) - self._thread = None - self.server_close() - self.ready.clear() - - class TestHTTPServer(ControlMixin, HTTPServer): - """ - An HTTP server which is controllable using :class:`ControlMixin`. - - :param addr: A tuple with the IP address and port to listen on. - :param handler: A handler callable which will be called with a - single parameter - the request - in order to - process the request. - :param poll_interval: The polling interval in seconds. - :param log: Pass ``True`` to enable log messages. - """ - def __init__(self, addr, handler, poll_interval=0.5, - log=False, sslctx=None): - class DelegatingHTTPRequestHandler(BaseHTTPRequestHandler): - def __getattr__(self, name, default=None): - if name.startswith('do_'): - return self.process_request - raise AttributeError(name) - - def process_request(self): - self.server._handler(self) - - def log_message(self, format, *args): - if log: - super(DelegatingHTTPRequestHandler, - self).log_message(format, *args) - HTTPServer.__init__(self, addr, DelegatingHTTPRequestHandler) - ControlMixin.__init__(self, handler, poll_interval) - self.sslctx = sslctx - - def get_request(self): - try: - sock, addr = self.socket.accept() - if self.sslctx: - sock = self.sslctx.wrap_socket(sock, server_side=True) - except OSError as e: - # socket errors are silenced by the caller, print them here - sys.stderr.write("Got an error:\n%s\n" % e) - raise - return sock, addr - - class TestTCPServer(ControlMixin, ThreadingTCPServer): - """ - A TCP server which is controllable using :class:`ControlMixin`. - - :param addr: A tuple with the IP address and port to listen on. - :param handler: A handler callable which will be called with a single - parameter - the request - in order to process the request. - :param poll_interval: The polling interval in seconds. - :bind_and_activate: If True (the default), binds the server and starts it - listening. If False, you need to call - :meth:`server_bind` and :meth:`server_activate` at - some later time before calling :meth:`start`, so that - the server will set up the socket and listen on it. - """ - - allow_reuse_address = True - - def __init__(self, addr, handler, poll_interval=0.5, - bind_and_activate=True): - class DelegatingTCPRequestHandler(StreamRequestHandler): - - def handle(self): - self.server._handler(self) - ThreadingTCPServer.__init__(self, addr, DelegatingTCPRequestHandler, - bind_and_activate) - ControlMixin.__init__(self, handler, poll_interval) - - def server_bind(self): - super(TestTCPServer, self).server_bind() - self.port = self.socket.getsockname()[1] - - class TestUDPServer(ControlMixin, ThreadingUDPServer): - """ - A UDP server which is controllable using :class:`ControlMixin`. - - :param addr: A tuple with the IP address and port to listen on. - :param handler: A handler callable which will be called with a - single parameter - the request - in order to - process the request. - :param poll_interval: The polling interval for shutdown requests, - in seconds. - :bind_and_activate: If True (the default), binds the server and - starts it listening. If False, you need to - call :meth:`server_bind` and - :meth:`server_activate` at some later time - before calling :meth:`start`, so that the server will - set up the socket and listen on it. - """ - def __init__(self, addr, handler, poll_interval=0.5, - bind_and_activate=True): - class DelegatingUDPRequestHandler(DatagramRequestHandler): - - def handle(self): - self.server._handler(self) - - def finish(self): - data = self.wfile.getvalue() - if data: - try: - super(DelegatingUDPRequestHandler, self).finish() - except OSError: - if not self.server._closed: - raise - - ThreadingUDPServer.__init__(self, addr, - DelegatingUDPRequestHandler, - bind_and_activate) - ControlMixin.__init__(self, handler, poll_interval) - self._closed = False - - def server_bind(self): - super(TestUDPServer, self).server_bind() - self.port = self.socket.getsockname()[1] - - def server_close(self): - super(TestUDPServer, self).server_close() - self._closed = True - - if hasattr(socket, "AF_UNIX"): - class TestUnixStreamServer(TestTCPServer): - address_family = socket.AF_UNIX - - class TestUnixDatagramServer(TestUDPServer): - address_family = socket.AF_UNIX - - # - end of server_helper section - - class SMTPHandlerTest(BaseTest): - # bpo-14314, bpo-19665, bpo-34092: don't wait forever, timeout of 1 minute - TIMEOUT = 60.0 - - def test_basic(self): - sockmap = {} - server = TestSMTPServer((support.HOST, 0), self.process_message, 0.001, - sockmap) - server.start() - addr = (support.HOST, server.port) - h = logging.handlers.SMTPHandler(addr, 'me', 'you', 'Log', - timeout=self.TIMEOUT) - self.assertEqual(h.toaddrs, ['you']) - self.messages = [] - r = logging.makeLogRecord({'msg': 'Hello \u2713'}) - self.handled = threading.Event() - h.handle(r) - self.handled.wait(self.TIMEOUT) - server.stop() - self.assertTrue(self.handled.is_set()) - self.assertEqual(len(self.messages), 1) - peer, mailfrom, rcpttos, data = self.messages[0] - self.assertEqual(mailfrom, 'me') - self.assertEqual(rcpttos, ['you']) - self.assertIn('\nSubject: Log\n', data) - self.assertTrue(data.endswith('\n\nHello \u2713')) - h.close() - - def process_message(self, *args): - self.messages.append(args) - self.handled.set() - - class MemoryHandlerTest(BaseTest): - - """Tests for the MemoryHandler.""" - - # Do not bother with a logger name group. - expected_log_pat = r"^[\w.]+ -> (\w+): (\d+)$" - - def setUp(self): - BaseTest.setUp(self) - self.mem_hdlr = logging.handlers.MemoryHandler(10, logging.WARNING, - self.root_hdlr) - self.mem_logger = logging.getLogger('mem') - self.mem_logger.propagate = 0 - self.mem_logger.addHandler(self.mem_hdlr) - - def tearDown(self): - self.mem_hdlr.close() - BaseTest.tearDown(self) - - def test_flush(self): - # The memory handler flushes to its target handler based on specific - # criteria (message count and message level). - self.mem_logger.debug(self.next_message()) - self.assert_log_lines([]) - self.mem_logger.info(self.next_message()) - self.assert_log_lines([]) - # This will flush because the level is >= logging.WARNING - self.mem_logger.warning(self.next_message()) - lines = [ - ('DEBUG', '1'), - ('INFO', '2'), - ('WARNING', '3'), - ] - self.assert_log_lines(lines) - for n in (4, 14): - for i in range(9): - self.mem_logger.debug(self.next_message()) - self.assert_log_lines(lines) - # This will flush because it's the 10th message since the last - # flush. - self.mem_logger.debug(self.next_message()) - lines = lines + [('DEBUG', str(i)) for i in range(n, n + 10)] - self.assert_log_lines(lines) - - self.mem_logger.debug(self.next_message()) - self.assert_log_lines(lines) - - def test_flush_on_close(self): - """ - Test that the flush-on-close configuration works as expected. - """ - self.mem_logger.debug(self.next_message()) - self.assert_log_lines([]) - self.mem_logger.info(self.next_message()) - self.assert_log_lines([]) - self.mem_logger.removeHandler(self.mem_hdlr) - # Default behaviour is to flush on close. Check that it happens. - self.mem_hdlr.close() - lines = [ - ('DEBUG', '1'), - ('INFO', '2'), - ] - self.assert_log_lines(lines) - # Now configure for flushing not to be done on close. - self.mem_hdlr = logging.handlers.MemoryHandler(10, logging.WARNING, - self.root_hdlr, - False) - self.mem_logger.addHandler(self.mem_hdlr) - self.mem_logger.debug(self.next_message()) - self.assert_log_lines(lines) # no change - self.mem_logger.info(self.next_message()) - self.assert_log_lines(lines) # no change - self.mem_logger.removeHandler(self.mem_hdlr) - self.mem_hdlr.close() - # assert that no new lines have been added - self.assert_log_lines(lines) # no change - - def test_race_between_set_target_and_flush(self): - class MockRaceConditionHandler: - def __init__(self, mem_hdlr): - self.mem_hdlr = mem_hdlr - self.threads = [] - - def removeTarget(self): - self.mem_hdlr.setTarget(None) - - def handle(self, msg): - thread = threading.Thread(target=self.removeTarget) - self.threads.append(thread) - thread.start() - - target = MockRaceConditionHandler(self.mem_hdlr) - try: - self.mem_hdlr.setTarget(target) - - for _ in range(10): - time.sleep(0.005) - self.mem_logger.info("not flushed") - self.mem_logger.warning("flushed") - finally: - for thread in target.threads: - support.join_thread(thread) - - - class ExceptionFormatter(logging.Formatter): - """A special exception formatter.""" - def formatException(self, ei): - return "Got a [%s]" % ei[0].__name__ - - - class ConfigFileTest(BaseTest): - - """Reading logging config from a .ini-style config file.""" - - check_no_resource_warning = support.check_no_resource_warning - expected_log_pat = r"^(\w+) \+\+ (\w+)$" - - # config0 is a standard configuration. - config0 = """ - [loggers] - keys=root - - [handlers] - keys=hand1 - - [formatters] - keys=form1 - - [logger_root] - level=WARNING - handlers=hand1 - - [handler_hand1] - class=StreamHandler - level=NOTSET - formatter=form1 - args=(sys.stdout,) - - [formatter_form1] - format=%(levelname)s ++ %(message)s - datefmt= - """ - - # config1 adds a little to the standard configuration. - config1 = """ - [loggers] - keys=root,parser - - [handlers] - keys=hand1 - - [formatters] - keys=form1 - - [logger_root] - level=WARNING - handlers= - - [logger_parser] - level=DEBUG - handlers=hand1 - propagate=1 - qualname=compiler.parser - - [handler_hand1] - class=StreamHandler - level=NOTSET - formatter=form1 - args=(sys.stdout,) - - [formatter_form1] - format=%(levelname)s ++ %(message)s - datefmt= - """ - - # config1a moves the handler to the root. - config1a = """ - [loggers] - keys=root,parser - - [handlers] - keys=hand1 - - [formatters] - keys=form1 - - [logger_root] - level=WARNING - handlers=hand1 - - [logger_parser] - level=DEBUG - handlers= - propagate=1 - qualname=compiler.parser - - [handler_hand1] - class=StreamHandler - level=NOTSET - formatter=form1 - args=(sys.stdout,) - - [formatter_form1] - format=%(levelname)s ++ %(message)s - datefmt= - """ - - # config2 has a subtle configuration error that should be reported - config2 = config1.replace("sys.stdout", "sys.stbout") - - # config3 has a less subtle configuration error - config3 = config1.replace("formatter=form1", "formatter=misspelled_name") - - # config4 specifies a custom formatter class to be loaded - config4 = """ - [loggers] - keys=root - - [handlers] - keys=hand1 - - [formatters] - keys=form1 - - [logger_root] - level=NOTSET - handlers=hand1 - - [handler_hand1] - class=StreamHandler - level=NOTSET - formatter=form1 - args=(sys.stdout,) - - [formatter_form1] - class=""" + __name__ + """.ExceptionFormatter - format=%(levelname)s:%(name)s:%(message)s - datefmt= - """ - - # config5 specifies a custom handler class to be loaded - config5 = config1.replace('class=StreamHandler', 'class=logging.StreamHandler') - - # config6 uses ', ' delimiters in the handlers and formatters sections - config6 = """ - [loggers] - keys=root,parser - - [handlers] - keys=hand1, hand2 - - [formatters] - keys=form1, form2 - - [logger_root] - level=WARNING - handlers= - - [logger_parser] - level=DEBUG - handlers=hand1 - propagate=1 - qualname=compiler.parser - - [handler_hand1] - class=StreamHandler - level=NOTSET - formatter=form1 - args=(sys.stdout,) - - [handler_hand2] - class=StreamHandler - level=NOTSET - formatter=form1 - args=(sys.stderr,) - - [formatter_form1] - format=%(levelname)s ++ %(message)s - datefmt= - - [formatter_form2] - format=%(message)s - datefmt= - """ - - # config7 adds a compiler logger, and uses kwargs instead of args. - config7 = """ - [loggers] - keys=root,parser,compiler - - [handlers] - keys=hand1 - - [formatters] - keys=form1 - - [logger_root] - level=WARNING - handlers=hand1 - - [logger_compiler] - level=DEBUG - handlers= - propagate=1 - qualname=compiler - - [logger_parser] - level=DEBUG - handlers= - propagate=1 - qualname=compiler.parser - - [handler_hand1] - class=StreamHandler - level=NOTSET - formatter=form1 - kwargs={'stream': sys.stdout,} - - [formatter_form1] - format=%(levelname)s ++ %(message)s - datefmt= - """ - - # config 8, check for resource warning - config8 = r""" - [loggers] - keys=root - - [handlers] - keys=file - - [formatters] - keys= - - [logger_root] - level=DEBUG - handlers=file - - [handler_file] - class=FileHandler - level=DEBUG - args=("{tempfile}",) - """ - - disable_test = """ - [loggers] - keys=root - - [handlers] - keys=screen - - [formatters] - keys= - - [logger_root] - level=DEBUG - handlers=screen - - [handler_screen] - level=DEBUG - class=StreamHandler - args=(sys.stdout,) - formatter= - """ - - def apply_config(self, conf, **kwargs): - file = io.StringIO(textwrap.dedent(conf)) - logging.config.fileConfig(file, **kwargs) - - def test_config0_ok(self): - # A simple config file which overrides the default settings. - with support.captured_stdout() as output: - self.apply_config(self.config0) - logger = logging.getLogger() - # Won't output anything - logger.info(self.next_message()) - # Outputs a message - logger.error(self.next_message()) - self.assert_log_lines([ - ('ERROR', '2'), - ], stream=output) - # Original logger output is empty. - self.assert_log_lines([]) - - def test_config0_using_cp_ok(self): - # A simple config file which overrides the default settings. - with support.captured_stdout() as output: - file = io.StringIO(textwrap.dedent(self.config0)) - cp = configparser.ConfigParser() - cp.read_file(file) - logging.config.fileConfig(cp) - logger = logging.getLogger() - # Won't output anything - logger.info(self.next_message()) - # Outputs a message - logger.error(self.next_message()) - self.assert_log_lines([ - ('ERROR', '2'), - ], stream=output) - # Original logger output is empty. - self.assert_log_lines([]) - - def test_config1_ok(self, config=config1): - # A config file defining a sub-parser as well. - with support.captured_stdout() as output: - self.apply_config(config) - logger = logging.getLogger("compiler.parser") - # Both will output a message - logger.info(self.next_message()) - logger.error(self.next_message()) - self.assert_log_lines([ - ('INFO', '1'), - ('ERROR', '2'), - ], stream=output) - # Original logger output is empty. - self.assert_log_lines([]) - - def test_config2_failure(self): - # A simple config file which overrides the default settings. - self.assertRaises(Exception, self.apply_config, self.config2) - - def test_config3_failure(self): - # A simple config file which overrides the default settings. - self.assertRaises(Exception, self.apply_config, self.config3) - - def test_config4_ok(self): - # A config file specifying a custom formatter class. - with support.captured_stdout() as output: - self.apply_config(self.config4) - logger = logging.getLogger() - try: - raise RuntimeError() - except RuntimeError: - logging.exception("just testing") - sys.stdout.seek(0) - self.assertEqual(output.getvalue(), - "ERROR:root:just testing\nGot a [RuntimeError]\n") - # Original logger output is empty - self.assert_log_lines([]) - - def test_config5_ok(self): - self.test_config1_ok(config=self.config5) - - def test_config6_ok(self): - self.test_config1_ok(config=self.config6) - - def test_config7_ok(self): - with support.captured_stdout() as output: - self.apply_config(self.config1a) - logger = logging.getLogger("compiler.parser") - # See issue #11424. compiler-hyphenated sorts - # between compiler and compiler.xyz and this - # was preventing compiler.xyz from being included - # in the child loggers of compiler because of an - # overzealous loop termination condition. - hyphenated = logging.getLogger('compiler-hyphenated') - # All will output a message - logger.info(self.next_message()) - logger.error(self.next_message()) - hyphenated.critical(self.next_message()) - self.assert_log_lines([ - ('INFO', '1'), - ('ERROR', '2'), - ('CRITICAL', '3'), - ], stream=output) - # Original logger output is empty. - self.assert_log_lines([]) - with support.captured_stdout() as output: - self.apply_config(self.config7) - logger = logging.getLogger("compiler.parser") - self.assertFalse(logger.disabled) - # Both will output a message - logger.info(self.next_message()) - logger.error(self.next_message()) - logger = logging.getLogger("compiler.lexer") - # Both will output a message - logger.info(self.next_message()) - logger.error(self.next_message()) - # Will not appear - hyphenated.critical(self.next_message()) - self.assert_log_lines([ - ('INFO', '4'), - ('ERROR', '5'), - ('INFO', '6'), - ('ERROR', '7'), - ], stream=output) - # Original logger output is empty. - self.assert_log_lines([]) - - def test_config8_ok(self): - - def cleanup(h1, fn): - h1.close() - os.remove(fn) - - with self.check_no_resource_warning(): - fd, fn = tempfile.mkstemp(".log", "test_logging-X-") - os.close(fd) - - # Replace single backslash with double backslash in windows - # to avoid unicode error during string formatting - if os.name == "nt": - fn = fn.replace("\\", "\\\\") - - config8 = self.config8.format(tempfile=fn) - - self.apply_config(config8) - self.apply_config(config8) - - handler = logging.root.handlers[0] - self.addCleanup(cleanup, handler, fn) - - def test_logger_disabling(self): - self.apply_config(self.disable_test) - logger = logging.getLogger('some_pristine_logger') - self.assertFalse(logger.disabled) - self.apply_config(self.disable_test) - self.assertTrue(logger.disabled) - self.apply_config(self.disable_test, disable_existing_loggers=False) - self.assertFalse(logger.disabled) - - def test_defaults_do_no_interpolation(self): - """bpo-33802 defaults should not get interpolated""" - ini = textwrap.dedent(""" - [formatters] - keys=default - - [formatter_default] - - [handlers] - keys=console - - [handler_console] - class=logging.StreamHandler - args=tuple() - - [loggers] - keys=root - - [logger_root] - formatter=default - handlers=console - """).strip() - fd, fn = tempfile.mkstemp(prefix='test_logging_', suffix='.ini') - try: - os.write(fd, ini.encode('ascii')) - os.close(fd) - logging.config.fileConfig( - fn, - defaults=dict( - version=1, - disable_existing_loggers=False, - formatters={ - "generic": { - "format": "%(asctime)s [%(process)d] [%(levelname)s] %(message)s", - "datefmt": "[%Y-%m-%d %H:%M:%S %z]", - "class": "logging.Formatter" - }, - }, - ) - ) - finally: - os.unlink(fn) - - - class SocketHandlerTest(BaseTest): - - """Test for SocketHandler objects.""" - - server_class = TestTCPServer - address = ('localhost', 0) - - def setUp(self): - """Set up a TCP server to receive log messages, and a SocketHandler - pointing to that server's address and port.""" - BaseTest.setUp(self) - # Issue #29177: deal with errors that happen during setup - self.server = self.sock_hdlr = self.server_exception = None - try: - self.server = server = self.server_class(self.address, - self.handle_socket, 0.01) - server.start() - # Uncomment next line to test error recovery in setUp() - # raise OSError('dummy error raised') - except OSError as e: - self.server_exception = e - return - server.ready.wait() - hcls = logging.handlers.SocketHandler - if isinstance(server.server_address, tuple): - self.sock_hdlr = hcls('localhost', server.port) - else: - self.sock_hdlr = hcls(server.server_address, None) - self.log_output = '' - self.root_logger.removeHandler(self.root_logger.handlers[0]) - self.root_logger.addHandler(self.sock_hdlr) - self.handled = threading.Semaphore(0) - - def tearDown(self): - """Shutdown the TCP server.""" - try: - if self.sock_hdlr: - self.root_logger.removeHandler(self.sock_hdlr) - self.sock_hdlr.close() - if self.server: - self.server.stop(2.0) - finally: - BaseTest.tearDown(self) - - def handle_socket(self, request): - conn = request.connection - while True: - chunk = conn.recv(4) - if len(chunk) < 4: - break - slen = struct.unpack(">L", chunk)[0] - chunk = conn.recv(slen) - while len(chunk) < slen: - chunk = chunk + conn.recv(slen - len(chunk)) - obj = pickle.loads(chunk) - record = logging.makeLogRecord(obj) - self.log_output += record.msg + '\n' - self.handled.release() - - def test_output(self): - # The log message sent to the SocketHandler is properly received. - if self.server_exception: - self.skipTest(self.server_exception) - logger = logging.getLogger("tcp") - logger.error("spam") - self.handled.acquire() - logger.debug("eggs") - self.handled.acquire() - self.assertEqual(self.log_output, "spam\neggs\n") - - def test_noserver(self): - if self.server_exception: - self.skipTest(self.server_exception) - # Avoid timing-related failures due to SocketHandler's own hard-wired - # one-second timeout on socket.create_connection() (issue #16264). - self.sock_hdlr.retryStart = 2.5 - # Kill the server - self.server.stop(2.0) - # The logging call should try to connect, which should fail - try: - raise RuntimeError('Deliberate mistake') - except RuntimeError: - self.root_logger.exception('Never sent') - self.root_logger.error('Never sent, either') - now = time.time() - self.assertGreater(self.sock_hdlr.retryTime, now) - time.sleep(self.sock_hdlr.retryTime - now + 0.001) - self.root_logger.error('Nor this') - - def _get_temp_domain_socket(): - fd, fn = tempfile.mkstemp(prefix='test_logging_', suffix='.sock') - os.close(fd) - # just need a name - file can't be present, or we'll get an - # 'address already in use' error. - os.remove(fn) - return fn - - @unittest.skipUnless(hasattr(socket, "AF_UNIX"), "Unix sockets required") - class UnixSocketHandlerTest(SocketHandlerTest): - - """Test for SocketHandler with unix sockets.""" - - if hasattr(socket, "AF_UNIX"): - server_class = TestUnixStreamServer - - def setUp(self): - # override the definition in the base class - self.address = _get_temp_domain_socket() - SocketHandlerTest.setUp(self) - - def tearDown(self): - SocketHandlerTest.tearDown(self) - support.unlink(self.address) - - class DatagramHandlerTest(BaseTest): - - """Test for DatagramHandler.""" - - server_class = TestUDPServer - address = ('localhost', 0) - - def setUp(self): - """Set up a UDP server to receive log messages, and a DatagramHandler - pointing to that server's address and port.""" - BaseTest.setUp(self) - # Issue #29177: deal with errors that happen during setup - self.server = self.sock_hdlr = self.server_exception = None - try: - self.server = server = self.server_class(self.address, - self.handle_datagram, 0.01) - server.start() - # Uncomment next line to test error recovery in setUp() - # raise OSError('dummy error raised') - except OSError as e: - self.server_exception = e - return - server.ready.wait() - hcls = logging.handlers.DatagramHandler - if isinstance(server.server_address, tuple): - self.sock_hdlr = hcls('localhost', server.port) - else: - self.sock_hdlr = hcls(server.server_address, None) - self.log_output = '' - self.root_logger.removeHandler(self.root_logger.handlers[0]) - self.root_logger.addHandler(self.sock_hdlr) - self.handled = threading.Event() - - def tearDown(self): - """Shutdown the UDP server.""" - try: - if self.server: - self.server.stop(2.0) - if self.sock_hdlr: - self.root_logger.removeHandler(self.sock_hdlr) - self.sock_hdlr.close() - finally: - BaseTest.tearDown(self) - - def handle_datagram(self, request): - slen = struct.pack('>L', 0) # length of prefix - packet = request.packet[len(slen):] - obj = pickle.loads(packet) - record = logging.makeLogRecord(obj) - self.log_output += record.msg + '\n' - self.handled.set() - - def test_output(self): - # The log message sent to the DatagramHandler is properly received. - if self.server_exception: - self.skipTest(self.server_exception) - logger = logging.getLogger("udp") - logger.error("spam") - self.handled.wait() - self.handled.clear() - logger.error("eggs") - self.handled.wait() - self.assertEqual(self.log_output, "spam\neggs\n") - - @unittest.skipUnless(hasattr(socket, "AF_UNIX"), "Unix sockets required") - class UnixDatagramHandlerTest(DatagramHandlerTest): - - """Test for DatagramHandler using Unix sockets.""" - - if hasattr(socket, "AF_UNIX"): - server_class = TestUnixDatagramServer - - def setUp(self): - # override the definition in the base class - self.address = _get_temp_domain_socket() - DatagramHandlerTest.setUp(self) - - def tearDown(self): - DatagramHandlerTest.tearDown(self) - support.unlink(self.address) - - class SysLogHandlerTest(BaseTest): - - """Test for SysLogHandler using UDP.""" - - server_class = TestUDPServer - address = ('localhost', 0) - - def setUp(self): - """Set up a UDP server to receive log messages, and a SysLogHandler - pointing to that server's address and port.""" - BaseTest.setUp(self) - # Issue #29177: deal with errors that happen during setup - self.server = self.sl_hdlr = self.server_exception = None - try: - self.server = server = self.server_class(self.address, - self.handle_datagram, 0.01) - server.start() - # Uncomment next line to test error recovery in setUp() - # raise OSError('dummy error raised') - except OSError as e: - self.server_exception = e - return - server.ready.wait() - hcls = logging.handlers.SysLogHandler - if isinstance(server.server_address, tuple): - self.sl_hdlr = hcls((server.server_address[0], server.port)) - else: - self.sl_hdlr = hcls(server.server_address) - self.log_output = '' - self.root_logger.removeHandler(self.root_logger.handlers[0]) - self.root_logger.addHandler(self.sl_hdlr) - self.handled = threading.Event() - - def tearDown(self): - """Shutdown the server.""" - try: - if self.server: - self.server.stop(2.0) - if self.sl_hdlr: - self.root_logger.removeHandler(self.sl_hdlr) - self.sl_hdlr.close() - finally: - BaseTest.tearDown(self) - - def handle_datagram(self, request): - self.log_output = request.packet - self.handled.set() - - def test_output(self): - if self.server_exception: - self.skipTest(self.server_exception) - # The log message sent to the SysLogHandler is properly received. - logger = logging.getLogger("slh") - logger.error("sp\xe4m") - self.handled.wait() - self.assertEqual(self.log_output, b'<11>sp\xc3\xa4m\x00') - self.handled.clear() - self.sl_hdlr.append_nul = False - logger.error("sp\xe4m") - self.handled.wait() - self.assertEqual(self.log_output, b'<11>sp\xc3\xa4m') - self.handled.clear() - self.sl_hdlr.ident = "h\xe4m-" - logger.error("sp\xe4m") - self.handled.wait() - self.assertEqual(self.log_output, b'<11>h\xc3\xa4m-sp\xc3\xa4m') - - @unittest.skipUnless(hasattr(socket, "AF_UNIX"), "Unix sockets required") - class UnixSysLogHandlerTest(SysLogHandlerTest): - - """Test for SysLogHandler with Unix sockets.""" - - if hasattr(socket, "AF_UNIX"): - server_class = TestUnixDatagramServer - - def setUp(self): - # override the definition in the base class - self.address = _get_temp_domain_socket() - SysLogHandlerTest.setUp(self) - - def tearDown(self): - SysLogHandlerTest.tearDown(self) - support.unlink(self.address) - - @unittest.skipUnless(support.IPV6_ENABLED, - 'IPv6 support required for this test.') - class IPv6SysLogHandlerTest(SysLogHandlerTest): - - """Test for SysLogHandler with IPv6 host.""" - - server_class = TestUDPServer - address = ('::1', 0) - - def setUp(self): - self.server_class.address_family = socket.AF_INET6 - super(IPv6SysLogHandlerTest, self).setUp() - - def tearDown(self): - self.server_class.address_family = socket.AF_INET - super(IPv6SysLogHandlerTest, self).tearDown() - - class HTTPHandlerTest(BaseTest): - """Test for HTTPHandler.""" - - def setUp(self): - """Set up an HTTP server to receive log messages, and a HTTPHandler - pointing to that server's address and port.""" - BaseTest.setUp(self) - self.handled = threading.Event() - - def handle_request(self, request): - self.command = request.command - self.log_data = urlparse(request.path) - if self.command == 'POST': - try: - rlen = int(request.headers['Content-Length']) - self.post_data = request.rfile.read(rlen) - except: - self.post_data = None - request.send_response(200) - request.end_headers() - self.handled.set() - - def test_output(self): - # The log message sent to the HTTPHandler is properly received. - logger = logging.getLogger("http") - root_logger = self.root_logger - root_logger.removeHandler(self.root_logger.handlers[0]) - for secure in (False, True): - addr = ('localhost', 0) - if secure: - try: - import ssl - except ImportError: - sslctx = None - else: - here = os.path.dirname(__file__) - localhost_cert = os.path.join(here, "keycert.pem") - sslctx = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER) - sslctx.load_cert_chain(localhost_cert) - - context = ssl.create_default_context(cafile=localhost_cert) - else: - sslctx = None - context = None - self.server = server = TestHTTPServer(addr, self.handle_request, - 0.01, sslctx=sslctx) - server.start() - server.ready.wait() - host = 'localhost:%d' % server.server_port - secure_client = secure and sslctx - self.h_hdlr = logging.handlers.HTTPHandler(host, '/frob', - secure=secure_client, - context=context, - credentials=('foo', 'bar')) - self.log_data = None - root_logger.addHandler(self.h_hdlr) - - for method in ('GET', 'POST'): - self.h_hdlr.method = method - self.handled.clear() - msg = "sp\xe4m" - logger.error(msg) - self.handled.wait() - self.assertEqual(self.log_data.path, '/frob') - self.assertEqual(self.command, method) - if method == 'GET': - d = parse_qs(self.log_data.query) - else: - d = parse_qs(self.post_data.decode('utf-8')) - self.assertEqual(d['name'], ['http']) - self.assertEqual(d['funcName'], ['test_output']) - self.assertEqual(d['msg'], [msg]) - - self.server.stop(2.0) - self.root_logger.removeHandler(self.h_hdlr) - self.h_hdlr.close() - - class MemoryTest(BaseTest): - - """Test memory persistence of logger objects.""" - - def setUp(self): - """Create a dict to remember potentially destroyed objects.""" - BaseTest.setUp(self) - self._survivors = {} - - def _watch_for_survival(self, *args): - """Watch the given objects for survival, by creating weakrefs to - them.""" - for obj in args: - key = id(obj), repr(obj) - self._survivors[key] = weakref.ref(obj) - - def _assertTruesurvival(self): - """Assert that all objects watched for survival have survived.""" - # Trigger cycle breaking. - gc.collect() - dead = [] - for (id_, repr_), ref in self._survivors.items(): - if ref() is None: - dead.append(repr_) - if dead: - self.fail("%d objects should have survived " - "but have been destroyed: %s" % (len(dead), ", ".join(dead))) - - def test_persistent_loggers(self): - # Logger objects are persistent and retain their configuration, even - # if visible references are destroyed. - self.root_logger.setLevel(logging.INFO) - foo = logging.getLogger("foo") - self._watch_for_survival(foo) - foo.setLevel(logging.DEBUG) - self.root_logger.debug(self.next_message()) - foo.debug(self.next_message()) - self.assert_log_lines([ - ('foo', 'DEBUG', '2'), - ]) - del foo - # foo has survived. - self._assertTruesurvival() - # foo has retained its settings. - bar = logging.getLogger("foo") - bar.debug(self.next_message()) - self.assert_log_lines([ - ('foo', 'DEBUG', '2'), - ('foo', 'DEBUG', '3'), - ]) - - - class EncodingTest(BaseTest): - def test_encoding_plain_file(self): - # In Python 2.x, a plain file object is treated as having no encoding. - log = logging.getLogger("test") - fd, fn = tempfile.mkstemp(".log", "test_logging-1-") - os.close(fd) - # the non-ascii data we write to the log. - data = "foo\x80" - try: - handler = logging.FileHandler(fn, encoding="utf-8") - log.addHandler(handler) - try: - # write non-ascii data to the log. - log.warning(data) - finally: - log.removeHandler(handler) - handler.close() - # check we wrote exactly those bytes, ignoring trailing \n etc - f = open(fn, encoding="utf-8") - try: - self.assertEqual(f.read().rstrip(), data) - finally: - f.close() - finally: - if os.path.isfile(fn): - os.remove(fn) - - def test_encoding_cyrillic_unicode(self): - log = logging.getLogger("test") - # Get a message in Unicode: Do svidanya in Cyrillic (meaning goodbye) - message = '\u0434\u043e \u0441\u0432\u0438\u0434\u0430\u043d\u0438\u044f' - # Ensure it's written in a Cyrillic encoding - writer_class = codecs.getwriter('cp1251') - writer_class.encoding = 'cp1251' - stream = io.BytesIO() - writer = writer_class(stream, 'strict') - handler = logging.StreamHandler(writer) - log.addHandler(handler) - try: - log.warning(message) - finally: - log.removeHandler(handler) - handler.close() - # check we wrote exactly those bytes, ignoring trailing \n etc - s = stream.getvalue() - # Compare against what the data should be when encoded in CP-1251 - self.assertEqual(s, b'\xe4\xee \xf1\xe2\xe8\xe4\xe0\xed\xe8\xff\n') - - - class WarningsTest(BaseTest): - - def test_warnings(self): - with warnings.catch_warnings(): - logging.captureWarnings(True) - self.addCleanup(logging.captureWarnings, False) - warnings.filterwarnings("always", category=UserWarning) - stream = io.StringIO() - h = logging.StreamHandler(stream) - logger = logging.getLogger("py.warnings") - logger.addHandler(h) - warnings.warn("I'm warning you...") - logger.removeHandler(h) - s = stream.getvalue() - h.close() - self.assertGreater(s.find("UserWarning: I'm warning you...\n"), 0) - - # See if an explicit file uses the original implementation - a_file = io.StringIO() - warnings.showwarning("Explicit", UserWarning, "dummy.py", 42, - a_file, "Dummy line") - s = a_file.getvalue() - a_file.close() - self.assertEqual(s, - "dummy.py:42: UserWarning: Explicit\n Dummy line\n") - - def test_warnings_no_handlers(self): - with warnings.catch_warnings(): - logging.captureWarnings(True) - self.addCleanup(logging.captureWarnings, False) - - # confirm our assumption: no loggers are set - logger = logging.getLogger("py.warnings") - self.assertEqual(logger.handlers, []) - - warnings.showwarning("Explicit", UserWarning, "dummy.py", 42) - self.assertEqual(len(logger.handlers), 1) - self.assertIsInstance(logger.handlers[0], logging.NullHandler) - - - def formatFunc(format, datefmt=None): - return logging.Formatter(format, datefmt) - - class myCustomFormatter: - def __init__(self, fmt, datefmt=None): - pass - - def handlerFunc(): - return logging.StreamHandler() - - class CustomHandler(logging.StreamHandler): - pass - - class ConfigDictTest(BaseTest): - - """Reading logging config from a dictionary.""" - - check_no_resource_warning = support.check_no_resource_warning - expected_log_pat = r"^(\w+) \+\+ (\w+)$" - - # config0 is a standard configuration. - config0 = { - 'version': 1, - 'formatters': { - 'form1' : { - 'format' : '%(levelname)s ++ %(message)s', - }, - }, - 'handlers' : { - 'hand1' : { - 'class' : 'logging.StreamHandler', - 'formatter' : 'form1', - 'level' : 'NOTSET', - 'stream' : 'ext://sys.stdout', - }, - }, - 'root' : { - 'level' : 'WARNING', - 'handlers' : ['hand1'], - }, - } - - # config1 adds a little to the standard configuration. - config1 = { - 'version': 1, - 'formatters': { - 'form1' : { - 'format' : '%(levelname)s ++ %(message)s', - }, - }, - 'handlers' : { - 'hand1' : { - 'class' : 'logging.StreamHandler', - 'formatter' : 'form1', - 'level' : 'NOTSET', - 'stream' : 'ext://sys.stdout', - }, - }, - 'loggers' : { - 'compiler.parser' : { - 'level' : 'DEBUG', - 'handlers' : ['hand1'], - }, - }, - 'root' : { - 'level' : 'WARNING', - }, - } - - # config1a moves the handler to the root. Used with config8a - config1a = { - 'version': 1, - 'formatters': { - 'form1' : { - 'format' : '%(levelname)s ++ %(message)s', - }, - }, - 'handlers' : { - 'hand1' : { - 'class' : 'logging.StreamHandler', - 'formatter' : 'form1', - 'level' : 'NOTSET', - 'stream' : 'ext://sys.stdout', - }, - }, - 'loggers' : { - 'compiler.parser' : { - 'level' : 'DEBUG', - }, - }, - 'root' : { - 'level' : 'WARNING', - 'handlers' : ['hand1'], - }, - } - - # config2 has a subtle configuration error that should be reported - config2 = { - 'version': 1, - 'formatters': { - 'form1' : { - 'format' : '%(levelname)s ++ %(message)s', - }, - }, - 'handlers' : { - 'hand1' : { - 'class' : 'logging.StreamHandler', - 'formatter' : 'form1', - 'level' : 'NOTSET', - 'stream' : 'ext://sys.stdbout', - }, - }, - 'loggers' : { - 'compiler.parser' : { - 'level' : 'DEBUG', - 'handlers' : ['hand1'], - }, - }, - 'root' : { - 'level' : 'WARNING', - }, - } - - # As config1 but with a misspelt level on a handler - config2a = { - 'version': 1, - 'formatters': { - 'form1' : { - 'format' : '%(levelname)s ++ %(message)s', - }, - }, - 'handlers' : { - 'hand1' : { - 'class' : 'logging.StreamHandler', - 'formatter' : 'form1', - 'level' : 'NTOSET', - 'stream' : 'ext://sys.stdout', - }, - }, - 'loggers' : { - 'compiler.parser' : { - 'level' : 'DEBUG', - 'handlers' : ['hand1'], - }, - }, - 'root' : { - 'level' : 'WARNING', - }, - } - - - # As config1 but with a misspelt level on a logger - config2b = { - 'version': 1, - 'formatters': { - 'form1' : { - 'format' : '%(levelname)s ++ %(message)s', - }, - }, - 'handlers' : { - 'hand1' : { - 'class' : 'logging.StreamHandler', - 'formatter' : 'form1', - 'level' : 'NOTSET', - 'stream' : 'ext://sys.stdout', - }, - }, - 'loggers' : { - 'compiler.parser' : { - 'level' : 'DEBUG', - 'handlers' : ['hand1'], - }, - }, - 'root' : { - 'level' : 'WRANING', - }, - } - - # config3 has a less subtle configuration error - config3 = { - 'version': 1, - 'formatters': { - 'form1' : { - 'format' : '%(levelname)s ++ %(message)s', - }, - }, - 'handlers' : { - 'hand1' : { - 'class' : 'logging.StreamHandler', - 'formatter' : 'misspelled_name', - 'level' : 'NOTSET', - 'stream' : 'ext://sys.stdout', - }, - }, - 'loggers' : { - 'compiler.parser' : { - 'level' : 'DEBUG', - 'handlers' : ['hand1'], - }, - }, - 'root' : { - 'level' : 'WARNING', - }, - } - - # config4 specifies a custom formatter class to be loaded - config4 = { - 'version': 1, - 'formatters': { - 'form1' : { - '()' : __name__ + '.ExceptionFormatter', - 'format' : '%(levelname)s:%(name)s:%(message)s', - }, - }, - 'handlers' : { - 'hand1' : { - 'class' : 'logging.StreamHandler', - 'formatter' : 'form1', - 'level' : 'NOTSET', - 'stream' : 'ext://sys.stdout', - }, - }, - 'root' : { - 'level' : 'NOTSET', - 'handlers' : ['hand1'], - }, - } - - # As config4 but using an actual callable rather than a string - config4a = { - 'version': 1, - 'formatters': { - 'form1' : { - '()' : ExceptionFormatter, - 'format' : '%(levelname)s:%(name)s:%(message)s', - }, - 'form2' : { - '()' : __name__ + '.formatFunc', - 'format' : '%(levelname)s:%(name)s:%(message)s', - }, - 'form3' : { - '()' : formatFunc, - 'format' : '%(levelname)s:%(name)s:%(message)s', - }, - }, - 'handlers' : { - 'hand1' : { - 'class' : 'logging.StreamHandler', - 'formatter' : 'form1', - 'level' : 'NOTSET', - 'stream' : 'ext://sys.stdout', - }, - 'hand2' : { - '()' : handlerFunc, - }, - }, - 'root' : { - 'level' : 'NOTSET', - 'handlers' : ['hand1'], - }, - } - - # config5 specifies a custom handler class to be loaded - config5 = { - 'version': 1, - 'formatters': { - 'form1' : { - 'format' : '%(levelname)s ++ %(message)s', - }, - }, - 'handlers' : { - 'hand1' : { - 'class' : __name__ + '.CustomHandler', - 'formatter' : 'form1', - 'level' : 'NOTSET', - 'stream' : 'ext://sys.stdout', - }, - }, - 'loggers' : { - 'compiler.parser' : { - 'level' : 'DEBUG', - 'handlers' : ['hand1'], - }, - }, - 'root' : { - 'level' : 'WARNING', - }, - } - - # config6 specifies a custom handler class to be loaded - # but has bad arguments - config6 = { - 'version': 1, - 'formatters': { - 'form1' : { - 'format' : '%(levelname)s ++ %(message)s', - }, - }, - 'handlers' : { - 'hand1' : { - 'class' : __name__ + '.CustomHandler', - 'formatter' : 'form1', - 'level' : 'NOTSET', - 'stream' : 'ext://sys.stdout', - '9' : 'invalid parameter name', - }, - }, - 'loggers' : { - 'compiler.parser' : { - 'level' : 'DEBUG', - 'handlers' : ['hand1'], - }, - }, - 'root' : { - 'level' : 'WARNING', - }, - } - - # config 7 does not define compiler.parser but defines compiler.lexer - # so compiler.parser should be disabled after applying it - config7 = { - 'version': 1, - 'formatters': { - 'form1' : { - 'format' : '%(levelname)s ++ %(message)s', - }, - }, - 'handlers' : { - 'hand1' : { - 'class' : 'logging.StreamHandler', - 'formatter' : 'form1', - 'level' : 'NOTSET', - 'stream' : 'ext://sys.stdout', - }, - }, - 'loggers' : { - 'compiler.lexer' : { - 'level' : 'DEBUG', - 'handlers' : ['hand1'], - }, - }, - 'root' : { - 'level' : 'WARNING', - }, - } - - # config8 defines both compiler and compiler.lexer - # so compiler.parser should not be disabled (since - # compiler is defined) - config8 = { - 'version': 1, - 'disable_existing_loggers' : False, - 'formatters': { - 'form1' : { - 'format' : '%(levelname)s ++ %(message)s', - }, - }, - 'handlers' : { - 'hand1' : { - 'class' : 'logging.StreamHandler', - 'formatter' : 'form1', - 'level' : 'NOTSET', - 'stream' : 'ext://sys.stdout', - }, - }, - 'loggers' : { - 'compiler' : { - 'level' : 'DEBUG', - 'handlers' : ['hand1'], - }, - 'compiler.lexer' : { - }, - }, - 'root' : { - 'level' : 'WARNING', - }, - } - - # config8a disables existing loggers - config8a = { - 'version': 1, - 'disable_existing_loggers' : True, - 'formatters': { - 'form1' : { - 'format' : '%(levelname)s ++ %(message)s', - }, - }, - 'handlers' : { - 'hand1' : { - 'class' : 'logging.StreamHandler', - 'formatter' : 'form1', - 'level' : 'NOTSET', - 'stream' : 'ext://sys.stdout', - }, - }, - 'loggers' : { - 'compiler' : { - 'level' : 'DEBUG', - 'handlers' : ['hand1'], - }, - 'compiler.lexer' : { - }, - }, - 'root' : { - 'level' : 'WARNING', - }, - } - - config9 = { - 'version': 1, - 'formatters': { - 'form1' : { - 'format' : '%(levelname)s ++ %(message)s', - }, - }, - 'handlers' : { - 'hand1' : { - 'class' : 'logging.StreamHandler', - 'formatter' : 'form1', - 'level' : 'WARNING', - 'stream' : 'ext://sys.stdout', - }, - }, - 'loggers' : { - 'compiler.parser' : { - 'level' : 'WARNING', - 'handlers' : ['hand1'], - }, - }, - 'root' : { - 'level' : 'NOTSET', - }, - } - - config9a = { - 'version': 1, - 'incremental' : True, - 'handlers' : { - 'hand1' : { - 'level' : 'WARNING', - }, - }, - 'loggers' : { - 'compiler.parser' : { - 'level' : 'INFO', - }, - }, - } - - config9b = { - 'version': 1, - 'incremental' : True, - 'handlers' : { - 'hand1' : { - 'level' : 'INFO', - }, - }, - 'loggers' : { - 'compiler.parser' : { - 'level' : 'INFO', - }, - }, - } - - # As config1 but with a filter added - config10 = { - 'version': 1, - 'formatters': { - 'form1' : { - 'format' : '%(levelname)s ++ %(message)s', - }, - }, - 'filters' : { - 'filt1' : { - 'name' : 'compiler.parser', - }, - }, - 'handlers' : { - 'hand1' : { - 'class' : 'logging.StreamHandler', - 'formatter' : 'form1', - 'level' : 'NOTSET', - 'stream' : 'ext://sys.stdout', - 'filters' : ['filt1'], - }, - }, - 'loggers' : { - 'compiler.parser' : { - 'level' : 'DEBUG', - 'filters' : ['filt1'], - }, - }, - 'root' : { - 'level' : 'WARNING', - 'handlers' : ['hand1'], - }, - } - - # As config1 but using cfg:// references - config11 = { - 'version': 1, - 'true_formatters': { - 'form1' : { - 'format' : '%(levelname)s ++ %(message)s', - }, - }, - 'handler_configs': { - 'hand1' : { - 'class' : 'logging.StreamHandler', - 'formatter' : 'form1', - 'level' : 'NOTSET', - 'stream' : 'ext://sys.stdout', - }, - }, - 'formatters' : 'cfg://true_formatters', - 'handlers' : { - 'hand1' : 'cfg://handler_configs[hand1]', - }, - 'loggers' : { - 'compiler.parser' : { - 'level' : 'DEBUG', - 'handlers' : ['hand1'], - }, - }, - 'root' : { - 'level' : 'WARNING', - }, - } - - # As config11 but missing the version key - config12 = { - 'true_formatters': { - 'form1' : { - 'format' : '%(levelname)s ++ %(message)s', - }, - }, - 'handler_configs': { - 'hand1' : { - 'class' : 'logging.StreamHandler', - 'formatter' : 'form1', - 'level' : 'NOTSET', - 'stream' : 'ext://sys.stdout', - }, - }, - 'formatters' : 'cfg://true_formatters', - 'handlers' : { - 'hand1' : 'cfg://handler_configs[hand1]', - }, - 'loggers' : { - 'compiler.parser' : { - 'level' : 'DEBUG', - 'handlers' : ['hand1'], - }, - }, - 'root' : { - 'level' : 'WARNING', - }, - } - - # As config11 but using an unsupported version - config13 = { - 'version': 2, - 'true_formatters': { - 'form1' : { - 'format' : '%(levelname)s ++ %(message)s', - }, - }, - 'handler_configs': { - 'hand1' : { - 'class' : 'logging.StreamHandler', - 'formatter' : 'form1', - 'level' : 'NOTSET', - 'stream' : 'ext://sys.stdout', - }, - }, - 'formatters' : 'cfg://true_formatters', - 'handlers' : { - 'hand1' : 'cfg://handler_configs[hand1]', - }, - 'loggers' : { - 'compiler.parser' : { - 'level' : 'DEBUG', - 'handlers' : ['hand1'], - }, - }, - 'root' : { - 'level' : 'WARNING', - }, - } - - # As config0, but with properties - config14 = { - 'version': 1, - 'formatters': { - 'form1' : { - 'format' : '%(levelname)s ++ %(message)s', - }, - }, - 'handlers' : { - 'hand1' : { - 'class' : 'logging.StreamHandler', - 'formatter' : 'form1', - 'level' : 'NOTSET', - 'stream' : 'ext://sys.stdout', - '.': { - 'foo': 'bar', - 'terminator': '!\n', - } - }, - }, - 'root' : { - 'level' : 'WARNING', - 'handlers' : ['hand1'], - }, - } - - out_of_order = { - "version": 1, - "formatters": { - "mySimpleFormatter": { - "format": "%(asctime)s (%(name)s) %(levelname)s: %(message)s", - "style": "$" - } - }, - "handlers": { - "fileGlobal": { - "class": "logging.StreamHandler", - "level": "DEBUG", - "formatter": "mySimpleFormatter" - }, - "bufferGlobal": { - "class": "logging.handlers.MemoryHandler", - "capacity": 5, - "formatter": "mySimpleFormatter", - "target": "fileGlobal", - "level": "DEBUG" - } - }, - "loggers": { - "mymodule": { - "level": "DEBUG", - "handlers": ["bufferGlobal"], - "propagate": "true" - } - } - } - - # Configuration with custom logging.Formatter subclass as '()' key and 'validate' set to False - custom_formatter_class_validate = { - 'version': 1, - 'formatters': { - 'form1': { - '()': __name__ + '.ExceptionFormatter', - 'format': '%(levelname)s:%(name)s:%(message)s', - 'validate': False, - }, - }, - 'handlers' : { - 'hand1' : { - 'class': 'logging.StreamHandler', - 'formatter': 'form1', - 'level': 'NOTSET', - 'stream': 'ext://sys.stdout', - }, - }, - "loggers": { - "my_test_logger_custom_formatter": { - "level": "DEBUG", - "handlers": ["hand1"], - "propagate": "true" - } - } - } - - # Configuration with custom logging.Formatter subclass as 'class' key and 'validate' set to False - custom_formatter_class_validate2 = { - 'version': 1, - 'formatters': { - 'form1': { - 'class': __name__ + '.ExceptionFormatter', - 'format': '%(levelname)s:%(name)s:%(message)s', - 'validate': False, - }, - }, - 'handlers' : { - 'hand1' : { - 'class': 'logging.StreamHandler', - 'formatter': 'form1', - 'level': 'NOTSET', - 'stream': 'ext://sys.stdout', - }, - }, - "loggers": { - "my_test_logger_custom_formatter": { - "level": "DEBUG", - "handlers": ["hand1"], - "propagate": "true" - } - } - } - - # Configuration with custom class that is not inherited from logging.Formatter - custom_formatter_class_validate3 = { - 'version': 1, - 'formatters': { - 'form1': { - 'class': __name__ + '.myCustomFormatter', - 'format': '%(levelname)s:%(name)s:%(message)s', - 'validate': False, - }, - }, - 'handlers' : { - 'hand1' : { - 'class': 'logging.StreamHandler', - 'formatter': 'form1', - 'level': 'NOTSET', - 'stream': 'ext://sys.stdout', - }, - }, - "loggers": { - "my_test_logger_custom_formatter": { - "level": "DEBUG", - "handlers": ["hand1"], - "propagate": "true" - } - } - } - - # Configuration with custom function and 'validate' set to False - custom_formatter_with_function = { - 'version': 1, - 'formatters': { - 'form1': { - '()': formatFunc, - 'format': '%(levelname)s:%(name)s:%(message)s', - 'validate': False, - }, - }, - 'handlers' : { - 'hand1' : { - 'class': 'logging.StreamHandler', - 'formatter': 'form1', - 'level': 'NOTSET', - 'stream': 'ext://sys.stdout', - }, - }, - "loggers": { - "my_test_logger_custom_formatter": { - "level": "DEBUG", - "handlers": ["hand1"], - "propagate": "true" - } - } - } - - def apply_config(self, conf): - logging.config.dictConfig(conf) - - def test_config0_ok(self): - # A simple config which overrides the default settings. - with support.captured_stdout() as output: - self.apply_config(self.config0) - logger = logging.getLogger() - # Won't output anything - logger.info(self.next_message()) - # Outputs a message - logger.error(self.next_message()) - self.assert_log_lines([ - ('ERROR', '2'), - ], stream=output) - # Original logger output is empty. - self.assert_log_lines([]) - - def test_config1_ok(self, config=config1): - # A config defining a sub-parser as well. - with support.captured_stdout() as output: - self.apply_config(config) - logger = logging.getLogger("compiler.parser") - # Both will output a message - logger.info(self.next_message()) - logger.error(self.next_message()) - self.assert_log_lines([ - ('INFO', '1'), - ('ERROR', '2'), - ], stream=output) - # Original logger output is empty. - self.assert_log_lines([]) - - def test_config2_failure(self): - # A simple config which overrides the default settings. - self.assertRaises(Exception, self.apply_config, self.config2) - - def test_config2a_failure(self): - # A simple config which overrides the default settings. - self.assertRaises(Exception, self.apply_config, self.config2a) - - def test_config2b_failure(self): - # A simple config which overrides the default settings. - self.assertRaises(Exception, self.apply_config, self.config2b) - - def test_config3_failure(self): - # A simple config which overrides the default settings. - self.assertRaises(Exception, self.apply_config, self.config3) - - def test_config4_ok(self): - # A config specifying a custom formatter class. - with support.captured_stdout() as output: - self.apply_config(self.config4) - #logger = logging.getLogger() - try: - raise RuntimeError() - except RuntimeError: - logging.exception("just testing") - sys.stdout.seek(0) - self.assertEqual(output.getvalue(), - "ERROR:root:just testing\nGot a [RuntimeError]\n") - # Original logger output is empty - self.assert_log_lines([]) - - def test_config4a_ok(self): - # A config specifying a custom formatter class. - with support.captured_stdout() as output: - self.apply_config(self.config4a) - #logger = logging.getLogger() - try: - raise RuntimeError() - except RuntimeError: - logging.exception("just testing") - sys.stdout.seek(0) - self.assertEqual(output.getvalue(), - "ERROR:root:just testing\nGot a [RuntimeError]\n") - # Original logger output is empty - self.assert_log_lines([]) - - def test_config5_ok(self): - self.test_config1_ok(config=self.config5) - - def test_config6_failure(self): - self.assertRaises(Exception, self.apply_config, self.config6) - - def test_config7_ok(self): - with support.captured_stdout() as output: - self.apply_config(self.config1) - logger = logging.getLogger("compiler.parser") - # Both will output a message - logger.info(self.next_message()) - logger.error(self.next_message()) - self.assert_log_lines([ - ('INFO', '1'), - ('ERROR', '2'), - ], stream=output) - # Original logger output is empty. - self.assert_log_lines([]) - with support.captured_stdout() as output: - self.apply_config(self.config7) - logger = logging.getLogger("compiler.parser") - self.assertTrue(logger.disabled) - logger = logging.getLogger("compiler.lexer") - # Both will output a message - logger.info(self.next_message()) - logger.error(self.next_message()) - self.assert_log_lines([ - ('INFO', '3'), - ('ERROR', '4'), - ], stream=output) - # Original logger output is empty. - self.assert_log_lines([]) - - # Same as test_config_7_ok but don't disable old loggers. - def test_config_8_ok(self): - with support.captured_stdout() as output: - self.apply_config(self.config1) - logger = logging.getLogger("compiler.parser") - # All will output a message - logger.info(self.next_message()) - logger.error(self.next_message()) - self.assert_log_lines([ - ('INFO', '1'), - ('ERROR', '2'), - ], stream=output) - # Original logger output is empty. - self.assert_log_lines([]) - with support.captured_stdout() as output: - self.apply_config(self.config8) - logger = logging.getLogger("compiler.parser") - self.assertFalse(logger.disabled) - # Both will output a message - logger.info(self.next_message()) - logger.error(self.next_message()) - logger = logging.getLogger("compiler.lexer") - # Both will output a message - logger.info(self.next_message()) - logger.error(self.next_message()) - self.assert_log_lines([ - ('INFO', '3'), - ('ERROR', '4'), - ('INFO', '5'), - ('ERROR', '6'), - ], stream=output) - # Original logger output is empty. - self.assert_log_lines([]) - - def test_config_8a_ok(self): - with support.captured_stdout() as output: - self.apply_config(self.config1a) - logger = logging.getLogger("compiler.parser") - # See issue #11424. compiler-hyphenated sorts - # between compiler and compiler.xyz and this - # was preventing compiler.xyz from being included - # in the child loggers of compiler because of an - # overzealous loop termination condition. - hyphenated = logging.getLogger('compiler-hyphenated') - # All will output a message - logger.info(self.next_message()) - logger.error(self.next_message()) - hyphenated.critical(self.next_message()) - self.assert_log_lines([ - ('INFO', '1'), - ('ERROR', '2'), - ('CRITICAL', '3'), - ], stream=output) - # Original logger output is empty. - self.assert_log_lines([]) - with support.captured_stdout() as output: - self.apply_config(self.config8a) - logger = logging.getLogger("compiler.parser") - self.assertFalse(logger.disabled) - # Both will output a message - logger.info(self.next_message()) - logger.error(self.next_message()) - logger = logging.getLogger("compiler.lexer") - # Both will output a message - logger.info(self.next_message()) - logger.error(self.next_message()) - # Will not appear - hyphenated.critical(self.next_message()) - self.assert_log_lines([ - ('INFO', '4'), - ('ERROR', '5'), - ('INFO', '6'), - ('ERROR', '7'), - ], stream=output) - # Original logger output is empty. - self.assert_log_lines([]) - - def test_config_9_ok(self): - with support.captured_stdout() as output: - self.apply_config(self.config9) - logger = logging.getLogger("compiler.parser") - # Nothing will be output since both handler and logger are set to WARNING - logger.info(self.next_message()) - self.assert_log_lines([], stream=output) - self.apply_config(self.config9a) - # Nothing will be output since handler is still set to WARNING - logger.info(self.next_message()) - self.assert_log_lines([], stream=output) - self.apply_config(self.config9b) - # Message should now be output - logger.info(self.next_message()) - self.assert_log_lines([ - ('INFO', '3'), - ], stream=output) - - def test_config_10_ok(self): - with support.captured_stdout() as output: - self.apply_config(self.config10) - logger = logging.getLogger("compiler.parser") - logger.warning(self.next_message()) - logger = logging.getLogger('compiler') - # Not output, because filtered - logger.warning(self.next_message()) - logger = logging.getLogger('compiler.lexer') - # Not output, because filtered - logger.warning(self.next_message()) - logger = logging.getLogger("compiler.parser.codegen") - # Output, as not filtered - logger.error(self.next_message()) - self.assert_log_lines([ - ('WARNING', '1'), - ('ERROR', '4'), - ], stream=output) - - def test_config11_ok(self): - self.test_config1_ok(self.config11) - - def test_config12_failure(self): - self.assertRaises(Exception, self.apply_config, self.config12) - - def test_config13_failure(self): - self.assertRaises(Exception, self.apply_config, self.config13) - - def test_config14_ok(self): - with support.captured_stdout() as output: - self.apply_config(self.config14) - h = logging._handlers['hand1'] - self.assertEqual(h.foo, 'bar') - self.assertEqual(h.terminator, '!\n') - logging.warning('Exclamation') - self.assertTrue(output.getvalue().endswith('Exclamation!\n')) - - def test_config15_ok(self): - - def cleanup(h1, fn): - h1.close() - os.remove(fn) - - with self.check_no_resource_warning(): - fd, fn = tempfile.mkstemp(".log", "test_logging-X-") - os.close(fd) - - config = { - "version": 1, - "handlers": { - "file": { - "class": "logging.FileHandler", - "filename": fn - } - }, - "root": { - "handlers": ["file"] - } - } - - self.apply_config(config) - self.apply_config(config) - - handler = logging.root.handlers[0] - self.addCleanup(cleanup, handler, fn) - - def setup_via_listener(self, text, verify=None): - text = text.encode("utf-8") - # Ask for a randomly assigned port (by using port 0) - t = logging.config.listen(0, verify) - t.start() - t.ready.wait() - # Now get the port allocated - port = t.port - t.ready.clear() - try: - sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - sock.settimeout(2.0) - sock.connect(('localhost', port)) - - slen = struct.pack('>L', len(text)) - s = slen + text - sentsofar = 0 - left = len(s) - while left > 0: - sent = sock.send(s[sentsofar:]) - sentsofar += sent - left -= sent - sock.close() - finally: - t.ready.wait(2.0) - logging.config.stopListening() - support.join_thread(t, 2.0) - - def test_listen_config_10_ok(self): - with support.captured_stdout() as output: - self.setup_via_listener(json.dumps(self.config10)) - logger = logging.getLogger("compiler.parser") - logger.warning(self.next_message()) - logger = logging.getLogger('compiler') - # Not output, because filtered - logger.warning(self.next_message()) - logger = logging.getLogger('compiler.lexer') - # Not output, because filtered - logger.warning(self.next_message()) - logger = logging.getLogger("compiler.parser.codegen") - # Output, as not filtered - logger.error(self.next_message()) - self.assert_log_lines([ - ('WARNING', '1'), - ('ERROR', '4'), - ], stream=output) - - def test_listen_config_1_ok(self): - with support.captured_stdout() as output: - self.setup_via_listener(textwrap.dedent(ConfigFileTest.config1)) - logger = logging.getLogger("compiler.parser") - # Both will output a message - logger.info(self.next_message()) - logger.error(self.next_message()) - self.assert_log_lines([ - ('INFO', '1'), - ('ERROR', '2'), - ], stream=output) - # Original logger output is empty. - self.assert_log_lines([]) - - def test_listen_verify(self): - - def verify_fail(stuff): - return None - - def verify_reverse(stuff): - return stuff[::-1] - - logger = logging.getLogger("compiler.parser") - to_send = textwrap.dedent(ConfigFileTest.config1) - # First, specify a verification function that will fail. - # We expect to see no output, since our configuration - # never took effect. - with support.captured_stdout() as output: - self.setup_via_listener(to_send, verify_fail) - # Both will output a message - logger.info(self.next_message()) - logger.error(self.next_message()) - self.assert_log_lines([], stream=output) - # Original logger output has the stuff we logged. - self.assert_log_lines([ - ('INFO', '1'), - ('ERROR', '2'), - ], pat=r"^[\w.]+ -> (\w+): (\d+)$") - - # Now, perform no verification. Our configuration - # should take effect. - - with support.captured_stdout() as output: - self.setup_via_listener(to_send) # no verify callable specified - logger = logging.getLogger("compiler.parser") - # Both will output a message - logger.info(self.next_message()) - logger.error(self.next_message()) - self.assert_log_lines([ - ('INFO', '3'), - ('ERROR', '4'), - ], stream=output) - # Original logger output still has the stuff we logged before. - self.assert_log_lines([ - ('INFO', '1'), - ('ERROR', '2'), - ], pat=r"^[\w.]+ -> (\w+): (\d+)$") - - # Now, perform verification which transforms the bytes. - - with support.captured_stdout() as output: - self.setup_via_listener(to_send[::-1], verify_reverse) - logger = logging.getLogger("compiler.parser") - # Both will output a message - logger.info(self.next_message()) - logger.error(self.next_message()) - self.assert_log_lines([ - ('INFO', '5'), - ('ERROR', '6'), - ], stream=output) - # Original logger output still has the stuff we logged before. - self.assert_log_lines([ - ('INFO', '1'), - ('ERROR', '2'), - ], pat=r"^[\w.]+ -> (\w+): (\d+)$") - - def test_out_of_order(self): - self.assertRaises(ValueError, self.apply_config, self.out_of_order) - - def test_out_of_order_with_dollar_style(self): - config = copy.deepcopy(self.out_of_order) - config['formatters']['mySimpleFormatter']['format'] = "${asctime} (${name}) ${levelname}: ${message}" - - self.apply_config(config) - handler = logging.getLogger('mymodule').handlers[0] - self.assertIsInstance(handler.target, logging.Handler) - self.assertIsInstance(handler.formatter._style, - logging.StringTemplateStyle) - - def test_custom_formatter_class_with_validate(self): - self.apply_config(self.custom_formatter_class_validate) - handler = logging.getLogger("my_test_logger_custom_formatter").handlers[0] - self.assertIsInstance(handler.formatter, ExceptionFormatter) - - def test_custom_formatter_class_with_validate2(self): - self.apply_config(self.custom_formatter_class_validate2) - handler = logging.getLogger("my_test_logger_custom_formatter").handlers[0] - self.assertIsInstance(handler.formatter, ExceptionFormatter) - - def test_custom_formatter_class_with_validate2_with_wrong_fmt(self): - config = self.custom_formatter_class_validate.copy() - config['formatters']['form1']['style'] = "$" - - # Exception should not be raise as we have configured 'validate' to False - self.apply_config(config) - handler = logging.getLogger("my_test_logger_custom_formatter").handlers[0] - self.assertIsInstance(handler.formatter, ExceptionFormatter) - - def test_custom_formatter_class_with_validate3(self): - self.assertRaises(ValueError, self.apply_config, self.custom_formatter_class_validate3) - - def test_custom_formatter_function_with_validate(self): - self.assertRaises(ValueError, self.apply_config, self.custom_formatter_with_function) - - def test_baseconfig(self): - d = { - 'atuple': (1, 2, 3), - 'alist': ['a', 'b', 'c'], - 'adict': {'d': 'e', 'f': 3 }, - 'nest1': ('g', ('h', 'i'), 'j'), - 'nest2': ['k', ['l', 'm'], 'n'], - 'nest3': ['o', 'cfg://alist', 'p'], - } - bc = logging.config.BaseConfigurator(d) - self.assertEqual(bc.convert('cfg://atuple[1]'), 2) - self.assertEqual(bc.convert('cfg://alist[1]'), 'b') - self.assertEqual(bc.convert('cfg://nest1[1][0]'), 'h') - self.assertEqual(bc.convert('cfg://nest2[1][1]'), 'm') - self.assertEqual(bc.convert('cfg://adict.d'), 'e') - self.assertEqual(bc.convert('cfg://adict[f]'), 3) - v = bc.convert('cfg://nest3') - self.assertEqual(v.pop(1), ['a', 'b', 'c']) - self.assertRaises(KeyError, bc.convert, 'cfg://nosuch') - self.assertRaises(ValueError, bc.convert, 'cfg://!') - self.assertRaises(KeyError, bc.convert, 'cfg://adict[2]') - - def test_namedtuple(self): - # see bpo-39142 - from collections import namedtuple - - class MyHandler(logging.StreamHandler): - def __init__(self, resource, *args, **kwargs): - super().__init__(*args, **kwargs) - self.resource: namedtuple = resource - - def emit(self, record): - record.msg += f' {self.resource.type}' - return super().emit(record) - - Resource = namedtuple('Resource', ['type', 'labels']) - resource = Resource(type='my_type', labels=['a']) - - config = { - 'version': 1, - 'handlers': { - 'myhandler': { - '()': MyHandler, - 'resource': resource - } - }, - 'root': {'level': 'INFO', 'handlers': ['myhandler']}, - } - with support.captured_stderr() as stderr: - self.apply_config(config) - logging.info('some log') - self.assertEqual(stderr.getvalue(), 'some log my_type\n') - - class ManagerTest(BaseTest): - def test_manager_loggerclass(self): - logged = [] - - class MyLogger(logging.Logger): - def _log(self, level, msg, args, exc_info=None, extra=None): - logged.append(msg) - - man = logging.Manager(None) - self.assertRaises(TypeError, man.setLoggerClass, int) - man.setLoggerClass(MyLogger) - logger = man.getLogger('test') - logger.warning('should appear in logged') - logging.warning('should not appear in logged') - - self.assertEqual(logged, ['should appear in logged']) - - def test_set_log_record_factory(self): - man = logging.Manager(None) - expected = object() - man.setLogRecordFactory(expected) - self.assertEqual(man.logRecordFactory, expected) - - class ChildLoggerTest(BaseTest): - def test_child_loggers(self): - r = logging.getLogger() - l1 = logging.getLogger('abc') - l2 = logging.getLogger('def.ghi') - c1 = r.getChild('xyz') - c2 = r.getChild('uvw.xyz') - self.assertIs(c1, logging.getLogger('xyz')) - self.assertIs(c2, logging.getLogger('uvw.xyz')) - c1 = l1.getChild('def') - c2 = c1.getChild('ghi') - c3 = l1.getChild('def.ghi') - self.assertIs(c1, logging.getLogger('abc.def')) - self.assertIs(c2, logging.getLogger('abc.def.ghi')) - self.assertIs(c2, c3) - - - class DerivedLogRecord(logging.LogRecord): - pass - - class LogRecordFactoryTest(BaseTest): - - def setUp(self): - class CheckingFilter(logging.Filter): - def __init__(self, cls): - self.cls = cls - - def filter(self, record): - t = type(record) - if t is not self.cls: - msg = 'Unexpected LogRecord type %s, expected %s' % (t, - self.cls) - raise TypeError(msg) - return True - - BaseTest.setUp(self) - self.filter = CheckingFilter(DerivedLogRecord) - self.root_logger.addFilter(self.filter) - self.orig_factory = logging.getLogRecordFactory() - - def tearDown(self): - self.root_logger.removeFilter(self.filter) - BaseTest.tearDown(self) - logging.setLogRecordFactory(self.orig_factory) - - def test_logrecord_class(self): - self.assertRaises(TypeError, self.root_logger.warning, - self.next_message()) - logging.setLogRecordFactory(DerivedLogRecord) - self.root_logger.error(self.next_message()) - self.assert_log_lines([ - ('root', 'ERROR', '2'), - ]) - - - class QueueHandlerTest(BaseTest): - # Do not bother with a logger name group. - expected_log_pat = r"^[\w.]+ -> (\w+): (\d+)$" - - def setUp(self): - BaseTest.setUp(self) - self.queue = queue.Queue(-1) - self.que_hdlr = logging.handlers.QueueHandler(self.queue) - self.name = 'que' - self.que_logger = logging.getLogger('que') - self.que_logger.propagate = False - self.que_logger.setLevel(logging.WARNING) - self.que_logger.addHandler(self.que_hdlr) - - def tearDown(self): - self.que_hdlr.close() - BaseTest.tearDown(self) - - def test_queue_handler(self): - self.que_logger.debug(self.next_message()) - self.assertRaises(queue.Empty, self.queue.get_nowait) - self.que_logger.info(self.next_message()) - self.assertRaises(queue.Empty, self.queue.get_nowait) - msg = self.next_message() - self.que_logger.warning(msg) - data = self.queue.get_nowait() - self.assertTrue(isinstance(data, logging.LogRecord)) - self.assertEqual(data.name, self.que_logger.name) - self.assertEqual((data.msg, data.args), (msg, None)) - - def test_formatting(self): - msg = self.next_message() - levelname = logging.getLevelName(logging.WARNING) - log_format_str = '{name} -> {levelname}: {message}' - formatted_msg = log_format_str.format(name=self.name, - levelname=levelname, message=msg) - formatter = logging.Formatter(self.log_format) - self.que_hdlr.setFormatter(formatter) - self.que_logger.warning(msg) - log_record = self.queue.get_nowait() - self.assertEqual(formatted_msg, log_record.msg) - self.assertEqual(formatted_msg, log_record.message) - - @unittest.skipUnless(hasattr(logging.handlers, 'QueueListener'), - 'logging.handlers.QueueListener required for this test') - def test_queue_listener(self): - handler = support.TestHandler(support.Matcher()) - listener = logging.handlers.QueueListener(self.queue, handler) - listener.start() - try: - self.que_logger.warning(self.next_message()) - self.que_logger.error(self.next_message()) - self.que_logger.critical(self.next_message()) - finally: - listener.stop() - self.assertTrue(handler.matches(levelno=logging.WARNING, message='1')) - self.assertTrue(handler.matches(levelno=logging.ERROR, message='2')) - self.assertTrue(handler.matches(levelno=logging.CRITICAL, message='3')) - handler.close() - - # Now test with respect_handler_level set - - handler = support.TestHandler(support.Matcher()) - handler.setLevel(logging.CRITICAL) - listener = logging.handlers.QueueListener(self.queue, handler, - respect_handler_level=True) - listener.start() - try: - self.que_logger.warning(self.next_message()) - self.que_logger.error(self.next_message()) - self.que_logger.critical(self.next_message()) - finally: - listener.stop() - self.assertFalse(handler.matches(levelno=logging.WARNING, message='4')) - self.assertFalse(handler.matches(levelno=logging.ERROR, message='5')) - self.assertTrue(handler.matches(levelno=logging.CRITICAL, message='6')) - handler.close() - - @unittest.skipUnless(hasattr(logging.handlers, 'QueueListener'), - 'logging.handlers.QueueListener required for this test') - def test_queue_listener_with_StreamHandler(self): - # Test that traceback only appends once (bpo-34334). - listener = logging.handlers.QueueListener(self.queue, self.root_hdlr) - listener.start() - try: - 1 / 0 - except ZeroDivisionError as e: - exc = e - self.que_logger.exception(self.next_message(), exc_info=exc) - listener.stop() - self.assertEqual(self.stream.getvalue().strip().count('Traceback'), 1) - - @unittest.skipUnless(hasattr(logging.handlers, 'QueueListener'), - 'logging.handlers.QueueListener required for this test') - def test_queue_listener_with_multiple_handlers(self): - # Test that queue handler format doesn't affect other handler formats (bpo-35726). - self.que_hdlr.setFormatter(self.root_formatter) - self.que_logger.addHandler(self.root_hdlr) - - listener = logging.handlers.QueueListener(self.queue, self.que_hdlr) - listener.start() - self.que_logger.error("error") - listener.stop() - self.assertEqual(self.stream.getvalue().strip(), "que -> ERROR: error") - - if hasattr(logging.handlers, 'QueueListener'): - import multiprocessing - from unittest.mock import patch - - class QueueListenerTest(BaseTest): - """ - Tests based on patch submitted for issue #27930. Ensure that - QueueListener handles all log messages. - """ - - repeat = 20 - - @staticmethod - def setup_and_log(log_queue, ident): - """ - Creates a logger with a QueueHandler that logs to a queue read by a - QueueListener. Starts the listener, logs five messages, and stops - the listener. - """ - logger = logging.getLogger('test_logger_with_id_%s' % ident) - logger.setLevel(logging.DEBUG) - handler = logging.handlers.QueueHandler(log_queue) - logger.addHandler(handler) - listener = logging.handlers.QueueListener(log_queue) - listener.start() - - logger.info('one') - logger.info('two') - logger.info('three') - logger.info('four') - logger.info('five') - - listener.stop() - logger.removeHandler(handler) - handler.close() - - @patch.object(logging.handlers.QueueListener, 'handle') - def test_handle_called_with_queue_queue(self, mock_handle): - for i in range(self.repeat): - log_queue = queue.Queue() - self.setup_and_log(log_queue, '%s_%s' % (self.id(), i)) - self.assertEqual(mock_handle.call_count, 5 * self.repeat, - 'correct number of handled log messages') - - @patch.object(logging.handlers.QueueListener, 'handle') - def test_handle_called_with_mp_queue(self, mock_handle): - # bpo-28668: The multiprocessing (mp) module is not functional - # when the mp.synchronize module cannot be imported. - support.skip_if_broken_multiprocessing_synchronize() - for i in range(self.repeat): - log_queue = multiprocessing.Queue() - self.setup_and_log(log_queue, '%s_%s' % (self.id(), i)) - log_queue.close() - log_queue.join_thread() - self.assertEqual(mock_handle.call_count, 5 * self.repeat, - 'correct number of handled log messages') - - @staticmethod - def get_all_from_queue(log_queue): - try: - while True: - yield log_queue.get_nowait() - except queue.Empty: - return [] - - def test_no_messages_in_queue_after_stop(self): - """ - Five messages are logged then the QueueListener is stopped. This - test then gets everything off the queue. Failure of this test - indicates that messages were not registered on the queue until - _after_ the QueueListener stopped. - """ - # bpo-28668: The multiprocessing (mp) module is not functional - # when the mp.synchronize module cannot be imported. - support.skip_if_broken_multiprocessing_synchronize() - for i in range(self.repeat): - queue = multiprocessing.Queue() - self.setup_and_log(queue, '%s_%s' %(self.id(), i)) - # time.sleep(1) - items = list(self.get_all_from_queue(queue)) - queue.close() - queue.join_thread() - - expected = [[], [logging.handlers.QueueListener._sentinel]] - self.assertIn(items, expected, - 'Found unexpected messages in queue: %s' % ( - [m.msg if isinstance(m, logging.LogRecord) - else m for m in items])) - - def test_calls_task_done_after_stop(self): - # Issue 36813: Make sure queue.join does not deadlock. - log_queue = queue.Queue() - listener = logging.handlers.QueueListener(log_queue) - listener.start() - listener.stop() - with self.assertRaises(ValueError): - # Make sure all tasks are done and .join won't block. - log_queue.task_done() - - - ZERO = datetime.timedelta(0) - - class UTC(datetime.tzinfo): - def utcoffset(self, dt): - return ZERO - - dst = utcoffset - - def tzname(self, dt): - return 'UTC' - - utc = UTC() - - class FormatterTest(unittest.TestCase): - def setUp(self): - self.common = { - 'name': 'formatter.test', - 'level': logging.DEBUG, - 'pathname': os.path.join('path', 'to', 'dummy.ext'), - 'lineno': 42, - 'exc_info': None, - 'func': None, - 'msg': 'Message with %d %s', - 'args': (2, 'placeholders'), - } - self.variants = { - } - - def get_record(self, name=None): - result = dict(self.common) - if name is not None: - result.update(self.variants[name]) - return logging.makeLogRecord(result) - - def assert_error_message(self, exception, message, *args, **kwargs): - try: - self.assertRaises(exception, *args, **kwargs) - except exception as e: - self.assertEqual(message, e.message) - - def test_percent(self): - # Test %-formatting - r = self.get_record() - f = logging.Formatter('${%(message)s}') - self.assertEqual(f.format(r), '${Message with 2 placeholders}') - f = logging.Formatter('%(random)s') - self.assertRaises(ValueError, f.format, r) - self.assertFalse(f.usesTime()) - f = logging.Formatter('%(asctime)s') - self.assertTrue(f.usesTime()) - f = logging.Formatter('%(asctime)-15s') - self.assertTrue(f.usesTime()) - f = logging.Formatter('%(asctime)#15s') - self.assertTrue(f.usesTime()) - - def test_braces(self): - # Test {}-formatting - r = self.get_record() - f = logging.Formatter('$%{message}%$', style='{') - self.assertEqual(f.format(r), '$%Message with 2 placeholders%$') - f = logging.Formatter('{random}', style='{') - self.assertRaises(ValueError, f.format, r) - f = logging.Formatter("{message}", style='{') - self.assertFalse(f.usesTime()) - f = logging.Formatter('{asctime}', style='{') - self.assertTrue(f.usesTime()) - f = logging.Formatter('{asctime!s:15}', style='{') - self.assertTrue(f.usesTime()) - f = logging.Formatter('{asctime:15}', style='{') - self.assertTrue(f.usesTime()) - - def test_dollars(self): - # Test $-formatting - r = self.get_record() - f = logging.Formatter('${message}', style='$') - self.assertEqual(f.format(r), 'Message with 2 placeholders') - f = logging.Formatter('$message', style='$') - self.assertEqual(f.format(r), 'Message with 2 placeholders') - f = logging.Formatter('$$%${message}%$$', style='$') - self.assertEqual(f.format(r), '$%Message with 2 placeholders%$') - f = logging.Formatter('${random}', style='$') - self.assertRaises(ValueError, f.format, r) - self.assertFalse(f.usesTime()) - f = logging.Formatter('${asctime}', style='$') - self.assertTrue(f.usesTime()) - f = logging.Formatter('$asctime', style='$') - self.assertTrue(f.usesTime()) - f = logging.Formatter('${message}', style='$') - self.assertFalse(f.usesTime()) - f = logging.Formatter('${asctime}--', style='$') - self.assertTrue(f.usesTime()) - - def test_format_validate(self): - # Check correct formatting - # Percentage style - f = logging.Formatter("%(levelname)-15s - %(message) 5s - %(process)03d - %(module) - %(asctime)*.3s") - self.assertEqual(f._fmt, "%(levelname)-15s - %(message) 5s - %(process)03d - %(module) - %(asctime)*.3s") - f = logging.Formatter("%(asctime)*s - %(asctime)*.3s - %(process)-34.33o") - self.assertEqual(f._fmt, "%(asctime)*s - %(asctime)*.3s - %(process)-34.33o") - f = logging.Formatter("%(process)#+027.23X") - self.assertEqual(f._fmt, "%(process)#+027.23X") - f = logging.Formatter("%(foo)#.*g") - self.assertEqual(f._fmt, "%(foo)#.*g") - - # StrFormat Style - f = logging.Formatter("$%{message}%$ - {asctime!a:15} - {customfield['key']}", style="{") - self.assertEqual(f._fmt, "$%{message}%$ - {asctime!a:15} - {customfield['key']}") - f = logging.Formatter("{process:.2f} - {custom.f:.4f}", style="{") - self.assertEqual(f._fmt, "{process:.2f} - {custom.f:.4f}") - f = logging.Formatter("{customfield!s:#<30}", style="{") - self.assertEqual(f._fmt, "{customfield!s:#<30}") - f = logging.Formatter("{message!r}", style="{") - self.assertEqual(f._fmt, "{message!r}") - f = logging.Formatter("{message!s}", style="{") - self.assertEqual(f._fmt, "{message!s}") - f = logging.Formatter("{message!a}", style="{") - self.assertEqual(f._fmt, "{message!a}") - f = logging.Formatter("{process!r:4.2}", style="{") - self.assertEqual(f._fmt, "{process!r:4.2}") - f = logging.Formatter("{process!s:<#30,.12f}- {custom:=+#30,.1d} - {module:^30}", style="{") - self.assertEqual(f._fmt, "{process!s:<#30,.12f}- {custom:=+#30,.1d} - {module:^30}") - f = logging.Formatter("{process!s:{w},.{p}}", style="{") - self.assertEqual(f._fmt, "{process!s:{w},.{p}}") - f = logging.Formatter("{foo:12.{p}}", style="{") - self.assertEqual(f._fmt, "{foo:12.{p}}") - f = logging.Formatter("{foo:{w}.6}", style="{") - self.assertEqual(f._fmt, "{foo:{w}.6}") - f = logging.Formatter("{foo[0].bar[1].baz}", style="{") - self.assertEqual(f._fmt, "{foo[0].bar[1].baz}") - f = logging.Formatter("{foo[k1].bar[k2].baz}", style="{") - self.assertEqual(f._fmt, "{foo[k1].bar[k2].baz}") - f = logging.Formatter("{12[k1].bar[k2].baz}", style="{") - self.assertEqual(f._fmt, "{12[k1].bar[k2].baz}") - - # Dollar style - f = logging.Formatter("${asctime} - $message", style="$") - self.assertEqual(f._fmt, "${asctime} - $message") - f = logging.Formatter("$bar $$", style="$") - self.assertEqual(f._fmt, "$bar $$") - f = logging.Formatter("$bar $$$$", style="$") - self.assertEqual(f._fmt, "$bar $$$$") # this would print two $($$) - - # Testing when ValueError being raised from incorrect format - # Percentage Style - self.assertRaises(ValueError, logging.Formatter, "%(asctime)Z") - self.assertRaises(ValueError, logging.Formatter, "%(asctime)b") - self.assertRaises(ValueError, logging.Formatter, "%(asctime)*") - self.assertRaises(ValueError, logging.Formatter, "%(asctime)*3s") - self.assertRaises(ValueError, logging.Formatter, "%(asctime)_") - self.assertRaises(ValueError, logging.Formatter, '{asctime}') - self.assertRaises(ValueError, logging.Formatter, '${message}') - self.assertRaises(ValueError, logging.Formatter, '%(foo)#12.3*f') # with both * and decimal number as precision - self.assertRaises(ValueError, logging.Formatter, '%(foo)0*.8*f') - - # StrFormat Style - # Testing failure for '-' in field name - self.assert_error_message( - ValueError, - "invalid field name/expression: 'name-thing'", - logging.Formatter, "{name-thing}", style="{" - ) - # Testing failure for style mismatch - self.assert_error_message( - ValueError, - "invalid format: no fields", - logging.Formatter, '%(asctime)s', style='{' - ) - # Testing failure for invalid conversion - self.assert_error_message( - ValueError, - "invalid conversion: 'Z'" - ) - self.assertRaises(ValueError, logging.Formatter, '{asctime!s:#30,15f}', style='{') - self.assert_error_message( - ValueError, - "invalid format: expected ':' after conversion specifier", - logging.Formatter, '{asctime!aa:15}', style='{' - ) - # Testing failure for invalid spec - self.assert_error_message( - ValueError, - "bad specifier: '.2ff'", - logging.Formatter, '{process:.2ff}', style='{' - ) - self.assertRaises(ValueError, logging.Formatter, '{process:.2Z}', style='{') - self.assertRaises(ValueError, logging.Formatter, '{process!s:<##30,12g}', style='{') - self.assertRaises(ValueError, logging.Formatter, '{process!s:<#30#,12g}', style='{') - self.assertRaises(ValueError, logging.Formatter, '{process!s:{{w}},{{p}}}', style='{') - # Testing failure for mismatch braces - self.assert_error_message( - ValueError, - "invalid format: unmatched '{' in format spec", - logging.Formatter, '{process', style='{' - ) - self.assert_error_message( - ValueError, - "invalid format: unmatched '{' in format spec", - logging.Formatter, 'process}', style='{' - ) - self.assertRaises(ValueError, logging.Formatter, '{{foo!r:4.2}', style='{') - self.assertRaises(ValueError, logging.Formatter, '{{foo!r:4.2}}', style='{') - self.assertRaises(ValueError, logging.Formatter, '{foo/bar}', style='{') - self.assertRaises(ValueError, logging.Formatter, '{foo:{{w}}.{{p}}}}', style='{') - self.assertRaises(ValueError, logging.Formatter, '{foo!X:{{w}}.{{p}}}', style='{') - self.assertRaises(ValueError, logging.Formatter, '{foo!a:random}', style='{') - self.assertRaises(ValueError, logging.Formatter, '{foo!a:ran{dom}', style='{') - self.assertRaises(ValueError, logging.Formatter, '{foo!a:ran{d}om}', style='{') - self.assertRaises(ValueError, logging.Formatter, '{foo.!a:d}', style='{') - - # Dollar style - # Testing failure for mismatch bare $ - self.assert_error_message( - ValueError, - "invalid format: bare \'$\' not allowed", - logging.Formatter, '$bar $$$', style='$' - ) - self.assert_error_message( - ValueError, - "invalid format: bare \'$\' not allowed", - logging.Formatter, 'bar $', style='$' - ) - self.assert_error_message( - ValueError, - "invalid format: bare \'$\' not allowed", - logging.Formatter, 'foo $.', style='$' - ) - # Testing failure for mismatch style - self.assert_error_message( - ValueError, - "invalid format: no fields", - logging.Formatter, '{asctime}', style='$' - ) - self.assertRaises(ValueError, logging.Formatter, '%(asctime)s', style='$') - - # Testing failure for incorrect fields - self.assert_error_message( - ValueError, - "invalid format: no fields", - logging.Formatter, 'foo', style='$' - ) - self.assertRaises(ValueError, logging.Formatter, '${asctime', style='$') - - def test_invalid_style(self): - self.assertRaises(ValueError, logging.Formatter, None, None, 'x') - - def test_time(self): - r = self.get_record() - dt = datetime.datetime(1993, 4, 21, 8, 3, 0, 0, utc) - # We use None to indicate we want the local timezone - # We're essentially converting a UTC time to local time - r.created = time.mktime(dt.astimezone(None).timetuple()) - r.msecs = 123 - f = logging.Formatter('%(asctime)s %(message)s') - f.converter = time.gmtime - self.assertEqual(f.formatTime(r), '1993-04-21 08:03:00,123') - self.assertEqual(f.formatTime(r, '%Y:%d'), '1993:21') - f.format(r) - self.assertEqual(r.asctime, '1993-04-21 08:03:00,123') - - class TestBufferingFormatter(logging.BufferingFormatter): - def formatHeader(self, records): - return '[(%d)' % len(records) - - def formatFooter(self, records): - return '(%d)]' % len(records) - - class BufferingFormatterTest(unittest.TestCase): - def setUp(self): - self.records = [ - logging.makeLogRecord({'msg': 'one'}), - logging.makeLogRecord({'msg': 'two'}), - ] - - def test_default(self): - f = logging.BufferingFormatter() - self.assertEqual('', f.format([])) - self.assertEqual('onetwo', f.format(self.records)) - - def test_custom(self): - f = TestBufferingFormatter() - self.assertEqual('[(2)onetwo(2)]', f.format(self.records)) - lf = logging.Formatter('<%(message)s>') - f = TestBufferingFormatter(lf) - self.assertEqual('[(2)(2)]', f.format(self.records)) - - class ExceptionTest(BaseTest): - def test_formatting(self): pass - - class LastResortTest(BaseTest): - def test_last_resort(self): - # Test the last resort handler - root = self.root_logger - root.removeHandler(self.root_hdlr) - old_lastresort = logging.lastResort - old_raise_exceptions = logging.raiseExceptions - - try: - with support.captured_stderr() as stderr: - root.debug('This should not appear') - self.assertEqual(stderr.getvalue(), '') - root.warning('Final chance!') - self.assertEqual(stderr.getvalue(), 'Final chance!\n') - - # No handlers and no last resort, so 'No handlers' message - logging.lastResort = None - with support.captured_stderr() as stderr: - root.warning('Final chance!') - msg = 'No handlers could be found for logger "root"\n' - self.assertEqual(stderr.getvalue(), msg) - - # 'No handlers' message only printed once - with support.captured_stderr() as stderr: - root.warning('Final chance!') - self.assertEqual(stderr.getvalue(), '') - - # If raiseExceptions is False, no message is printed - root.manager.emittedNoHandlerWarning = False - logging.raiseExceptions = False - with support.captured_stderr() as stderr: - root.warning('Final chance!') - self.assertEqual(stderr.getvalue(), '') - finally: - root.addHandler(self.root_hdlr) - logging.lastResort = old_lastresort - logging.raiseExceptions = old_raise_exceptions - - - class FakeHandler: - - def __init__(self, identifier, called): - for method in ('acquire', 'flush', 'close', 'release'): - setattr(self, method, self.record_call(identifier, method, called)) - - def record_call(self, identifier, method_name, called): - def inner(): - called.append('{} - {}'.format(identifier, method_name)) - return inner - - - class RecordingHandler(logging.NullHandler): - - def __init__(self, *args, **kwargs): - super(RecordingHandler, self).__init__(*args, **kwargs) - self.records = [] - - def handle(self, record): - """Keep track of all the emitted records.""" - self.records.append(record) - - - class ShutdownTest(BaseTest): - - """Test suite for the shutdown method.""" - - def setUp(self): - super(ShutdownTest, self).setUp() - self.called = [] - - raise_exceptions = logging.raiseExceptions - self.addCleanup(setattr, logging, 'raiseExceptions', raise_exceptions) - - def raise_error(self, error): - def inner(): - raise error() - return inner - - def test_no_failure(self): - # create some fake handlers - handler0 = FakeHandler(0, self.called) - handler1 = FakeHandler(1, self.called) - handler2 = FakeHandler(2, self.called) - - # create live weakref to those handlers - handlers = map(logging.weakref.ref, [handler0, handler1, handler2]) - - logging.shutdown(handlerList=list(handlers)) - - expected = ['2 - acquire', '2 - flush', '2 - close', '2 - release', - '1 - acquire', '1 - flush', '1 - close', '1 - release', - '0 - acquire', '0 - flush', '0 - close', '0 - release'] - self.assertEqual(expected, self.called) - - def _test_with_failure_in_method(self, method, error): - handler = FakeHandler(0, self.called) - setattr(handler, method, self.raise_error(error)) - handlers = [logging.weakref.ref(handler)] - - logging.shutdown(handlerList=list(handlers)) - - self.assertEqual('0 - release', self.called[-1]) - - def test_with_ioerror_in_acquire(self): - self._test_with_failure_in_method('acquire', OSError) - - def test_with_ioerror_in_flush(self): - self._test_with_failure_in_method('flush', OSError) - - def test_with_ioerror_in_close(self): - self._test_with_failure_in_method('close', OSError) - - def test_with_valueerror_in_acquire(self): - self._test_with_failure_in_method('acquire', ValueError) - - def test_with_valueerror_in_flush(self): - self._test_with_failure_in_method('flush', ValueError) - - def test_with_valueerror_in_close(self): - self._test_with_failure_in_method('close', ValueError) - - def test_with_other_error_in_acquire_without_raise(self): - logging.raiseExceptions = False - self._test_with_failure_in_method('acquire', IndexError) - - def test_with_other_error_in_flush_without_raise(self): - logging.raiseExceptions = False - self._test_with_failure_in_method('flush', IndexError) - - def test_with_other_error_in_close_without_raise(self): - logging.raiseExceptions = False - self._test_with_failure_in_method('close', IndexError) - - def test_with_other_error_in_acquire_with_raise(self): - logging.raiseExceptions = True - self.assertRaises(IndexError, self._test_with_failure_in_method, - 'acquire', IndexError) - - def test_with_other_error_in_flush_with_raise(self): - logging.raiseExceptions = True - self.assertRaises(IndexError, self._test_with_failure_in_method, - 'flush', IndexError) - - def test_with_other_error_in_close_with_raise(self): - logging.raiseExceptions = True - self.assertRaises(IndexError, self._test_with_failure_in_method, - 'close', IndexError) - - - class ModuleLevelMiscTest(BaseTest): - - """Test suite for some module level methods.""" - - def test_disable(self): - old_disable = logging.root.manager.disable - # confirm our assumptions are correct - self.assertEqual(old_disable, 0) - self.addCleanup(logging.disable, old_disable) - - logging.disable(83) - self.assertEqual(logging.root.manager.disable, 83) - - self.assertRaises(ValueError, logging.disable, "doesnotexists") - - class _NotAnIntOrString: - pass - - self.assertRaises(TypeError, logging.disable, _NotAnIntOrString()) - - logging.disable("WARN") - - # test the default value introduced in 3.7 - # (Issue #28524) - logging.disable() - self.assertEqual(logging.root.manager.disable, logging.CRITICAL) - - def _test_log(self, method, level=None): - called = [] - support.patch(self, logging, 'basicConfig', - lambda *a, **kw: called.append((a, kw))) - - recording = RecordingHandler() - logging.root.addHandler(recording) - - log_method = getattr(logging, method) - if level is not None: - log_method(level, "test me: %r", recording) - else: - log_method("test me: %r", recording) - - self.assertEqual(len(recording.records), 1) - record = recording.records[0] - self.assertEqual(record.getMessage(), "test me: %r" % recording) - - expected_level = level if level is not None else getattr(logging, method.upper()) - self.assertEqual(record.levelno, expected_level) - - # basicConfig was not called! - self.assertEqual(called, []) - - def test_log(self): - self._test_log('log', logging.ERROR) - - def test_debug(self): - self._test_log('debug') - - def test_info(self): - self._test_log('info') - - def test_warning(self): - self._test_log('warning') - - def test_error(self): - self._test_log('error') - - def test_critical(self): - self._test_log('critical') - - def test_set_logger_class(self): - self.assertRaises(TypeError, logging.setLoggerClass, object) - - class MyLogger(logging.Logger): - pass - - logging.setLoggerClass(MyLogger) - self.assertEqual(logging.getLoggerClass(), MyLogger) - - logging.setLoggerClass(logging.Logger) - self.assertEqual(logging.getLoggerClass(), logging.Logger) - - def test_subclass_logger_cache(self): - # bpo-37258 - message = [] - - class MyLogger(logging.getLoggerClass()): - def __init__(self, name='MyLogger', level=logging.NOTSET): - super().__init__(name, level) - message.append('initialized') - - logging.setLoggerClass(MyLogger) - logger = logging.getLogger('just_some_logger') - self.assertEqual(message, ['initialized']) - stream = io.StringIO() - h = logging.StreamHandler(stream) - logger.addHandler(h) - try: - logger.setLevel(logging.DEBUG) - logger.debug("hello") - self.assertEqual(stream.getvalue().strip(), "hello") - - stream.truncate(0) - stream.seek(0) - - logger.setLevel(logging.INFO) - logger.debug("hello") - self.assertEqual(stream.getvalue(), "") - finally: - logger.removeHandler(h) - h.close() - logging.setLoggerClass(logging.Logger) - - @support.requires_type_collecting - def test_logging_at_shutdown(self): - # Issue #20037 - code = """if 1: - import logging - - class A: - def __del__(self): - try: - raise ValueError("some error") - except Exception: - logging.exception("exception in __del__") - - a = A()""" - rc, out, err = assert_python_ok("-c", code) - err = err.decode() - self.assertIn("exception in __del__", err) - self.assertIn("ValueError: some error", err) - - def test_recursion_error(self): - # Issue 36272 - code = """if 1: - import logging - - def rec(): - logging.error("foo") - rec() - - rec()""" - rc, out, err = assert_python_failure("-c", code) - err = err.decode() - self.assertNotIn("Cannot recover from stack overflow.", err) - self.assertEqual(rc, 1) - - - class LogRecordTest(BaseTest): - def test_str_rep(self): - r = logging.makeLogRecord({}) - s = str(r) - self.assertTrue(s.startswith('')) - - def test_dict_arg(self): - h = RecordingHandler() - r = logging.getLogger() - r.addHandler(h) - d = {'less' : 'more' } - logging.warning('less is %(less)s', d) - self.assertIs(h.records[0].args, d) - self.assertEqual(h.records[0].message, 'less is more') - r.removeHandler(h) - h.close() - - def test_multiprocessing(self): - r = logging.makeLogRecord({}) - self.assertEqual(r.processName, 'MainProcess') - try: - import multiprocessing as mp - r = logging.makeLogRecord({}) - self.assertEqual(r.processName, mp.current_process().name) - except ImportError: - pass - - def test_optional(self): - r = logging.makeLogRecord({}) - NOT_NONE = self.assertIsNotNone - NOT_NONE(r.thread) - NOT_NONE(r.threadName) - NOT_NONE(r.process) - NOT_NONE(r.processName) - log_threads = logging.logThreads - log_processes = logging.logProcesses - log_multiprocessing = logging.logMultiprocessing - try: - logging.logThreads = False - logging.logProcesses = False - logging.logMultiprocessing = False - r = logging.makeLogRecord({}) - NONE = self.assertIsNone - NONE(r.thread) - NONE(r.threadName) - NONE(r.process) - NONE(r.processName) - finally: - logging.logThreads = log_threads - logging.logProcesses = log_processes - logging.logMultiprocessing = log_multiprocessing - - class BasicConfigTest(unittest.TestCase): - - """Test suite for logging.basicConfig.""" - - def setUp(self): - super(BasicConfigTest, self).setUp() - self.handlers = logging.root.handlers - self.saved_handlers = logging._handlers.copy() - self.saved_handler_list = logging._handlerList[:] - self.original_logging_level = logging.root.level - self.addCleanup(self.cleanup) - logging.root.handlers = [] - - def tearDown(self): - for h in logging.root.handlers[:]: - logging.root.removeHandler(h) - h.close() - super(BasicConfigTest, self).tearDown() - - def cleanup(self): - setattr(logging.root, 'handlers', self.handlers) - logging._handlers.clear() - logging._handlers.update(self.saved_handlers) - logging._handlerList[:] = self.saved_handler_list - logging.root.setLevel(self.original_logging_level) - - def test_no_kwargs(self): - logging.basicConfig() - - # handler defaults to a StreamHandler to sys.stderr - self.assertEqual(len(logging.root.handlers), 1) - handler = logging.root.handlers[0] - self.assertIsInstance(handler, logging.StreamHandler) - self.assertEqual(handler.stream, sys.stderr) - - formatter = handler.formatter - # format defaults to logging.BASIC_FORMAT - self.assertEqual(formatter._style._fmt, logging.BASIC_FORMAT) - # datefmt defaults to None - self.assertIsNone(formatter.datefmt) - # style defaults to % - self.assertIsInstance(formatter._style, logging.PercentStyle) - - # level is not explicitly set - self.assertEqual(logging.root.level, self.original_logging_level) - - def test_strformatstyle(self): - with support.captured_stdout() as output: - logging.basicConfig(stream=sys.stdout, style="{") - logging.error("Log an error") - sys.stdout.seek(0) - self.assertEqual(output.getvalue().strip(), - "ERROR:root:Log an error") - - def test_stringtemplatestyle(self): - with support.captured_stdout() as output: - logging.basicConfig(stream=sys.stdout, style="$") - logging.error("Log an error") - sys.stdout.seek(0) - self.assertEqual(output.getvalue().strip(), - "ERROR:root:Log an error") - - def test_filename(self): - - def cleanup(h1, h2, fn): - h1.close() - h2.close() - os.remove(fn) - - logging.basicConfig(filename='test.log') - - self.assertEqual(len(logging.root.handlers), 1) - handler = logging.root.handlers[0] - self.assertIsInstance(handler, logging.FileHandler) - - expected = logging.FileHandler('test.log', 'a') - self.assertEqual(handler.stream.mode, expected.stream.mode) - self.assertEqual(handler.stream.name, expected.stream.name) - self.addCleanup(cleanup, handler, expected, 'test.log') - - def test_filemode(self): - - def cleanup(h1, h2, fn): - h1.close() - h2.close() - os.remove(fn) - - logging.basicConfig(filename='test.log', filemode='wb') - - handler = logging.root.handlers[0] - expected = logging.FileHandler('test.log', 'wb') - self.assertEqual(handler.stream.mode, expected.stream.mode) - self.addCleanup(cleanup, handler, expected, 'test.log') - - def test_stream(self): - stream = io.StringIO() - self.addCleanup(stream.close) - logging.basicConfig(stream=stream) - - self.assertEqual(len(logging.root.handlers), 1) - handler = logging.root.handlers[0] - self.assertIsInstance(handler, logging.StreamHandler) - self.assertEqual(handler.stream, stream) - - def test_format(self): - logging.basicConfig(format='%(asctime)s - %(message)s') - - formatter = logging.root.handlers[0].formatter - self.assertEqual(formatter._style._fmt, '%(asctime)s - %(message)s') - - def test_datefmt(self): - logging.basicConfig(datefmt='bar') - - formatter = logging.root.handlers[0].formatter - self.assertEqual(formatter.datefmt, 'bar') - - def test_style(self): - logging.basicConfig(style='$') - - formatter = logging.root.handlers[0].formatter - self.assertIsInstance(formatter._style, logging.StringTemplateStyle) - - def test_level(self): - old_level = logging.root.level - self.addCleanup(logging.root.setLevel, old_level) - - logging.basicConfig(level=57) - self.assertEqual(logging.root.level, 57) - # Test that second call has no effect - logging.basicConfig(level=58) - self.assertEqual(logging.root.level, 57) - - def test_incompatible(self): - assertRaises = self.assertRaises - handlers = [logging.StreamHandler()] - stream = sys.stderr - assertRaises(ValueError, logging.basicConfig, filename='test.log', - stream=stream) - assertRaises(ValueError, logging.basicConfig, filename='test.log', - handlers=handlers) - assertRaises(ValueError, logging.basicConfig, stream=stream, - handlers=handlers) - # Issue 23207: test for invalid kwargs - assertRaises(ValueError, logging.basicConfig, loglevel=logging.INFO) - # Should pop both filename and filemode even if filename is None - logging.basicConfig(filename=None, filemode='a') - - def test_handlers(self): - handlers = [ - logging.StreamHandler(), - logging.StreamHandler(sys.stdout), - logging.StreamHandler(), - ] - f = logging.Formatter() - handlers[2].setFormatter(f) - logging.basicConfig(handlers=handlers) - self.assertIs(handlers[0], logging.root.handlers[0]) - self.assertIs(handlers[1], logging.root.handlers[1]) - self.assertIs(handlers[2], logging.root.handlers[2]) - self.assertIsNotNone(handlers[0].formatter) - self.assertIsNotNone(handlers[1].formatter) - self.assertIs(handlers[2].formatter, f) - self.assertIs(handlers[0].formatter, handlers[1].formatter) - - def test_force(self): - old_string_io = io.StringIO() - new_string_io = io.StringIO() - old_handlers = [logging.StreamHandler(old_string_io)] - new_handlers = [logging.StreamHandler(new_string_io)] - logging.basicConfig(level=logging.WARNING, handlers=old_handlers) - logging.warning('warn') - logging.info('info') - logging.debug('debug') - self.assertEqual(len(logging.root.handlers), 1) - logging.basicConfig(level=logging.INFO, handlers=new_handlers, - force=True) - logging.warning('warn') - logging.info('info') - logging.debug('debug') - self.assertEqual(len(logging.root.handlers), 1) - self.assertEqual(old_string_io.getvalue().strip(), - 'WARNING:root:warn') - self.assertEqual(new_string_io.getvalue().strip(), - 'WARNING:root:warn\nINFO:root:info') - - def _test_log(self, method, level=None): - # logging.root has no handlers so basicConfig should be called - called = [] - - old_basic_config = logging.basicConfig - def my_basic_config(*a, **kw): - old_basic_config() - old_level = logging.root.level - logging.root.setLevel(100) # avoid having messages in stderr - self.addCleanup(logging.root.setLevel, old_level) - called.append((a, kw)) - - support.patch(self, logging, 'basicConfig', my_basic_config) - - log_method = getattr(logging, method) - if level is not None: - log_method(level, "test me") - else: - log_method("test me") - - # basicConfig was called with no arguments - self.assertEqual(called, [((), {})]) - - def test_log(self): - self._test_log('log', logging.WARNING) - - def test_debug(self): - self._test_log('debug') - - def test_info(self): - self._test_log('info') - - def test_warning(self): - self._test_log('warning') - - def test_error(self): - self._test_log('error') - - def test_critical(self): - self._test_log('critical') - - - class LoggerAdapterTest(unittest.TestCase): - def setUp(self): - super(LoggerAdapterTest, self).setUp() - old_handler_list = logging._handlerList[:] - - self.recording = RecordingHandler() - self.logger = logging.root - self.logger.addHandler(self.recording) - self.addCleanup(self.logger.removeHandler, self.recording) - self.addCleanup(self.recording.close) - - def cleanup(): - logging._handlerList[:] = old_handler_list - - self.addCleanup(cleanup) - self.addCleanup(logging.shutdown) - self.adapter = logging.LoggerAdapter(logger=self.logger, extra=None) - - def test_exception(self): - msg = 'testing exception: %r' - exc = None - try: - 1 / 0 - except ZeroDivisionError as e: - exc = e - self.adapter.exception(msg, self.recording) - - self.assertEqual(len(self.recording.records), 1) - record = self.recording.records[0] - self.assertEqual(record.levelno, logging.ERROR) - self.assertEqual(record.msg, msg) - self.assertEqual(record.args, (self.recording,)) - self.assertEqual(record.exc_info, - (exc.__class__, exc, exc.__traceback__)) - - def test_exception_excinfo(self): - try: - 1 / 0 - except ZeroDivisionError as e: - exc = e - - self.adapter.exception('exc_info test', exc_info=exc) - - self.assertEqual(len(self.recording.records), 1) - record = self.recording.records[0] - self.assertEqual(record.exc_info, - (exc.__class__, exc, exc.__traceback__)) - - def test_critical(self): - msg = 'critical test! %r' - self.adapter.critical(msg, self.recording) - - self.assertEqual(len(self.recording.records), 1) - record = self.recording.records[0] - self.assertEqual(record.levelno, logging.CRITICAL) - self.assertEqual(record.msg, msg) - self.assertEqual(record.args, (self.recording,)) - - def test_is_enabled_for(self): - old_disable = self.adapter.logger.manager.disable - self.adapter.logger.manager.disable = 33 - self.addCleanup(setattr, self.adapter.logger.manager, 'disable', - old_disable) - self.assertFalse(self.adapter.isEnabledFor(32)) - - def test_has_handlers(self): - self.assertTrue(self.adapter.hasHandlers()) - - for handler in self.logger.handlers: - self.logger.removeHandler(handler) - - self.assertFalse(self.logger.hasHandlers()) - self.assertFalse(self.adapter.hasHandlers()) - - def test_nested(self): - class Adapter(logging.LoggerAdapter): - prefix = 'Adapter' - - def process(self, msg, kwargs): - return f"{self.prefix} {msg}", kwargs - - msg = 'Adapters can be nested, yo.' - adapter = Adapter(logger=self.logger, extra=None) - adapter_adapter = Adapter(logger=adapter, extra=None) - adapter_adapter.prefix = 'AdapterAdapter' - self.assertEqual(repr(adapter), repr(adapter_adapter)) - adapter_adapter.log(logging.CRITICAL, msg, self.recording) - self.assertEqual(len(self.recording.records), 1) - record = self.recording.records[0] - self.assertEqual(record.levelno, logging.CRITICAL) - self.assertEqual(record.msg, f"Adapter AdapterAdapter {msg}") - self.assertEqual(record.args, (self.recording,)) - orig_manager = adapter_adapter.manager - self.assertIs(adapter.manager, orig_manager) - self.assertIs(self.logger.manager, orig_manager) - temp_manager = object() - try: - adapter_adapter.manager = temp_manager - self.assertIs(adapter_adapter.manager, temp_manager) - self.assertIs(adapter.manager, temp_manager) - self.assertIs(self.logger.manager, temp_manager) - finally: - adapter_adapter.manager = orig_manager - self.assertIs(adapter_adapter.manager, orig_manager) - self.assertIs(adapter.manager, orig_manager) - self.assertIs(self.logger.manager, orig_manager) - - - class LoggerTest(BaseTest): - - def setUp(self): - super(LoggerTest, self).setUp() - self.recording = RecordingHandler() - self.logger = logging.Logger(name='blah') - self.logger.addHandler(self.recording) - self.addCleanup(self.logger.removeHandler, self.recording) - self.addCleanup(self.recording.close) - self.addCleanup(logging.shutdown) - - def test_set_invalid_level(self): - self.assertRaises(TypeError, self.logger.setLevel, object()) - - def test_exception(self): - msg = 'testing exception: %r' - exc = None - try: - 1 / 0 - except ZeroDivisionError as e: - exc = e - self.logger.exception(msg, self.recording) - - self.assertEqual(len(self.recording.records), 1) - record = self.recording.records[0] - self.assertEqual(record.levelno, logging.ERROR) - self.assertEqual(record.msg, msg) - self.assertEqual(record.args, (self.recording,)) - self.assertEqual(record.exc_info, - (exc.__class__, exc, exc.__traceback__)) - - def test_log_invalid_level_with_raise(self): - with support.swap_attr(logging, 'raiseExceptions', True): - self.assertRaises(TypeError, self.logger.log, '10', 'test message') - - def test_log_invalid_level_no_raise(self): - with support.swap_attr(logging, 'raiseExceptions', False): - self.logger.log('10', 'test message') # no exception happens - - def test_find_caller_with_stack_info(self): - called = [] - support.patch(self, logging.traceback, 'print_stack', - lambda f, file: called.append(file.getvalue())) - - self.logger.findCaller(stack_info=True) - - self.assertEqual(len(called), 1) - self.assertEqual('Stack (most recent call last):\n', called[0]) - - def test_find_caller_with_stacklevel(self): - the_level = 1 - - def innermost(): - self.logger.warning('test', stacklevel=the_level) - - def inner(): - innermost() - - def outer(): - inner() - - records = self.recording.records - outer() - self.assertEqual(records[-1].funcName, 'innermost') - lineno = records[-1].lineno - the_level += 1 - outer() - self.assertEqual(records[-1].funcName, 'inner') - self.assertGreater(records[-1].lineno, lineno) - lineno = records[-1].lineno - the_level += 1 - outer() - self.assertEqual(records[-1].funcName, 'outer') - self.assertGreater(records[-1].lineno, lineno) - lineno = records[-1].lineno - the_level += 1 - outer() - self.assertEqual(records[-1].funcName, 'test_find_caller_with_stacklevel') - self.assertGreater(records[-1].lineno, lineno) - - def test_make_record_with_extra_overwrite(self): - name = 'my record' - level = 13 - fn = lno = msg = args = exc_info = func = sinfo = None - rv = logging._logRecordFactory(name, level, fn, lno, msg, args, - exc_info, func, sinfo) - - for key in ('message', 'asctime') + tuple(rv.__dict__.keys()): - extra = {key: 'some value'} - self.assertRaises(KeyError, self.logger.makeRecord, name, level, - fn, lno, msg, args, exc_info, - extra=extra, sinfo=sinfo) - - def test_make_record_with_extra_no_overwrite(self): - name = 'my record' - level = 13 - fn = lno = msg = args = exc_info = func = sinfo = None - extra = {'valid_key': 'some value'} - result = self.logger.makeRecord(name, level, fn, lno, msg, args, - exc_info, extra=extra, sinfo=sinfo) - self.assertIn('valid_key', result.__dict__) - - def test_has_handlers(self): - self.assertTrue(self.logger.hasHandlers()) - - for handler in self.logger.handlers: - self.logger.removeHandler(handler) - self.assertFalse(self.logger.hasHandlers()) - - def test_has_handlers_no_propagate(self): - child_logger = logging.getLogger('blah.child') - child_logger.propagate = False - self.assertFalse(child_logger.hasHandlers()) - - def test_is_enabled_for(self): - old_disable = self.logger.manager.disable - self.logger.manager.disable = 23 - self.addCleanup(setattr, self.logger.manager, 'disable', old_disable) - self.assertFalse(self.logger.isEnabledFor(22)) - - def test_is_enabled_for_disabled_logger(self): - old_disabled = self.logger.disabled - old_disable = self.logger.manager.disable - - self.logger.disabled = True - self.logger.manager.disable = 21 - - self.addCleanup(setattr, self.logger, 'disabled', old_disabled) - self.addCleanup(setattr, self.logger.manager, 'disable', old_disable) - - self.assertFalse(self.logger.isEnabledFor(22)) - - def test_root_logger_aliases(self): - root = logging.getLogger() - self.assertIs(root, logging.root) - self.assertIs(root, logging.getLogger(None)) - self.assertIs(root, logging.getLogger('')) - self.assertIs(root, logging.getLogger('foo').root) - self.assertIs(root, logging.getLogger('foo.bar').root) - self.assertIs(root, logging.getLogger('foo').parent) - - self.assertIsNot(root, logging.getLogger('\0')) - self.assertIsNot(root, logging.getLogger('foo.bar').parent) - - def test_invalid_names(self): - self.assertRaises(TypeError, logging.getLogger, any) - self.assertRaises(TypeError, logging.getLogger, b'foo') - - def test_pickling(self): - for proto in range(pickle.HIGHEST_PROTOCOL + 1): - for name in ('', 'root', 'foo', 'foo.bar', 'baz.bar'): - logger = logging.getLogger(name) - s = pickle.dumps(logger, proto) - unpickled = pickle.loads(s) - self.assertIs(unpickled, logger) - - def test_caching(self): - root = self.root_logger - logger1 = logging.getLogger("abc") - logger2 = logging.getLogger("abc.def") - - # Set root logger level and ensure cache is empty - root.setLevel(logging.ERROR) - self.assertEqual(logger2.getEffectiveLevel(), logging.ERROR) - self.assertEqual(logger2._cache, {}) - - # Ensure cache is populated and calls are consistent - self.assertTrue(logger2.isEnabledFor(logging.ERROR)) - self.assertFalse(logger2.isEnabledFor(logging.DEBUG)) - self.assertEqual(logger2._cache, {logging.ERROR: True, logging.DEBUG: False}) - self.assertEqual(root._cache, {}) - self.assertTrue(logger2.isEnabledFor(logging.ERROR)) - - # Ensure root cache gets populated - self.assertEqual(root._cache, {}) - self.assertTrue(root.isEnabledFor(logging.ERROR)) - self.assertEqual(root._cache, {logging.ERROR: True}) - - # Set parent logger level and ensure caches are emptied - logger1.setLevel(logging.CRITICAL) - self.assertEqual(logger2.getEffectiveLevel(), logging.CRITICAL) - self.assertEqual(logger2._cache, {}) - - # Ensure logger2 uses parent logger's effective level - self.assertFalse(logger2.isEnabledFor(logging.ERROR)) - - # Set level to NOTSET and ensure caches are empty - logger2.setLevel(logging.NOTSET) - self.assertEqual(logger2.getEffectiveLevel(), logging.CRITICAL) - self.assertEqual(logger2._cache, {}) - self.assertEqual(logger1._cache, {}) - self.assertEqual(root._cache, {}) - - # Verify logger2 follows parent and not root - self.assertFalse(logger2.isEnabledFor(logging.ERROR)) - self.assertTrue(logger2.isEnabledFor(logging.CRITICAL)) - self.assertFalse(logger1.isEnabledFor(logging.ERROR)) - self.assertTrue(logger1.isEnabledFor(logging.CRITICAL)) - self.assertTrue(root.isEnabledFor(logging.ERROR)) - - # Disable logging in manager and ensure caches are clear - logging.disable() - self.assertEqual(logger2.getEffectiveLevel(), logging.CRITICAL) - self.assertEqual(logger2._cache, {}) - self.assertEqual(logger1._cache, {}) - self.assertEqual(root._cache, {}) - - # Ensure no loggers are enabled - self.assertFalse(logger1.isEnabledFor(logging.CRITICAL)) - self.assertFalse(logger2.isEnabledFor(logging.CRITICAL)) - self.assertFalse(root.isEnabledFor(logging.CRITICAL)) - - - class BaseFileTest(BaseTest): - "Base class for handler tests that write log files" - - def setUp(self): - BaseTest.setUp(self) - fd, self.fn = tempfile.mkstemp(".log", "test_logging-2-") - os.close(fd) - self.rmfiles = [] - - def tearDown(self): - for fn in self.rmfiles: - os.unlink(fn) - if os.path.exists(self.fn): - os.unlink(self.fn) - BaseTest.tearDown(self) - - def assertLogFile(self, filename): - "Assert a log file is there and register it for deletion" - self.assertTrue(os.path.exists(filename), - msg="Log file %r does not exist" % filename) - self.rmfiles.append(filename) - - - class FileHandlerTest(BaseFileTest): - def test_delay(self): - os.unlink(self.fn) - fh = logging.FileHandler(self.fn, delay=True) - self.assertIsNone(fh.stream) - self.assertFalse(os.path.exists(self.fn)) - fh.handle(logging.makeLogRecord({})) - self.assertIsNotNone(fh.stream) - self.assertTrue(os.path.exists(self.fn)) - fh.close() - - class RotatingFileHandlerTest(BaseFileTest): - def next_rec(self): - return logging.LogRecord('n', logging.DEBUG, 'p', 1, - self.next_message(), None, None, None) - - def test_should_not_rollover(self): - # If maxbytes is zero rollover never occurs - rh = logging.handlers.RotatingFileHandler(self.fn, maxBytes=0) - self.assertFalse(rh.shouldRollover(None)) - rh.close() - - def test_should_rollover(self): - rh = logging.handlers.RotatingFileHandler(self.fn, maxBytes=1) - self.assertTrue(rh.shouldRollover(self.next_rec())) - rh.close() - - def test_file_created(self): - # checks that the file is created and assumes it was created - # by us - rh = logging.handlers.RotatingFileHandler(self.fn) - rh.emit(self.next_rec()) - self.assertLogFile(self.fn) - rh.close() - - def test_rollover_filenames(self): - def namer(name): - return name + ".test" - rh = logging.handlers.RotatingFileHandler( - self.fn, backupCount=2, maxBytes=1) - rh.namer = namer - rh.emit(self.next_rec()) - self.assertLogFile(self.fn) - rh.emit(self.next_rec()) - self.assertLogFile(namer(self.fn + ".1")) - rh.emit(self.next_rec()) - self.assertLogFile(namer(self.fn + ".2")) - self.assertFalse(os.path.exists(namer(self.fn + ".3"))) - rh.close() - - @support.requires_zlib - def test_rotator(self): - def namer(name): - return name + ".gz" - - def rotator(source, dest): - with open(source, "rb") as sf: - data = sf.read() - compressed = zlib.compress(data, 9) - with open(dest, "wb") as df: - df.write(compressed) - os.remove(source) - - rh = logging.handlers.RotatingFileHandler( - self.fn, backupCount=2, maxBytes=1) - rh.rotator = rotator - rh.namer = namer - m1 = self.next_rec() - rh.emit(m1) - self.assertLogFile(self.fn) - m2 = self.next_rec() - rh.emit(m2) - fn = namer(self.fn + ".1") - self.assertLogFile(fn) - newline = os.linesep - with open(fn, "rb") as f: - compressed = f.read() - data = zlib.decompress(compressed) - self.assertEqual(data.decode("ascii"), m1.msg + newline) - rh.emit(self.next_rec()) - fn = namer(self.fn + ".2") - self.assertLogFile(fn) - with open(fn, "rb") as f: - compressed = f.read() - data = zlib.decompress(compressed) - self.assertEqual(data.decode("ascii"), m1.msg + newline) - rh.emit(self.next_rec()) - fn = namer(self.fn + ".2") - with open(fn, "rb") as f: - compressed = f.read() - data = zlib.decompress(compressed) - self.assertEqual(data.decode("ascii"), m2.msg + newline) - self.assertFalse(os.path.exists(namer(self.fn + ".3"))) - rh.close() - - class TimedRotatingFileHandlerTest(BaseFileTest): - # other test methods added below - def test_rollover(self): - fh = logging.handlers.TimedRotatingFileHandler(self.fn, 'S', - backupCount=1) - fmt = logging.Formatter('%(asctime)s %(message)s') - fh.setFormatter(fmt) - r1 = logging.makeLogRecord({'msg': 'testing - initial'}) - fh.emit(r1) - self.assertLogFile(self.fn) - time.sleep(1.1) # a little over a second ... - r2 = logging.makeLogRecord({'msg': 'testing - after delay'}) - fh.emit(r2) - fh.close() - # At this point, we should have a recent rotated file which we - # can test for the existence of. However, in practice, on some - # machines which run really slowly, we don't know how far back - # in time to go to look for the log file. So, we go back a fair - # bit, and stop as soon as we see a rotated file. In theory this - # could of course still fail, but the chances are lower. - found = False - now = datetime.datetime.now() - GO_BACK = 5 * 60 # seconds - for secs in range(GO_BACK): - prev = now - datetime.timedelta(seconds=secs) - fn = self.fn + prev.strftime(".%Y-%m-%d_%H-%M-%S") - found = os.path.exists(fn) - if found: - self.rmfiles.append(fn) - break - msg = 'No rotated files found, went back %d seconds' % GO_BACK - if not found: - # print additional diagnostics - dn, fn = os.path.split(self.fn) - files = [f for f in os.listdir(dn) if f.startswith(fn)] - print('Test time: %s' % now.strftime("%Y-%m-%d %H-%M-%S"), file=sys.stderr) - print('The only matching files are: %s' % files, file=sys.stderr) - for f in files: - print('Contents of %s:' % f) - path = os.path.join(dn, f) - with open(path, 'r') as tf: - print(tf.read()) - self.assertTrue(found, msg=msg) - - def test_invalid(self): - assertRaises = self.assertRaises - assertRaises(ValueError, logging.handlers.TimedRotatingFileHandler, - self.fn, 'X', delay=True) - assertRaises(ValueError, logging.handlers.TimedRotatingFileHandler, - self.fn, 'W', delay=True) - assertRaises(ValueError, logging.handlers.TimedRotatingFileHandler, - self.fn, 'W7', delay=True) - - def test_compute_rollover_daily_attime(self): - currentTime = 0 - atTime = datetime.time(12, 0, 0) - rh = logging.handlers.TimedRotatingFileHandler( - self.fn, when='MIDNIGHT', interval=1, backupCount=0, utc=True, - atTime=atTime) - try: - actual = rh.computeRollover(currentTime) - self.assertEqual(actual, currentTime + 12 * 60 * 60) - - actual = rh.computeRollover(currentTime + 13 * 60 * 60) - self.assertEqual(actual, currentTime + 36 * 60 * 60) - finally: - rh.close() - - #@unittest.skipIf(True, 'Temporarily skipped while failures investigated.') - def test_compute_rollover_weekly_attime(self): - currentTime = int(time.time()) - today = currentTime - currentTime % 86400 - - atTime = datetime.time(12, 0, 0) - - wday = time.gmtime(today).tm_wday - for day in range(7): - rh = logging.handlers.TimedRotatingFileHandler( - self.fn, when='W%d' % day, interval=1, backupCount=0, utc=True, - atTime=atTime) - try: - if wday > day: - # The rollover day has already passed this week, so we - # go over into next week - expected = (7 - wday + day) - else: - expected = (day - wday) - # At this point expected is in days from now, convert to seconds - expected *= 24 * 60 * 60 - # Add in the rollover time - expected += 12 * 60 * 60 - # Add in adjustment for today - expected += today - actual = rh.computeRollover(today) - if actual != expected: - print('failed in timezone: %d' % time.timezone) - print('local vars: %s' % locals()) - self.assertEqual(actual, expected) - if day == wday: - # goes into following week - expected += 7 * 24 * 60 * 60 - actual = rh.computeRollover(today + 13 * 60 * 60) - if actual != expected: - print('failed in timezone: %d' % time.timezone) - print('local vars: %s' % locals()) - self.assertEqual(actual, expected) - finally: - rh.close() - - - def secs(**kw): - return datetime.timedelta(**kw) // datetime.timedelta(seconds=1) - - for when, exp in (('S', 1), - ('M', 60), - ('H', 60 * 60), - ('D', 60 * 60 * 24), - ('MIDNIGHT', 60 * 60 * 24), - # current time (epoch start) is a Thursday, W0 means Monday - ('W0', secs(days=4, hours=24)), - ): - def test_compute_rollover(self, when=when, exp=exp): - rh = logging.handlers.TimedRotatingFileHandler( - self.fn, when=when, interval=1, backupCount=0, utc=True) - currentTime = 0.0 - actual = rh.computeRollover(currentTime) - if exp != actual: - # Failures occur on some systems for MIDNIGHT and W0. - # Print detailed calculation for MIDNIGHT so we can try to see - # what's going on - if when == 'MIDNIGHT': - try: - if rh.utc: - t = time.gmtime(currentTime) - else: - t = time.localtime(currentTime) - currentHour = t[3] - currentMinute = t[4] - currentSecond = t[5] - # r is the number of seconds left between now and midnight - r = logging.handlers._MIDNIGHT - ((currentHour * 60 + - currentMinute) * 60 + - currentSecond) - result = currentTime + r - print('t: %s (%s)' % (t, rh.utc), file=sys.stderr) - print('currentHour: %s' % currentHour, file=sys.stderr) - print('currentMinute: %s' % currentMinute, file=sys.stderr) - print('currentSecond: %s' % currentSecond, file=sys.stderr) - print('r: %s' % r, file=sys.stderr) - print('result: %s' % result, file=sys.stderr) - except Exception: - print('exception in diagnostic code: %s' % sys.exc_info()[1], file=sys.stderr) - self.assertEqual(exp, actual) - rh.close() - setattr(TimedRotatingFileHandlerTest, "test_compute_rollover_%s" % when, test_compute_rollover) - - - @unittest.skipUnless(win32evtlog, 'win32evtlog/win32evtlogutil/pywintypes required for this test.') - class NTEventLogHandlerTest(BaseTest): - def test_basic(self): - logtype = 'Application' - elh = win32evtlog.OpenEventLog(None, logtype) - num_recs = win32evtlog.GetNumberOfEventLogRecords(elh) - - try: - h = logging.handlers.NTEventLogHandler('test_logging') - except pywintypes.error as e: - if e.winerror == 5: # access denied - raise unittest.SkipTest('Insufficient privileges to run test') - raise - - r = logging.makeLogRecord({'msg': 'Test Log Message'}) - h.handle(r) - h.close() - # Now see if the event is recorded - self.assertLess(num_recs, win32evtlog.GetNumberOfEventLogRecords(elh)) - flags = win32evtlog.EVENTLOG_BACKWARDS_READ | \ - win32evtlog.EVENTLOG_SEQUENTIAL_READ - found = False - GO_BACK = 100 - events = win32evtlog.ReadEventLog(elh, flags, GO_BACK) - for e in events: - if e.SourceName != 'test_logging': - continue - msg = win32evtlogutil.SafeFormatMessage(e, logtype) - if msg != 'Test Log Message\r\n': - continue - found = True - break - msg = 'Record not found in event log, went back %d records' % GO_BACK - self.assertTrue(found, msg=msg) - - - class MiscTestCase(unittest.TestCase): - def test__all__(self): - blacklist = {'logThreads', 'logMultiprocessing', - 'logProcesses', 'currentframe', - 'PercentStyle', 'StrFormatStyle', 'StringTemplateStyle', - 'Filterer', 'PlaceHolder', 'Manager', 'RootLogger', - 'root', 'threading'} - support.check__all__(self, logging, blacklist=blacklist) - - - # Set the locale to the platform-dependent default. I have no idea - # why the test does this, but in any case we save the current locale - # first and restore it at the end. - @support.run_with_locale('LC_ALL', '') - def test_main(): - tests = [ - BuiltinLevelsTest, BasicFilterTest, CustomLevelsAndFiltersTest, - HandlerTest, MemoryHandlerTest, ConfigFileTest, SocketHandlerTest, - DatagramHandlerTest, MemoryTest, EncodingTest, WarningsTest, - ConfigDictTest, ManagerTest, FormatterTest, BufferingFormatterTest, - StreamHandlerTest, LogRecordFactoryTest, ChildLoggerTest, - QueueHandlerTest, ShutdownTest, ModuleLevelMiscTest, BasicConfigTest, - LoggerAdapterTest, LoggerTest, SMTPHandlerTest, FileHandlerTest, - RotatingFileHandlerTest, LastResortTest, LogRecordTest, - ExceptionTest, SysLogHandlerTest, IPv6SysLogHandlerTest, HTTPHandlerTest, - NTEventLogHandlerTest, TimedRotatingFileHandlerTest, - UnixSocketHandlerTest, UnixDatagramHandlerTest, UnixSysLogHandlerTest, - MiscTestCase - ] - if hasattr(logging.handlers, 'QueueListener'): - tests.append(QueueListenerTest) - support.run_unittest(*tests) - - if __name__ == "__main__": - test_main() diff --git a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_long.yaml b/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_long.yaml deleted file mode 100644 index 73df1cc9c..000000000 --- a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_long.yaml +++ /dev/null @@ -1,1368 +0,0 @@ -python: | - import unittest - from test import support - - import sys - - import random - import math - import array - - # SHIFT should match the value in longintrepr.h for best testing. - SHIFT = sys.int_info.bits_per_digit - BASE = 2 ** SHIFT - MASK = BASE - 1 - KARATSUBA_CUTOFF = 70 # from longobject.c - - # Max number of base BASE digits to use in test cases. Doubling - # this will more than double the runtime. - MAXDIGITS = 15 - - # build some special values - special = [0, 1, 2, BASE, BASE >> 1, 0x5555555555555555, 0xaaaaaaaaaaaaaaaa] - # some solid strings of one bits - p2 = 4 # 0 and 1 already added - for i in range(2*SHIFT): - special.append(p2 - 1) - p2 = p2 << 1 - del p2 - # add complements & negations - special += [~x for x in special] + [-x for x in special] - - DBL_MAX = sys.float_info.max - DBL_MAX_EXP = sys.float_info.max_exp - DBL_MIN_EXP = sys.float_info.min_exp - DBL_MANT_DIG = sys.float_info.mant_dig - DBL_MIN_OVERFLOW = 2**DBL_MAX_EXP - 2**(DBL_MAX_EXP - DBL_MANT_DIG - 1) - - - # Pure Python version of correctly-rounded integer-to-float conversion. - def int_to_float(n): - """ - Correctly-rounded integer-to-float conversion. - - """ - # Constants, depending only on the floating-point format in use. - # We use an extra 2 bits of precision for rounding purposes. - PRECISION = sys.float_info.mant_dig + 2 - SHIFT_MAX = sys.float_info.max_exp - PRECISION - Q_MAX = 1 << PRECISION - ROUND_HALF_TO_EVEN_CORRECTION = [0, -1, -2, 1, 0, -1, 2, 1] - - # Reduce to the case where n is positive. - if n == 0: - return 0.0 - elif n < 0: - return -int_to_float(-n) - - # Convert n to a 'floating-point' number q * 2**shift, where q is an - # integer with 'PRECISION' significant bits. When shifting n to create q, - # the least significant bit of q is treated as 'sticky'. That is, the - # least significant bit of q is set if either the corresponding bit of n - # was already set, or any one of the bits of n lost in the shift was set. - shift = n.bit_length() - PRECISION - q = n << -shift if shift < 0 else (n >> shift) | bool(n & ~(-1 << shift)) - - # Round half to even (actually rounds to the nearest multiple of 4, - # rounding ties to a multiple of 8). - q += ROUND_HALF_TO_EVEN_CORRECTION[q & 7] - - # Detect overflow. - if shift + (q == Q_MAX) > SHIFT_MAX: - raise OverflowError("integer too large to convert to float") - - # Checks: q is exactly representable, and q**2**shift doesn't overflow. - assert q % 4 == 0 and q // 4 <= 2**(sys.float_info.mant_dig) - assert q * 2**shift <= sys.float_info.max - - # Some circularity here, since float(q) is doing an int-to-float - # conversion. But here q is of bounded size, and is exactly representable - # as a float. In a low-level C-like language, this operation would be a - # simple cast (e.g., from unsigned long long to double). - return math.ldexp(float(q), shift) - - - # pure Python version of correctly-rounded true division - def truediv(a, b): - """Correctly-rounded true division for integers.""" - negative = a^b < 0 - a, b = abs(a), abs(b) - - # exceptions: division by zero, overflow - if not b: - raise ZeroDivisionError("division by zero") - if a >= DBL_MIN_OVERFLOW * b: - raise OverflowError("int/int too large to represent as a float") - - # find integer d satisfying 2**(d - 1) <= a/b < 2**d - d = a.bit_length() - b.bit_length() - if d >= 0 and a >= 2**d * b or d < 0 and a * 2**-d >= b: - d += 1 - - # compute 2**-exp * a / b for suitable exp - exp = max(d, DBL_MIN_EXP) - DBL_MANT_DIG - a, b = a << max(-exp, 0), b << max(exp, 0) - q, r = divmod(a, b) - - # round-half-to-even: fractional part is r/b, which is > 0.5 iff - # 2*r > b, and == 0.5 iff 2*r == b. - if 2*r > b or 2*r == b and q % 2 == 1: - q += 1 - - result = math.ldexp(q, exp) - return -result if negative else result - - - class LongTest(unittest.TestCase): - - # Get quasi-random long consisting of ndigits digits (in base BASE). - # quasi == the most-significant digit will not be 0, and the number - # is constructed to contain long strings of 0 and 1 bits. These are - # more likely than random bits to provoke digit-boundary errors. - # The sign of the number is also random. - - def getran(self, ndigits): - self.assertGreater(ndigits, 0) - nbits_hi = ndigits * SHIFT - nbits_lo = nbits_hi - SHIFT + 1 - answer = 0 - nbits = 0 - r = int(random.random() * (SHIFT * 2)) | 1 # force 1 bits to start - while nbits < nbits_lo: - bits = (r >> 1) + 1 - bits = min(bits, nbits_hi - nbits) - self.assertTrue(1 <= bits <= SHIFT) - nbits = nbits + bits - answer = answer << bits - if r & 1: - answer = answer | ((1 << bits) - 1) - r = int(random.random() * (SHIFT * 2)) - self.assertTrue(nbits_lo <= nbits <= nbits_hi) - if random.random() < 0.5: - answer = -answer - return answer - - # Get random long consisting of ndigits random digits (relative to base - # BASE). The sign bit is also random. - - def getran2(ndigits): - answer = 0 - for i in range(ndigits): - answer = (answer << SHIFT) | random.randint(0, MASK) - if random.random() < 0.5: - answer = -answer - return answer - - def check_division(self, x, y): - eq = self.assertEqual - with self.subTest(x=x, y=y): - q, r = divmod(x, y) - q2, r2 = x//y, x%y - pab, pba = x*y, y*x - eq(pab, pba, "multiplication does not commute") - eq(q, q2, "divmod returns different quotient than /") - eq(r, r2, "divmod returns different mod than %") - eq(x, q*y + r, "x != q*y + r after divmod") - if y > 0: - self.assertTrue(0 <= r < y, "bad mod from divmod") - else: - self.assertTrue(y < r <= 0, "bad mod from divmod") - - def test_division(self): - digits = list(range(1, MAXDIGITS+1)) + list(range(KARATSUBA_CUTOFF, - KARATSUBA_CUTOFF + 14)) - digits.append(KARATSUBA_CUTOFF * 3) - for lenx in digits: - x = self.getran(lenx) - for leny in digits: - y = self.getran(leny) or 1 - self.check_division(x, y) - - # specific numbers chosen to exercise corner cases of the - # current long division implementation - - # 30-bit cases involving a quotient digit estimate of BASE+1 - self.check_division(1231948412290879395966702881, - 1147341367131428698) - self.check_division(815427756481275430342312021515587883, - 707270836069027745) - self.check_division(627976073697012820849443363563599041, - 643588798496057020) - self.check_division(1115141373653752303710932756325578065, - 1038556335171453937726882627) - # 30-bit cases that require the post-subtraction correction step - self.check_division(922498905405436751940989320930368494, - 949985870686786135626943396) - self.check_division(768235853328091167204009652174031844, - 1091555541180371554426545266) - - # 15-bit cases involving a quotient digit estimate of BASE+1 - self.check_division(20172188947443, 615611397) - self.check_division(1020908530270155025, 950795710) - self.check_division(128589565723112408, 736393718) - self.check_division(609919780285761575, 18613274546784) - # 15-bit cases that require the post-subtraction correction step - self.check_division(710031681576388032, 26769404391308) - self.check_division(1933622614268221, 30212853348836) - - - - def test_karatsuba(self): - digits = list(range(1, 5)) + list(range(KARATSUBA_CUTOFF, - KARATSUBA_CUTOFF + 10)) - digits.extend([KARATSUBA_CUTOFF * 10, KARATSUBA_CUTOFF * 100]) - - bits = [digit * SHIFT for digit in digits] - - # Test products of long strings of 1 bits -- (2**x-1)*(2**y-1) == - # 2**(x+y) - 2**x - 2**y + 1, so the proper result is easy to check. - for abits in bits: - a = (1 << abits) - 1 - for bbits in bits: - if bbits < abits: - continue - with self.subTest(abits=abits, bbits=bbits): - b = (1 << bbits) - 1 - x = a * b - y = ((1 << (abits + bbits)) - - (1 << abits) - - (1 << bbits) + - 1) - self.assertEqual(x, y) - - def check_bitop_identities_1(self, x): - eq = self.assertEqual - with self.subTest(x=x): - eq(x & 0, 0) - eq(x | 0, x) - eq(x ^ 0, x) - eq(x & -1, x) - eq(x | -1, -1) - eq(x ^ -1, ~x) - eq(x, ~~x) - eq(x & x, x) - eq(x | x, x) - eq(x ^ x, 0) - eq(x & ~x, 0) - eq(x | ~x, -1) - eq(x ^ ~x, -1) - eq(-x, 1 + ~x) - eq(-x, ~(x-1)) - for n in range(2*SHIFT): - p2 = 2 ** n - with self.subTest(x=x, n=n, p2=p2): - eq(x << n >> n, x) - eq(x // p2, x >> n) - eq(x * p2, x << n) - eq(x & -p2, x >> n << n) - eq(x & -p2, x & ~(p2 - 1)) - - def check_bitop_identities_2(self, x, y): - eq = self.assertEqual - with self.subTest(x=x, y=y): - eq(x & y, y & x) - eq(x | y, y | x) - eq(x ^ y, y ^ x) - eq(x ^ y ^ x, y) - eq(x & y, ~(~x | ~y)) - eq(x | y, ~(~x & ~y)) - eq(x ^ y, (x | y) & ~(x & y)) - eq(x ^ y, (x & ~y) | (~x & y)) - eq(x ^ y, (x | y) & (~x | ~y)) - - def check_bitop_identities_3(self, x, y, z): - eq = self.assertEqual - with self.subTest(x=x, y=y, z=z): - eq((x & y) & z, x & (y & z)) - eq((x | y) | z, x | (y | z)) - eq((x ^ y) ^ z, x ^ (y ^ z)) - eq(x & (y | z), (x & y) | (x & z)) - eq(x | (y & z), (x | y) & (x | z)) - - def test_bitop_identities(self): - for x in special: - self.check_bitop_identities_1(x) - digits = range(1, MAXDIGITS+1) - for lenx in digits: - x = self.getran(lenx) - self.check_bitop_identities_1(x) - for leny in digits: - y = self.getran(leny) - self.check_bitop_identities_2(x, y) - self.check_bitop_identities_3(x, y, self.getran((lenx + leny)//2)) - - def slow_format(self, x, base): - digits = [] - sign = 0 - if x < 0: - sign, x = 1, -x - while x: - x, r = divmod(x, base) - digits.append(int(r)) - digits.reverse() - digits = digits or [0] - return '-'[:sign] + \ - {2: '0b', 8: '0o', 10: '', 16: '0x'}[base] + \ - "".join("0123456789abcdef"[i] for i in digits) - - def check_format_1(self, x): - for base, mapper in (2, bin), (8, oct), (10, str), (10, repr), (16, hex): - got = mapper(x) - with self.subTest(x=x, mapper=mapper.__name__): - expected = self.slow_format(x, base) - self.assertEqual(got, expected) - with self.subTest(got=got): - self.assertEqual(int(got, 0), x) - - def test_format(self): - for x in special: - self.check_format_1(x) - for i in range(10): - for lenx in range(1, MAXDIGITS+1): - x = self.getran(lenx) - self.check_format_1(x) - - def test_long(self): - # Check conversions from string - LL = [ - ('1' + '0'*20, 10**20), - ('1' + '0'*100, 10**100) - ] - for s, v in LL: - for sign in "", "+", "-": - for prefix in "", " ", "\t", " \t\t ": - ss = prefix + sign + s - vv = v - if sign == "-" and v is not ValueError: - vv = -v - try: - self.assertEqual(int(ss), vv) - except ValueError: - pass - - # trailing L should no longer be accepted... - self.assertRaises(ValueError, int, '123L') - self.assertRaises(ValueError, int, '123l') - self.assertRaises(ValueError, int, '0L') - self.assertRaises(ValueError, int, '-37L') - self.assertRaises(ValueError, int, '0x32L', 16) - self.assertRaises(ValueError, int, '1L', 21) - # ... but it's just a normal digit if base >= 22 - self.assertEqual(int('1L', 22), 43) - - # tests with base 0 - self.assertEqual(int('000', 0), 0) - self.assertEqual(int('0o123', 0), 83) - self.assertEqual(int('0x123', 0), 291) - self.assertEqual(int('0b100', 0), 4) - self.assertEqual(int(' 0O123 ', 0), 83) - self.assertEqual(int(' 0X123 ', 0), 291) - self.assertEqual(int(' 0B100 ', 0), 4) - self.assertEqual(int('0', 0), 0) - self.assertEqual(int('+0', 0), 0) - self.assertEqual(int('-0', 0), 0) - self.assertEqual(int('00', 0), 0) - self.assertRaises(ValueError, int, '08', 0) - self.assertRaises(ValueError, int, '-012395', 0) - - # invalid bases - invalid_bases = [-909, - 2**31-1, 2**31, -2**31, -2**31-1, - 2**63-1, 2**63, -2**63, -2**63-1, - 2**100, -2**100, - ] - for base in invalid_bases: - self.assertRaises(ValueError, int, '42', base) - - # Invalid unicode string - # See bpo-34087 - self.assertRaises(ValueError, int, '\u3053\u3093\u306b\u3061\u306f') - - - def test_conversion(self): - - class JustLong: - # test that __long__ no longer used in 3.x - def __long__(self): - return 42 - self.assertRaises(TypeError, int, JustLong()) - - class LongTrunc: - # __long__ should be ignored in 3.x - def __long__(self): - return 42 - def __trunc__(self): - return 1729 - self.assertEqual(int(LongTrunc()), 1729) - - def check_float_conversion(self, n): - # Check that int -> float conversion behaviour matches - # that of the pure Python version above. - try: - actual = float(n) - except OverflowError: - actual = 'overflow' - - try: - expected = int_to_float(n) - except OverflowError: - expected = 'overflow' - - msg = ("Error in conversion of integer {} to float. " - "Got {}, expected {}.".format(n, actual, expected)) - self.assertEqual(actual, expected, msg) - - @support.requires_IEEE_754 - def test_float_conversion(self): - - exact_values = [0, 1, 2, - 2**53-3, - 2**53-2, - 2**53-1, - 2**53, - 2**53+2, - 2**54-4, - 2**54-2, - 2**54, - 2**54+4] - for x in exact_values: - self.assertEqual(float(x), x) - self.assertEqual(float(-x), -x) - - # test round-half-even - for x, y in [(1, 0), (2, 2), (3, 4), (4, 4), (5, 4), (6, 6), (7, 8)]: - for p in range(15): - self.assertEqual(int(float(2**p*(2**53+x))), 2**p*(2**53+y)) - - for x, y in [(0, 0), (1, 0), (2, 0), (3, 4), (4, 4), (5, 4), (6, 8), - (7, 8), (8, 8), (9, 8), (10, 8), (11, 12), (12, 12), - (13, 12), (14, 16), (15, 16)]: - for p in range(15): - self.assertEqual(int(float(2**p*(2**54+x))), 2**p*(2**54+y)) - - # behaviour near extremes of floating-point range - int_dbl_max = int(DBL_MAX) - top_power = 2**DBL_MAX_EXP - halfway = (int_dbl_max + top_power)//2 - self.assertEqual(float(int_dbl_max), DBL_MAX) - self.assertEqual(float(int_dbl_max+1), DBL_MAX) - self.assertEqual(float(halfway-1), DBL_MAX) - self.assertRaises(OverflowError, float, halfway) - self.assertEqual(float(1-halfway), -DBL_MAX) - self.assertRaises(OverflowError, float, -halfway) - self.assertRaises(OverflowError, float, top_power-1) - self.assertRaises(OverflowError, float, top_power) - self.assertRaises(OverflowError, float, top_power+1) - self.assertRaises(OverflowError, float, 2*top_power-1) - self.assertRaises(OverflowError, float, 2*top_power) - self.assertRaises(OverflowError, float, top_power*top_power) - - for p in range(100): - x = 2**p * (2**53 + 1) + 1 - y = 2**p * (2**53 + 2) - self.assertEqual(int(float(x)), y) - - x = 2**p * (2**53 + 1) - y = 2**p * 2**53 - self.assertEqual(int(float(x)), y) - - # Compare builtin float conversion with pure Python int_to_float - # function above. - test_values = [ - int_dbl_max-1, int_dbl_max, int_dbl_max+1, - halfway-1, halfway, halfway + 1, - top_power-1, top_power, top_power+1, - 2*top_power-1, 2*top_power, top_power*top_power, - ] - test_values.extend(exact_values) - for p in range(-4, 8): - for x in range(-128, 128): - test_values.append(2**(p+53) + x) - for value in test_values: - self.check_float_conversion(value) - self.check_float_conversion(-value) - - def test_float_overflow(self): - for x in -2.0, -1.0, 0.0, 1.0, 2.0: - self.assertEqual(float(int(x)), x) - - shuge = '12345' * 120 - huge = 1 << 30000 - mhuge = -huge - namespace = {'huge': huge, 'mhuge': mhuge, 'shuge': shuge, 'math': math} - for test in ["float(huge)", "float(mhuge)", - "complex(huge)", "complex(mhuge)", - "complex(huge, 1)", "complex(mhuge, 1)", - "complex(1, huge)", "complex(1, mhuge)", - "1. + huge", "huge + 1.", "1. + mhuge", "mhuge + 1.", - "1. - huge", "huge - 1.", "1. - mhuge", "mhuge - 1.", - "1. * huge", "huge * 1.", "1. * mhuge", "mhuge * 1.", - "1. // huge", "huge // 1.", "1. // mhuge", "mhuge // 1.", - "1. / huge", "huge / 1.", "1. / mhuge", "mhuge / 1.", - "1. ** huge", "huge ** 1.", "1. ** mhuge", "mhuge ** 1.", - "math.sin(huge)", "math.sin(mhuge)", - "math.sqrt(huge)", "math.sqrt(mhuge)", # should do better - # math.floor() of an int returns an int now - ##"math.floor(huge)", "math.floor(mhuge)", - ]: - - self.assertRaises(OverflowError, eval, test, namespace) - - # XXX Perhaps float(shuge) can raise OverflowError on some box? - # The comparison should not. - self.assertNotEqual(float(shuge), int(shuge), - "float(shuge) should not equal int(shuge)") - - def test_logs(self): - LOG10E = math.log10(math.e) - - for exp in list(range(10)) + [100, 1000, 10000]: - value = 10 ** exp - log10 = math.log10(value) - self.assertAlmostEqual(log10, exp) - - # log10(value) == exp, so log(value) == log10(value)/log10(e) == - # exp/LOG10E - expected = exp / LOG10E - log = math.log(value) - self.assertAlmostEqual(log, expected) - - for bad in -(1 << 10000), -2, 0: - self.assertRaises(ValueError, math.log, bad) - self.assertRaises(ValueError, math.log10, bad) - - def test_mixed_compares(self): - eq = self.assertEqual - - # We're mostly concerned with that mixing floats and ints does the - # right stuff, even when ints are too large to fit in a float. - # The safest way to check the results is to use an entirely different - # method, which we do here via a skeletal rational class (which - # represents all Python ints and floats exactly). - class Rat: - def __init__(self, value): - if isinstance(value, int): - self.n = value - self.d = 1 - elif isinstance(value, float): - # Convert to exact rational equivalent. - f, e = math.frexp(abs(value)) - assert f == 0 or 0.5 <= f < 1.0 - # |value| = f * 2**e exactly - - # Suck up CHUNK bits at a time; 28 is enough so that we suck - # up all bits in 2 iterations for all known binary double- - # precision formats, and small enough to fit in an int. - CHUNK = 28 - top = 0 - # invariant: |value| = (top + f) * 2**e exactly - while f: - f = math.ldexp(f, CHUNK) - digit = int(f) - assert digit >> CHUNK == 0 - top = (top << CHUNK) | digit - f -= digit - assert 0.0 <= f < 1.0 - e -= CHUNK - - # Now |value| = top * 2**e exactly. - if e >= 0: - n = top << e - d = 1 - else: - n = top - d = 1 << -e - if value < 0: - n = -n - self.n = n - self.d = d - assert float(n) / float(d) == value - else: - raise TypeError("can't deal with %r" % value) - - def _cmp__(self, other): - if not isinstance(other, Rat): - other = Rat(other) - x, y = self.n * other.d, self.d * other.n - return (x > y) - (x < y) - def __eq__(self, other): - return self._cmp__(other) == 0 - def __ge__(self, other): - return self._cmp__(other) >= 0 - def __gt__(self, other): - return self._cmp__(other) > 0 - def __le__(self, other): - return self._cmp__(other) <= 0 - def __lt__(self, other): - return self._cmp__(other) < 0 - - cases = [0, 0.001, 0.99, 1.0, 1.5, 1e20, 1e200] - # 2**48 is an important boundary in the internals. 2**53 is an - # important boundary for IEEE double precision. - for t in 2.0**48, 2.0**50, 2.0**53: - cases.extend([t - 1.0, t - 0.3, t, t + 0.3, t + 1.0, - int(t-1), int(t), int(t+1)]) - cases.extend([0, 1, 2, sys.maxsize, float(sys.maxsize)]) - # 1 << 20000 should exceed all double formats. int(1e200) is to - # check that we get equality with 1e200 above. - t = int(1e200) - cases.extend([0, 1, 2, 1 << 20000, t-1, t, t+1]) - cases.extend([-x for x in cases]) - for x in cases: - Rx = Rat(x) - for y in cases: - Ry = Rat(y) - Rcmp = (Rx > Ry) - (Rx < Ry) - with self.subTest(x=x, y=y, Rcmp=Rcmp): - xycmp = (x > y) - (x < y) - eq(Rcmp, xycmp) - eq(x == y, Rcmp == 0) - eq(x != y, Rcmp != 0) - eq(x < y, Rcmp < 0) - eq(x <= y, Rcmp <= 0) - eq(x > y, Rcmp > 0) - eq(x >= y, Rcmp >= 0) - - def test__format__(self): - self.assertEqual(format(123456789, 'd'), '123456789') - self.assertEqual(format(123456789, 'd'), '123456789') - self.assertEqual(format(123456789, ','), '123,456,789') - self.assertEqual(format(123456789, '_'), '123_456_789') - - # sign and aligning are interdependent - self.assertEqual(format(1, "-"), '1') - self.assertEqual(format(-1, "-"), '-1') - self.assertEqual(format(1, "-3"), ' 1') - self.assertEqual(format(-1, "-3"), ' -1') - self.assertEqual(format(1, "+3"), ' +1') - self.assertEqual(format(-1, "+3"), ' -1') - self.assertEqual(format(1, " 3"), ' 1') - self.assertEqual(format(-1, " 3"), ' -1') - self.assertEqual(format(1, " "), ' 1') - self.assertEqual(format(-1, " "), '-1') - - # hex - self.assertEqual(format(3, "x"), "3") - self.assertEqual(format(3, "X"), "3") - self.assertEqual(format(1234, "x"), "4d2") - self.assertEqual(format(-1234, "x"), "-4d2") - self.assertEqual(format(1234, "8x"), " 4d2") - self.assertEqual(format(-1234, "8x"), " -4d2") - self.assertEqual(format(1234, "x"), "4d2") - self.assertEqual(format(-1234, "x"), "-4d2") - self.assertEqual(format(-3, "x"), "-3") - self.assertEqual(format(-3, "X"), "-3") - self.assertEqual(format(int('be', 16), "x"), "be") - self.assertEqual(format(int('be', 16), "X"), "BE") - self.assertEqual(format(-int('be', 16), "x"), "-be") - self.assertEqual(format(-int('be', 16), "X"), "-BE") - self.assertRaises(ValueError, format, 1234567890, ',x') - self.assertEqual(format(1234567890, '_x'), '4996_02d2') - self.assertEqual(format(1234567890, '_X'), '4996_02D2') - - # octal - self.assertEqual(format(3, "o"), "3") - self.assertEqual(format(-3, "o"), "-3") - self.assertEqual(format(1234, "o"), "2322") - self.assertEqual(format(-1234, "o"), "-2322") - self.assertEqual(format(1234, "-o"), "2322") - self.assertEqual(format(-1234, "-o"), "-2322") - self.assertEqual(format(1234, " o"), " 2322") - self.assertEqual(format(-1234, " o"), "-2322") - self.assertEqual(format(1234, "+o"), "+2322") - self.assertEqual(format(-1234, "+o"), "-2322") - self.assertRaises(ValueError, format, 1234567890, ',o') - self.assertEqual(format(1234567890, '_o'), '111_4540_1322') - - # binary - self.assertEqual(format(3, "b"), "11") - self.assertEqual(format(-3, "b"), "-11") - self.assertEqual(format(1234, "b"), "10011010010") - self.assertEqual(format(-1234, "b"), "-10011010010") - self.assertEqual(format(1234, "-b"), "10011010010") - self.assertEqual(format(-1234, "-b"), "-10011010010") - self.assertEqual(format(1234, " b"), " 10011010010") - self.assertEqual(format(-1234, " b"), "-10011010010") - self.assertEqual(format(1234, "+b"), "+10011010010") - self.assertEqual(format(-1234, "+b"), "-10011010010") - self.assertRaises(ValueError, format, 1234567890, ',b') - self.assertEqual(format(12345, '_b'), '11_0000_0011_1001') - - # make sure these are errors - self.assertRaises(ValueError, format, 3, "1.3") # precision disallowed - self.assertRaises(ValueError, format, 3, "_c") # underscore, - self.assertRaises(ValueError, format, 3, ",c") # comma, and - self.assertRaises(ValueError, format, 3, "+c") # sign not allowed - # with 'c' - - self.assertRaisesRegex(ValueError, 'Cannot specify both', format, 3, '_,') - self.assertRaisesRegex(ValueError, 'Cannot specify both', format, 3, ',_') - self.assertRaisesRegex(ValueError, 'Cannot specify both', format, 3, '_,d') - self.assertRaisesRegex(ValueError, 'Cannot specify both', format, 3, ',_d') - - self.assertRaisesRegex(ValueError, "Cannot specify ',' with 's'", format, 3, ',s') - self.assertRaisesRegex(ValueError, "Cannot specify '_' with 's'", format, 3, '_s') - - # ensure that only int and float type specifiers work - for format_spec in ([chr(x) for x in range(ord('a'), ord('z')+1)] + - [chr(x) for x in range(ord('A'), ord('Z')+1)]): - if not format_spec in 'bcdoxXeEfFgGn%': - self.assertRaises(ValueError, format, 0, format_spec) - self.assertRaises(ValueError, format, 1, format_spec) - self.assertRaises(ValueError, format, -1, format_spec) - self.assertRaises(ValueError, format, 2**100, format_spec) - self.assertRaises(ValueError, format, -(2**100), format_spec) - - # ensure that float type specifiers work; format converts - # the int to a float - for format_spec in 'eEfFgG%': - for value in [0, 1, -1, 100, -100, 1234567890, -1234567890]: - self.assertEqual(format(value, format_spec), - format(float(value), format_spec)) - - def test_nan_inf(self): - self.assertRaises(OverflowError, int, float('inf')) - self.assertRaises(OverflowError, int, float('-inf')) - self.assertRaises(ValueError, int, float('nan')) - - def test_mod_division(self): - with self.assertRaises(ZeroDivisionError): - _ = 1 % 0 - - self.assertEqual(13 % 10, 3) - self.assertEqual(-13 % 10, 7) - self.assertEqual(13 % -10, -7) - self.assertEqual(-13 % -10, -3) - - self.assertEqual(12 % 4, 0) - self.assertEqual(-12 % 4, 0) - self.assertEqual(12 % -4, 0) - self.assertEqual(-12 % -4, 0) - - def test_true_division(self): - huge = 1 << 40000 - mhuge = -huge - self.assertEqual(huge / huge, 1.0) - self.assertEqual(mhuge / mhuge, 1.0) - self.assertEqual(huge / mhuge, -1.0) - self.assertEqual(mhuge / huge, -1.0) - self.assertEqual(1 / huge, 0.0) - self.assertEqual(1 / huge, 0.0) - self.assertEqual(1 / mhuge, 0.0) - self.assertEqual(1 / mhuge, 0.0) - self.assertEqual((666 * huge + (huge >> 1)) / huge, 666.5) - self.assertEqual((666 * mhuge + (mhuge >> 1)) / mhuge, 666.5) - self.assertEqual((666 * huge + (huge >> 1)) / mhuge, -666.5) - self.assertEqual((666 * mhuge + (mhuge >> 1)) / huge, -666.5) - self.assertEqual(huge / (huge << 1), 0.5) - self.assertEqual((1000000 * huge) / huge, 1000000) - - namespace = {'huge': huge, 'mhuge': mhuge} - - for overflow in ["float(huge)", "float(mhuge)", - "huge / 1", "huge / 2", "huge / -1", "huge / -2", - "mhuge / 100", "mhuge / 200"]: - self.assertRaises(OverflowError, eval, overflow, namespace) - - for underflow in ["1 / huge", "2 / huge", "-1 / huge", "-2 / huge", - "100 / mhuge", "200 / mhuge"]: - result = eval(underflow, namespace) - self.assertEqual(result, 0.0, - "expected underflow to 0 from %r" % underflow) - - for zero in ["huge / 0", "mhuge / 0"]: - self.assertRaises(ZeroDivisionError, eval, zero, namespace) - - def test_floordiv(self): - with self.assertRaises(ZeroDivisionError): - _ = 1 // 0 - - self.assertEqual(2 // 3, 0) - self.assertEqual(2 // -3, -1) - self.assertEqual(-2 // 3, -1) - self.assertEqual(-2 // -3, 0) - - self.assertEqual(-11 // -3, 3) - self.assertEqual(-11 // 3, -4) - self.assertEqual(11 // -3, -4) - self.assertEqual(11 // 3, 3) - - self.assertEqual(-12 // -3, 4) - self.assertEqual(-12 // 3, -4) - self.assertEqual(12 // -3, -4) - self.assertEqual(12 // 3, 4) - - def check_truediv(self, a, b, skip_small=True): - """Verify that the result of a/b is correctly rounded, by - comparing it with a pure Python implementation of correctly - rounded division. b should be nonzero.""" - - # skip check for small a and b: in this case, the current - # implementation converts the arguments to float directly and - # then applies a float division. This can give doubly-rounded - # results on x87-using machines (particularly 32-bit Linux). - if skip_small and max(abs(a), abs(b)) < 2**DBL_MANT_DIG: - return - - try: - # use repr so that we can distinguish between -0.0 and 0.0 - expected = repr(truediv(a, b)) - except OverflowError: - expected = 'overflow' - except ZeroDivisionError: - expected = 'zerodivision' - - try: - got = repr(a / b) - except OverflowError: - got = 'overflow' - except ZeroDivisionError: - got = 'zerodivision' - - self.assertEqual(expected, got, "Incorrectly rounded division {}/{}: " - "expected {}, got {}".format(a, b, expected, got)) - - @support.requires_IEEE_754 - def test_correctly_rounded_true_division(self): - # more stringent tests than those above, checking that the - # result of true division of ints is always correctly rounded. - # This test should probably be considered CPython-specific. - - # Exercise all the code paths not involving Gb-sized ints. - # ... divisions involving zero - self.check_truediv(123, 0) - self.check_truediv(-456, 0) - self.check_truediv(0, 3) - self.check_truediv(0, -3) - self.check_truediv(0, 0) - # ... overflow or underflow by large margin - self.check_truediv(671 * 12345 * 2**DBL_MAX_EXP, 12345) - self.check_truediv(12345, 345678 * 2**(DBL_MANT_DIG - DBL_MIN_EXP)) - # ... a much larger or smaller than b - self.check_truediv(12345*2**100, 98765) - self.check_truediv(12345*2**30, 98765*7**81) - # ... a / b near a boundary: one of 1, 2**DBL_MANT_DIG, 2**DBL_MIN_EXP, - # 2**DBL_MAX_EXP, 2**(DBL_MIN_EXP-DBL_MANT_DIG) - bases = (0, DBL_MANT_DIG, DBL_MIN_EXP, - DBL_MAX_EXP, DBL_MIN_EXP - DBL_MANT_DIG) - for base in bases: - for exp in range(base - 15, base + 15): - self.check_truediv(75312*2**max(exp, 0), 69187*2**max(-exp, 0)) - self.check_truediv(69187*2**max(exp, 0), 75312*2**max(-exp, 0)) - - # overflow corner case - for m in [1, 2, 7, 17, 12345, 7**100, - -1, -2, -5, -23, -67891, -41**50]: - for n in range(-10, 10): - self.check_truediv(m*DBL_MIN_OVERFLOW + n, m) - self.check_truediv(m*DBL_MIN_OVERFLOW + n, -m) - - # check detection of inexactness in shifting stage - for n in range(250): - # (2**DBL_MANT_DIG+1)/(2**DBL_MANT_DIG) lies halfway - # between two representable floats, and would usually be - # rounded down under round-half-to-even. The tiniest of - # additions to the numerator should cause it to be rounded - # up instead. - self.check_truediv((2**DBL_MANT_DIG + 1)*12345*2**200 + 2**n, - 2**DBL_MANT_DIG*12345) - - # 1/2731 is one of the smallest division cases that's subject - # to double rounding on IEEE 754 machines working internally with - # 64-bit precision. On such machines, the next check would fail, - # were it not explicitly skipped in check_truediv. - self.check_truediv(1, 2731) - - # a particularly bad case for the old algorithm: gives an - # error of close to 3.5 ulps. - self.check_truediv(295147931372582273023, 295147932265116303360) - for i in range(1000): - self.check_truediv(10**(i+1), 10**i) - self.check_truediv(10**i, 10**(i+1)) - - # test round-half-to-even behaviour, normal result - for m in [1, 2, 4, 7, 8, 16, 17, 32, 12345, 7**100, - -1, -2, -5, -23, -67891, -41**50]: - for n in range(-10, 10): - self.check_truediv(2**DBL_MANT_DIG*m + n, m) - - # test round-half-to-even, subnormal result - for n in range(-20, 20): - self.check_truediv(n, 2**1076) - - # largeish random divisions: a/b where |a| <= |b| <= - # 2*|a|; |ans| is between 0.5 and 1.0, so error should - # always be bounded by 2**-54 with equality possible only - # if the least significant bit of q=ans*2**53 is zero. - for M in [10**10, 10**100, 10**1000]: - for i in range(1000): - a = random.randrange(1, M) - b = random.randrange(a, 2*a+1) - self.check_truediv(a, b) - self.check_truediv(-a, b) - self.check_truediv(a, -b) - self.check_truediv(-a, -b) - - # and some (genuinely) random tests - for _ in range(10000): - a_bits = random.randrange(1000) - b_bits = random.randrange(1, 1000) - x = random.randrange(2**a_bits) - y = random.randrange(1, 2**b_bits) - self.check_truediv(x, y) - self.check_truediv(x, -y) - self.check_truediv(-x, y) - self.check_truediv(-x, -y) - - def test_negative_shift_count(self): - with self.assertRaises(ValueError): - 42 << -3 - with self.assertRaises(ValueError): - 42 << -(1 << 1000) - with self.assertRaises(ValueError): - 42 >> -3 - with self.assertRaises(ValueError): - 42 >> -(1 << 1000) - - def test_lshift_of_zero(self): - self.assertEqual(0 << 0, 0) - self.assertEqual(0 << 10, 0) - with self.assertRaises(ValueError): - 0 << -1 - self.assertEqual(0 << (1 << 1000), 0) - with self.assertRaises(ValueError): - 0 << -(1 << 1000) - - @support.cpython_only - def test_huge_lshift_of_zero(self): - # Shouldn't try to allocate memory for a huge shift. See issue #27870. - # Other implementations may have a different boundary for overflow, - # or not raise at all. - self.assertEqual(0 << sys.maxsize, 0) - self.assertEqual(0 << (sys.maxsize + 1), 0) - - @support.cpython_only - @support.bigmemtest(sys.maxsize + 1000, memuse=2/15 * 2, dry_run=False) - def test_huge_lshift(self, size): - self.assertEqual(1 << (sys.maxsize + 1000), 1 << 1000 << sys.maxsize) - - def test_huge_rshift(self): - self.assertEqual(42 >> (1 << 1000), 0) - self.assertEqual((-42) >> (1 << 1000), -1) - - @support.cpython_only - @support.bigmemtest(sys.maxsize + 500, memuse=2/15, dry_run=False) - def test_huge_rshift_of_huge(self, size): - huge = ((1 << 500) + 11) << sys.maxsize - self.assertEqual(huge >> (sys.maxsize + 1), (1 << 499) + 5) - self.assertEqual(huge >> (sys.maxsize + 1000), 0) - - def test_small_ints(self): - for i in range(-5, 257): - self.assertIs(i, i + 0) - self.assertIs(i, i * 1) - self.assertIs(i, i - 0) - self.assertIs(i, i // 1) - self.assertIs(i, i & -1) - self.assertIs(i, i | 0) - self.assertIs(i, i ^ 0) - self.assertIs(i, ~~i) - self.assertIs(i, i**1) - self.assertIs(i, int(str(i))) - self.assertIs(i, i<<2>>2, str(i)) - # corner cases - i = 1 << 70 - self.assertIs(i - i, 0) - self.assertIs(0 * i, 0) - - def test_bit_length(self): - tiny = 1e-10 - for x in range(-65000, 65000): - k = x.bit_length() - # Check equivalence with Python version - self.assertEqual(k, len(bin(x).lstrip('-0b'))) - # Behaviour as specified in the docs - if x != 0: - self.assertTrue(2**(k-1) <= abs(x) < 2**k) - else: - self.assertEqual(k, 0) - # Alternative definition: x.bit_length() == 1 + floor(log_2(x)) - if x != 0: - # When x is an exact power of 2, numeric errors can - # cause floor(log(x)/log(2)) to be one too small; for - # small x this can be fixed by adding a small quantity - # to the quotient before taking the floor. - self.assertEqual(k, 1 + math.floor( - math.log(abs(x))/math.log(2) + tiny)) - - self.assertEqual((0).bit_length(), 0) - self.assertEqual((1).bit_length(), 1) - self.assertEqual((-1).bit_length(), 1) - self.assertEqual((2).bit_length(), 2) - self.assertEqual((-2).bit_length(), 2) - for i in [2, 3, 15, 16, 17, 31, 32, 33, 63, 64, 234]: - a = 2**i - self.assertEqual((a-1).bit_length(), i) - self.assertEqual((1-a).bit_length(), i) - self.assertEqual((a).bit_length(), i+1) - self.assertEqual((-a).bit_length(), i+1) - self.assertEqual((a+1).bit_length(), i+1) - self.assertEqual((-a-1).bit_length(), i+1) - - def test_round(self): - # check round-half-even algorithm. For round to nearest ten; - # rounding map is invariant under adding multiples of 20 - test_dict = {0:0, 1:0, 2:0, 3:0, 4:0, 5:0, - 6:10, 7:10, 8:10, 9:10, 10:10, 11:10, 12:10, 13:10, 14:10, - 15:20, 16:20, 17:20, 18:20, 19:20} - for offset in range(-520, 520, 20): - for k, v in test_dict.items(): - got = round(k+offset, -1) - expected = v+offset - self.assertEqual(got, expected) - self.assertIs(type(got), int) - - # larger second argument - self.assertEqual(round(-150, -2), -200) - self.assertEqual(round(-149, -2), -100) - self.assertEqual(round(-51, -2), -100) - self.assertEqual(round(-50, -2), 0) - self.assertEqual(round(-49, -2), 0) - self.assertEqual(round(-1, -2), 0) - self.assertEqual(round(0, -2), 0) - self.assertEqual(round(1, -2), 0) - self.assertEqual(round(49, -2), 0) - self.assertEqual(round(50, -2), 0) - self.assertEqual(round(51, -2), 100) - self.assertEqual(round(149, -2), 100) - self.assertEqual(round(150, -2), 200) - self.assertEqual(round(250, -2), 200) - self.assertEqual(round(251, -2), 300) - self.assertEqual(round(172500, -3), 172000) - self.assertEqual(round(173500, -3), 174000) - self.assertEqual(round(31415926535, -1), 31415926540) - self.assertEqual(round(31415926535, -2), 31415926500) - self.assertEqual(round(31415926535, -3), 31415927000) - self.assertEqual(round(31415926535, -4), 31415930000) - self.assertEqual(round(31415926535, -5), 31415900000) - self.assertEqual(round(31415926535, -6), 31416000000) - self.assertEqual(round(31415926535, -7), 31420000000) - self.assertEqual(round(31415926535, -8), 31400000000) - self.assertEqual(round(31415926535, -9), 31000000000) - self.assertEqual(round(31415926535, -10), 30000000000) - self.assertEqual(round(31415926535, -11), 0) - self.assertEqual(round(31415926535, -12), 0) - self.assertEqual(round(31415926535, -999), 0) - - # should get correct results even for huge inputs - for k in range(10, 100): - got = round(10**k + 324678, -3) - expect = 10**k + 325000 - self.assertEqual(got, expect) - self.assertIs(type(got), int) - - # nonnegative second argument: round(x, n) should just return x - for n in range(5): - for i in range(100): - x = random.randrange(-10000, 10000) - got = round(x, n) - self.assertEqual(got, x) - self.assertIs(type(got), int) - for huge_n in 2**31-1, 2**31, 2**63-1, 2**63, 2**100, 10**100: - self.assertEqual(round(8979323, huge_n), 8979323) - - # omitted second argument - for i in range(100): - x = random.randrange(-10000, 10000) - got = round(x) - self.assertEqual(got, x) - self.assertIs(type(got), int) - - # bad second argument - bad_exponents = ('brian', 2.0, 0j) - for e in bad_exponents: - self.assertRaises(TypeError, round, 3, e) - - def test_to_bytes(self): - def check(tests, byteorder, signed=False): - for test, expected in tests.items(): - try: - self.assertEqual( - test.to_bytes(len(expected), byteorder, signed=signed), - expected) - except Exception as err: - raise AssertionError( - "failed to convert {0} with byteorder={1} and signed={2}" - .format(test, byteorder, signed)) from err - - # Convert integers to signed big-endian byte arrays. - tests1 = { - 0: b'\x00', - 1: b'\x01', - -1: b'\xff', - -127: b'\x81', - -128: b'\x80', - -129: b'\xff\x7f', - 127: b'\x7f', - 129: b'\x00\x81', - -255: b'\xff\x01', - -256: b'\xff\x00', - 255: b'\x00\xff', - 256: b'\x01\x00', - 32767: b'\x7f\xff', - -32768: b'\xff\x80\x00', - 65535: b'\x00\xff\xff', - -65536: b'\xff\x00\x00', - -8388608: b'\x80\x00\x00' - } - check(tests1, 'big', signed=True) - - # Convert integers to signed little-endian byte arrays. - tests2 = { - 0: b'\x00', - 1: b'\x01', - -1: b'\xff', - -127: b'\x81', - -128: b'\x80', - -129: b'\x7f\xff', - 127: b'\x7f', - 129: b'\x81\x00', - -255: b'\x01\xff', - -256: b'\x00\xff', - 255: b'\xff\x00', - 256: b'\x00\x01', - 32767: b'\xff\x7f', - -32768: b'\x00\x80', - 65535: b'\xff\xff\x00', - -65536: b'\x00\x00\xff', - -8388608: b'\x00\x00\x80' - } - check(tests2, 'little', signed=True) - - # Convert integers to unsigned big-endian byte arrays. - tests3 = { - 0: b'\x00', - 1: b'\x01', - 127: b'\x7f', - 128: b'\x80', - 255: b'\xff', - 256: b'\x01\x00', - 32767: b'\x7f\xff', - 32768: b'\x80\x00', - 65535: b'\xff\xff', - 65536: b'\x01\x00\x00' - } - check(tests3, 'big', signed=False) - - # Convert integers to unsigned little-endian byte arrays. - tests4 = { - 0: b'\x00', - 1: b'\x01', - 127: b'\x7f', - 128: b'\x80', - 255: b'\xff', - 256: b'\x00\x01', - 32767: b'\xff\x7f', - 32768: b'\x00\x80', - 65535: b'\xff\xff', - 65536: b'\x00\x00\x01' - } - check(tests4, 'little', signed=False) - - self.assertRaises(OverflowError, (256).to_bytes, 1, 'big', signed=False) - self.assertRaises(OverflowError, (256).to_bytes, 1, 'big', signed=True) - self.assertRaises(OverflowError, (256).to_bytes, 1, 'little', signed=False) - self.assertRaises(OverflowError, (256).to_bytes, 1, 'little', signed=True) - self.assertRaises(OverflowError, (-1).to_bytes, 2, 'big', signed=False) - self.assertRaises(OverflowError, (-1).to_bytes, 2, 'little', signed=False) - self.assertEqual((0).to_bytes(0, 'big'), b'') - self.assertEqual((1).to_bytes(5, 'big'), b'\x00\x00\x00\x00\x01') - self.assertEqual((0).to_bytes(5, 'big'), b'\x00\x00\x00\x00\x00') - self.assertEqual((-1).to_bytes(5, 'big', signed=True), - b'\xff\xff\xff\xff\xff') - self.assertRaises(OverflowError, (1).to_bytes, 0, 'big') - - def test_from_bytes(self): - def check(tests, byteorder, signed=False): - for test, expected in tests.items(): - try: - self.assertEqual( - int.from_bytes(test, byteorder, signed=signed), - expected) - except Exception as err: - raise AssertionError( - "failed to convert {0} with byteorder={1!r} and signed={2}" - .format(test, byteorder, signed)) from err - - # Convert signed big-endian byte arrays to integers. - tests1 = { - b'': 0, - b'\x00': 0, - b'\x00\x00': 0, - b'\x01': 1, - b'\x00\x01': 1, - b'\xff': -1, - b'\xff\xff': -1, - b'\x81': -127, - b'\x80': -128, - b'\xff\x7f': -129, - b'\x7f': 127, - b'\x00\x81': 129, - b'\xff\x01': -255, - b'\xff\x00': -256, - b'\x00\xff': 255, - b'\x01\x00': 256, - b'\x7f\xff': 32767, - b'\x80\x00': -32768, - b'\x00\xff\xff': 65535, - b'\xff\x00\x00': -65536, - b'\x80\x00\x00': -8388608 - } - check(tests1, 'big', signed=True) - - # Convert signed little-endian byte arrays to integers. - tests2 = { - b'': 0, - b'\x00': 0, - b'\x00\x00': 0, - b'\x01': 1, - b'\x00\x01': 256, - b'\xff': -1, - b'\xff\xff': -1, - b'\x81': -127, - b'\x80': -128, - b'\x7f\xff': -129, - b'\x7f': 127, - b'\x81\x00': 129, - b'\x01\xff': -255, - b'\x00\xff': -256, - b'\xff\x00': 255, - b'\x00\x01': 256, - b'\xff\x7f': 32767, - b'\x00\x80': -32768, - b'\xff\xff\x00': 65535, - b'\x00\x00\xff': -65536, - b'\x00\x00\x80': -8388608 - } - check(tests2, 'little', signed=True) - - # Convert unsigned big-endian byte arrays to integers. - tests3 = { - b'': 0, - b'\x00': 0, - b'\x01': 1, - b'\x7f': 127, - b'\x80': 128, - b'\xff': 255, - b'\x01\x00': 256, - b'\x7f\xff': 32767, - b'\x80\x00': 32768, - b'\xff\xff': 65535, - b'\x01\x00\x00': 65536, - } - check(tests3, 'big', signed=False) - - # Convert integers to unsigned little-endian byte arrays. - tests4 = { - b'': 0, - b'\x00': 0, - b'\x01': 1, - b'\x7f': 127, - b'\x80': 128, - b'\xff': 255, - b'\x00\x01': 256, - b'\xff\x7f': 32767, - b'\x00\x80': 32768, - b'\xff\xff': 65535, - b'\x00\x00\x01': 65536, - } - check(tests4, 'little', signed=False) - - class myint(int): - pass - - self.assertIs(type(myint.from_bytes(b'\x00', 'big')), myint) - self.assertEqual(myint.from_bytes(b'\x01', 'big'), 1) - self.assertIs( - type(myint.from_bytes(b'\x00', 'big', signed=False)), myint) - self.assertEqual(myint.from_bytes(b'\x01', 'big', signed=False), 1) - self.assertIs(type(myint.from_bytes(b'\x00', 'little')), myint) - self.assertEqual(myint.from_bytes(b'\x01', 'little'), 1) - self.assertIs(type(myint.from_bytes( - b'\x00', 'little', signed=False)), myint) - self.assertEqual(myint.from_bytes(b'\x01', 'little', signed=False), 1) - self.assertEqual( - int.from_bytes([255, 0, 0], 'big', signed=True), -65536) - self.assertEqual( - int.from_bytes((255, 0, 0), 'big', signed=True), -65536) - self.assertEqual(int.from_bytes( - bytearray(b'\xff\x00\x00'), 'big', signed=True), -65536) - self.assertEqual(int.from_bytes( - bytearray(b'\xff\x00\x00'), 'big', signed=True), -65536) - self.assertEqual(int.from_bytes( - array.array('B', b'\xff\x00\x00'), 'big', signed=True), -65536) - self.assertEqual(int.from_bytes( - memoryview(b'\xff\x00\x00'), 'big', signed=True), -65536) - self.assertRaises(ValueError, int.from_bytes, [256], 'big') - self.assertRaises(ValueError, int.from_bytes, [0], 'big\x00') - self.assertRaises(ValueError, int.from_bytes, [0], 'little\x00') - self.assertRaises(TypeError, int.from_bytes, "", 'big') - self.assertRaises(TypeError, int.from_bytes, "\x00", 'big') - self.assertRaises(TypeError, int.from_bytes, 0, 'big') - self.assertRaises(TypeError, int.from_bytes, 0, 'big', True) - self.assertRaises(TypeError, myint.from_bytes, "", 'big') - self.assertRaises(TypeError, myint.from_bytes, "\x00", 'big') - self.assertRaises(TypeError, myint.from_bytes, 0, 'big') - self.assertRaises(TypeError, int.from_bytes, 0, 'big', True) - - class myint2(int): - def __new__(cls, value): - return int.__new__(cls, value + 1) - - i = myint2.from_bytes(b'\x01', 'big') - self.assertIs(type(i), myint2) - self.assertEqual(i, 2) - - class myint3(int): - def __init__(self, value): - self.foo = 'bar' - - i = myint3.from_bytes(b'\x01', 'big') - self.assertIs(type(i), myint3) - self.assertEqual(i, 1) - self.assertEqual(getattr(i, 'foo', 'none'), 'bar') - - def test_access_to_nonexistent_digit_0(self): - # http://bugs.python.org/issue14630: A bug in _PyLong_Copy meant that - # ob_digit[0] was being incorrectly accessed for instances of a - # subclass of int, with value 0. - class Integer(int): - def __new__(cls, value=0): - self = int.__new__(cls, value) - self.foo = 'foo' - return self - - integers = [Integer(0) for i in range(1000)] - for n in map(int, integers): - self.assertEqual(n, 0) - - def test_shift_bool(self): - # Issue #21422: ensure that bool << int and bool >> int return int - for value in (True, False): - for shift in (0, 2): - self.assertEqual(type(value << shift), int) - self.assertEqual(type(value >> shift), int) - - def test_as_integer_ratio(self): - class myint(int): - pass - tests = [10, 0, -10, 1, sys.maxsize + 1, True, False, myint(42)] - for value in tests: - numerator, denominator = value.as_integer_ratio() - self.assertEqual((numerator, denominator), (int(value), 1)) - self.assertEqual(type(numerator), int) - self.assertEqual(type(denominator), int) - - - if __name__ == "__main__": - unittest.main() diff --git a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_longexp.yaml b/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_longexp.yaml deleted file mode 100644 index 155742aae..000000000 --- a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_longexp.yaml +++ /dev/null @@ -1,11 +0,0 @@ -python: | - import unittest - - class LongExpText(unittest.TestCase): - def test_longexp(self): - REPS = 65580 - l = eval("[" + "2," * REPS + "]") - self.assertEqual(len(l), REPS) - - if __name__ == "__main__": - unittest.main() diff --git a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_mailbox.yaml b/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_mailbox.yaml deleted file mode 100644 index 19c17a30f..000000000 --- a/transpiler/src/test/resources/org/polystat/py2eo/transpiler/testParserPrinter/test_mailbox.yaml +++ /dev/null @@ -1,2314 +0,0 @@ -python: | - import os - import sys - import time - import stat - import socket - import email - import email.message - import re - import io - import tempfile - from test import support - import unittest - import textwrap - import mailbox - import glob - - - class TestBase: - - all_mailbox_types = (mailbox.Message, mailbox.MaildirMessage, - mailbox.mboxMessage, mailbox.MHMessage, - mailbox.BabylMessage, mailbox.MMDFMessage) - - def _check_sample(self, msg): - # Inspect a mailbox.Message representation of the sample message - self.assertIsInstance(msg, email.message.Message) - self.assertIsInstance(msg, mailbox.Message) - for key, value in _sample_headers.items(): - self.assertIn(value, msg.get_all(key)) - self.assertTrue(msg.is_multipart()) - self.assertEqual(len(msg.get_payload()), len(_sample_payloads)) - for i, payload in enumerate(_sample_payloads): - part = msg.get_payload(i) - self.assertIsInstance(part, email.message.Message) - self.assertNotIsInstance(part, mailbox.Message) - self.assertEqual(part.get_payload(), payload) - - def _delete_recursively(self, target): - # Delete a file or delete a directory recursively - if os.path.isdir(target): - support.rmtree(target) - elif os.path.exists(target): - support.unlink(target) - - - class TestMailbox(TestBase): - - maxDiff = None - - _factory = None # Overridden by subclasses to reuse tests - _template = 'From: foo\n\n%s\n' - - def setUp(self): - self._path = support.TESTFN - self._delete_recursively(self._path) - self._box = self._factory(self._path) - - def tearDown(self): - self._box.close() - self._delete_recursively(self._path) - - def test_add(self): - # Add copies of a sample message - keys = [] - keys.append(self._box.add(self._template % 0)) - self.assertEqual(len(self._box), 1) - keys.append(self._box.add(mailbox.Message(_sample_message))) - self.assertEqual(len(self._box), 2) - keys.append(self._box.add(email.message_from_string(_sample_message))) - self.assertEqual(len(self._box), 3) - keys.append(self._box.add(io.BytesIO(_bytes_sample_message))) - self.assertEqual(len(self._box), 4) - keys.append(self._box.add(_sample_message)) - self.assertEqual(len(self._box), 5) - keys.append(self._box.add(_bytes_sample_message)) - self.assertEqual(len(self._box), 6) - with self.assertWarns(DeprecationWarning): - keys.append(self._box.add( - io.TextIOWrapper(io.BytesIO(_bytes_sample_message)))) - self.assertEqual(len(self._box), 7) - self.assertEqual(self._box.get_string(keys[0]), self._template % 0) - for i in (1, 2, 3, 4, 5, 6): - self._check_sample(self._box[keys[i]]) - - _nonascii_msg = textwrap.dedent("""\ - From: foo - Subject: Falinaptár házhozszállítással. Már rendeltél? - - 0 - """) - - def test_add_invalid_8bit_bytes_header(self): - key = self._box.add(self._nonascii_msg.encode('latin-1')) - self.assertEqual(len(self._box), 1) - self.assertEqual(self._box.get_bytes(key), - self._nonascii_msg.encode('latin-1')) - - def test_invalid_nonascii_header_as_string(self): - subj = self._nonascii_msg.splitlines()[1] - key = self._box.add(subj.encode('latin-1')) - self.assertEqual(self._box.get_string(key), - 'Subject: =?unknown-8bit?b?RmFsaW5hcHThciBo4Xpob3pzeuFsbO104XNz' - 'YWwuIE3hciByZW5kZWx06Ww/?=\n\n') - - def test_add_nonascii_string_header_raises(self): - with self.assertRaisesRegex(ValueError, "ASCII-only"): - self._box.add(self._nonascii_msg) - self._box.flush() - self.assertEqual(len(self._box), 0) - self.assertMailboxEmpty() - - def test_add_that_raises_leaves_mailbox_empty(self): - def raiser(*args, **kw): - raise Exception("a fake error") - support.patch(self, email.generator.BytesGenerator, 'flatten', raiser) - with self.assertRaises(Exception): - self._box.add(email.message_from_string("From: Alphöso")) - self.assertEqual(len(self._box), 0) - self._box.close() - self.assertMailboxEmpty() - - _non_latin_bin_msg = textwrap.dedent("""\ - From: foo@bar.com - To: báz - Subject: Maintenant je vous présente mon collègue, le pouf célèbre - \tJean de Baddie - Mime-Version: 1.0 - Content-Type: text/plain; charset="utf-8" - Content-Transfer-Encoding: 8bit - - Да, они летят. - """).encode('utf-8') - - def test_add_8bit_body(self): - key = self._box.add(self._non_latin_bin_msg) - self.assertEqual(self._box.get_bytes(key), - self._non_latin_bin_msg) - with self._box.get_file(key) as f: - self.assertEqual(f.read(), - self._non_latin_bin_msg.replace(b'\n', - os.linesep.encode())) - self.assertEqual(self._box[key].get_payload(), - "Да, они летят.\n") - - def test_add_binary_file(self): - with tempfile.TemporaryFile('wb+') as f: - f.write(_bytes_sample_message) - f.seek(0) - key = self._box.add(f) - self.assertEqual(self._box.get_bytes(key).split(b'\n'), - _bytes_sample_message.split(b'\n')) - - def test_add_binary_nonascii_file(self): - with tempfile.TemporaryFile('wb+') as f: - f.write(self._non_latin_bin_msg) - f.seek(0) - key = self._box.add(f) - self.assertEqual(self._box.get_bytes(key).split(b'\n'), - self._non_latin_bin_msg.split(b'\n')) - - def test_add_text_file_warns(self): - with tempfile.TemporaryFile('w+') as f: - f.write(_sample_message) - f.seek(0) - with self.assertWarns(DeprecationWarning): - key = self._box.add(f) - self.assertEqual(self._box.get_bytes(key).split(b'\n'), - _bytes_sample_message.split(b'\n')) - - def test_add_StringIO_warns(self): - with self.assertWarns(DeprecationWarning): - key = self._box.add(io.StringIO(self._template % "0")) - self.assertEqual(self._box.get_string(key), self._template % "0") - - def test_add_nonascii_StringIO_raises(self): - with self.assertWarns(DeprecationWarning): - with self.assertRaisesRegex(ValueError, "ASCII-only"): - self._box.add(io.StringIO(self._nonascii_msg)) - self.assertEqual(len(self._box), 0) - self._box.close() - self.assertMailboxEmpty() - - def test_remove(self): - # Remove messages using remove() - self._test_remove_or_delitem(self._box.remove) - - def test_delitem(self): - # Remove messages using __delitem__() - self._test_remove_or_delitem(self._box.__delitem__) - - def _test_remove_or_delitem(self, method): - # (Used by test_remove() and test_delitem().) - key0 = self._box.add(self._template % 0) - key1 = self._box.add(self._template % 1) - self.assertEqual(len(self._box), 2) - method(key0) - self.assertEqual(len(self._box), 1) - self.assertRaises(KeyError, lambda: self._box[key0]) - self.assertRaises(KeyError, lambda: method(key0)) - self.assertEqual(self._box.get_string(key1), self._template % 1) - key2 = self._box.add(self._template % 2) - self.assertEqual(len(self._box), 2) - method(key2) - self.assertEqual(len(self._box), 1) - self.assertRaises(KeyError, lambda: self._box[key2]) - self.assertRaises(KeyError, lambda: method(key2)) - self.assertEqual(self._box.get_string(key1), self._template % 1) - method(key1) - self.assertEqual(len(self._box), 0) - self.assertRaises(KeyError, lambda: self._box[key1]) - self.assertRaises(KeyError, lambda: method(key1)) - - def test_discard(self, repetitions=10): - # Discard messages - key0 = self._box.add(self._template % 0) - key1 = self._box.add(self._template % 1) - self.assertEqual(len(self._box), 2) - self._box.discard(key0) - self.assertEqual(len(self._box), 1) - self.assertRaises(KeyError, lambda: self._box[key0]) - self._box.discard(key0) - self.assertEqual(len(self._box), 1) - self.assertRaises(KeyError, lambda: self._box[key0]) - - def test_get(self): - # Retrieve messages using get() - key0 = self._box.add(self._template % 0) - msg = self._box.get(key0) - self.assertEqual(msg['from'], 'foo') - self.assertEqual(msg.get_payload(), '0\n') - self.assertIsNone(self._box.get('foo')) - self.assertIs(self._box.get('foo', False), False) - self._box.close() - self._box = self._factory(self._path) - key1 = self._box.add(self._template % 1) - msg = self._box.get(key1) - self.assertEqual(msg['from'], 'foo') - self.assertEqual(msg.get_payload(), '1\n') - - def test_getitem(self): - # Retrieve message using __getitem__() - key0 = self._box.add(self._template % 0) - msg = self._box[key0] - self.assertEqual(msg['from'], 'foo') - self.assertEqual(msg.get_payload(), '0\n') - self.assertRaises(KeyError, lambda: self._box['foo']) - self._box.discard(key0) - self.assertRaises(KeyError, lambda: self._box[key0]) - - def test_get_message(self): - # Get Message representations of messages - key0 = self._box.add(self._template % 0) - key1 = self._box.add(_sample_message) - msg0 = self._box.get_message(key0) - self.assertIsInstance(msg0, mailbox.Message) - self.assertEqual(msg0['from'], 'foo') - self.assertEqual(msg0.get_payload(), '0\n') - self._check_sample(self._box.get_message(key1)) - - def test_get_bytes(self): - # Get bytes representations of messages - key0 = self._box.add(self._template % 0) - key1 = self._box.add(_sample_message) - self.assertEqual(self._box.get_bytes(key0), - (self._template % 0).encode('ascii')) - self.assertEqual(self._box.get_bytes(key1), _bytes_sample_message) - - def test_get_string(self): - # Get string representations of messages - key0 = self._box.add(self._template % 0) - key1 = self._box.add(_sample_message) - self.assertEqual(self._box.get_string(key0), self._template % 0) - self.assertEqual(self._box.get_string(key1).split('\n'), - _sample_message.split('\n')) - - def test_get_file(self): - # Get file representations of messages - key0 = self._box.add(self._template % 0) - key1 = self._box.add(_sample_message) - with self._box.get_file(key0) as file: - data0 = file.read() - with self._box.get_file(key1) as file: - data1 = file.read() - self.assertEqual(data0.decode('ascii').replace(os.linesep, '\n'), - self._template % 0) - self.assertEqual(data1.decode('ascii').replace(os.linesep, '\n'), - _sample_message) - - def test_get_file_can_be_closed_twice(self): - # Issue 11700 - key = self._box.add(_sample_message) - f = self._box.get_file(key) - f.close() - f.close() - - def test_iterkeys(self): - # Get keys using iterkeys() - self._check_iteration(self._box.iterkeys, do_keys=True, do_values=False) - - def test_keys(self): - # Get keys using keys() - self._check_iteration(self._box.keys, do_keys=True, do_values=False) - - def test_itervalues(self): - # Get values using itervalues() - self._check_iteration(self._box.itervalues, do_keys=False, - do_values=True) - - def test_iter(self): - # Get values using __iter__() - self._check_iteration(self._box.__iter__, do_keys=False, - do_values=True) - - def test_values(self): - # Get values using values() - self._check_iteration(self._box.values, do_keys=False, do_values=True) - - def test_iteritems(self): - # Get keys and values using iteritems() - self._check_iteration(self._box.iteritems, do_keys=True, - do_values=True) - - def test_items(self): - # Get keys and values using items() - self._check_iteration(self._box.items, do_keys=True, do_values=True) - - def _check_iteration(self, method, do_keys, do_values, repetitions=10): - for value in method(): - self.fail("Not empty") - keys, values = [], [] - for i in range(repetitions): - keys.append(self._box.add(self._template % i)) - values.append(self._template % i) - if do_keys and not do_values: - returned_keys = list(method()) - elif do_values and not do_keys: - returned_values = list(method()) - else: - returned_keys, returned_values = [], [] - for key, value in method(): - returned_keys.append(key) - returned_values.append(value) - if do_keys: - self.assertEqual(len(keys), len(returned_keys)) - self.assertEqual(set(keys), set(returned_keys)) - if do_values: - count = 0 - for value in returned_values: - self.assertEqual(value['from'], 'foo') - self.assertLess(int(value.get_payload()), repetitions) - count += 1 - self.assertEqual(len(values), count) - - def test_contains(self): - # Check existence of keys using __contains__() - self.assertNotIn('foo', self._box) - key0 = self._box.add(self._template % 0) - self.assertIn(key0, self._box) - self.assertNotIn('foo', self._box) - key1 = self._box.add(self._template % 1) - self.assertIn(key1, self._box) - self.assertIn(key0, self._box) - self.assertNotIn('foo', self._box) - self._box.remove(key0) - self.assertNotIn(key0, self._box) - self.assertIn(key1, self._box) - self.assertNotIn('foo', self._box) - self._box.remove(key1) - self.assertNotIn(key1, self._box) - self.assertNotIn(key0, self._box) - self.assertNotIn('foo', self._box) - - def test_len(self, repetitions=10): - # Get message count - keys = [] - for i in range(repetitions): - self.assertEqual(len(self._box), i) - keys.append(self._box.add(self._template % i)) - self.assertEqual(len(self._box), i + 1) - for i in range(repetitions): - self.assertEqual(len(self._box), repetitions - i) - self._box.remove(keys[i]) - self.assertEqual(len(self._box), repetitions - i - 1) - - def test_set_item(self): - # Modify messages using __setitem__() - key0 = self._box.add(self._template % 'original 0') - self.assertEqual(self._box.get_string(key0), - self._template % 'original 0') - key1 = self._box.add(self._template % 'original 1') - self.assertEqual(self._box.get_string(key1), - self._template % 'original 1') - self._box[key0] = self._template % 'changed 0' - self.assertEqual(self._box.get_string(key0), - self._template % 'changed 0') - self._box[key1] = self._template % 'changed 1' - self.assertEqual(self._box.get_string(key1), - self._template % 'changed 1') - self._box[key0] = _sample_message - self._check_sample(self._box[key0]) - self._box[key1] = self._box[key0] - self._check_sample(self._box[key1]) - self._box[key0] = self._template % 'original 0' - self.assertEqual(self._box.get_string(key0), - self._template % 'original 0') - self._check_sample(self._box[key1]) - self.assertRaises(KeyError, - lambda: self._box.__setitem__('foo', 'bar')) - self.assertRaises(KeyError, lambda: self._box['foo']) - self.assertEqual(len(self._box), 2) - - def test_clear(self, iterations=10): - # Remove all messages using clear() - keys = [] - for i in range(iterations): - self._box.add(self._template % i) - for i, key in enumerate(keys): - self.assertEqual(self._box.get_string(key), self._template % i) - self._box.clear() - self.assertEqual(len(self._box), 0) - for i, key in enumerate(keys): - self.assertRaises(KeyError, lambda: self._box.get_string(key)) - - def test_pop(self): - # Get and remove a message using pop() - key0 = self._box.add(self._template % 0) - self.assertIn(key0, self._box) - key1 = self._box.add(self._template % 1) - self.assertIn(key1, self._box) - self.assertEqual(self._box.pop(key0).get_payload(), '0\n') - self.assertNotIn(key0, self._box) - self.assertIn(key1, self._box) - key2 = self._box.add(self._template % 2) - self.assertIn(key2, self._box) - self.assertEqual(self._box.pop(key2).get_payload(), '2\n') - self.assertNotIn(key2, self._box) - self.assertIn(key1, self._box) - self.assertEqual(self._box.pop(key1).get_payload(), '1\n') - self.assertNotIn(key1, self._box) - self.assertEqual(len(self._box), 0) - - def test_popitem(self, iterations=10): - # Get and remove an arbitrary (key, message) using popitem() - keys = [] - for i in range(10): - keys.append(self._box.add(self._template % i)) - seen = [] - for i in range(10): - key, msg = self._box.popitem() - self.assertIn(key, keys) - self.assertNotIn(key, seen) - seen.append(key) - self.assertEqual(int(msg.get_payload()), keys.index(key)) - self.assertEqual(len(self._box), 0) - for key in keys: - self.assertRaises(KeyError, lambda: self._box[key]) - - def test_update(self): - # Modify multiple messages using update() - key0 = self._box.add(self._template % 'original 0') - key1 = self._box.add(self._template % 'original 1') - key2 = self._box.add(self._template % 'original 2') - self._box.update({key0: self._template % 'changed 0', - key2: _sample_message}) - self.assertEqual(len(self._box), 3) - self.assertEqual(self._box.get_string(key0), - self._template % 'changed 0') - self.assertEqual(self._box.get_string(key1), - self._template % 'original 1') - self._check_sample(self._box[key2]) - self._box.update([(key2, self._template % 'changed 2'), - (key1, self._template % 'changed 1'), - (key0, self._template % 'original 0')]) - self.assertEqual(len(self._box), 3) - self.assertEqual(self._box.get_string(key0), - self._template % 'original 0') - self.assertEqual(self._box.get_string(key1), - self._template % 'changed 1') - self.assertEqual(self._box.get_string(key2), - self._template % 'changed 2') - self.assertRaises(KeyError, - lambda: self._box.update({'foo': 'bar', - key0: self._template % "changed 0"})) - self.assertEqual(len(self._box), 3) - self.assertEqual(self._box.get_string(key0), - self._template % "changed 0") - self.assertEqual(self._box.get_string(key1), - self._template % "changed 1") - self.assertEqual(self._box.get_string(key2), - self._template % "changed 2") - - def test_flush(self): - # Write changes to disk - self._test_flush_or_close(self._box.flush, True) - - def test_popitem_and_flush_twice(self): - # See #15036. - self._box.add(self._template % 0) - self._box.add(self._template % 1) - self._box.flush() - - self._box.popitem() - self._box.flush() - self._box.popitem() - self._box.flush() - - def test_lock_unlock(self): - # Lock and unlock the mailbox - self.assertFalse(os.path.exists(self._get_lock_path())) - self._box.lock() - self.assertTrue(os.path.exists(self._get_lock_path())) - self._box.unlock() - self.assertFalse(os.path.exists(self._get_lock_path())) - - def test_close(self): - # Close mailbox and flush changes to disk - self._test_flush_or_close(self._box.close, False) - - def _test_flush_or_close(self, method, should_call_close): - contents = [self._template % i for i in range(3)] - self._box.add(contents[0]) - self._box.add(contents[1]) - self._box.add(contents[2]) - oldbox = self._box - method() - if should_call_close: - self._box.close() - self._box = self._factory(self._path) - keys = self._box.keys() - self.assertEqual(len(keys), 3) - for key in keys: - self.assertIn(self._box.get_string(key), contents) - oldbox.close() - - def test_dump_message(self): - # Write message representations to disk - for input in (email.message_from_string(_sample_message), - _sample_message, io.BytesIO(_bytes_sample_message)): - output = io.BytesIO() - self._box._dump_message(input, output) - self.assertEqual(output.getvalue(), - _bytes_sample_message.replace(b'\n', os.linesep.encode())) - output = io.BytesIO() - self.assertRaises(TypeError, - lambda: self._box._dump_message(None, output)) - - def _get_lock_path(self): - # Return the path of the dot lock file. May be overridden. - return self._path + '.lock' - - - class TestMailboxSuperclass(TestBase, unittest.TestCase): - - def test_notimplemented(self): - # Test that all Mailbox methods raise NotImplementedException. - box = mailbox.Mailbox('path') - self.assertRaises(NotImplementedError, lambda: box.add('')) - self.assertRaises(NotImplementedError, lambda: box.remove('')) - self.assertRaises(NotImplementedError, lambda: box.__delitem__('')) - self.assertRaises(NotImplementedError, lambda: box.discard('')) - self.assertRaises(NotImplementedError, lambda: box.__setitem__('', '')) - self.assertRaises(NotImplementedError, lambda: box.iterkeys()) - self.assertRaises(NotImplementedError, lambda: box.keys()) - self.assertRaises(NotImplementedError, lambda: box.itervalues().__next__()) - self.assertRaises(NotImplementedError, lambda: box.__iter__().__next__()) - self.assertRaises(NotImplementedError, lambda: box.values()) - self.assertRaises(NotImplementedError, lambda: box.iteritems().__next__()) - self.assertRaises(NotImplementedError, lambda: box.items()) - self.assertRaises(NotImplementedError, lambda: box.get('')) - self.assertRaises(NotImplementedError, lambda: box.__getitem__('')) - self.assertRaises(NotImplementedError, lambda: box.get_message('')) - self.assertRaises(NotImplementedError, lambda: box.get_string('')) - self.assertRaises(NotImplementedError, lambda: box.get_bytes('')) - self.assertRaises(NotImplementedError, lambda: box.get_file('')) - self.assertRaises(NotImplementedError, lambda: '' in box) - self.assertRaises(NotImplementedError, lambda: box.__contains__('')) - self.assertRaises(NotImplementedError, lambda: box.__len__()) - self.assertRaises(NotImplementedError, lambda: box.clear()) - self.assertRaises(NotImplementedError, lambda: box.pop('')) - self.assertRaises(NotImplementedError, lambda: box.popitem()) - self.assertRaises(NotImplementedError, lambda: box.update((('', ''),))) - self.assertRaises(NotImplementedError, lambda: box.flush()) - self.assertRaises(NotImplementedError, lambda: box.lock()) - self.assertRaises(NotImplementedError, lambda: box.unlock()) - self.assertRaises(NotImplementedError, lambda: box.close()) - - - class TestMaildir(TestMailbox, unittest.TestCase): - - _factory = lambda self, path, factory=None: mailbox.Maildir(path, factory) - - def setUp(self): - TestMailbox.setUp(self) - if (os.name == 'nt') or (sys.platform == 'cygwin'): - self._box.colon = '!' - - def assertMailboxEmpty(self): - self.assertEqual(os.listdir(os.path.join(self._path, 'tmp')), []) - - def test_add_MM(self): - # Add a MaildirMessage instance - msg = mailbox.MaildirMessage(self._template % 0) - msg.set_subdir('cur') - msg.set_info('foo') - key = self._box.add(msg) - self.assertTrue(os.path.exists(os.path.join(self._path, 'cur', '%s%sfoo' % - (key, self._box.colon)))) - - def test_get_MM(self): - # Get a MaildirMessage instance - msg = mailbox.MaildirMessage(self._template % 0) - msg.set_subdir('cur') - msg.set_flags('RF') - key = self._box.add(msg) - msg_returned = self._box.get_message(key) - self.assertIsInstance(msg_returned, mailbox.MaildirMessage) - self.assertEqual(msg_returned.get_subdir(), 'cur') - self.assertEqual(msg_returned.get_flags(), 'FR') - - def test_set_MM(self): - # Set with a MaildirMessage instance - msg0 = mailbox.MaildirMessage(self._template % 0) - msg0.set_flags('TP') - key = self._box.add(msg0) - msg_returned = self._box.get_message(key) - self.assertEqual(msg_returned.get_subdir(), 'new') - self.assertEqual(msg_returned.get_flags(), 'PT') - msg1 = mailbox.MaildirMessage(self._template % 1) - self._box[key] = msg1 - msg_returned = self._box.get_message(key) - self.assertEqual(msg_returned.get_subdir(), 'new') - self.assertEqual(msg_returned.get_flags(), '') - self.assertEqual(msg_returned.get_payload(), '1\n') - msg2 = mailbox.MaildirMessage(self._template % 2) - msg2.set_info('2,S') - self._box[key] = msg2 - self._box[key] = self._template % 3 - msg_returned = self._box.get_message(key) - self.assertEqual(msg_returned.get_subdir(), 'new') - self.assertEqual(msg_returned.get_flags(), 'S') - self.assertEqual(msg_returned.get_payload(), '3\n') - - def test_consistent_factory(self): - # Add a message. - msg = mailbox.MaildirMessage(self._template % 0) - msg.set_subdir('cur') - msg.set_flags('RF') - key = self._box.add(msg) - - # Create new mailbox with - class FakeMessage(mailbox.MaildirMessage): - pass - box = mailbox.Maildir(self._path, factory=FakeMessage) - box.colon = self._box.colon - msg2 = box.get_message(key) - self.assertIsInstance(msg2, FakeMessage) - - def test_initialize_new(self): - # Initialize a non-existent mailbox - self.tearDown() - self._box = mailbox.Maildir(self._path) - self._check_basics() - self._delete_recursively(self._path) - self._box = self._factory(self._path, factory=None) - self._check_basics() - - def test_initialize_existing(self): - # Initialize an existing mailbox - self.tearDown() - for subdir in '', 'tmp', 'new', 'cur': - os.mkdir(os.path.normpath(os.path.join(self._path, subdir))) - self._box = mailbox.Maildir(self._path) - self._check_basics() - - def _check_basics(self, factory=None): - # (Used by test_open_new() and test_open_existing().) - self.assertEqual(self._box._path, os.path.abspath(self._path)) - self.assertEqual(self._box._factory, factory) - for subdir in '', 'tmp', 'new', 'cur': - path = os.path.join(self._path, subdir) - mode = os.stat(path)[stat.ST_MODE] - self.assertTrue(stat.S_ISDIR(mode), "Not a directory: '%s'" % path) - - def test_list_folders(self): - # List folders - self._box.add_folder('one') - self._box.add_folder('two') - self._box.add_folder('three') - self.assertEqual(len(self._box.list_folders()), 3) - self.assertEqual(set(self._box.list_folders()), - set(('one', 'two', 'three'))) - - def test_get_folder(self): - # Open folders - self._box.add_folder('foo.bar') - folder0 = self._box.get_folder('foo.bar') - folder0.add(self._template % 'bar') - self.assertTrue(os.path.isdir(os.path.join(self._path, '.foo.bar'))) - folder1 = self._box.get_folder('foo.bar') - self.assertEqual(folder1.get_string(folder1.keys()[0]), - self._template % 'bar') - - def test_add_and_remove_folders(self): - # Delete folders - self._box.add_folder('one') - self._box.add_folder('two') - self.assertEqual(len(self._box.list_folders()), 2) - self.assertEqual(set(self._box.list_folders()), set(('one', 'two'))) - self._box.remove_folder('one') - self.assertEqual(len(self._box.list_folders()), 1) - self.assertEqual(set(self._box.list_folders()), set(('two',))) - self._box.add_folder('three') - self.assertEqual(len(self._box.list_folders()), 2) - self.assertEqual(set(self._box.list_folders()), set(('two', 'three'))) - self._box.remove_folder('three') - self.assertEqual(len(self._box.list_folders()), 1) - self.assertEqual(set(self._box.list_folders()), set(('two',))) - self._box.remove_folder('two') - self.assertEqual(len(self._box.list_folders()), 0) - self.assertEqual(self._box.list_folders(), []) - - def test_clean(self): - # Remove old files from 'tmp' - foo_path = os.path.join(self._path, 'tmp', 'foo') - bar_path = os.path.join(self._path, 'tmp', 'bar') - with open(foo_path, 'w') as f: - f.write("@") - with open(bar_path, 'w') as f: - f.write("@") - self._box.clean() - self.assertTrue(os.path.exists(foo_path)) - self.assertTrue(os.path.exists(bar_path)) - foo_stat = os.stat(foo_path) - os.utime(foo_path, (time.time() - 129600 - 2, - foo_stat.st_mtime)) - self._box.clean() - self.assertFalse(os.path.exists(foo_path)) - self.assertTrue(os.path.exists(bar_path)) - - def test_create_tmp(self, repetitions=10): - # Create files in tmp directory - hostname = socket.gethostname() - if '/' in hostname: - hostname = hostname.replace('/', r'\057') - if ':' in hostname: - hostname = hostname.replace(':', r'\072') - pid = os.getpid() - pattern = re.compile(r"(?P