From b5686d01cad68b1e91281ec8a77879dd4670c8d5 Mon Sep 17 00:00:00 2001 From: Jeong YunWon Date: Thu, 29 Jul 2021 22:47:34 +0900 Subject: [PATCH 1/3] Update test_bytes.py to 3.9.6 --- Lib/test/test_bytes.py | 86 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 84 insertions(+), 2 deletions(-) diff --git a/Lib/test/test_bytes.py b/Lib/test/test_bytes.py index e7d78a1a4c..32b3b6baef 100644 --- a/Lib/test/test_bytes.py +++ b/Lib/test/test_bytes.py @@ -12,12 +12,14 @@ import functools import pickle import tempfile +import textwrap import unittest import test.support import test.string_tests import test.list_tests from test.support import bigaddrspacetest, MAX_Py_ssize_t +from test.support.script_helper import assert_python_failure if sys.flags.bytes_warning: @@ -319,6 +321,62 @@ def test_decode(self): # Default encoding is utf-8 self.assertEqual(self.type2test(b'\xe2\x98\x83').decode(), '\u2603') + def test_check_encoding_errors(self): + # bpo-37388: bytes(str) and bytes.encode() must check encoding + # and errors arguments in dev mode + invalid = 'Boom, Shaka Laka, Boom!' + encodings = ('ascii', 'utf8', 'latin1') + code = textwrap.dedent(f''' + import sys + type2test = {self.type2test.__name__} + encodings = {encodings!r} + + for data in ('', 'short string'): + try: + type2test(data, encoding={invalid!r}) + except LookupError: + pass + else: + sys.exit(21) + + for encoding in encodings: + try: + type2test(data, encoding=encoding, errors={invalid!r}) + except LookupError: + pass + else: + sys.exit(22) + + for data in (b'', b'short string'): + data = type2test(data) + print(repr(data)) + try: + data.decode(encoding={invalid!r}) + except LookupError: + sys.exit(10) + else: + sys.exit(23) + + try: + data.decode(errors={invalid!r}) + except LookupError: + pass + else: + sys.exit(24) + + for encoding in encodings: + try: + data.decode(encoding=encoding, errors={invalid!r}) + except LookupError: + pass + else: + sys.exit(25) + + sys.exit(10) + ''') + proc = assert_python_failure('-X', 'dev', '-c', code) + self.assertEqual(proc.rc, 10, proc) + def test_from_int(self): b = self.type2test(0) self.assertEqual(b, self.type2test()) @@ -494,9 +552,13 @@ def test_join(self): 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 + seq = [b"abc"] * 100000 + expected = b"abc" + b".:abc" * 99999 self.assertEqual(dot_join(seq), expected) + # Stress test with empty separator + seq = [b"abc"] * 100000 + expected = b"abc" * 100000 + self.assertEqual(self.type2test(b"").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. @@ -917,6 +979,15 @@ def test_translate(self): c = b.translate(None, delete=b'e') self.assertEqual(c, b'hllo') + def test_sq_item(self): + _testcapi = test.support.import_module('_testcapi') + obj = self.type2test((42,)) + with self.assertRaises(IndexError): + _testcapi.sequence_getitem(obj, -2) + with self.assertRaises(IndexError): + _testcapi.sequence_getitem(obj, 1) + self.assertEqual(_testcapi.sequence_getitem(obj, 0), 42) + class BytesTest(BaseBytesTest, unittest.TestCase): type2test = bytes @@ -978,6 +1049,7 @@ def test_from_format(self): c_char_p) PyBytes_FromFormat = pythonapi.PyBytes_FromFormat + PyBytes_FromFormat.argtypes = (c_char_p,) PyBytes_FromFormat.restype = py_object # basic tests @@ -1615,6 +1687,16 @@ def test_iterator_length_hint(self): # 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): # From 2d3b85b28c81c92b7aba4adb0eea3090a233fa6b Mon Sep 17 00:00:00 2001 From: Jeong YunWon Date: Thu, 29 Jul 2021 22:54:23 +0900 Subject: [PATCH 2/3] Mark unexpected failre of new test_bytes tests --- Lib/test/test_bytes.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Lib/test/test_bytes.py b/Lib/test/test_bytes.py index 32b3b6baef..05ab7bdaa7 100644 --- a/Lib/test/test_bytes.py +++ b/Lib/test/test_bytes.py @@ -321,6 +321,8 @@ def test_decode(self): # Default encoding is utf-8 self.assertEqual(self.type2test(b'\xe2\x98\x83').decode(), '\u2603') + # TODO: RUSTPYTHON + @unittest.expectedFailure def test_check_encoding_errors(self): # bpo-37388: bytes(str) and bytes.encode() must check encoding # and errors arguments in dev mode From 4890f09c576fc2bb0654c67eecc1ca52a0353c06 Mon Sep 17 00:00:00 2001 From: Nikita Sobolev Date: Fri, 30 Jul 2021 19:09:48 +0300 Subject: [PATCH 3/3] Fixes `type.__module__` issue, refs #2310 (#2763) * Fixes `type.__module__` issue, refs #2310 --- extra_tests/snippets/builtin_type.py | 46 ++++++++++++++++++++++++++++ vm/src/builtins/pytype.rs | 16 ++++++++++ 2 files changed, 62 insertions(+) create mode 100644 extra_tests/snippets/builtin_type.py diff --git a/extra_tests/snippets/builtin_type.py b/extra_tests/snippets/builtin_type.py new file mode 100644 index 0000000000..1831d23550 --- /dev/null +++ b/extra_tests/snippets/builtin_type.py @@ -0,0 +1,46 @@ +assert type.__module__ == 'builtins' +assert type.__qualname__ == 'type' +assert type.__name__ == 'type' +assert isinstance(type.__doc__, str) +assert object.__qualname__ == 'object' +assert int.__qualname__ == 'int' + + +class A(type): + pass + + +class B(type): + __module__ = 'b' + __qualname__ = 'BB' + + +class C: + pass + + +class D: + __module__ = 'd' + __qualname__ = 'DD' + + +assert A.__module__ == '__main__' +assert A.__qualname__ == 'A' +assert B.__module__ == 'b' +assert B.__qualname__ == 'BB' +assert C.__module__ == '__main__' +assert C.__qualname__ == 'C' +assert D.__module__ == 'd' +assert D.__qualname__ == 'DD' + + +# Regression to +# https://github.com/RustPython/RustPython/issues/2310 +import builtins +assert builtins.iter.__class__.__module__ == 'builtins' +assert builtins.iter.__class__.__qualname__ == 'builtin_function_or_method' + +assert iter.__class__.__module__ == 'builtins' +assert iter.__class__.__qualname__ == 'builtin_function_or_method' +assert type(iter).__module__ == 'builtins' +assert type(iter).__qualname__ == 'builtin_function_or_method' diff --git a/vm/src/builtins/pytype.rs b/vm/src/builtins/pytype.rs index bfaccec322..9236e572c8 100644 --- a/vm/src/builtins/pytype.rs +++ b/vm/src/builtins/pytype.rs @@ -306,6 +306,14 @@ impl PyType { .read() .get("__qualname__") .cloned() + // We need to exclude this method from going into recursion: + .and_then(|found| { + if found.isinstance(&vm.ctx.types.getset_type) { + None + } else { + Some(found) + } + }) .unwrap_or_else(|| vm.ctx.new_str(self.name.clone())) } @@ -316,6 +324,14 @@ impl PyType { .read() .get("__module__") .cloned() + // We need to exclude this method from going into recursion: + .and_then(|found| { + if found.isinstance(&vm.ctx.types.getset_type) { + None + } else { + Some(found) + } + }) .unwrap_or_else(|| vm.ctx.new_str("builtins")) }