From 86c7507233929366ff17c9666200a33123491a8e Mon Sep 17 00:00:00 2001
From: Rami Ali <flowergrass@users.noreply.github.com>
Date: Tue, 7 Feb 2017 15:55:37 +1100
Subject: [PATCH] tests/cpydiff: Add initial set of tests for uPy-CPython
 differences.

These tests are intended to fail, as they provide a programatic record of
differences between uPy and CPython.  They also contain a special comment
at the start of the file which has meta-data describing the difference,
including known causes and known workarounds.
---
 tests/cpydiff/core_arguments.py               | 10 +++++++
 tests/cpydiff/core_class_delnotimpl.py        | 16 +++++++++++
 tests/cpydiff/core_class_superaslocal.py      | 13 +++++++++
 tests/cpydiff/core_class_supermultiple.py     | 27 +++++++++++++++++++
 tests/cpydiff/core_class_superproperty.py     | 18 +++++++++++++
 tests/cpydiff/core_function_instancevar.py    | 11 ++++++++
 tests/cpydiff/core_function_unpacking.py      |  7 +++++
 tests/cpydiff/core_generator_noexit.py        | 24 +++++++++++++++++
 tests/cpydiff/core_import_prereg.py           | 17 ++++++++++++
 tests/cpydiff/core_mro.py                     | 15 +++++++++++
 tests/cpydiff/modules/__init__.py             |  0
 tests/cpydiff/modules/foo.py                  |  2 ++
 tests/cpydiff/modules_array_containment.py    |  8 ++++++
 tests/cpydiff/modules_array_deletion.py       | 10 +++++++
 tests/cpydiff/modules_array_subscrstep.py     |  9 +++++++
 tests/cpydiff/modules_deque.py                |  9 +++++++
 tests/cpydiff/modules_json_nonserializable.py | 14 ++++++++++
 tests/cpydiff/modules_struct_fewargs.py       | 12 +++++++++
 tests/cpydiff/modules_struct_manyargs.py      | 12 +++++++++
 tests/cpydiff/modules_sys_stdassign.py        |  9 +++++++
 tests/cpydiff/syntax_spaces.py                | 18 +++++++++++++
 tests/cpydiff/syntax_unicode_nameesc.py       |  7 +++++
 tests/cpydiff/types_bytearray_sliceassign.py  |  9 +++++++
 tests/cpydiff/types_bytes_keywords.py         |  7 +++++
 tests/cpydiff/types_bytes_subscrstep.py       |  7 +++++
 tests/cpydiff/types_exception_chaining.py     | 10 +++++++
 tests/cpydiff/types_exception_instancevar.py  |  9 +++++++
 tests/cpydiff/types_exception_loops.py        | 12 +++++++++
 tests/cpydiff/types_exception_subclassinit.py | 11 ++++++++
 tests/cpydiff/types_float_rounding.py         |  9 +++++++
 tests/cpydiff/types_int_subclassconv.py       | 11 ++++++++
 tests/cpydiff/types_int_tobytesfloat.py       | 10 +++++++
 tests/cpydiff/types_list_delete_subscrstep.py |  9 +++++++
 tests/cpydiff/types_list_store_subscrstep.py  |  9 +++++++
 tests/cpydiff/types_str_decodeerror.py        | 11 ++++++++
 tests/cpydiff/types_str_endswith.py           |  7 +++++
 tests/cpydiff/types_str_formatsubscr.py       |  7 +++++
 tests/cpydiff/types_str_keywords.py           |  7 +++++
 tests/cpydiff/types_str_rsplitnone.py         |  7 +++++
 tests/cpydiff/types_str_subclassequality.py   | 11 ++++++++
 tests/cpydiff/types_str_subscrstep.py         |  7 +++++
 tests/cpydiff/types_tuple_subscrstep.py       |  7 +++++
 42 files changed, 445 insertions(+)
 create mode 100644 tests/cpydiff/core_arguments.py
 create mode 100644 tests/cpydiff/core_class_delnotimpl.py
 create mode 100644 tests/cpydiff/core_class_superaslocal.py
 create mode 100644 tests/cpydiff/core_class_supermultiple.py
 create mode 100644 tests/cpydiff/core_class_superproperty.py
 create mode 100644 tests/cpydiff/core_function_instancevar.py
 create mode 100644 tests/cpydiff/core_function_unpacking.py
 create mode 100644 tests/cpydiff/core_generator_noexit.py
 create mode 100644 tests/cpydiff/core_import_prereg.py
 create mode 100644 tests/cpydiff/core_mro.py
 create mode 100644 tests/cpydiff/modules/__init__.py
 create mode 100644 tests/cpydiff/modules/foo.py
 create mode 100644 tests/cpydiff/modules_array_containment.py
 create mode 100644 tests/cpydiff/modules_array_deletion.py
 create mode 100644 tests/cpydiff/modules_array_subscrstep.py
 create mode 100644 tests/cpydiff/modules_deque.py
 create mode 100644 tests/cpydiff/modules_json_nonserializable.py
 create mode 100644 tests/cpydiff/modules_struct_fewargs.py
 create mode 100644 tests/cpydiff/modules_struct_manyargs.py
 create mode 100644 tests/cpydiff/modules_sys_stdassign.py
 create mode 100644 tests/cpydiff/syntax_spaces.py
 create mode 100644 tests/cpydiff/syntax_unicode_nameesc.py
 create mode 100644 tests/cpydiff/types_bytearray_sliceassign.py
 create mode 100644 tests/cpydiff/types_bytes_keywords.py
 create mode 100644 tests/cpydiff/types_bytes_subscrstep.py
 create mode 100644 tests/cpydiff/types_exception_chaining.py
 create mode 100644 tests/cpydiff/types_exception_instancevar.py
 create mode 100644 tests/cpydiff/types_exception_loops.py
 create mode 100644 tests/cpydiff/types_exception_subclassinit.py
 create mode 100644 tests/cpydiff/types_float_rounding.py
 create mode 100644 tests/cpydiff/types_int_subclassconv.py
 create mode 100644 tests/cpydiff/types_int_tobytesfloat.py
 create mode 100644 tests/cpydiff/types_list_delete_subscrstep.py
 create mode 100644 tests/cpydiff/types_list_store_subscrstep.py
 create mode 100644 tests/cpydiff/types_str_decodeerror.py
 create mode 100644 tests/cpydiff/types_str_endswith.py
 create mode 100644 tests/cpydiff/types_str_formatsubscr.py
 create mode 100644 tests/cpydiff/types_str_keywords.py
 create mode 100644 tests/cpydiff/types_str_rsplitnone.py
 create mode 100644 tests/cpydiff/types_str_subclassequality.py
 create mode 100644 tests/cpydiff/types_str_subscrstep.py
 create mode 100644 tests/cpydiff/types_tuple_subscrstep.py

