| [case testStrSplit] | |
| from typing import NewType, Optional, List, Union | |
| NewStr = NewType("NewStr", str) | |
| def do_split(s: Union[str, NewStr], sep: Optional[str] = None, max_split: Optional[int] = None) -> List[str]: | |
| if sep is not None: | |
| if max_split is not None: | |
| return s.split(sep, max_split) | |
| else: | |
| return s.split(sep) | |
| return s.split() | |
| [typing fixtures/typing-full.pyi] | |
| [out] | |
| def do_split(s, sep, max_split): | |
| s :: str | |
| sep :: union[str, None] | |
| max_split :: union[int, None] | |
| r0, r1, r2 :: object | |
| r3 :: bit | |
| r4 :: object | |
| r5 :: bit | |
| r6 :: str | |
| r7 :: int | |
| r8 :: list | |
| r9 :: str | |
| r10, r11 :: list | |
| L0: | |
| if is_error(sep) goto L1 else goto L2 | |
| L1: | |
| r0 = box(None, 1) | |
| sep = r0 | |
| L2: | |
| if is_error(max_split) goto L3 else goto L4 | |
| L3: | |
| r1 = box(None, 1) | |
| max_split = r1 | |
| L4: | |
| r2 = load_address _Py_NoneStruct | |
| r3 = sep != r2 | |
| if r3 goto L5 else goto L9 :: bool | |
| L5: | |
| r4 = load_address _Py_NoneStruct | |
| r5 = max_split != r4 | |
| if r5 goto L6 else goto L7 :: bool | |
| L6: | |
| r6 = cast(str, sep) | |
| r7 = unbox(int, max_split) | |
| r8 = CPyStr_Split(s, r6, r7) | |
| return r8 | |
| L7: | |
| r9 = cast(str, sep) | |
| r10 = PyUnicode_Split(s, r9, -1) | |
| return r10 | |
| L8: | |
| L9: | |
| r11 = PyUnicode_Split(s, 0, -1) | |
| return r11 | |
| [case testStrEquality] | |
| from typing import NewType, Union | |
| NewStr = NewType("NewStr", str) | |
| def eq(x: str, y: str) -> bool: | |
| return x == y | |
| def neq(x: str, y: Union[str, NewStr]) -> bool: | |
| return x != y | |
| [typing fixtures/typing-full.pyi] | |
| [out] | |
| def eq(x, y): | |
| x, y :: str | |
| r0 :: bool | |
| L0: | |
| r0 = CPyStr_Equal(x, y) | |
| return r0 | |
| def neq(x, y): | |
| x, y :: str | |
| r0 :: bool | |
| r1 :: bit | |
| L0: | |
| r0 = CPyStr_Equal(x, y) | |
| r1 = r0 == 0 | |
| return r1 | |
| [case testStrReplace] | |
| from typing import NewType, Optional, Union | |
| NewStr = NewType("NewStr", str) | |
| def do_replace(s: Union[str, NewStr], old_substr: str, new_substr: str, max_count: Optional[int] = None) -> str: | |
| if max_count is not None: | |
| return s.replace(old_substr, new_substr, max_count) | |
| else: | |
| return s.replace(old_substr, new_substr) | |
| [typing fixtures/typing-full.pyi] | |
| [out] | |
| def do_replace(s, old_substr, new_substr, max_count): | |
| s, old_substr, new_substr :: str | |
| max_count :: union[int, None] | |
| r0, r1 :: object | |
| r2 :: bit | |
| r3 :: int | |
| r4, r5 :: str | |
| L0: | |
| if is_error(max_count) goto L1 else goto L2 | |
| L1: | |
| r0 = box(None, 1) | |
| max_count = r0 | |
| L2: | |
| r1 = load_address _Py_NoneStruct | |
| r2 = max_count != r1 | |
| if r2 goto L3 else goto L4 :: bool | |
| L3: | |
| r3 = unbox(int, max_count) | |
| r4 = CPyStr_Replace(s, old_substr, new_substr, r3) | |
| return r4 | |
| L4: | |
| r5 = PyUnicode_Replace(s, old_substr, new_substr, -1) | |
| return r5 | |
| L5: | |
| unreachable | |
| [case testStrStartswithEndswithTuple] | |
| from typing import NewType, Tuple, Union | |
| NewStr = NewType("NewStr", str) | |
| def do_startswith(s1: Union[str, NewStr], s2: Tuple[str, ...]) -> bool: | |
| return s1.startswith(s2) | |
| def do_endswith(s1: Union[str, NewStr], s2: Tuple[str, ...]) -> bool: | |
| return s1.endswith(s2) | |
| def do_tuple_literal_args(s1: Union[str, NewStr]) -> None: | |
| x = s1.startswith(("a", "b")) | |
| y = s1.endswith(("a", "b")) | |
| [typing fixtures/typing-full.pyi] | |
| [out] | |
| def do_startswith(s1, s2): | |
| s1 :: str | |
| s2 :: tuple | |
| r0 :: bool | |
| L0: | |
| r0 = CPyStr_Startswith(s1, s2) | |
| return r0 | |
| def do_endswith(s1, s2): | |
| s1 :: str | |
| s2 :: tuple | |
| r0 :: bool | |
| L0: | |
| r0 = CPyStr_Endswith(s1, s2) | |
| return r0 | |
| def do_tuple_literal_args(s1): | |
| s1, r0, r1 :: str | |
| r2 :: tuple[str, str] | |
| r3 :: object | |
| r4, x :: bool | |
| r5, r6 :: str | |
| r7 :: tuple[str, str] | |
| r8 :: object | |
| r9, y :: bool | |
| L0: | |
| r0 = 'a' | |
| r1 = 'b' | |
| r2 = (r0, r1) | |
| r3 = box(tuple[str, str], r2) | |
| r4 = CPyStr_Startswith(s1, r3) | |
| x = r4 | |
| r5 = 'a' | |
| r6 = 'b' | |
| r7 = (r5, r6) | |
| r8 = box(tuple[str, str], r7) | |
| r9 = CPyStr_Endswith(s1, r8) | |
| y = r9 | |
| return 1 | |
| [case testStrToBool] | |
| from typing import NewType, Union | |
| NewStr = NewType("NewStr", str) | |
| def is_true(x: Union[str, NewStr]) -> bool: | |
| if x: | |
| return True | |
| else: | |
| return False | |
| [typing fixtures/typing-full.pyi] | |
| [out] | |
| def is_true(x): | |
| x :: str | |
| r0 :: bit | |
| L0: | |
| r0 = CPyStr_IsTrue(x) | |
| if r0 goto L1 else goto L2 :: bool | |
| L1: | |
| return 1 | |
| L2: | |
| return 0 | |
| L3: | |
| unreachable | |
| [case testStringFormatMethod] | |
| from typing import NewType, Union | |
| NewStr = NewType("NewStr", str) | |
| def f(s: Union[str, NewStr], num: int) -> None: | |
| s1 = "Hi! I'm {}, and I'm {} years old.".format(s, num) | |
| s2 = ''.format() | |
| s3 = 'abc'.format() | |
| s4 = '}}{}{{{}}}{{{}'.format(num, num, num) | |
| [typing fixtures/typing-full.pyi] | |
| [out] | |
| def f(s, num): | |
| s :: str | |
| num :: int | |
| r0, r1, r2, r3, r4, s1, r5, s2, r6, s3, r7, r8, r9, r10, r11, r12, r13, s4 :: str | |
| L0: | |
| r0 = CPyTagged_Str(num) | |
| r1 = "Hi! I'm " | |
| r2 = ", and I'm " | |
| r3 = ' years old.' | |
| r4 = CPyStr_Build(5, r1, s, r2, r0, r3) | |
| s1 = r4 | |
| r5 = '' | |
| s2 = r5 | |
| r6 = 'abc' | |
| s3 = r6 | |
| r7 = CPyTagged_Str(num) | |
| r8 = CPyTagged_Str(num) | |
| r9 = CPyTagged_Str(num) | |
| r10 = '}' | |
| r11 = '{' | |
| r12 = '}{' | |
| r13 = CPyStr_Build(6, r10, r7, r11, r8, r12, r9) | |
| s4 = r13 | |
| return 1 | |
| [case testFStrings_64bit] | |
| from typing import NewType, Union | |
| NewStr = NewType("NewStr", str) | |
| def f(var: Union[str, NewStr], num: int) -> None: | |
| s1 = f"Hi! I'm {var}. I am {num} years old." | |
| s2 = f'Hello {var:>{num}}' | |
| s3 = f'' | |
| s4 = f'abc' | |
| [typing fixtures/typing-full.pyi] | |
| [out] | |
| def f(var, num): | |
| var :: str | |
| num :: int | |
| r0, r1, r2, r3, r4, s1, r5, r6, r7, r8, r9, r10, r11 :: str | |
| r12 :: object[3] | |
| r13 :: object_ptr | |
| r14 :: object | |
| r15 :: str | |
| r16 :: list | |
| r17 :: ptr | |
| r18, s2, r19, s3, r20, s4 :: str | |
| L0: | |
| r0 = "Hi! I'm " | |
| r1 = '. I am ' | |
| r2 = CPyTagged_Str(num) | |
| r3 = ' years old.' | |
| r4 = CPyStr_Build(5, r0, var, r1, r2, r3) | |
| s1 = r4 | |
| r5 = '' | |
| r6 = 'Hello ' | |
| r7 = '{:{}}' | |
| r8 = '>' | |
| r9 = CPyTagged_Str(num) | |
| r10 = CPyStr_Build(2, r8, r9) | |
| r11 = 'format' | |
| r12 = [r7, var, r10] | |
| r13 = load_address r12 | |
| r14 = PyObject_VectorcallMethod(r11, r13, 9223372036854775811, 0) | |
| keep_alive r7, var, r10 | |
| r15 = cast(str, r14) | |
| r16 = PyList_New(2) | |
| r17 = list_items r16 | |
| buf_init_item r17, 0, r6 | |
| buf_init_item r17, 1, r15 | |
| keep_alive r16 | |
| r18 = PyUnicode_Join(r5, r16) | |
| s2 = r18 | |
| r19 = '' | |
| s3 = r19 | |
| r20 = 'abc' | |
| s4 = r20 | |
| return 1 | |
| [case testStringFormattingCStyle] | |
| from typing import NewType, Union | |
| NewStr = NewType("NewStr", str) | |
| def f(var: Union[str, NewStr], num: int) -> None: | |
| s1 = "Hi! I'm %s." % var | |
| s2 = "I am %d years old." % num | |
| s3 = "Hi! I'm %s. I am %d years old." % (var, num) | |
| s4 = "Float: %f" % num | |
| [typing fixtures/typing-full.pyi] | |
| [out] | |
| def f(var, num): | |
| var :: str | |
| num :: int | |
| r0, r1, r2, s1, r3, r4, r5, r6, s2, r7, r8, r9, r10, r11, s3, r12 :: str | |
| r13, r14 :: object | |
| r15, s4 :: str | |
| L0: | |
| r0 = "Hi! I'm " | |
| r1 = '.' | |
| r2 = CPyStr_Build(3, r0, var, r1) | |
| s1 = r2 | |
| r3 = CPyTagged_Str(num) | |
| r4 = 'I am ' | |
| r5 = ' years old.' | |
| r6 = CPyStr_Build(3, r4, r3, r5) | |
| s2 = r6 | |
| r7 = CPyTagged_Str(num) | |
| r8 = "Hi! I'm " | |
| r9 = '. I am ' | |
| r10 = ' years old.' | |
| r11 = CPyStr_Build(5, r8, var, r9, r7, r10) | |
| s3 = r11 | |
| r12 = 'Float: %f' | |
| r13 = box(int, num) | |
| r14 = PyNumber_Remainder(r12, r13) | |
| r15 = cast(str, r14) | |
| s4 = r15 | |
| return 1 | |
| [case testDecode] | |
| def f(b: bytes) -> None: | |
| b.decode() | |
| b.decode('Utf_8') | |
| b.decode('utf-8') | |
| b.decode('UTF8') | |
| b.decode('latin1') | |
| b.decode('Latin-1') | |
| b.decode('ascii') | |
| encoding = 'utf-8' | |
| b.decode(encoding) | |
| b.decode('utf-8', 'backslashreplace') | |
| def variants(b: bytes) -> None: | |
| b.decode(encoding="UTF_8") | |
| b.decode("ascii", errors="strict") | |
| [out] | |
| def f(b): | |
| b :: bytes | |
| r0, r1, r2, r3, r4, r5, r6, r7, encoding, r8, r9, r10, r11 :: str | |
| L0: | |
| r0 = CPy_DecodeUTF8(b) | |
| r1 = CPy_DecodeUTF8(b) | |
| r2 = CPy_DecodeUTF8(b) | |
| r3 = CPy_DecodeUTF8(b) | |
| r4 = CPy_DecodeLatin1(b) | |
| r5 = CPy_DecodeLatin1(b) | |
| r6 = CPy_DecodeASCII(b) | |
| r7 = 'utf-8' | |
| encoding = r7 | |
| r8 = CPy_Decode(b, encoding, 0) | |
| r9 = 'utf-8' | |
| r10 = 'backslashreplace' | |
| r11 = CPy_Decode(b, r9, r10) | |
| return 1 | |
| def variants(b): | |
| b :: bytes | |
| r0, r1 :: str | |
| L0: | |
| r0 = CPy_DecodeUTF8(b) | |
| r1 = CPy_DecodeASCII(b) | |
| return 1 | |
| [case testEncode_64bit] | |
| from typing import NewType, Union | |
| NewStr = NewType("NewStr", str) | |
| def f(s: Union[str, NewStr]) -> None: | |
| s.encode() | |
| s.encode('utf-8') | |
| s.encode('utf8', 'strict') | |
| s.encode('latin1', errors='strict') | |
| s.encode(encoding='ascii') | |
| s.encode(errors='strict', encoding='latin-1') | |
| s.encode('utf-8', 'backslashreplace') | |
| s.encode('ascii', 'backslashreplace') | |
| encoding = 'utf8' | |
| s.encode(encoding) | |
| errors = 'strict' | |
| s.encode('utf8', errors) | |
| s.encode('utf8', errors=errors) | |
| s.encode(errors=errors) | |
| s.encode(encoding=encoding, errors=errors) | |
| s.encode('latin2') | |
| [typing fixtures/typing-full.pyi] | |
| [out] | |
| def f(s): | |
| s :: str | |
| r0, r1, r2, r3, r4, r5 :: bytes | |
| r6, r7 :: str | |
| r8 :: bytes | |
| r9, r10 :: str | |
| r11 :: bytes | |
| r12, encoding :: str | |
| r13 :: bytes | |
| r14, errors, r15 :: str | |
| r16 :: bytes | |
| r17, r18 :: str | |
| r19 :: object[3] | |
| r20 :: object_ptr | |
| r21, r22 :: object | |
| r23 :: str | |
| r24 :: object[2] | |
| r25 :: object_ptr | |
| r26, r27 :: object | |
| r28 :: str | |
| r29 :: object[3] | |
| r30 :: object_ptr | |
| r31, r32 :: object | |
| r33 :: str | |
| r34 :: bytes | |
| L0: | |
| r0 = PyUnicode_AsUTF8String(s) | |
| r1 = PyUnicode_AsUTF8String(s) | |
| r2 = PyUnicode_AsUTF8String(s) | |
| r3 = PyUnicode_AsLatin1String(s) | |
| r4 = PyUnicode_AsASCIIString(s) | |
| r5 = PyUnicode_AsLatin1String(s) | |
| r6 = 'utf-8' | |
| r7 = 'backslashreplace' | |
| r8 = CPy_Encode(s, r6, r7) | |
| r9 = 'ascii' | |
| r10 = 'backslashreplace' | |
| r11 = CPy_Encode(s, r9, r10) | |
| r12 = 'utf8' | |
| encoding = r12 | |
| r13 = CPy_Encode(s, encoding, 0) | |
| r14 = 'strict' | |
| errors = r14 | |
| r15 = 'utf8' | |
| r16 = CPy_Encode(s, r15, errors) | |
| r17 = 'utf8' | |
| r18 = 'encode' | |
| r19 = [s, r17, errors] | |
| r20 = load_address r19 | |
| r21 = ('errors',) | |
| r22 = PyObject_VectorcallMethod(r18, r20, 9223372036854775810, r21) | |
| keep_alive s, r17, errors | |
| r23 = 'encode' | |
| r24 = [s, errors] | |
| r25 = load_address r24 | |
| r26 = ('errors',) | |
| r27 = PyObject_VectorcallMethod(r23, r25, 9223372036854775809, r26) | |
| keep_alive s, errors | |
| r28 = 'encode' | |
| r29 = [s, encoding, errors] | |
| r30 = load_address r29 | |
| r31 = ('encoding', 'errors') | |
| r32 = PyObject_VectorcallMethod(r28, r30, 9223372036854775809, r31) | |
| keep_alive s, encoding, errors | |
| r33 = 'latin2' | |
| r34 = CPy_Encode(s, r33, 0) | |
| return 1 | |
| [case testOrd] | |
| from typing import NewType, Union | |
| NewStr = NewType("NewStr", str) | |
| def str_ord(x: Union[str, NewStr]) -> int: | |
| return ord(x) | |
| def str_ord_literal() -> int: | |
| return ord("a") | |
| def bytes_ord(x: bytes) -> int: | |
| return ord(x) | |
| def bytes_ord_literal() -> int: | |
| return ord(b"a") | |
| def any_ord(x) -> int: | |
| return ord(x) | |
| [typing fixtures/typing-full.pyi] | |
| [out] | |
| def str_ord(x): | |
| x :: str | |
| r0 :: int | |
| L0: | |
| r0 = CPyStr_Ord(x) | |
| return r0 | |
| def str_ord_literal(): | |
| L0: | |
| return 194 | |
| def bytes_ord(x): | |
| x :: bytes | |
| r0 :: int | |
| L0: | |
| r0 = CPyBytes_Ord(x) | |
| return r0 | |
| def bytes_ord_literal(): | |
| L0: | |
| return 194 | |
| def any_ord(x): | |
| x, r0 :: object | |
| r1 :: str | |
| r2 :: object | |
| r3 :: object[1] | |
| r4 :: object_ptr | |
| r5 :: object | |
| r6 :: int | |
| L0: | |
| r0 = builtins :: module | |
| r1 = 'ord' | |
| r2 = CPyObject_GetAttr(r0, r1) | |
| r3 = [x] | |
| r4 = load_address r3 | |
| r5 = PyObject_Vectorcall(r2, r4, 1, 0) | |
| keep_alive x | |
| r6 = unbox(int, r5) | |
| return r6 | |
| [case testOrdOfStrIndex_64bit] | |
| from mypy_extensions import i64, i32, i16, u8 | |
| def ord_str_index(s: str, i: int) -> int: | |
| return ord(s[i]) | |
| def ord_str_index_i64(s: str, i: i64) -> int: | |
| return ord(s[i]) | |
| def ord_str_index_to_i32(s: str, i: i64) -> i32: | |
| return ord(s[i]) | |
| def ord_str_index_to_i16(s: str, i: i64) -> i16: | |
| return ord(s[i]) | |
| def ord_str_index_to_u8(s: str, i: i64) -> u8: | |
| return ord(s[i]) | |
| def ord_str_index_to_i64(s: str, i: i64) -> i64: | |
| return ord(s[i]) | |
| [typing fixtures/typing-full.pyi] | |
| [out] | |
| def ord_str_index(s, i): | |
| s :: str | |
| i :: int | |
| r0 :: native_int | |
| r1 :: bit | |
| r2, r3 :: i64 | |
| r4 :: ptr | |
| r5 :: c_ptr | |
| r6, r7 :: i64 | |
| r8, r9 :: bool | |
| r10 :: short_int | |
| L0: | |
| r0 = i & 1 | |
| r1 = r0 == 0 | |
| if r1 goto L1 else goto L2 :: bool | |
| L1: | |
| r2 = i >> 1 | |
| r3 = r2 | |
| goto L3 | |
| L2: | |
| r4 = i ^ 1 | |
| r5 = r4 | |
| r6 = CPyLong_AsInt64(r5) | |
| r3 = r6 | |
| keep_alive i | |
| L3: | |
| r7 = CPyStr_AdjustIndex(s, r3) | |
| r8 = CPyStr_RangeCheck(s, r7) | |
| if r8 goto L5 else goto L4 :: bool | |
| L4: | |
| r9 = raise IndexError('index out of range') | |
| unreachable | |
| L5: | |
| r10 = CPyStr_GetItemUnsafeAsInt(s, r7) | |
| return r10 | |
| def ord_str_index_i64(s, i): | |
| s :: str | |
| i, r0 :: i64 | |
| r1, r2 :: bool | |
| r3 :: short_int | |
| L0: | |
| r0 = CPyStr_AdjustIndex(s, i) | |
| r1 = CPyStr_RangeCheck(s, r0) | |
| if r1 goto L2 else goto L1 :: bool | |
| L1: | |
| r2 = raise IndexError('index out of range') | |
| unreachable | |
| L2: | |
| r3 = CPyStr_GetItemUnsafeAsInt(s, r0) | |
| return r3 | |
| def ord_str_index_to_i32(s, i): | |
| s :: str | |
| i, r0 :: i64 | |
| r1, r2 :: bool | |
| r3 :: short_int | |
| r4, r5 :: bit | |
| r6 :: native_int | |
| r7, r8 :: i32 | |
| L0: | |
| r0 = CPyStr_AdjustIndex(s, i) | |
| r1 = CPyStr_RangeCheck(s, r0) | |
| if r1 goto L2 else goto L1 :: bool | |
| L1: | |
| r2 = raise IndexError('index out of range') | |
| unreachable | |
| L2: | |
| r3 = CPyStr_GetItemUnsafeAsInt(s, r0) | |
| r4 = r3 < 4294967296 :: signed | |
| if r4 goto L3 else goto L5 :: bool | |
| L3: | |
| r5 = r3 >= -4294967296 :: signed | |
| if r5 goto L4 else goto L5 :: bool | |
| L4: | |
| r6 = r3 >> 1 | |
| r7 = truncate r6: native_int to i32 | |
| r8 = r7 | |
| goto L6 | |
| L5: | |
| CPyInt32_Overflow() | |
| unreachable | |
| L6: | |
| return r8 | |
| def ord_str_index_to_i16(s, i): | |
| s :: str | |
| i, r0 :: i64 | |
| r1, r2 :: bool | |
| r3 :: short_int | |
| r4, r5 :: bit | |
| r6 :: native_int | |
| r7, r8 :: i16 | |
| L0: | |
| r0 = CPyStr_AdjustIndex(s, i) | |
| r1 = CPyStr_RangeCheck(s, r0) | |
| if r1 goto L2 else goto L1 :: bool | |
| L1: | |
| r2 = raise IndexError('index out of range') | |
| unreachable | |
| L2: | |
| r3 = CPyStr_GetItemUnsafeAsInt(s, r0) | |
| r4 = r3 < 65536 :: signed | |
| if r4 goto L3 else goto L5 :: bool | |
| L3: | |
| r5 = r3 >= -65536 :: signed | |
| if r5 goto L4 else goto L5 :: bool | |
| L4: | |
| r6 = r3 >> 1 | |
| r7 = truncate r6: native_int to i16 | |
| r8 = r7 | |
| goto L6 | |
| L5: | |
| CPyInt16_Overflow() | |
| unreachable | |
| L6: | |
| return r8 | |
| def ord_str_index_to_u8(s, i): | |
| s :: str | |
| i, r0 :: i64 | |
| r1, r2 :: bool | |
| r3 :: short_int | |
| r4, r5 :: bit | |
| r6 :: native_int | |
| r7, r8 :: u8 | |
| L0: | |
| r0 = CPyStr_AdjustIndex(s, i) | |
| r1 = CPyStr_RangeCheck(s, r0) | |
| if r1 goto L2 else goto L1 :: bool | |
| L1: | |
| r2 = raise IndexError('index out of range') | |
| unreachable | |
| L2: | |
| r3 = CPyStr_GetItemUnsafeAsInt(s, r0) | |
| r4 = r3 < 512 :: signed | |
| if r4 goto L3 else goto L5 :: bool | |
| L3: | |
| r5 = r3 >= 0 :: signed | |
| if r5 goto L4 else goto L5 :: bool | |
| L4: | |
| r6 = r3 >> 1 | |
| r7 = truncate r6: native_int to u8 | |
| r8 = r7 | |
| goto L6 | |
| L5: | |
| CPyUInt8_Overflow() | |
| unreachable | |
| L6: | |
| return r8 | |
| def ord_str_index_to_i64(s, i): | |
| s :: str | |
| i, r0 :: i64 | |
| r1, r2 :: bool | |
| r3 :: short_int | |
| r4 :: i64 | |
| L0: | |
| r0 = CPyStr_AdjustIndex(s, i) | |
| r1 = CPyStr_RangeCheck(s, r0) | |
| if r1 goto L2 else goto L1 :: bool | |
| L1: | |
| r2 = raise IndexError('index out of range') | |
| unreachable | |
| L2: | |
| r3 = CPyStr_GetItemUnsafeAsInt(s, r0) | |
| r4 = r3 >> 1 | |
| return r4 | |
| [case testStrip] | |
| from typing import NewType, Union | |
| NewStr = NewType("NewStr", str) | |
| def do_strip(s: Union[str, NewStr]) -> None: | |
| s.lstrip("x") | |
| s.strip("y") | |
| s.rstrip("z") | |
| s.lstrip() | |
| s.strip() | |
| s.rstrip() | |
| [typing fixtures/typing-full.pyi] | |
| [out] | |
| def do_strip(s): | |
| s, r0, r1, r2, r3, r4, r5, r6, r7, r8 :: str | |
| L0: | |
| r0 = 'x' | |
| r1 = CPyStr_LStrip(s, r0) | |
| r2 = 'y' | |
| r3 = CPyStr_Strip(s, r2) | |
| r4 = 'z' | |
| r5 = CPyStr_RStrip(s, r4) | |
| r6 = CPyStr_LStrip(s, 0) | |
| r7 = CPyStr_Strip(s, 0) | |
| r8 = CPyStr_RStrip(s, 0) | |
| return 1 | |
| [case testCountAll_64bit] | |
| from typing import NewType, Union | |
| NewStr = NewType("NewStr", str) | |
| def do_count(s: str) -> int: | |
| return s.count("x") | |
| [typing fixtures/typing-full.pyi] | |
| [out] | |
| def do_count(s): | |
| s, r0 :: str | |
| r1 :: native_int | |
| r2, r3, r4 :: bit | |
| r5, r6, r7 :: int | |
| L0: | |
| r0 = 'x' | |
| r1 = CPyStr_Count(s, r0, 0) | |
| r2 = r1 >= 0 :: signed | |
| r3 = r1 <= 4611686018427387903 :: signed | |
| if r3 goto L1 else goto L2 :: bool | |
| L1: | |
| r4 = r1 >= -4611686018427387904 :: signed | |
| if r4 goto L3 else goto L2 :: bool | |
| L2: | |
| r5 = CPyTagged_FromInt64(r1) | |
| r6 = r5 | |
| goto L4 | |
| L3: | |
| r7 = r1 << 1 | |
| r6 = r7 | |
| L4: | |
| return r6 | |
| [case testCountStart_64bit] | |
| from typing import NewType, Union | |
| NewStr = NewType("NewStr", str) | |
| def do_count(s: str, start: int) -> int: | |
| return s.count("x", start) | |
| [typing fixtures/typing-full.pyi] | |
| [out] | |
| def do_count(s, start): | |
| s :: str | |
| start :: int | |
| r0 :: str | |
| r1 :: native_int | |
| r2, r3, r4 :: bit | |
| r5, r6, r7 :: int | |
| L0: | |
| r0 = 'x' | |
| r1 = CPyStr_Count(s, r0, start) | |
| r2 = r1 >= 0 :: signed | |
| r3 = r1 <= 4611686018427387903 :: signed | |
| if r3 goto L1 else goto L2 :: bool | |
| L1: | |
| r4 = r1 >= -4611686018427387904 :: signed | |
| if r4 goto L3 else goto L2 :: bool | |
| L2: | |
| r5 = CPyTagged_FromInt64(r1) | |
| r6 = r5 | |
| goto L4 | |
| L3: | |
| r7 = r1 << 1 | |
| r6 = r7 | |
| L4: | |
| return r6 | |
| [case testCountStartEnd_64bit] | |
| from typing import NewType, Union | |
| NewStr = NewType("NewStr", str) | |
| def do_count(s: str, start: int, end: int) -> int: | |
| return s.count("x", start, end) | |
| [typing fixtures/typing-full.pyi] | |
| [out] | |
| def do_count(s, start, end): | |
| s :: str | |
| start, end :: int | |
| r0 :: str | |
| r1 :: native_int | |
| r2, r3, r4 :: bit | |
| r5, r6, r7 :: int | |
| L0: | |
| r0 = 'x' | |
| r1 = CPyStr_CountFull(s, r0, start, end) | |
| r2 = r1 >= 0 :: signed | |
| r3 = r1 <= 4611686018427387903 :: signed | |
| if r3 goto L1 else goto L2 :: bool | |
| L1: | |
| r4 = r1 >= -4611686018427387904 :: signed | |
| if r4 goto L3 else goto L2 :: bool | |
| L2: | |
| r5 = CPyTagged_FromInt64(r1) | |
| r6 = r5 | |
| goto L4 | |
| L3: | |
| r7 = r1 << 1 | |
| r6 = r7 | |
| L4: | |
| return r6 | |
| [case testFStringFromConstants] | |
| from typing import Final | |
| string: Final = "abc" | |
| integer: Final = 123 | |
| floating: Final = 3.14 | |
| boolean: Final = True | |
| def test(x: str) -> str: | |
| return f"{string}{integer}{floating}{boolean}{x}{boolean}{floating}{integer}{string}{x}{string}{integer}{floating}{boolean}" | |
| def test2(x: str) -> str: | |
| return f"{string}{integer}{floating}{boolean}{x}{boolean}{floating}{integer}{string}{x}{string}{integer}{floating}{boolean}{x}" | |
| def test3(x: str) -> str: | |
| return f"{x}{string}{integer}{floating}{boolean}{x}{boolean}{floating}{integer}{string}{x}{string}{integer}{floating}{boolean}{x}" | |
| [out] | |
| def test(x): | |
| x, r0, r1, r2, r3 :: str | |
| L0: | |
| r0 = 'abc1233.14True' | |
| r1 = 'True3.14123abc' | |
| r2 = 'abc1233.14True' | |
| r3 = CPyStr_Build(5, r0, x, r1, x, r2) | |
| return r3 | |
| def test2(x): | |
| x, r0, r1, r2, r3 :: str | |
| L0: | |
| r0 = 'abc1233.14True' | |
| r1 = 'True3.14123abc' | |
| r2 = 'abc1233.14True' | |
| r3 = CPyStr_Build(6, r0, x, r1, x, r2, x) | |
| return r3 | |
| def test3(x): | |
| x, r0, r1, r2, r3 :: str | |
| L0: | |
| r0 = 'abc1233.14True' | |
| r1 = 'True3.14123abc' | |
| r2 = 'abc1233.14True' | |
| r3 = CPyStr_Build(7, x, r0, x, r1, x, r2, x) | |
| return r3 | |
| [case testOptionalStrEquality1] | |
| from typing import Optional | |
| def opt_opt(x: Optional[str], y: Optional[str]) -> bool: | |
| return x == y | |
| [out] | |
| def opt_opt(x, y): | |
| x, y :: union[str, None] | |
| r0 :: object | |
| r1 :: bit | |
| r2 :: object | |
| r3 :: bit | |
| r4 :: bool | |
| r5 :: object | |
| r6 :: bit | |
| r7, r8 :: str | |
| r9 :: bool | |
| L0: | |
| r0 = load_address _Py_NoneStruct | |
| r1 = x == r0 | |
| if r1 goto L1 else goto L2 :: bool | |
| L1: | |
| r2 = load_address _Py_NoneStruct | |
| r3 = y == r2 | |
| r4 = r3 | |
| goto L5 | |
| L2: | |
| r5 = load_address _Py_NoneStruct | |
| r6 = y == r5 | |
| if r6 goto L3 else goto L4 :: bool | |
| L3: | |
| r4 = 0 | |
| goto L5 | |
| L4: | |
| r7 = unchecked borrow cast(str, x) | |
| r8 = unchecked borrow cast(str, y) | |
| r9 = CPyStr_Equal(r7, r8) | |
| r4 = r9 | |
| L5: | |
| keep_alive x, y | |
| return r4 | |
| [case testOptionalStrEquality2] | |
| from typing import Optional | |
| def opt_non_opt(x: Optional[str], y: str) -> bool: | |
| return x == y | |
| [out] | |
| def opt_non_opt(x, y): | |
| x :: union[str, None] | |
| y :: str | |
| r0 :: object | |
| r1 :: bit | |
| r2 :: bool | |
| r3 :: str | |
| r4 :: bool | |
| L0: | |
| r0 = load_address _Py_NoneStruct | |
| r1 = x == r0 | |
| if r1 goto L1 else goto L2 :: bool | |
| L1: | |
| r2 = 0 | |
| goto L3 | |
| L2: | |
| r3 = unchecked borrow cast(str, x) | |
| r4 = CPyStr_Equal(r3, y) | |
| r2 = r4 | |
| L3: | |
| keep_alive x | |
| return r2 | |
| [case testStrEqLiteral] | |
| from typing import Final | |
| literal: Final = "literal" | |
| def literal_rhs(x: str) -> bool: | |
| return x == literal | |
| def literal_lhs(x: str) -> bool: | |
| return literal == x | |
| def literal_both() -> bool: | |
| return literal == "literal" | |
| [out] | |
| def literal_rhs(x): | |
| x, r0 :: str | |
| r1 :: bool | |
| L0: | |
| r0 = 'literal' | |
| r1 = CPyStr_EqualLiteral(x, r0, 7) | |
| return r1 | |
| def literal_lhs(x): | |
| x, r0 :: str | |
| r1 :: bool | |
| L0: | |
| r0 = 'literal' | |
| r1 = CPyStr_EqualLiteral(x, r0, 7) | |
| return r1 | |
| def literal_both(): | |
| r0, r1 :: str | |
| L0: | |
| r0 = 'literal' | |
| r1 = 'literal' | |
| return 1 | |
| [case testStrMultiply] | |
| def s_times_i(s: str, n: int) -> str: | |
| return s * n | |
| def i_times_s(s: str, n: int) -> str: | |
| return n * s | |
| [out] | |
| def s_times_i(s, n): | |
| s :: str | |
| n :: int | |
| r0 :: str | |
| L0: | |
| r0 = CPyStr_Multiply(s, n) | |
| return r0 | |
| def i_times_s(s, n): | |
| s :: str | |
| n :: int | |
| r0 :: str | |
| L0: | |
| r0 = CPyStr_Multiply(s, n) | |
| return r0 | |
| [case testStrLower] | |
| def do_lower(s: str) -> str: | |
| return s.lower() | |
| [out] | |
| def do_lower(s): | |
| s, r0 :: str | |
| L0: | |
| r0 = CPyStr_Lower(s) | |
| return r0 | |
| [case testStrUpper] | |
| def do_upper(s: str) -> str: | |
| return s.upper() | |
| [out] | |
| def do_upper(s): | |
| s, r0 :: str | |
| L0: | |
| r0 = CPyStr_Upper(s) | |
| return r0 | |
| [case testStrIsSpace] | |
| def is_space(x: str) -> bool: | |
| return x.isspace() | |
| [out] | |
| def is_space(x): | |
| x :: str | |
| r0 :: bool | |
| L0: | |
| r0 = CPyStr_IsSpace(x) | |
| return r0 | |
| [case testStrIsAlnum] | |
| def is_alnum(x: str) -> bool: | |
| return x.isalnum() | |
| [out] | |
| def is_alnum(x): | |
| x :: str | |
| r0 :: bool | |
| L0: | |
| r0 = CPyStr_IsAlnum(x) | |
| return r0 | |
| [case testStrIsDigit] | |
| def is_digit(x: str) -> bool: | |
| return x.isdigit() | |
| [out] | |
| def is_digit(x): | |
| x :: str | |
| r0 :: bool | |
| L0: | |
| r0 = CPyStr_IsDigit(x) | |
| return r0 | |
| [case testStrIndexEqLiteral_64bit] | |
| def is_comma(s: str, i: int) -> bool: | |
| return s[i] == "," | |
| def is_comma_swapped(s: str, i: int) -> bool: | |
| return "," == s[i] | |
| def is_comma_ne(s: str, i: int) -> bool: | |
| return s[i] != "," | |
| [out] | |
| def is_comma(s, i): | |
| s :: str | |
| i :: int | |
| r0 :: native_int | |
| r1 :: bit | |
| r2, r3 :: i64 | |
| r4 :: ptr | |
| r5 :: c_ptr | |
| r6, r7 :: i64 | |
| r8, r9 :: bool | |
| r10 :: short_int | |
| r11 :: bit | |
| L0: | |
| r0 = i & 1 | |
| r1 = r0 == 0 | |
| if r1 goto L1 else goto L2 :: bool | |
| L1: | |
| r2 = i >> 1 | |
| r3 = r2 | |
| goto L3 | |
| L2: | |
| r4 = i ^ 1 | |
| r5 = r4 | |
| r6 = CPyLong_AsInt64(r5) | |
| r3 = r6 | |
| keep_alive i | |
| L3: | |
| r7 = CPyStr_AdjustIndex(s, r3) | |
| r8 = CPyStr_RangeCheck(s, r7) | |
| if r8 goto L5 else goto L4 :: bool | |
| L4: | |
| r9 = raise IndexError('index out of range') | |
| unreachable | |
| L5: | |
| r10 = CPyStr_GetItemUnsafeAsInt(s, r7) | |
| r11 = int_eq r10, 88 | |
| return r11 | |
| def is_comma_swapped(s, i): | |
| s :: str | |
| i :: int | |
| r0 :: native_int | |
| r1 :: bit | |
| r2, r3 :: i64 | |
| r4 :: ptr | |
| r5 :: c_ptr | |
| r6, r7 :: i64 | |
| r8, r9 :: bool | |
| r10 :: short_int | |
| r11 :: bit | |
| L0: | |
| r0 = i & 1 | |
| r1 = r0 == 0 | |
| if r1 goto L1 else goto L2 :: bool | |
| L1: | |
| r2 = i >> 1 | |
| r3 = r2 | |
| goto L3 | |
| L2: | |
| r4 = i ^ 1 | |
| r5 = r4 | |
| r6 = CPyLong_AsInt64(r5) | |
| r3 = r6 | |
| keep_alive i | |
| L3: | |
| r7 = CPyStr_AdjustIndex(s, r3) | |
| r8 = CPyStr_RangeCheck(s, r7) | |
| if r8 goto L5 else goto L4 :: bool | |
| L4: | |
| r9 = raise IndexError('index out of range') | |
| unreachable | |
| L5: | |
| r10 = CPyStr_GetItemUnsafeAsInt(s, r7) | |
| r11 = int_eq r10, 88 | |
| return r11 | |
| def is_comma_ne(s, i): | |
| s :: str | |
| i :: int | |
| r0 :: native_int | |
| r1 :: bit | |
| r2, r3 :: i64 | |
| r4 :: ptr | |
| r5 :: c_ptr | |
| r6, r7 :: i64 | |
| r8, r9 :: bool | |
| r10 :: short_int | |
| r11 :: bit | |
| L0: | |
| r0 = i & 1 | |
| r1 = r0 == 0 | |
| if r1 goto L1 else goto L2 :: bool | |
| L1: | |
| r2 = i >> 1 | |
| r3 = r2 | |
| goto L3 | |
| L2: | |
| r4 = i ^ 1 | |
| r5 = r4 | |
| r6 = CPyLong_AsInt64(r5) | |
| r3 = r6 | |
| keep_alive i | |
| L3: | |
| r7 = CPyStr_AdjustIndex(s, r3) | |
| r8 = CPyStr_RangeCheck(s, r7) | |
| if r8 goto L5 else goto L4 :: bool | |
| L4: | |
| r9 = raise IndexError('index out of range') | |
| unreachable | |
| L5: | |
| r10 = CPyStr_GetItemUnsafeAsInt(s, r7) | |
| r11 = int_ne r10, 88 | |
| return r11 | |
| [case testStrIndexEqLiteralNoSpecialize] | |
| def two_char_literal(s: str, i: int) -> bool: | |
| # Multi-char literals don't match the specialization; falls through to | |
| # the generic str equality path. | |
| return s[i] == "ab" | |
| def empty_literal(s: str, i: int) -> bool: | |
| # Empty string literals also fall through; the generic path returns False. | |
| return s[i] == "" | |
| [out] | |
| def two_char_literal(s, i): | |
| s :: str | |
| i :: int | |
| r0, r1 :: str | |
| r2 :: bool | |
| L0: | |
| r0 = CPyStr_GetItem(s, i) | |
| r1 = 'ab' | |
| r2 = CPyStr_EqualLiteral(r0, r1, 2) | |
| return r2 | |
| def empty_literal(s, i): | |
| s :: str | |
| i :: int | |
| r0, r1 :: str | |
| r2 :: bool | |
| L0: | |
| r0 = CPyStr_GetItem(s, i) | |
| r1 = '' | |
| r2 = CPyStr_EqualLiteral(r0, r1, 0) | |
| return r2 | |
| [case testUnicodeSurrogate] | |
| # flags: --native-parser | |
| def f() -> str: | |
| return "\ud800" | |
| def test_surrogate() -> None: | |
| assert ord(f()) == 0xd800 | |
| assert ord("\udfff") == 0xdfff | |
| assert repr("foobar\x00\xab\ud912\U00012345") == r"'foobar\x00«\ud912𒍅'" | |
| [out] | |
| main:4: error: Surrogate codepoints in string literals not supported, use chr(...) instead | |
| main:8: error: Surrogate codepoints in string literals not supported, use chr(...) instead | |
| main:9: error: Surrogate codepoints in string literals not supported, use chr(...) instead |