diff --git a/tests/cpydiff/core_arguments.py b/tests/cpydiff/core_arguments.py
new file mode 100644
index 000000000..a0831ab40
--- /dev/null
+++ b/tests/cpydiff/core_arguments.py
@@ -0,0 +1,10 @@
+"""
+categories: Core
+description: Error messages may display incorrect argument counts
+cause: Unknown
+workaround: Unknown
+"""
+try:
+    [].append()
+except Exception as e:
+    print(e)
diff --git a/tests/cpydiff/core_class_delnotimpl.py b/tests/cpydiff/core_class_delnotimpl.py
new file mode 100644
index 000000000..c51c3d536
--- /dev/null
+++ b/tests/cpydiff/core_class_delnotimpl.py
@@ -0,0 +1,16 @@
+"""
+categories: Core,Classes
+description: Special method __del__ not implemented for user-defined classes
+cause: Unknown
+workaround: Unknown
+"""
+import gc
+
+class Foo():
+    def __del__(self):
+        print('__del__')
+
+f = Foo()
+del f
+
+gc.collect()
diff --git a/tests/cpydiff/core_class_superaslocal.py b/tests/cpydiff/core_class_superaslocal.py
new file mode 100644
index 000000000..fc07ccb38
--- /dev/null
+++ b/tests/cpydiff/core_class_superaslocal.py
@@ -0,0 +1,13 @@
+"""
+categories: Core,Classes
+description: Bug when using "super" as a local
+cause: Unknown
+workaround: Unknown
+"""
+class A:
+    def foo(self):
+        super = [1]
+        super.pop()
+        print(super)
+
+A().foo()
diff --git a/tests/cpydiff/core_class_supermultiple.py b/tests/cpydiff/core_class_supermultiple.py
new file mode 100644
index 000000000..adf4a17a8
--- /dev/null
+++ b/tests/cpydiff/core_class_supermultiple.py
@@ -0,0 +1,27 @@
+"""
+categories: Core,Classes
+description: When inheriting from multiple classes super() only calls one class
+cause: Depth first non-exhaustive method resolution order
+workaround: Unknown
+"""
+class A:
+    def __init__(self):
+        print("A.__init__")
+
+class B(A):
+    def __init__(self):
+        print("B.__init__")
+        super().__init__()
+
+class C(A):
+    def __init__(self):
+        print("C.__init__")
+        super().__init__()
+
+
+class D(B,C):
+    def __init__(self):
+        print("D.__init__")
+        super().__init__()
+
+D()
diff --git a/tests/cpydiff/core_class_superproperty.py b/tests/cpydiff/core_class_superproperty.py
new file mode 100644
index 000000000..1ec210550
--- /dev/null
+++ b/tests/cpydiff/core_class_superproperty.py
@@ -0,0 +1,18 @@
+"""
+categories: Core,Classes
+description: Calling super() getter property in subclass will return a property object, not the value
+cause: Unknown
+workaround: Unknown
+"""
+class A:
+    @property
+    def p(self):
+        return {"a":10}
+
+class AA(A):
+    @property
+    def p(self):
+        return super().p
+
+a = AA()
+print(a.p)
diff --git a/tests/cpydiff/core_function_instancevar.py b/tests/cpydiff/core_function_instancevar.py
new file mode 100644
index 000000000..ab027b166
--- /dev/null
+++ b/tests/cpydiff/core_function_instancevar.py
@@ -0,0 +1,11 @@
+"""
+categories: Core,Functions
+description: Assign instance variable to function
+cause: Unknown
+workaround: Unknown
+"""
+def f():
+    pass
+
+f.x = 0
+print(f.x)
diff --git a/tests/cpydiff/core_function_unpacking.py b/tests/cpydiff/core_function_unpacking.py
new file mode 100644
index 000000000..f0cc24055
--- /dev/null
+++ b/tests/cpydiff/core_function_unpacking.py
@@ -0,0 +1,7 @@
+"""
+categories: Core,Functions
+description: Unpacking function arguments in non-last position gives incorrect result
+cause: Unknown
+workaround: Unknown
+"""
+print(*(1, 2), 3)
diff --git a/tests/cpydiff/core_generator_noexit.py b/tests/cpydiff/core_generator_noexit.py
new file mode 100644
index 000000000..c25fbe75a
--- /dev/null
+++ b/tests/cpydiff/core_generator_noexit.py
@@ -0,0 +1,24 @@
+"""
+categories: Core,Generator
+description: Context manager __exit__() not called in a generator which does not run to completion
+cause: Unknown
+workaround: Unknown
+"""
+class foo(object):
+    def __enter__(self):
+        print('Enter')
+    def __exit__(self, *args):
+        print('Exit')
+
+def bar(x):
+    with foo():
+        while True:
+            x += 1
+            yield x
+
+def func():
+    g = bar(0)
+    for _ in range(3):
+        print(next(g))
+
+func()
diff --git a/tests/cpydiff/core_import_prereg.py b/tests/cpydiff/core_import_prereg.py
new file mode 100644
index 000000000..ab04cfc99
--- /dev/null
+++ b/tests/cpydiff/core_import_prereg.py
@@ -0,0 +1,17 @@
+"""
+categories: Core,import
+description: Failed to load modules are still registered as loaded
+cause: Unknown
+workaround: Unknown
+"""
+import sys
+
+try:
+    from modules import foo
+except NameError as e:
+    print(e)
+try:
+    from modules import foo
+    print('Should not get here')
+except NameError as e:
+    print(e)
diff --git a/tests/cpydiff/core_mro.py b/tests/cpydiff/core_mro.py
new file mode 100644
index 000000000..35b898b30
--- /dev/null
+++ b/tests/cpydiff/core_mro.py
@@ -0,0 +1,15 @@
+"""
+categories: Core
+description: Method Resolution Order (MRO) is not compliant with CPython
+cause: Unknown
+workaround: Unknown
+"""
+class Foo:
+    def __str__(self):
+        return "Foo"
+
+class C(tuple, Foo):
+    pass
+
+t = C((1, 2, 3))
+print(t)
diff --git a/tests/cpydiff/modules/__init__.py b/tests/cpydiff/modules/__init__.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/tests/cpydiff/modules/foo.py b/tests/cpydiff/modules/foo.py
new file mode 100644
index 000000000..e6e33a7b4
--- /dev/null
+++ b/tests/cpydiff/modules/foo.py
@@ -0,0 +1,2 @@
+print('foo')
+xxx
diff --git a/tests/cpydiff/modules_array_containment.py b/tests/cpydiff/modules_array_containment.py
new file mode 100644
index 000000000..190a3c276
--- /dev/null
+++ b/tests/cpydiff/modules_array_containment.py
@@ -0,0 +1,8 @@
+"""
+categories: Modules,array
+description: Looking for integer not implemented
+cause: Unknown
+workaround: Unknown
+"""
+import array
+print(1 in array.array('B', b'12'))
diff --git a/tests/cpydiff/modules_array_deletion.py b/tests/cpydiff/modules_array_deletion.py
new file mode 100644
index 000000000..97f988da2
--- /dev/null
+++ b/tests/cpydiff/modules_array_deletion.py
@@ -0,0 +1,10 @@
+"""
+categories: Modules,array
+description: Array deletion not implemented
+cause: Unknown
+workaround: Unknown
+"""
+import array
+a = array.array('b', (1, 2, 3))
+del a[1]
+print(a)
diff --git a/tests/cpydiff/modules_array_subscrstep.py b/tests/cpydiff/modules_array_subscrstep.py
new file mode 100644
index 000000000..1103f1826
--- /dev/null
+++ b/tests/cpydiff/modules_array_subscrstep.py
@@ -0,0 +1,9 @@
+"""
+categories: Modules,array
+description: Subscript with step != 1 is not yet implemented
+cause: Unknown
+workaround: Unknown
+"""
+import array
+a = array.array('b', (1, 2, 3))
+print(a[3:2:2])
diff --git a/tests/cpydiff/modules_deque.py b/tests/cpydiff/modules_deque.py
new file mode 100644
index 000000000..dc9369d02
--- /dev/null
+++ b/tests/cpydiff/modules_deque.py
@@ -0,0 +1,9 @@
+"""
+categories: Modules,deque
+description: Deque not implemented
+cause: Unknown
+workaround: Use regular queues or lists creatively
+"""
+import collections
+D = collections.deque()
+print(D)
diff --git a/tests/cpydiff/modules_json_nonserializable.py b/tests/cpydiff/modules_json_nonserializable.py
new file mode 100644
index 000000000..913b734e8
--- /dev/null
+++ b/tests/cpydiff/modules_json_nonserializable.py
@@ -0,0 +1,14 @@
+"""
+categories: Modules,json
+description: JSON module does not throw exception when object is not serialisable
+cause: Unknown
+workaround: Unknown
+"""
+import json
+a = bytes(x for x in range(256))
+try:
+    z = json.dumps(a)
+    x = json.loads(z)
+    print('Should not get here')
+except TypeError:
+    print('TypeError')
diff --git a/tests/cpydiff/modules_struct_fewargs.py b/tests/cpydiff/modules_struct_fewargs.py
new file mode 100644
index 000000000..08d32ca67
--- /dev/null
+++ b/tests/cpydiff/modules_struct_fewargs.py
@@ -0,0 +1,12 @@
+"""
+categories: Modules,struct
+description: Struct pack with too few args, not checked by uPy
+cause: Unknown
+workaround: Unknown
+"""
+import struct
+try:
+    print(struct.pack('bb', 1))
+    print('Should not get here')
+except:
+    print('struct.error')
diff --git a/tests/cpydiff/modules_struct_manyargs.py b/tests/cpydiff/modules_struct_manyargs.py
new file mode 100644
index 000000000..cdbb5c672
--- /dev/null
+++ b/tests/cpydiff/modules_struct_manyargs.py
@@ -0,0 +1,12 @@
+"""
+categories: Modules,struct
+description: Struct pack with too many args, not checked by uPy
+cause: Unknown
+workaround: Unknown
+"""
+import struct
+try:
+    print(struct.pack('bb', 1, 2, 3))
+    print('Should not get here')
+except:
+    print('struct.error')
diff --git a/tests/cpydiff/modules_sys_stdassign.py b/tests/cpydiff/modules_sys_stdassign.py
new file mode 100644
index 000000000..096af430e
--- /dev/null
+++ b/tests/cpydiff/modules_sys_stdassign.py
@@ -0,0 +1,9 @@
+"""
+categories: Modules,sys
+description: Override sys.stdin, sys.stdout and sys.stderr. Impossible as they are stored in read-only memory.
+cause: Unknown
+workaround: Unknown
+"""
+import sys
+sys.stdin = None
+print(sys.stdin)
diff --git a/tests/cpydiff/syntax_spaces.py b/tests/cpydiff/syntax_spaces.py
new file mode 100644
index 000000000..8578a51e2
--- /dev/null
+++ b/tests/cpydiff/syntax_spaces.py
@@ -0,0 +1,18 @@
+"""
+categories: Syntax,Spaces
+description: uPy requires spaces between literal numbers and keywords, CPy doesn't
+cause: Unknown
+workaround: Unknown
+"""
+try:
+    print(eval('1and 0'))
+except SyntaxError:
+    print('Should have worked')
+try:
+    print(eval('1or 0'))
+except SyntaxError:
+    print('Should have worked')
+try:
+    print(eval('1if 1else 0'))
+except SyntaxError:
+    print('Should have worked')
diff --git a/tests/cpydiff/syntax_unicode_nameesc.py b/tests/cpydiff/syntax_unicode_nameesc.py
new file mode 100644
index 000000000..21628c974
--- /dev/null
+++ b/tests/cpydiff/syntax_unicode_nameesc.py
@@ -0,0 +1,7 @@
+"""
+categories: Syntax,Unicode
+description: Unicode name escapes are not implemented
+cause: Unknown
+workaround: Unknown
+"""
+print("\N{LATIN SMALL LETTER A}")
diff --git a/tests/cpydiff/types_bytearray_sliceassign.py b/tests/cpydiff/types_bytearray_sliceassign.py
new file mode 100644
index 000000000..e4068b04b
--- /dev/null
+++ b/tests/cpydiff/types_bytearray_sliceassign.py
@@ -0,0 +1,9 @@
+"""
+categories: Types,bytearray
+description: Array slice assignment with unsupported RHS
+cause: Unknown
+workaround: Unknown
+"""
+b = bytearray(4)
+b[0:1] = [1, 2]
+print(b)
diff --git a/tests/cpydiff/types_bytes_keywords.py b/tests/cpydiff/types_bytes_keywords.py
new file mode 100644
index 000000000..35119e28f
--- /dev/null
+++ b/tests/cpydiff/types_bytes_keywords.py
@@ -0,0 +1,7 @@
+"""
+categories: Types,bytes
+description: bytes(...) with keywords not implemented
+cause: Unknown
+workaround: Input the encoding format directly. eg. ``print(bytes('abc', 'utf-8'))``
+"""
+print(bytes('abc', encoding='utf8'))
diff --git a/tests/cpydiff/types_bytes_subscrstep.py b/tests/cpydiff/types_bytes_subscrstep.py
new file mode 100644
index 000000000..fd1602d65
--- /dev/null
+++ b/tests/cpydiff/types_bytes_subscrstep.py
@@ -0,0 +1,7 @@
+"""
+categories: Types,bytes
+description: Bytes subscr with step != 1 not implemented
+cause: Unknown
+workaround: Unknown
+"""
+print(b'123'[0:3:2])
diff --git a/tests/cpydiff/types_exception_chaining.py b/tests/cpydiff/types_exception_chaining.py
new file mode 100644
index 000000000..836c4eb3e
--- /dev/null
+++ b/tests/cpydiff/types_exception_chaining.py
@@ -0,0 +1,10 @@
+"""
+categories: Types,Exception
+description: Exception chaining not implemented
+cause: Unknown
+workaround: Unknown
+"""
+try:
+    raise TypeError
+except TypeError:
+    raise ValueError
diff --git a/tests/cpydiff/types_exception_instancevar.py b/tests/cpydiff/types_exception_instancevar.py
new file mode 100644
index 000000000..d1015e96c
--- /dev/null
+++ b/tests/cpydiff/types_exception_instancevar.py
@@ -0,0 +1,9 @@
+"""
+categories: Types,Exception
+description: Assign instance variable to exception
+cause: Unknown
+workaround: Unknown
+"""
+e = Exception()
+e.x = 0
+print(e.x)
diff --git a/tests/cpydiff/types_exception_loops.py b/tests/cpydiff/types_exception_loops.py
new file mode 100644
index 000000000..a142e4757
--- /dev/null
+++ b/tests/cpydiff/types_exception_loops.py
@@ -0,0 +1,12 @@
+"""
+categories: Types,Exception
+description: While loop guards will obscure exception line number reporting due to being optimised onto the end of the code block
+cause: Unknown
+workaround: Unknown
+"""
+l = ["-foo", "-bar"]
+
+i = 0
+while l[i][0] == "-":
+    print("iter")
+    i += 1
diff --git a/tests/cpydiff/types_exception_subclassinit.py b/tests/cpydiff/types_exception_subclassinit.py
new file mode 100644
index 000000000..177094646
--- /dev/null
+++ b/tests/cpydiff/types_exception_subclassinit.py
@@ -0,0 +1,11 @@
+"""
+categories: Types,Exception
+description: Exception.__init__ raises TypeError if overridden and called by subclass
+cause: Unknown
+workaround: Unknown
+"""
+class A(Exception):
+    def __init__(self):
+        Exception.__init__(self)
+
+a = A()
diff --git a/tests/cpydiff/types_float_rounding.py b/tests/cpydiff/types_float_rounding.py
new file mode 100644
index 000000000..647f61ba2
--- /dev/null
+++ b/tests/cpydiff/types_float_rounding.py
@@ -0,0 +1,9 @@
+"""
+categories: Types,float
+description: uPy and CPython outputs formats differ
+cause: Unknown
+workaround: Unknown
+"""
+print('%.1g' % -9.9)
+print('%.1e' % 9.99)
+print('%.1e' % 0.999)
diff --git a/tests/cpydiff/types_int_subclassconv.py b/tests/cpydiff/types_int_subclassconv.py
new file mode 100644
index 000000000..565fbad4b
--- /dev/null
+++ b/tests/cpydiff/types_int_subclassconv.py
@@ -0,0 +1,11 @@
+"""
+categories: Types,int
+description: No int conversion for int-derived types available
+cause: Unknown
+workaround: Unknown
+"""
+class A(int):
+    __add__ = lambda self, other: A(int(self) + other)
+
+a = A(42)
+print(a+a)
diff --git a/tests/cpydiff/types_int_tobytesfloat.py b/tests/cpydiff/types_int_tobytesfloat.py
new file mode 100644
index 000000000..5d5b980fa
--- /dev/null
+++ b/tests/cpydiff/types_int_tobytesfloat.py
@@ -0,0 +1,10 @@
+"""
+categories: Types,int
+description: Incorrect error message when passing float into to_bytes
+cause: Unknown
+workaround: Unknown
+"""
+try:
+    int('1').to_bytes(1.0)
+except TypeError as e:
+    print(e)
diff --git a/tests/cpydiff/types_list_delete_subscrstep.py b/tests/cpydiff/types_list_delete_subscrstep.py
new file mode 100644
index 000000000..f524fa8dc
--- /dev/null
+++ b/tests/cpydiff/types_list_delete_subscrstep.py
@@ -0,0 +1,9 @@
+"""
+categories: Types,list
+description: List delete with step != 1 not implemented
+cause: Unknown
+workaround: Unknown
+"""
+l = [1, 2, 3, 4]
+del l[0:4:2]
+print(l)
diff --git a/tests/cpydiff/types_list_store_subscrstep.py b/tests/cpydiff/types_list_store_subscrstep.py
new file mode 100644
index 000000000..2de2e1a3c
--- /dev/null
+++ b/tests/cpydiff/types_list_store_subscrstep.py
@@ -0,0 +1,9 @@
+"""
+categories: Types,list
+description: List store with step != 1 not implemented
+cause: Unknown
+workaround: Unknown
+"""
+l = [1, 2, 3, 4]
+l[0:4:2] = [5, 6]
+print(l)
diff --git a/tests/cpydiff/types_str_decodeerror.py b/tests/cpydiff/types_str_decodeerror.py
new file mode 100644
index 000000000..944db98fe
--- /dev/null
+++ b/tests/cpydiff/types_str_decodeerror.py
@@ -0,0 +1,11 @@
+"""
+categories: Types,str
+description: UnicodeDecodeError not raised when expected
+cause: Unknown
+workaround: Unknown
+"""
+try:
+    print(repr(str(b"\xa1\x80", 'utf8')))
+    print('Should not get here')
+except UnicodeDecodeError:
+    print('UnicodeDecodeError')
diff --git a/tests/cpydiff/types_str_endswith.py b/tests/cpydiff/types_str_endswith.py
new file mode 100644
index 000000000..ac2600bd2
--- /dev/null
+++ b/tests/cpydiff/types_str_endswith.py
@@ -0,0 +1,7 @@
+"""
+categories: Types,str
+description: Start/end indices such as str.endswith(s, start) not implemented
+cause: Unknown
+workaround: Unknown
+"""
+print('abc'.endswith('c', 1))
diff --git a/tests/cpydiff/types_str_formatsubscr.py b/tests/cpydiff/types_str_formatsubscr.py
new file mode 100644
index 000000000..dd1d8d33d
--- /dev/null
+++ b/tests/cpydiff/types_str_formatsubscr.py
@@ -0,0 +1,7 @@
+"""
+categories: Types,str
+description: Attributes/subscr not implemented
+cause: Unknown
+workaround: Unknown
+"""
+print('{a[0]}'.format(a=[1, 2]))
diff --git a/tests/cpydiff/types_str_keywords.py b/tests/cpydiff/types_str_keywords.py
new file mode 100644
index 000000000..b336b1a73
--- /dev/null
+++ b/tests/cpydiff/types_str_keywords.py
@@ -0,0 +1,7 @@
+"""
+categories: Types,str
+description: str(...) with keywords not implemented
+cause: Unknown
+workaround: Input the encoding format directly. eg ``print(bytes('abc', 'utf-8'))``
+"""
+print(str(b'abc', encoding='utf8'))
diff --git a/tests/cpydiff/types_str_rsplitnone.py b/tests/cpydiff/types_str_rsplitnone.py
new file mode 100644
index 000000000..cadf86987
--- /dev/null
+++ b/tests/cpydiff/types_str_rsplitnone.py
@@ -0,0 +1,7 @@
+"""
+categories: Types,str
+description: None as first argument for rsplit such as str.rsplit(None, n) not implemented
+cause: Unknown
+workaround: Unknown
+"""
+print('a a a'.rsplit(None, 1))
diff --git a/tests/cpydiff/types_str_subclassequality.py b/tests/cpydiff/types_str_subclassequality.py
new file mode 100644
index 000000000..8aec1ea78
--- /dev/null
+++ b/tests/cpydiff/types_str_subclassequality.py
@@ -0,0 +1,11 @@
+"""
+categories: Types,str
+description: Instance of a subclass of str cannot be compared for equality with an instance of a str
+cause: Unknown
+workaround: Unknown
+"""
+class S(str):
+    pass
+
+s = S('hello')
+print(s == 'hello')
diff --git a/tests/cpydiff/types_str_subscrstep.py b/tests/cpydiff/types_str_subscrstep.py
new file mode 100644
index 000000000..0c2fce1b1
--- /dev/null
+++ b/tests/cpydiff/types_str_subscrstep.py
@@ -0,0 +1,7 @@
+"""
+categories: Types,str
+description: Subscript with step != 1 is not yet implemented
+cause: Unknown
+workaround: Unknown
+"""
+print('abcdefghi'[0:9:2])
diff --git a/tests/cpydiff/types_tuple_subscrstep.py b/tests/cpydiff/types_tuple_subscrstep.py
new file mode 100644
index 000000000..f90f3c5bf
--- /dev/null
+++ b/tests/cpydiff/types_tuple_subscrstep.py
@@ -0,0 +1,7 @@
+"""
+categories: Types,tuple
+description: Tuple load with step != 1 not implemented
+cause: Unknown
+workaround: Unknown
+"""
+print((1, 2, 3, 4)[0:4:2])
-- 
GitLab