diff options
| author | Scott Shawcroft <scott.shawcroft@gmail.com> | 2017-06-20 10:56:05 -0700 |
|---|---|---|
| committer | Scott Shawcroft <scott.shawcroft@gmail.com> | 2017-06-20 10:56:05 -0700 |
| commit | 30ee7019ca651bce1fe966c1089fe977d51dc92b (patch) | |
| tree | 0114b6f744dd175b7722dd8edcbe24f4ee84bb45 /tests/basics | |
| parent | 97fcdfbd08c922efd7470d6482d7c7c703ffc0ae (diff) | |
| parent | 869cdcfdfc860b1177baf9b0f8818915ba54f3f5 (diff) | |
Merge tag 'v1.9.1'2.0.0-alpha.0
Fixes for stmhal USB mass storage, lwIP bindings and VFS regressions
This release provides an important fix for the USB mass storage device in
the stmhal port by implementing the SCSI SYNCHRONIZE_CACHE command, which
is now require by some Operating Systems. There are also fixes for the
lwIP bindings to improve non-blocking sockets and error codes. The VFS has
some regressions fixed including the ability to statvfs the root.
All changes are listed below.
py core:
- modbuiltins: add core-provided version of input() function
- objstr: catch case of negative "maxsplit" arg to str.rsplit()
- persistentcode: allow to compile with complex numbers disabled
- objstr: allow to compile with obj-repr D, and unicode disabled
- modsys: allow to compile with obj-repr D and PY_ATTRTUPLE disabled
- provide mp_decode_uint_skip() to help reduce stack usage
- makeqstrdefs.py: make script run correctly with Python 2.6
- objstringio: if created from immutable object, follow copy on write policy
extmod:
- modlwip: connect: for non-blocking mode, return EINPROGRESS
- modlwip: fix error codes for duplicate calls to connect()
- modlwip: accept: fix error code for non-blocking mode
- vfs: allow to statvfs the root directory
- vfs: allow "buffering" and "encoding" args to VFS's open()
- modframebuf: fix signed/unsigned comparison pendantic warning
lib:
- libm: use isfinite instead of finitef, for C99 compatibility
- utils/interrupt_char: remove support for KBD_EXCEPTION disabled
tests:
- basics/string_rsplit: add tests for negative "maxsplit" argument
- float: convert "sys.exit()" to "raise SystemExit"
- float/builtin_float_minmax: PEP8 fixes
- basics: convert "sys.exit()" to "raise SystemExit"
- convert remaining "sys.exit()" to "raise SystemExit"
unix port:
- convert to use core-provided version of built-in import()
- Makefile: replace references to make with $(MAKE)
windows port:
- convert to use core-provided version of built-in import()
qemu-arm port:
- Makefile: adjust object-file lists to get correct dependencies
- enable micropython.mem_*() functions to allow more tests
stmhal port:
- boards: enable DAC for NUCLEO_F767ZI board
- add support for NUCLEO_F446RE board
- pass USB handler as parameter to allow more than one USB handler
- usb: use local USB handler variable in Start-of-Frame handler
- usb: make state for USB device private to top-level USB driver
- usbdev: for MSC implement SCSI SYNCHRONIZE_CACHE command
- convert from using stmhal's input() to core provided version
cc3200 port:
- convert from using stmhal's input() to core provided version
teensy port:
- convert from using stmhal's input() to core provided version
esp8266 port:
- Makefile: replace references to make with $(MAKE)
- Makefile: add clean-modules target
- convert from using stmhal's input() to core provided version
zephyr port:
- modusocket: getaddrinfo: Fix mp_obj_len() usage
- define MICROPY_PY_SYS_PLATFORM (to "zephyr")
- machine_pin: use native Zephyr types for Zephyr API calls
docs:
- machine.Pin: remove out_value() method
- machine.Pin: add on() and off() methods
- esp8266: consistently replace Pin.high/low methods with .on/off
- esp8266/quickref: polish Pin.on()/off() examples
- network: move confusingly-named cc3200 Server class to its reference
- uos: deconditionalize, remove minor port-specific details
- uos: move cc3200 port legacy VFS mounting functions to its ref doc
- machine: sort machine classes in logical order, not alphabetically
- network: first step to describe standard network class interface
examples:
- embedding: use core-provided KeyboardInterrupt object
Diffstat (limited to 'tests/basics')
145 files changed, 1092 insertions, 339 deletions
diff --git a/tests/basics/array1.py b/tests/basics/array1.py index 43f775b79..bad879035 100644 --- a/tests/basics/array1.py +++ b/tests/basics/array1.py @@ -1,9 +1,8 @@ try: import array except ImportError: - import sys print("SKIP") - sys.exit() + raise SystemExit a = array.array('B', [1, 2, 3]) print(a, len(a)) diff --git a/tests/basics/array_add.py b/tests/basics/array_add.py index 41cd77b42..76ce59f76 100644 --- a/tests/basics/array_add.py +++ b/tests/basics/array_add.py @@ -2,9 +2,8 @@ try: import array except ImportError: - import sys print("SKIP") - sys.exit() + raise SystemExit a1 = array.array('I', [1]) a2 = array.array('I', [2]) diff --git a/tests/basics/array_construct.py b/tests/basics/array_construct.py index cafa57784..2221de990 100644 --- a/tests/basics/array_construct.py +++ b/tests/basics/array_construct.py @@ -3,9 +3,8 @@ try: from array import array except ImportError: - import sys print("SKIP") - sys.exit() + raise SystemExit # tuple, list print(array('b', (1, 2))) diff --git a/tests/basics/array_construct2.py b/tests/basics/array_construct2.py index d1c1a6c70..c305b7f01 100644 --- a/tests/basics/array_construct2.py +++ b/tests/basics/array_construct2.py @@ -1,9 +1,8 @@ try: from array import array except ImportError: - import sys print("SKIP") - sys.exit() + raise SystemExit # construct from something with unknown length (requires generators) print(array('i', (i for i in range(10)))) diff --git a/tests/basics/array_construct_endian.py b/tests/basics/array_construct_endian.py index bf34b05d1..990d7b1ea 100644 --- a/tests/basics/array_construct_endian.py +++ b/tests/basics/array_construct_endian.py @@ -3,9 +3,8 @@ try: from array import array except ImportError: - import sys print("SKIP") - sys.exit() + raise SystemExit # raw copy from bytes, bytearray print(array('h', b'12')) diff --git a/tests/basics/array_q.py b/tests/basics/array_intbig.py index 2975cd385..5702a8ae6 100644 --- a/tests/basics/array_q.py +++ b/tests/basics/array_intbig.py @@ -1,11 +1,13 @@ -# test array('q') and array('Q') +# test array types QqLl that require big-ints try: from array import array except ImportError: - import sys print("SKIP") - sys.exit() + raise SystemExit + +print(array('L', [0, 2**32-1])) +print(array('l', [-2**31, 0, 2**31-1])) print(array('q')) print(array('Q')) diff --git a/tests/basics/array_micropython.py b/tests/basics/array_micropython.py index 8e904bdfe..e26ad7ae9 100644 --- a/tests/basics/array_micropython.py +++ b/tests/basics/array_micropython.py @@ -1,5 +1,9 @@ # test MicroPython-specific features of array.array -import array +try: + import array +except ImportError: + print("SKIP") + raise SystemExit # arrays of objects a = array.array('O') diff --git a/tests/basics/attrtuple1.py b/tests/basics/attrtuple1.py index c4daaaf25..78a0fbed1 100644 --- a/tests/basics/attrtuple1.py +++ b/tests/basics/attrtuple1.py @@ -4,6 +4,14 @@ import sys t = sys.implementation +# It can be just a normal tuple on small ports +try: + t.name +except AttributeError: + print("SKIP") + raise SystemExit + + # test printing of attrtuple print(str(t).find("version=") > 0) diff --git a/tests/basics/boundmeth1.py b/tests/basics/boundmeth1.py index a72887275..f483ba406 100644 --- a/tests/basics/boundmeth1.py +++ b/tests/basics/boundmeth1.py @@ -22,3 +22,9 @@ print(m(1)) # bound method with lots of extra args m = A().h print(m(1, 2, 3, 4, 5, 6)) + +# can't assign attributes to a bound method +try: + A().f.x = 1 +except AttributeError: + print('AttributeError') diff --git a/tests/basics/builtin_abs.py b/tests/basics/builtin_abs.py index 788bc450f..142344e22 100644 --- a/tests/basics/builtin_abs.py +++ b/tests/basics/builtin_abs.py @@ -4,11 +4,3 @@ print(abs(False)) print(abs(True)) print(abs(1)) print(abs(-1)) - -# bignum -print(abs(123456789012345678901234567890)) -print(abs(-123456789012345678901234567890)) - -# edge cases for 32 and 64 bit archs (small int overflow when negating) -print(abs(-0x3fffffff - 1)) -print(abs(-0x3fffffffffffffff - 1)) diff --git a/tests/basics/builtin_abs_intbig.py b/tests/basics/builtin_abs_intbig.py new file mode 100644 index 000000000..3dd5ea89f --- /dev/null +++ b/tests/basics/builtin_abs_intbig.py @@ -0,0 +1,9 @@ +# test builtin abs + +# bignum +print(abs(123456789012345678901234567890)) +print(abs(-123456789012345678901234567890)) + +# edge cases for 32 and 64 bit archs (small int overflow when negating) +print(abs(-0x3fffffff - 1)) +print(abs(-0x3fffffffffffffff - 1)) diff --git a/tests/basics/builtin_bin.py b/tests/basics/builtin_bin.py index f6b6079de..85af406ce 100644 --- a/tests/basics/builtin_bin.py +++ b/tests/basics/builtin_bin.py @@ -8,5 +8,4 @@ print(bin(-15)) print(bin(12345)) print(bin(0b10101)) -print(bin(12345678901234567890)) print(bin(0b10101010101010101010)) diff --git a/tests/basics/builtin_bin_intbig.py b/tests/basics/builtin_bin_intbig.py new file mode 100644 index 000000000..345e1f687 --- /dev/null +++ b/tests/basics/builtin_bin_intbig.py @@ -0,0 +1,3 @@ +# test builtin bin function + +print(bin(12345678901234567890)) diff --git a/tests/basics/builtin_delattr.py b/tests/basics/builtin_delattr.py index 3743df227..65bd0f210 100644 --- a/tests/basics/builtin_delattr.py +++ b/tests/basics/builtin_delattr.py @@ -1,4 +1,9 @@ # test builtin delattr +try: + delattr +except: + print("SKIP") + raise SystemExit class A: pass a = A() diff --git a/tests/basics/builtin_dir.py b/tests/basics/builtin_dir.py index 843467e78..16e7e669e 100644 --- a/tests/basics/builtin_dir.py +++ b/tests/basics/builtin_dir.py @@ -5,7 +5,7 @@ print('__name__' in dir()) # dir of module import sys -print('platform' in dir(sys)) +print('exit' in dir(sys)) # dir of type print('append' in dir(list)) diff --git a/tests/basics/builtin_divmod.py b/tests/basics/builtin_divmod.py index c3b865819..26b3ae382 100644 --- a/tests/basics/builtin_divmod.py +++ b/tests/basics/builtin_divmod.py @@ -10,18 +10,6 @@ except ZeroDivisionError: print("ZeroDivisionError") try: - divmod(1 << 65, 0) -except ZeroDivisionError: - print("ZeroDivisionError") - -try: divmod('a', 'b') except TypeError: print("TypeError") - -# bignum -l = (1 << 65) + 123 -print(divmod(3, l)) -print(divmod(l, 5)) -print(divmod(l + 3, l)) -print(divmod(l * 20, l + 2)) diff --git a/tests/basics/builtin_divmod_intbig.py b/tests/basics/builtin_divmod_intbig.py new file mode 100644 index 000000000..758e83415 --- /dev/null +++ b/tests/basics/builtin_divmod_intbig.py @@ -0,0 +1,13 @@ +# test builtin divmod + +try: + divmod(1 << 65, 0) +except ZeroDivisionError: + print("ZeroDivisionError") + +# bignum +l = (1 << 65) + 123 +print(divmod(3, l)) +print(divmod(l, 5)) +print(divmod(l + 3, l)) +print(divmod(l * 20, l + 2)) diff --git a/tests/basics/builtin_hash.py b/tests/basics/builtin_hash.py index ffea08e57..704895fbb 100644 --- a/tests/basics/builtin_hash.py +++ b/tests/basics/builtin_hash.py @@ -4,8 +4,6 @@ print(hash(False)) print(hash(True)) print({():1}) # hash tuple print({(1,):1}) # hash non-empty tuple -print({1 << 66:1}) # hash big int -print({-(1 << 66):2}) # hash negative big int print(hash in {hash:1}) # hash function try: @@ -50,9 +48,3 @@ class E: def __hash__(self): return True print(hash(E())) - -# __hash__ returning a large number should be truncated -class F: - def __hash__(self): - return 1 << 70 | 1 -print(hash(F()) != 0) diff --git a/tests/basics/builtin_hash_intbig.py b/tests/basics/builtin_hash_intbig.py new file mode 100644 index 000000000..0092c0f3a --- /dev/null +++ b/tests/basics/builtin_hash_intbig.py @@ -0,0 +1,10 @@ +# test builtin hash function + +print({1 << 66:1}) # hash big int +print({-(1 << 66):2}) # hash negative big int + +# __hash__ returning a large number should be truncated +class F: + def __hash__(self): + return 1 << 70 | 1 +print(hash(F()) != 0) diff --git a/tests/basics/builtin_help.py b/tests/basics/builtin_help.py new file mode 100644 index 000000000..6ec39653f --- /dev/null +++ b/tests/basics/builtin_help.py @@ -0,0 +1,17 @@ +# test builtin help function + +try: + help +except NameError: + print("SKIP") + raise SystemExit + +help() # no args +help(help) # help for a function +help(int) # help for a class +help(1) # help for an instance +import micropython +help(micropython) # help for a module +help('modules') # list available modules + +print('done') # so last bit of output is predictable diff --git a/tests/basics/builtin_help.py.exp b/tests/basics/builtin_help.py.exp new file mode 100644 index 000000000..ed8a7d74b --- /dev/null +++ b/tests/basics/builtin_help.py.exp @@ -0,0 +1,14 @@ +######## +object <function> is of type function +object <class 'int'> is of type type + from_bytes -- <classmethod> + to_bytes -- <function> +object 1 is of type int + from_bytes -- <classmethod> + to_bytes -- <function> +object <module 'micropython'> is of type module + __name__ -- micropython + const -- <function> + opt_level -- <function> +######## +done diff --git a/tests/basics/builtin_hex.py b/tests/basics/builtin_hex.py index 7d1c98a7a..95d74257e 100644 --- a/tests/basics/builtin_hex.py +++ b/tests/basics/builtin_hex.py @@ -7,6 +7,3 @@ print(hex(-15)) print(hex(12345)) print(hex(0x12345)) - -print(hex(12345678901234567890)) -print(hex(0x12345678901234567890)) diff --git a/tests/basics/builtin_hex_intbig.py b/tests/basics/builtin_hex_intbig.py new file mode 100644 index 000000000..7049ca3f5 --- /dev/null +++ b/tests/basics/builtin_hex_intbig.py @@ -0,0 +1,4 @@ +# test builtin hex function + +print(hex(12345678901234567890)) +print(hex(0x12345678901234567890)) diff --git a/tests/basics/builtin_minmax.py b/tests/basics/builtin_minmax.py index d395d4421..184398e64 100644 --- a/tests/basics/builtin_minmax.py +++ b/tests/basics/builtin_minmax.py @@ -1,4 +1,10 @@ # test builtin min and max functions +try: + min + max +except: + print("SKIP") + raise SystemExit print(min(0,1)) print(min(1,0)) diff --git a/tests/basics/builtin_oct.py b/tests/basics/builtin_oct.py index d8ba8e434..6dc48a6fa 100644 --- a/tests/basics/builtin_oct.py +++ b/tests/basics/builtin_oct.py @@ -7,6 +7,3 @@ print(oct(-15)) print(oct(12345)) print(oct(0o12345)) - -print(oct(12345678901234567890)) -print(oct(0o12345670123456701234)) diff --git a/tests/basics/builtin_oct_intbig.py b/tests/basics/builtin_oct_intbig.py new file mode 100644 index 000000000..4dc28ab46 --- /dev/null +++ b/tests/basics/builtin_oct_intbig.py @@ -0,0 +1,4 @@ +# test builtin oct function + +print(oct(12345678901234567890)) +print(oct(0o12345670123456701234)) diff --git a/tests/basics/builtin_override.py b/tests/basics/builtin_override.py index e245985ad..9f91341ed 100644 --- a/tests/basics/builtin_override.py +++ b/tests/basics/builtin_override.py @@ -3,7 +3,12 @@ import builtins # override generic builtin -builtins.abs = lambda x: x + 1 +try: + builtins.abs = lambda x: x + 1 +except AttributeError: + print("SKIP") + raise SystemExit + print(abs(1)) # __build_class__ is handled in a special way diff --git a/tests/basics/builtin_pow.py b/tests/basics/builtin_pow.py index a19ab8c84..5012a76be 100644 --- a/tests/basics/builtin_pow.py +++ b/tests/basics/builtin_pow.py @@ -1,11 +1,7 @@ # test builtin pow() with integral values - # 2 arg version + print(pow(0, 1)) print(pow(1, 0)) print(pow(-2, 3)) print(pow(3, 8)) - -# 3 arg version -print(pow(3, 4, 7)) - diff --git a/tests/basics/builtin_pow3.py b/tests/basics/builtin_pow3.py new file mode 100644 index 000000000..69b57e548 --- /dev/null +++ b/tests/basics/builtin_pow3.py @@ -0,0 +1,24 @@ +# test builtin pow() with integral values +# 3 arg version + +try: + print(pow(3, 4, 7)) +except NotImplementedError: + print("SKIP") + raise SystemExit + +# 3 arg pow is defined to only work on integers +try: + print(pow("x", 5, 6)) +except TypeError: + print("TypeError expected") + +try: + print(pow(4, "y", 6)) +except TypeError: + print("TypeError expected") + +try: + print(pow(4, 5, "z")) +except TypeError: + print("TypeError expected") diff --git a/tests/basics/builtin_pow3_intbig.py b/tests/basics/builtin_pow3_intbig.py new file mode 100644 index 000000000..bedc8b36b --- /dev/null +++ b/tests/basics/builtin_pow3_intbig.py @@ -0,0 +1,22 @@ +# test builtin pow() with integral values +# 3 arg version + +try: + print(pow(3, 4, 7)) +except NotImplementedError: + print("SKIP") + raise SystemExit + +print(pow(555557, 1000002, 1000003)) + +# Tests for 3 arg pow with large values + +# This value happens to be prime +x = 0xd48a1e2a099b1395895527112937a391d02d4a208bce5d74b281cf35a57362502726f79a632f063a83c0eba66196712d963aa7279ab8a504110a668c0fc38a7983c51e6ee7a85cae87097686ccdc359ee4bbf2c583bce524e3f7836bded1c771a4efcb25c09460a862fc98e18f7303df46aaeb34da46b0c4d61d5cd78350f3edb60e6bc4befa712a849 +y = 0x3accf60bb1a5365e4250d1588eb0fe6cd81ad495e9063f90880229f2a625e98c59387238670936afb2cafc5b79448e4414d6cd5e9901aa845aa122db58ddd7b9f2b17414600a18c47494ed1f3d49d005a5 + +print(hex(pow(2, 200, x))) # Should not overflow, just 1 << 200 +print(hex(pow(2, x-1, x))) # Should be 1, since x is prime +print(hex(pow(y, x-1, x))) # Should be 1, since x is prime +print(hex(pow(y, y-1, x))) # Should be a 'big value' +print(hex(pow(y, y-1, y))) # Should be a 'big value' diff --git a/tests/basics/builtin_property.py b/tests/basics/builtin_property.py index 403abd62f..89c3d4936 100644 --- a/tests/basics/builtin_property.py +++ b/tests/basics/builtin_property.py @@ -1,4 +1,9 @@ # test builtin property +try: + property +except: + print("SKIP") + raise SystemExit # create a property object explicitly property() diff --git a/tests/basics/builtin_range.py b/tests/basics/builtin_range.py index 59fc0344a..0e2fabd82 100644 --- a/tests/basics/builtin_range.py +++ b/tests/basics/builtin_range.py @@ -33,11 +33,16 @@ print(range(1, 4)[0:]) print(range(1, 4)[1:]) print(range(1, 4)[:-1]) print(range(7, -2, -4)[:]) +print(range(1, 100, 5)[5:15:3]) +print(range(1, 100, 5)[15:5:-3]) +print(range(100, 1, -5)[5:15:3]) +print(range(100, 1, -5)[15:5:-3]) -# attrs -print(range(1, 2, 3).start) -print(range(1, 2, 3).stop) -print(range(1, 2, 3).step) +# zero step +try: + range(1, 2, 0) +except ValueError: + print("ValueError") # bad unary op try: @@ -50,9 +55,3 @@ try: range(1)[0] = 1 except TypeError: print("TypeError") - -# bad attr (can't store) -try: - range(4).start = 0 -except AttributeError: - print('AttributeError') diff --git a/tests/basics/builtin_range_attrs.py b/tests/basics/builtin_range_attrs.py new file mode 100644 index 000000000..05d666d13 --- /dev/null +++ b/tests/basics/builtin_range_attrs.py @@ -0,0 +1,18 @@ +# test attributes of builtin range type + +try: + range(0).start +except AttributeError: + print("SKIP") + raise SystemExit + +# attrs +print(range(1, 2, 3).start) +print(range(1, 2, 3).stop) +print(range(1, 2, 3).step) + +# bad attr (can't store) +try: + range(4).start = 0 +except AttributeError: + print('AttributeError') diff --git a/tests/basics/builtin_reversed.py b/tests/basics/builtin_reversed.py index f129a4f5d..f43505a8b 100644 --- a/tests/basics/builtin_reversed.py +++ b/tests/basics/builtin_reversed.py @@ -1,4 +1,9 @@ # test the builtin reverse() function +try: + reversed +except: + print("SKIP") + raise SystemExit # list print(list(reversed([]))) diff --git a/tests/basics/builtin_sorted.py b/tests/basics/builtin_sorted.py index a4f71a15e..6435f86d0 100644 --- a/tests/basics/builtin_sorted.py +++ b/tests/basics/builtin_sorted.py @@ -1,4 +1,10 @@ # test builtin sorted +try: + sorted + set +except: + print("SKIP") + raise SystemExit print(sorted(set(range(100)))) print(sorted(set(range(100)), key=lambda x: x + 100*(x % 2))) diff --git a/tests/basics/bytearray_construct.py b/tests/basics/bytearray_construct.py index 1c45f6fcf..9c8f3adaa 100644 --- a/tests/basics/bytearray_construct.py +++ b/tests/basics/bytearray_construct.py @@ -1,12 +1,6 @@ # test construction of bytearray from different objects -from array import array - # bytes, tuple, list print(bytearray(b'123')) print(bytearray((1, 2))) print(bytearray([1, 2])) - -# arrays -print(bytearray(array('b', [1, 2]))) -print(bytearray(array('h', [0x101, 0x202]))) diff --git a/tests/basics/bytearray_construct_array.py b/tests/basics/bytearray_construct_array.py new file mode 100644 index 000000000..bde5fa08b --- /dev/null +++ b/tests/basics/bytearray_construct_array.py @@ -0,0 +1,10 @@ +# test construction of bytearray from different objects +try: + from array import array +except ImportError: + print("SKIP") + raise SystemExit + +# arrays +print(bytearray(array('b', [1, 2]))) +print(bytearray(array('h', [0x101, 0x202]))) diff --git a/tests/basics/bytearray_construct_endian.py b/tests/basics/bytearray_construct_endian.py index dbd635c0c..0002f19c5 100644 --- a/tests/basics/bytearray_construct_endian.py +++ b/tests/basics/bytearray_construct_endian.py @@ -1,6 +1,9 @@ # test construction of bytearray from different objects - -from array import array +try: + from array import array +except ImportError: + print("SKIP") + raise SystemExit # arrays print(bytearray(array('h', [1, 2]))) diff --git a/tests/basics/bytearray_longint.py b/tests/basics/bytearray_intbig.py index 334eabe12..334eabe12 100644 --- a/tests/basics/bytearray_longint.py +++ b/tests/basics/bytearray_intbig.py diff --git a/tests/basics/bytearray_slice_assign.py b/tests/basics/bytearray_slice_assign.py index 510e784da..48f5938a5 100644 --- a/tests/basics/bytearray_slice_assign.py +++ b/tests/basics/bytearray_slice_assign.py @@ -2,8 +2,7 @@ try: bytearray()[:] = bytearray() except TypeError: print("SKIP") - import sys - sys.exit() + raise SystemExit # test slices; only 2 argument version supported by Micro Python at the moment x = bytearray(range(10)) @@ -51,6 +50,11 @@ b = bytearray(10) b[:-1] = bytearray(500) print(len(b), b[0], b[-1]) +# extension with self on RHS +b = bytearray(x) +b[4:] = b +print(b) + # Assignment of bytes to array slice b = bytearray(2) b[1:1] = b"12345" diff --git a/tests/basics/bytes_add.py b/tests/basics/bytes_add.py index 7a887db23..ebccf0662 100644 --- a/tests/basics/bytes_add.py +++ b/tests/basics/bytes_add.py @@ -3,9 +3,6 @@ print(b"123" + b"456") print(b"123" + bytearray(2)) -import array - -# should be byteorder-neutral -print(b"123" + array.array('h', [0x1515])) - -print(b"\x01\x02" + array.array('b', [1, 2])) +print(b"123" + b"") # RHS is empty, can be optimised +print(b"" + b"123") # LHS is empty, can be optimised +print(b"" + bytearray(1)) # LHS is empty but can't be optimised diff --git a/tests/basics/bytes_add_array.py b/tests/basics/bytes_add_array.py new file mode 100644 index 000000000..b17556d83 --- /dev/null +++ b/tests/basics/bytes_add_array.py @@ -0,0 +1,11 @@ +# test bytes + other +try: + import array +except ImportError: + print("SKIP") + raise SystemExit + +# should be byteorder-neutral +print(b"123" + array.array('h', [0x1515])) + +print(b"\x01\x02" + array.array('b', [1, 2])) diff --git a/tests/basics/bytes_add_endian.py b/tests/basics/bytes_add_endian.py index 5471280d9..8cfffa7b6 100644 --- a/tests/basics/bytes_add_endian.py +++ b/tests/basics/bytes_add_endian.py @@ -1,5 +1,8 @@ # test bytes + other - -import array +try: + import array +except ImportError: + print("SKIP") + raise SystemExit print(b"123" + array.array('i', [1])) diff --git a/tests/basics/bytes_compare2.py b/tests/basics/bytes_compare2.py index 8959da3ae..4d5de21d2 100644 --- a/tests/basics/bytes_compare2.py +++ b/tests/basics/bytes_compare2.py @@ -3,9 +3,3 @@ print(b"123" == bytearray(b"123")) print(b'123' < bytearray(b"124")) print(b'123' > bytearray(b"122")) print(bytearray(b"23") in b"1234") - -import array - -print(array.array('b', [1, 2]) in b'\x01\x02\x03') -# CPython gives False here -#print(b"\x01\x02\x03" == array.array("B", [1, 2, 3])) diff --git a/tests/basics/bytes_compare_array.py b/tests/basics/bytes_compare_array.py new file mode 100644 index 000000000..ad378de70 --- /dev/null +++ b/tests/basics/bytes_compare_array.py @@ -0,0 +1,9 @@ +try: + import array +except ImportError: + print("SKIP") + raise SystemExit + +print(array.array('b', [1, 2]) in b'\x01\x02\x03') +# CPython gives False here +#print(b"\x01\x02\x03" == array.array("B", [1, 2, 3])) diff --git a/tests/basics/bytes_construct.py b/tests/basics/bytes_construct.py index 59e02f063..0d638c08f 100644 --- a/tests/basics/bytes_construct.py +++ b/tests/basics/bytes_construct.py @@ -1,19 +1,10 @@ # test construction of bytes from different objects -from array import array - # tuple, list, bytearray print(bytes((1, 2))) print(bytes([1, 2])) print(bytes(bytearray(4))) -# arrays -print(bytes(array('b', [1, 2]))) -print(bytes(array('h', [0x101, 0x202]))) - -# long ints -print(ord(bytes([14953042807679334000 & 0xff]))) - # constructor value out of range try: bytes([-1]) diff --git a/tests/basics/bytes_construct_array.py b/tests/basics/bytes_construct_array.py new file mode 100644 index 000000000..453eb5901 --- /dev/null +++ b/tests/basics/bytes_construct_array.py @@ -0,0 +1,10 @@ +# test construction of bytes from different objects +try: + from array import array +except ImportError: + print("SKIP") + raise SystemExit + +# arrays +print(bytes(array('b', [1, 2]))) +print(bytes(array('h', [0x101, 0x202]))) diff --git a/tests/basics/bytes_construct_endian.py b/tests/basics/bytes_construct_endian.py index 1912f63a4..cf1a9f408 100644 --- a/tests/basics/bytes_construct_endian.py +++ b/tests/basics/bytes_construct_endian.py @@ -1,6 +1,10 @@ # test construction of bytes from different objects -from array import array +try: + from array import array +except ImportError: + print("SKIP") + raise SystemExit # arrays print(bytes(array('h', [1, 2]))) diff --git a/tests/basics/bytes_construct_intbig.py b/tests/basics/bytes_construct_intbig.py new file mode 100644 index 000000000..c32de185f --- /dev/null +++ b/tests/basics/bytes_construct_intbig.py @@ -0,0 +1,4 @@ +# test construction of bytes from different objects + +# long ints +print(ord(bytes([14953042807679334000 & 0xff]))) diff --git a/tests/basics/bytes_partition.py b/tests/basics/bytes_partition.py index 7d3ffaaaa..5b503f544 100644 --- a/tests/basics/bytes_partition.py +++ b/tests/basics/bytes_partition.py @@ -2,8 +2,7 @@ try: str.partition except AttributeError: print("SKIP") - import sys - sys.exit() + raise SystemExit print(b"asdf".partition(b'g')) print(b"asdf".partition(b'a')) diff --git a/tests/basics/class_delattr_setattr.py b/tests/basics/class_delattr_setattr.py new file mode 100644 index 000000000..190b4875b --- /dev/null +++ b/tests/basics/class_delattr_setattr.py @@ -0,0 +1,62 @@ +# test __delattr__ and __setattr__ + +# feature test for __setattr__/__delattr__ +try: + class Test(): + def __delattr__(self, attr): pass + del Test().noexist +except AttributeError: + print('SKIP') + raise SystemExit + +# this class just prints the calls to see if they were executed +class A(): + def __getattr__(self, attr): + print('get', attr) + return 1 + def __setattr__(self, attr, val): + print('set', attr, val) + def __delattr__(self, attr): + print('del', attr) +a = A() + +# check basic behaviour +print(getattr(a, 'foo')) +setattr(a, 'bar', 2) +delattr(a, 'baz') + +# check meta behaviour +getattr(a, '__getattr__') # should not call A.__getattr__ +getattr(a, '__setattr__') # should not call A.__getattr__ +getattr(a, '__delattr__') # should not call A.__getattr__ +setattr(a, '__setattr__', 1) # should call A.__setattr__ +delattr(a, '__delattr__') # should call A.__delattr__ + +# this class acts like a dictionary +class B: + def __init__(self, d): + # store the dict in the class, not instance, so + # we don't get infinite recursion in __getattr_ + B.d = d + + def __getattr__(self, attr): + if attr in B.d: + return B.d[attr] + else: + raise AttributeError(attr) + + def __setattr__(self, attr, value): + B.d[attr] = value + + def __delattr__(self, attr): + del B.d[attr] + +a = B({"a":1, "b":2}) +print(a.a, a.b) +a.a = 3 +print(a.a, a.b) +del a.a +try: + print(a.a) +except AttributeError: + print("AttributeError") diff --git a/tests/basics/class_descriptor.py b/tests/basics/class_descriptor.py index 25b373e47..eb88ba7b9 100644 --- a/tests/basics/class_descriptor.py +++ b/tests/basics/class_descriptor.py @@ -18,6 +18,12 @@ class Main: Forward = Descriptor() m = Main() +try: + m.__class__ +except AttributeError: + print("SKIP") + raise SystemExit + r = m.Forward if 'Descriptor' in repr(r.__class__): print('SKIP') diff --git a/tests/basics/class_new.py b/tests/basics/class_new.py index a6a34c581..9a7072ad0 100644 --- a/tests/basics/class_new.py +++ b/tests/basics/class_new.py @@ -1,3 +1,10 @@ +try: + # If we don't expose object.__new__ (small ports), there's + # nothing to test. + object.__new__ +except AttributeError: + print("SKIP") + raise SystemExit class A: def __new__(cls): print("A.__new__") diff --git a/tests/basics/class_store_class.py b/tests/basics/class_store_class.py index 10b94d3c6..797f88f85 100644 --- a/tests/basics/class_store_class.py +++ b/tests/basics/class_store_class.py @@ -5,7 +5,11 @@ try: from collections import namedtuple except ImportError: - from ucollections import namedtuple + try: + from ucollections import namedtuple + except ImportError: + print("SKIP") + raise SystemExit _DefragResultBase = namedtuple('DefragResult', [ 'foo', 'bar' ]) diff --git a/tests/basics/class_super.py b/tests/basics/class_super.py index 4b052d8f3..1338ef452 100644 --- a/tests/basics/class_super.py +++ b/tests/basics/class_super.py @@ -20,3 +20,17 @@ class A: def p(self): print(str(super())[:18]) A().p() + + +# test compiler's handling of long expressions with super +class A: + bar = 123 + def foo(self): + print('A foo') + return [1, 2, 3] +class B(A): + def foo(self): + print('B foo') + print(super().bar) # accessing attribute after super() + return super().foo().count(2) # calling a subsequent method +print(B().foo()) diff --git a/tests/basics/class_super_aslocal.py b/tests/basics/class_super_aslocal.py new file mode 100644 index 000000000..c9259110a --- /dev/null +++ b/tests/basics/class_super_aslocal.py @@ -0,0 +1,9 @@ +# test using the name "super" as a local variable + +class A: + def foo(self): + super = [1, 2] + super.pop() + print(super) + +A().foo() diff --git a/tests/basics/class_super_closure.py b/tests/basics/class_super_closure.py new file mode 100644 index 000000000..41acae90d --- /dev/null +++ b/tests/basics/class_super_closure.py @@ -0,0 +1,18 @@ +# test that no-arg super() works when self is closed over + +class A: + def __init__(self): + self.val = 4 + def foo(self): + # we access a member of self to check that self is correct + return list(range(self.val)) +class B(A): + def foo(self): + # self is closed over because it's referenced in the list comprehension + # and then super() must detect this and load from the closure cell + return [self.bar(i) for i in super().foo()] + def bar(self, x): + return 2 * x + +print(A().foo()) +print(B().foo()) diff --git a/tests/basics/class_super_object.py b/tests/basics/class_super_object.py index 21b97328e..1fddbb38f 100644 --- a/tests/basics/class_super_object.py +++ b/tests/basics/class_super_object.py @@ -1,4 +1,11 @@ # Calling object.__init__() via super().__init__ +try: + # If we don't expose object.__init__ (small ports), there's + # nothing to test. + object.__init__ +except AttributeError: + print("SKIP") + raise SystemExit class Test(object): def __init__(self): diff --git a/tests/basics/comprehension1.py b/tests/basics/comprehension1.py index 7f541ee53..892d6b4e3 100644 --- a/tests/basics/comprehension1.py +++ b/tests/basics/comprehension1.py @@ -14,7 +14,6 @@ def f(): print(d[0], d[1], d[2], d[3], d[4]) # set comprehension - - print({a for a in range(5)}) + # see set_comprehension.py f() diff --git a/tests/basics/containment.py b/tests/basics/containment.py index f8be04e92..bae366113 100644 --- a/tests/basics/containment.py +++ b/tests/basics/containment.py @@ -1,5 +1,6 @@ +# sets, see set_containment for i in 1, 2: - for o in {1:2}, {1}, {1:2}.keys(): + for o in {1:2}, {1:2}.keys(): print("{} in {}: {}".format(i, o, i in o)) print("{} not in {}: {}".format(i, o, i not in o)) diff --git a/tests/basics/dict_fromkeys.py b/tests/basics/dict_fromkeys.py index bfad347c8..7b11319a2 100644 --- a/tests/basics/dict_fromkeys.py +++ b/tests/basics/dict_fromkeys.py @@ -7,7 +7,3 @@ d = dict.fromkeys([1, 2, 3, 4], 42) l = list(d.values()) l.sort() print(l) - -# argument to fromkeys has no __len__ -d = dict.fromkeys(reversed(range(1))) -print(d) diff --git a/tests/basics/dict_fromkeys2.py b/tests/basics/dict_fromkeys2.py new file mode 100644 index 000000000..dce1e8ef5 --- /dev/null +++ b/tests/basics/dict_fromkeys2.py @@ -0,0 +1,10 @@ +try: + reversed +except: + print("SKIP") + raise SystemExit + +# argument to fromkeys has no __len__ +d = dict.fromkeys(reversed(range(1))) +#d = dict.fromkeys((x for x in range(1))) +print(d) diff --git a/tests/basics/enumerate.py b/tests/basics/enumerate.py index 00595cb0f..4f8239bf7 100644 --- a/tests/basics/enumerate.py +++ b/tests/basics/enumerate.py @@ -1,3 +1,9 @@ +try: + enumerate +except: + print("SKIP") + raise SystemExit + print(list(enumerate([]))) print(list(enumerate([1, 2, 3]))) print(list(enumerate([1, 2, 3], 5))) diff --git a/tests/basics/errno1.py b/tests/basics/errno1.py index eae1bbe1b..63930b767 100644 --- a/tests/basics/errno1.py +++ b/tests/basics/errno1.py @@ -4,8 +4,7 @@ try: import uerrno except ImportError: print("SKIP") - import sys - sys.exit() + raise SystemExit # check that constants exist and are integers print(type(uerrno.EIO)) diff --git a/tests/basics/filter.py b/tests/basics/filter.py index 5883e3d00..c6d97cf9b 100644 --- a/tests/basics/filter.py +++ b/tests/basics/filter.py @@ -1,2 +1,8 @@ +try: + filter +except: + print("SKIP") + raise SystemExit + print(list(filter(lambda x: x & 1, range(-3, 4)))) print(list(filter(None, range(-3, 4)))) diff --git a/tests/basics/floordivide.py b/tests/basics/floordivide.py index 930313d6c..60e7634b1 100644 --- a/tests/basics/floordivide.py +++ b/tests/basics/floordivide.py @@ -12,18 +12,3 @@ print(a // b) print(a // -b) print(-a // b) print(-a // -b) - -if True: - a = 987654321987987987987987987987 - b = 19 - - print(a // b) - print(a // -b) - print(-a // b) - print(-a // -b) - a = 10000000000000000000000000000000000000000000 - b = 100 - print(a // b) - print(a // -b) - print(-a // b) - print(-a // -b) diff --git a/tests/basics/floordivide_intbig.py b/tests/basics/floordivide_intbig.py new file mode 100644 index 000000000..422329fcd --- /dev/null +++ b/tests/basics/floordivide_intbig.py @@ -0,0 +1,15 @@ +# check modulo matches python definition + +a = 987654321987987987987987987987 +b = 19 + +print(a // b) +print(a // -b) +print(-a // b) +print(-a // -b) +a = 10000000000000000000000000000000000000000000 +b = 100 +print(a // b) +print(a // -b) +print(-a // b) +print(-a // -b) diff --git a/tests/basics/for_range.py b/tests/basics/for_range.py index 58a8f7caa..fc736277d 100644 --- a/tests/basics/for_range.py +++ b/tests/basics/for_range.py @@ -6,6 +6,13 @@ for x in range(*(1, 3)): for x in range(1, *(6, 2)): print(x) +# zero step +try: + for x in range(1, 2, 0): + pass +except ValueError: + print('ValueError') + # apply args using ** try: for x in range(**{'end':1}): diff --git a/tests/basics/frozenset1.py b/tests/basics/frozenset1.py index 7a4a33540..7bec24c29 100644 --- a/tests/basics/frozenset1.py +++ b/tests/basics/frozenset1.py @@ -4,8 +4,7 @@ try: frozenset except NameError: print("SKIP") - import sys - sys.exit() + raise SystemExit s = frozenset() print(s) diff --git a/tests/basics/frozenset_add.py b/tests/basics/frozenset_add.py index 415a8c2e1..fe24fbaf1 100644 --- a/tests/basics/frozenset_add.py +++ b/tests/basics/frozenset_add.py @@ -2,8 +2,7 @@ try: frozenset except NameError: print("SKIP") - import sys - sys.exit() + raise SystemExit s = frozenset({1, 2, 3, 4}) try: diff --git a/tests/basics/frozenset_binop.py b/tests/basics/frozenset_binop.py index 5cc07e9e1..61af07a23 100644 --- a/tests/basics/frozenset_binop.py +++ b/tests/basics/frozenset_binop.py @@ -2,8 +2,7 @@ try: frozenset except NameError: print("SKIP") - import sys - sys.exit() + raise SystemExit sets = [ frozenset(), frozenset({1}), frozenset({1, 2}), frozenset({1, 2, 3}), frozenset({2, 3}), diff --git a/tests/basics/frozenset_copy.py b/tests/basics/frozenset_copy.py index 92e115d34..c90f541a1 100644 --- a/tests/basics/frozenset_copy.py +++ b/tests/basics/frozenset_copy.py @@ -2,8 +2,7 @@ try: frozenset except NameError: print("SKIP") - import sys - sys.exit() + raise SystemExit s = frozenset({1, 2, 3, 4}) t = s.copy() diff --git a/tests/basics/frozenset_difference.py b/tests/basics/frozenset_difference.py index 3d142f959..bc8b9c21c 100644 --- a/tests/basics/frozenset_difference.py +++ b/tests/basics/frozenset_difference.py @@ -2,8 +2,7 @@ try: frozenset except NameError: print("SKIP") - import sys - sys.exit() + raise SystemExit l = [1, 2, 3, 4] s = frozenset(l) diff --git a/tests/basics/frozenset_set.py b/tests/basics/frozenset_set.py index b334694b5..3bf456acf 100644 --- a/tests/basics/frozenset_set.py +++ b/tests/basics/frozenset_set.py @@ -2,8 +2,7 @@ try: frozenset except NameError: print("SKIP") - import sys - sys.exit() + raise SystemExit # Examples from https://docs.python.org/3/library/stdtypes.html#set # "Instances of set are compared to instances of frozenset based on their diff --git a/tests/basics/fun_calldblstar3.py b/tests/basics/fun_calldblstar3.py index 4367e68df..b796d52c7 100644 --- a/tests/basics/fun_calldblstar3.py +++ b/tests/basics/fun_calldblstar3.py @@ -5,7 +5,8 @@ def foo(**kw): class Mapping: def keys(self): - return ['a', 'b', 'c'] + # the long string checks the case of string interning + return ['a', 'b', 'c', 'abcdefghijklmnopqrst'] def __getitem__(self, key): if key == 'a': diff --git a/tests/basics/fun_callstar.py b/tests/basics/fun_callstar.py index 2275d3d4f..a27a288a3 100644 --- a/tests/basics/fun_callstar.py +++ b/tests/basics/fun_callstar.py @@ -17,6 +17,11 @@ foo(*range(3)) # pos then iterator foo(1, *range(2, 4)) +# an iterator with many elements +def foo(*rest): + print(rest) +foo(*range(10)) + # method calls with *pos class A: diff --git a/tests/basics/fun_error.py b/tests/basics/fun_error.py index 305b24911..367fe0b7f 100644 --- a/tests/basics/fun_error.py +++ b/tests/basics/fun_error.py @@ -27,8 +27,5 @@ test_exc("[].sort(1)", TypeError) # function with keyword args given extra keyword args test_exc("[].sort(noexist=1)", TypeError) -# function with keyword args not given a specific keyword arg -test_exc("enumerate()", TypeError) - # kw given for positional, but a different positional is missing test_exc("def f(x, y): pass\nf(x=1)", TypeError) diff --git a/tests/basics/fun_error2.py b/tests/basics/fun_error2.py new file mode 100644 index 000000000..2a00396e6 --- /dev/null +++ b/tests/basics/fun_error2.py @@ -0,0 +1,18 @@ +# test errors from bad function calls +try: + enumerate +except: + print("SKIP") + raise SystemExit + +def test_exc(code, exc): + try: + exec(code) + print("no exception") + except exc: + print("right exception") + except: + print("wrong exception") + +# function with keyword args not given a specific keyword arg +test_exc("enumerate()", TypeError) diff --git a/tests/basics/gc1.py b/tests/basics/gc1.py index be6c6faed..dcbe0bfcf 100644 --- a/tests/basics/gc1.py +++ b/tests/basics/gc1.py @@ -4,8 +4,7 @@ try: import gc except ImportError: print("SKIP") - import sys - sys.exit() + raise SystemExit print(gc.isenabled()) gc.disable() diff --git a/tests/basics/gen_yield_from_close.py b/tests/basics/gen_yield_from_close.py index d66691ff9..833986105 100644 --- a/tests/basics/gen_yield_from_close.py +++ b/tests/basics/gen_yield_from_close.py @@ -102,7 +102,7 @@ except RuntimeError: # case where close is propagated up to a built-in iterator def gen8(): - g = reversed([2, 1]) + g = range(2) yield from g g = gen8() print(next(g)) diff --git a/tests/basics/gen_yield_from_throw2.py b/tests/basics/gen_yield_from_throw2.py index 2cff9e08b..0abfdd8cc 100644 --- a/tests/basics/gen_yield_from_throw2.py +++ b/tests/basics/gen_yield_from_throw2.py @@ -1,5 +1,5 @@ -# uPy differs from CPython for this test -# generator ignored GeneratorExit +# generator ignores a thrown GeneratorExit (this is allowed) + def gen(): try: yield 123 @@ -7,9 +7,12 @@ def gen(): print('GeneratorExit') yield 456 +# thrown a class g = gen() print(next(g)) -try: - g.throw(GeneratorExit) -except RuntimeError: - print('RuntimeError') +print(g.throw(GeneratorExit)) + +# thrown an instance +g = gen() +print(next(g)) +print(g.throw(GeneratorExit())) diff --git a/tests/basics/gen_yield_from_throw2.py.exp b/tests/basics/gen_yield_from_throw2.py.exp deleted file mode 100644 index d5805b494..000000000 --- a/tests/basics/gen_yield_from_throw2.py.exp +++ /dev/null @@ -1,3 +0,0 @@ -123 -GeneratorExit -RuntimeError diff --git a/tests/basics/gen_yield_from_throw3.py b/tests/basics/gen_yield_from_throw3.py new file mode 100644 index 000000000..0f6c7c842 --- /dev/null +++ b/tests/basics/gen_yield_from_throw3.py @@ -0,0 +1,30 @@ +# yield-from a user-defined generator with a throw() method + +class Iter: + def __iter__(self): + return self + + def __next__(self): + return 1 + + def throw(self, x): + print('throw', x) + return 456 + +def gen(): + yield from Iter() + +# calling close() should not call throw() +g = gen() +print(next(g)) +g.close() + +# can throw a non-exception object +g = gen() +print(next(g)) +print(g.throw(123)) + +# throwing an exception class just injects that class +g = gen() +print(next(g)) +print(g.throw(ZeroDivisionError)) diff --git a/tests/basics/int_mpz.py b/tests/basics/int_big1.py index 425bc21b6..425bc21b6 100644 --- a/tests/basics/int_mpz.py +++ b/tests/basics/int_big1.py diff --git a/tests/basics/int_bytes.py b/tests/basics/int_bytes.py index 2f468da44..93c00bba1 100644 --- a/tests/basics/int_bytes.py +++ b/tests/basics/int_bytes.py @@ -1,7 +1,10 @@ print((10).to_bytes(1, "little")) print((111111).to_bytes(4, "little")) print((100).to_bytes(10, "little")) -print((2**64).to_bytes(9, "little")) print(int.from_bytes(b"\x00\x01\0\0\0\0\0\0", "little")) print(int.from_bytes(b"\x01\0\0\0\0\0\0\0", "little")) print(int.from_bytes(b"\x00\x01\0\0\0\0\0\0", "little")) + +# check that extra zero bytes don't change the internal int value +print(int.from_bytes(bytes(20), "little") == 0) +print(int.from_bytes(b"\x01" + bytes(20), "little") == 1) diff --git a/tests/basics/int_bytes_intbig.py b/tests/basics/int_bytes_intbig.py new file mode 100644 index 000000000..0e0ad1cbb --- /dev/null +++ b/tests/basics/int_bytes_intbig.py @@ -0,0 +1,12 @@ +print((2**64).to_bytes(9, "little")) + +b = bytes(range(20)) + +il = int.from_bytes(b, "little") +ib = int.from_bytes(b, "big") +print(il) +print(ib) +print(il.to_bytes(20, "little")) + +# check that extra zero bytes don't change the internal int value +print(int.from_bytes(b + bytes(10), "little") == int.from_bytes(b, "little")) diff --git a/tests/basics/int_bytes_notimpl.py b/tests/basics/int_bytes_notimpl.py index b47d6ab58..b149f4496 100644 --- a/tests/basics/int_bytes_notimpl.py +++ b/tests/basics/int_bytes_notimpl.py @@ -2,8 +2,3 @@ try: print((10).to_bytes(1, "big")) except Exception as e: print(type(e)) - -try: - print(int.from_bytes(b"\0", "big")) -except Exception as e: - print(type(e)) diff --git a/tests/basics/int_bytes_notimpl.py.exp b/tests/basics/int_bytes_notimpl.py.exp index d1bf338eb..606649a69 100644 --- a/tests/basics/int_bytes_notimpl.py.exp +++ b/tests/basics/int_bytes_notimpl.py.exp @@ -1,2 +1 @@ <class 'NotImplementedError'> -<class 'NotImplementedError'> diff --git a/tests/basics/int_constfolding.py b/tests/basics/int_constfolding.py index aa38fa6b8..7bb538378 100644 --- a/tests/basics/int_constfolding.py +++ b/tests/basics/int_constfolding.py @@ -7,19 +7,11 @@ print(+100) # negation print(-1) print(-(-1)) -print(-0x3fffffff) # 32-bit edge case -print(-0x3fffffffffffffff) # 64-bit edge case -print(-(-0x3fffffff - 1)) # 32-bit edge case -print(-(-0x3fffffffffffffff - 1)) # 64-bit edge case # 1's complement print(~0) print(~1) print(~-1) -print(~0x3fffffff) # 32-bit edge case -print(~0x3fffffffffffffff) # 64-bit edge case -print(~(-0x3fffffff - 1)) # 32-bit edge case -print(~(-0x3fffffffffffffff - 1)) # 64-bit edge case # addition print(1 + 2) @@ -37,9 +29,3 @@ print(123 // 7, 123 % 7) print(-123 // 7, -123 % 7) print(123 // -7, 123 % -7) print(-123 // -7, -123 % -7) - -# zero big-num on rhs -print(1 + ((1 << 65) - (1 << 65))) - -# negative big-num on rhs -print(1 + (-(1 << 65))) diff --git a/tests/basics/int_constfolding_intbig.py b/tests/basics/int_constfolding_intbig.py new file mode 100644 index 000000000..714f1559a --- /dev/null +++ b/tests/basics/int_constfolding_intbig.py @@ -0,0 +1,19 @@ +# tests int constant folding in compiler + +# negation +print(-0x3fffffff) # 32-bit edge case +print(-0x3fffffffffffffff) # 64-bit edge case +print(-(-0x3fffffff - 1)) # 32-bit edge case +print(-(-0x3fffffffffffffff - 1)) # 64-bit edge case + +# 1's complement +print(~0x3fffffff) # 32-bit edge case +print(~0x3fffffffffffffff) # 64-bit edge case +print(~(-0x3fffffff - 1)) # 32-bit edge case +print(~(-0x3fffffffffffffff - 1)) # 64-bit edge case + +# zero big-num on rhs +print(1 + ((1 << 65) - (1 << 65))) + +# negative big-num on rhs +print(1 + (-(1 << 65))) diff --git a/tests/basics/int_divmod.py b/tests/basics/int_divmod.py index 3c76cd958..2e878135f 100644 --- a/tests/basics/int_divmod.py +++ b/tests/basics/int_divmod.py @@ -5,11 +5,3 @@ for i in range(-2, 3): for j in range(-4, 5): if j != 0: print(i, j, i // j, i % j, divmod(i, j)) - -# this tests bignum modulo -a = 987654321987987987987987987987 -b = 19 -print(a % b) -print(a % -b) -print(-a % b) -print(-a % -b) diff --git a/tests/basics/int_divmod_intbig.py b/tests/basics/int_divmod_intbig.py new file mode 100644 index 000000000..ea8de07f2 --- /dev/null +++ b/tests/basics/int_divmod_intbig.py @@ -0,0 +1,9 @@ +# test integer floor division and modulo + +# this tests bignum modulo +a = 987654321987987987987987987987 +b = 19 +print(a % b) +print(a % -b) +print(-a % b) +print(-a % -b) diff --git a/tests/basics/int_long.py b/tests/basics/int_intbig.py index a22075d1f..a22075d1f 100644 --- a/tests/basics/int_long.py +++ b/tests/basics/int_intbig.py diff --git a/tests/basics/iter0.py b/tests/basics/iter0.py index 6110e8fa5..d20ade7fe 100644 --- a/tests/basics/iter0.py +++ b/tests/basics/iter0.py @@ -4,3 +4,6 @@ try: pass except TypeError: print('TypeError') + +# builtin type that is iterable, calling __next__ explicitly +print(iter(range(4)).__next__()) diff --git a/tests/basics/iter_of_iter.py b/tests/basics/iter_of_iter.py index 70282aa97..d775b6a44 100644 --- a/tests/basics/iter_of_iter.py +++ b/tests/basics/iter_of_iter.py @@ -4,5 +4,4 @@ i = iter(iter([1, 2, 3])) print(list(i)) i = iter(iter({1:2, 3:4, 5:6})) print(sorted(i)) -i = iter(iter({1, 2, 3})) -print(sorted(i)) +# set, see set_iter_of_iter.py diff --git a/tests/basics/lexer.py b/tests/basics/lexer.py index 5f12afa70..244de8cb9 100644 --- a/tests/basics/lexer.py +++ b/tests/basics/lexer.py @@ -9,6 +9,14 @@ exec("\n") exec("\n\n") exec("\r") exec("\r\r") +exec("\t") +exec("\r\n") +exec("\nprint(1)") +exec("\rprint(2)") +exec("\r\nprint(3)") +exec("\n5") +exec("\r6") +exec("\r\n7") print(eval("1")) print(eval("12")) print(eval("123")) @@ -19,6 +27,14 @@ print(eval("1\r")) print(eval("12\r")) print(eval("123\r")) +# line continuation +print(eval("'123' \\\r '456'")) +print(eval("'123' \\\n '456'")) +print(eval("'123' \\\r\n '456'")) +print(eval("'123'\\\r'456'")) +print(eval("'123'\\\n'456'")) +print(eval("'123'\\\r\n'456'")) + # backslash used to escape a line-break in a string print('a\ b') diff --git a/tests/basics/list_slice_3arg.py b/tests/basics/list_slice_3arg.py index 8578d5855..a5eda8034 100644 --- a/tests/basics/list_slice_3arg.py +++ b/tests/basics/list_slice_3arg.py @@ -26,3 +26,14 @@ print(x[-1:-1:-1]) print(x[-1:-2:-1]) print(x[-1:-11:-1]) print(x[-10:-11:-1]) +print(x[:-15:-1]) + +# test negative indices that are out-of-bounds +print([][::-1]) +print([1][::-1]) +print([][0:-10:-1]) +print([1][0:-10:-1]) +print([][:-20:-1]) +print([1][:-20:-1]) +print([][-20::-1]) +print([1][-20::-1]) diff --git a/tests/basics/list_slice_assign.py b/tests/basics/list_slice_assign.py index baa9a0081..1ad1ef27c 100644 --- a/tests/basics/list_slice_assign.py +++ b/tests/basics/list_slice_assign.py @@ -34,3 +34,14 @@ print(l) l = list(x) del l[:-3] print(l) + +# assign a tuple +l = [1, 2, 3] +l[0:1] = (10, 11, 12) +print(l) + +# RHS of slice must be an iterable +try: + [][0:1] = 123 +except TypeError: + print('TypeError') diff --git a/tests/basics/list_slice_assign_grow.py b/tests/basics/list_slice_assign_grow.py index 12b1541e3..fa256235f 100644 --- a/tests/basics/list_slice_assign_grow.py +++ b/tests/basics/list_slice_assign_grow.py @@ -26,3 +26,8 @@ print(l) l = list(x) l[100:100] = [10, 20, 30, 40] print(l) + +# growing by using itself on RHS +l = list(range(10)) +l[4:] = l +print(l) diff --git a/tests/basics/map.py b/tests/basics/map.py index 62dca44ed..8fce352c2 100644 --- a/tests/basics/map.py +++ b/tests/basics/map.py @@ -1,4 +1,4 @@ print(list(map(lambda x: x & 1, range(-3, 4)))) print(list(map(abs, range(-3, 4)))) -print(list(map(set, [[i] for i in range(-3, 4)]))) +print(list(map(tuple, [[i] for i in range(-3, 4)]))) print(list(map(pow, range(4), range(4)))) diff --git a/tests/basics/memoryview1.py b/tests/basics/memoryview1.py index 1cd411195..c4cc6ffab 100644 --- a/tests/basics/memoryview1.py +++ b/tests/basics/memoryview1.py @@ -1,4 +1,9 @@ # test memoryview +try: + memoryview +except: + print("SKIP") + raise SystemExit # test reading from bytes b = b'1234' @@ -12,6 +17,10 @@ try: m[0] = 1 except TypeError: print("TypeError") +try: + m[0:2] = b'00' +except TypeError: + print("TypeError") # test writing to bytearray b = bytearray(b) diff --git a/tests/basics/memoryview2.py b/tests/basics/memoryview2.py index 5117d7a68..06a7be59f 100644 --- a/tests/basics/memoryview2.py +++ b/tests/basics/memoryview2.py @@ -1,13 +1,13 @@ # test memoryview accessing maximum values for signed/unsigned elements - -from array import array +try: + from array import array + memoryview +except: + print("SKIP") + raise SystemExit print(list(memoryview(b'\x7f\x80\x81\xff'))) print(list(memoryview(array('b', [0x7f, -0x80])))) print(list(memoryview(array('B', [0x7f, 0x80, 0x81, 0xff])))) print(list(memoryview(array('h', [0x7f00, -0x8000])))) print(list(memoryview(array('H', [0x7f00, 0x8000, 0x8100, 0xffff])))) - -# these constructors give an internal overflow in uPy -#print(list(memoryview(array('i', [0x7f000000, -0x80000000])))) -#print(list(memoryview(array('I', [0x7f000000, 0x80000000, 0x81000000, 0xffffffff])))) diff --git a/tests/basics/memoryview_gc.py b/tests/basics/memoryview_gc.py index a1e4baad4..d366cbbb1 100644 --- a/tests/basics/memoryview_gc.py +++ b/tests/basics/memoryview_gc.py @@ -1,4 +1,9 @@ # test memoryview retains pointer to original object/buffer +try: + memoryview +except: + print("SKIP") + raise SystemExit b = bytearray(10) m = memoryview(b)[1:] diff --git a/tests/basics/memoryview_intbig.py b/tests/basics/memoryview_intbig.py new file mode 100644 index 000000000..a76d9cbec --- /dev/null +++ b/tests/basics/memoryview_intbig.py @@ -0,0 +1,10 @@ +# test memoryview accessing maximum values for signed/unsigned elements +try: + from array import array + memoryview +except: + print("SKIP") + raise SystemExit + +print(list(memoryview(array('i', [0x7f000000, -0x80000000])))) +print(list(memoryview(array('I', [0x7f000000, 0x80000000, 0x81000000, 0xffffffff])))) diff --git a/tests/basics/namedtuple1.py b/tests/basics/namedtuple1.py index 346e32fbf..b9a007240 100644 --- a/tests/basics/namedtuple1.py +++ b/tests/basics/namedtuple1.py @@ -1,7 +1,11 @@ try: - from collections import namedtuple + try: + from collections import namedtuple + except ImportError: + from ucollections import namedtuple except ImportError: - from ucollections import namedtuple + print("SKIP") + raise SystemExit T = namedtuple("Tup", ["foo", "bar"]) # CPython prints fully qualified name, what we don't bother to do so far @@ -71,7 +75,7 @@ T4 = namedtuple("TupTuple", ("foo", "bar")) t = T4(1, 2) print(t.foo, t.bar) -# Try single string with comma field seperator +# Try single string with comma field separator # Not implemented so far #T2 = namedtuple("TupComma", "foo,bar") #t = T2(1, 2) diff --git a/tests/basics/object_dict.py b/tests/basics/object_dict.py index e6fb7b3d9..7bf7094e3 100644 --- a/tests/basics/object_dict.py +++ b/tests/basics/object_dict.py @@ -1,4 +1,3 @@ -import sys class Foo: @@ -9,6 +8,6 @@ class Foo: o = Foo() if not hasattr(o, "__dict__"): print("SKIP") - sys.exit() + raise SystemExit print(o.__dict__ == {'a': 1, 'b': 'bar'}) diff --git a/tests/basics/object_new.py b/tests/basics/object_new.py index befb5bfc2..a9c9482cb 100644 --- a/tests/basics/object_new.py +++ b/tests/basics/object_new.py @@ -2,6 +2,13 @@ # (non-initialized) instance of class. # See e.g. http://infohost.nmt.edu/tcc/help/pubs/python/web/new-new-method.html # TODO: Find reference in CPython docs +try: + # If we don't expose object.__new__ (small ports), there's + # nothing to test. + object.__new__ +except AttributeError: + print("SKIP") + raise SystemExit class Foo: diff --git a/tests/basics/op_error.py b/tests/basics/op_error.py index 19ce04bc5..b30b5f0a3 100644 --- a/tests/basics/op_error.py +++ b/tests/basics/op_error.py @@ -20,11 +20,9 @@ test_exc("False in True", TypeError) test_exc("1 * {}", TypeError) test_exc("1 in 1", TypeError) test_exc("bytearray() // 2", TypeError) -test_exc("m = memoryview(bytearray())\nm += bytearray()", TypeError) # object with buffer protocol needed on rhs test_exc("bytearray(1) + 1", TypeError) -test_exc("(1 << 70) in 1", TypeError) # unsupported subscription test_exc("1[0]", TypeError) diff --git a/tests/basics/op_error_intbig.py b/tests/basics/op_error_intbig.py new file mode 100644 index 000000000..432c05a9f --- /dev/null +++ b/tests/basics/op_error_intbig.py @@ -0,0 +1,13 @@ +# test errors from bad operations (unary, binary, etc) + +def test_exc(code, exc): + try: + exec(code) + print("no exception") + except exc: + print("right exception") + except: + print("wrong exception") + +# object with buffer protocol needed on rhs +test_exc("(1 << 70) in 1", TypeError) diff --git a/tests/basics/op_error_memoryview.py b/tests/basics/op_error_memoryview.py new file mode 100644 index 000000000..8d4403f77 --- /dev/null +++ b/tests/basics/op_error_memoryview.py @@ -0,0 +1,18 @@ +# test errors from bad operations (unary, binary, etc) +try: + memoryview +except: + print("SKIP") + raise SystemExit + +def test_exc(code, exc): + try: + exec(code) + print("no exception") + except exc: + print("right exception") + except: + print("wrong exception") + +# unsupported binary operators +test_exc("m = memoryview(bytearray())\nm += bytearray()", TypeError) diff --git a/tests/basics/ordereddict1.py b/tests/basics/ordereddict1.py index 5e8b2413b..d1633f0bb 100644 --- a/tests/basics/ordereddict1.py +++ b/tests/basics/ordereddict1.py @@ -5,12 +5,22 @@ except ImportError: from ucollections import OrderedDict except ImportError: print("SKIP") - import sys - sys.exit() + raise SystemExit d = OrderedDict([(10, 20), ("b", 100), (1, 2)]) +print(len(d)) print(list(d.keys())) print(list(d.values())) del d["b"] +print(len(d)) +print(list(d.keys())) +print(list(d.values())) + +# access remaining elements after deleting +print(d[10], d[1]) + +# add an element after deleting +d["abc"] = 123 +print(len(d)) print(list(d.keys())) print(list(d.values())) diff --git a/tests/basics/ordereddict_eq.py b/tests/basics/ordereddict_eq.py index 274660877..c69daf880 100644 --- a/tests/basics/ordereddict_eq.py +++ b/tests/basics/ordereddict_eq.py @@ -5,8 +5,7 @@ except ImportError: from ucollections import OrderedDict except ImportError: print("SKIP") - import sys - sys.exit() + raise SystemExit x = OrderedDict() y = OrderedDict() diff --git a/tests/basics/parser.py b/tests/basics/parser.py index 8fb2a49bf..626b67ad7 100644 --- a/tests/basics/parser.py +++ b/tests/basics/parser.py @@ -4,8 +4,7 @@ try: compile except NameError: print("SKIP") - import sys - sys.exit() + raise SystemExit # completely empty string # uPy and CPy differ for this case diff --git a/tests/basics/python34.py b/tests/basics/python34.py index 7f7a1e015..a23f347d6 100644 --- a/tests/basics/python34.py +++ b/tests/basics/python34.py @@ -1,4 +1,4 @@ -# tests that differ when running under Python 3.4 vs 3.5 +# tests that differ when running under Python 3.4 vs 3.5/3.6 # from basics/fun_kwvarargs.py # test evaluation order of arguments (in 3.4 it's backwards, 3.5 it's fixed) @@ -13,14 +13,15 @@ f4(*print_ret(['a', 'b']), kw_arg=print_ret(None)) {print_ret(1):print_ret(2)} # from basics/syntaxerror.py -# can't have multiple * or ** (in 3.5 we can) def test_syntax(code): try: exec(code) except SyntaxError: print("SyntaxError") -test_syntax("f(*a, *b)") -test_syntax("f(**a, **b)") +test_syntax("f(*a, *b)") # can't have multiple * (in 3.5 we can) +test_syntax("f(**a, **b)") # can't have multiple ** (in 3.5 we can) +test_syntax("() = []") # can't assign to empty tuple (in 3.6 we can) +test_syntax("del ()") # can't delete empty tuple (in 3.6 we can) # from basics/sys1.py # uPy prints version 3.4 diff --git a/tests/basics/python34.py.exp b/tests/basics/python34.py.exp index 637f77ce8..f497df3b8 100644 --- a/tests/basics/python34.py.exp +++ b/tests/basics/python34.py.exp @@ -5,5 +5,7 @@ None 1 SyntaxError SyntaxError +SyntaxError +SyntaxError 3.4 3 4 diff --git a/tests/basics/set_binop.py b/tests/basics/set_binop.py index a3657d84b..7848920b6 100644 --- a/tests/basics/set_binop.py +++ b/tests/basics/set_binop.py @@ -29,6 +29,25 @@ for s in sets: print(set('abc') == 1) +# make sure inplace operators modify the set + +s1 = s2 = set('abc') +s1 |= set('ad') +print(s1 is s2, len(s1)) + +s1 = s2 = set('abc') +s1 ^= set('ad') +print(s1 is s2, len(s1)) + +s1 = s2 = set('abc') +s1 &= set('ad') +print(s1 is s2, len(s1)) + +s1 = s2 = set('abc') +s1 -= set('ad') +print(s1 is s2, len(s1)) + +# unsupported operator try: set('abc') * 2 except TypeError: diff --git a/tests/basics/set_comprehension.py b/tests/basics/set_comprehension.py new file mode 100644 index 000000000..12a9a29d3 --- /dev/null +++ b/tests/basics/set_comprehension.py @@ -0,0 +1 @@ +print({a for a in range(5)}) diff --git a/tests/basics/set_containment.py b/tests/basics/set_containment.py new file mode 100644 index 000000000..97694f74c --- /dev/null +++ b/tests/basics/set_containment.py @@ -0,0 +1,4 @@ +for i in 1, 2: + for o in {}, {1}, {2}: + print("{} in {}: {}".format(i, o, i in o)) + print("{} not in {}: {}".format(i, o, i not in o)) diff --git a/tests/basics/set_iter_of_iter.py b/tests/basics/set_iter_of_iter.py new file mode 100644 index 000000000..e3e91fa45 --- /dev/null +++ b/tests/basics/set_iter_of_iter.py @@ -0,0 +1,2 @@ +i = iter(iter({1, 2, 3})) +print(sorted(i)) diff --git a/tests/basics/set_type.py b/tests/basics/set_type.py index d790fa062..787a99e81 100644 --- a/tests/basics/set_type.py +++ b/tests/basics/set_type.py @@ -5,9 +5,8 @@ try: set except NameError: - import sys print("SKIP") - sys.exit() + raise SystemExit print(set) diff --git a/tests/basics/slice_attrs.py b/tests/basics/slice_attrs.py index 67456ff8e..e85ead4ba 100644 --- a/tests/basics/slice_attrs.py +++ b/tests/basics/slice_attrs.py @@ -8,9 +8,8 @@ class A: try: t = A()[1:2] except: - import sys print("SKIP") - sys.exit() + raise SystemExit A()[1:2:3] diff --git a/tests/basics/slice_bignum.py b/tests/basics/slice_intbig.py index cc820522b..cc820522b 100644 --- a/tests/basics/slice_bignum.py +++ b/tests/basics/slice_intbig.py diff --git a/tests/basics/special_methods.py b/tests/basics/special_methods.py index 1df7a7c4c..9f57247c1 100644 --- a/tests/basics/special_methods.py +++ b/tests/basics/special_methods.py @@ -105,42 +105,4 @@ cud1 > cud2 cud1 + cud2 cud1 - cud2 -# the following require MICROPY_PY_ALL_SPECIAL_METHODS -+cud1 --cud1 -~cud1 -cud1 * cud2 -cud1 / cud2 -cud2 // cud1 -cud1 += cud2 -cud1 -= cud2 - -# TODO: the following operations are not supported on every ports -# -# ne is not supported, !(eq) is called instead -#cud1 != cud2 -# -# binary and is not supported -# cud1 & cud2 -# -# binary lshift is not supported -# cud1<<1 -# -# modulus is not supported -# cud1 % 2 -# -# binary or is not supported -# cud1 | cud2 -# -# pow is not supported -# cud1**2 -# -# rshift is not suported -# cud1>>1 -# -# xor is not supported -# cud1^cud2 -# -# in the followin test, cpython still calls __eq__ -# cud3=cud1 -# cud3==cud1 +# more in special_methods2.py diff --git a/tests/basics/special_methods2.py b/tests/basics/special_methods2.py new file mode 100644 index 000000000..ba7cf27cd --- /dev/null +++ b/tests/basics/special_methods2.py @@ -0,0 +1,144 @@ +class Cud(): + + def __init__(self): + #print("__init__ called") + pass + + def __repr__(self): + print("__repr__ called") + return "" + + def __lt__(self, other): + print("__lt__ called") + + def __le__(self, other): + print("__le__ called") + + def __eq__(self, other): + print("__eq__ called") + + def __ne__(self, other): + print("__ne__ called") + + def __ge__(self, other): + print("__ge__ called") + + def __gt__(self, other): + print("__gt__ called") + + def __abs__(self): + print("__abs__ called") + + def __add__(self, other): + print("__add__ called") + + def __and__(self, other): + print("__and__ called") + + def __floordiv__(self, other): + print("__floordiv__ called") + + def __index__(self, other): + print("__index__ called") + + def __inv__(self): + print("__inv__ called") + + def __invert__(self): + print("__invert__ called") + + def __lshift__(self, val): + print("__lshift__ called") + + def __mod__(self, val): + print("__mod__ called") + + def __mul__(self, other): + print("__mul__ called") + + def __matmul__(self, other): + print("__matmul__ called") + + def __neg__(self): + print("__neg__ called") + + def __or__(self, other): + print("__or__ called") + + def __pos__(self): + print("__pos__ called") + + def __pow__(self, val): + print("__pow__ called") + + def __rshift__(self, val): + print("__rshift__ called") + + def __sub__(self, other): + print("__sub__ called") + + def __truediv__(self, other): + print("__truediv__ called") + + def __div__(self, other): + print("__div__ called") + + def __xor__(self, other): + print("__xor__ called") + + def __iadd__(self, other): + print("__iadd__ called") + return self + + def __isub__(self, other): + print("__isub__ called") + return self + +cud1 = Cud() +cud2 = Cud() + +try: + +cud1 +except TypeError: + print("SKIP") + raise SystemExit + +# the following require MICROPY_PY_ALL_SPECIAL_METHODS ++cud1 +-cud1 +~cud1 +cud1 * cud2 +cud1 / cud2 +cud2 // cud1 +cud1 += cud2 +cud1 -= cud2 + +# TODO: the following operations are not supported on every ports +# +# ne is not supported, !(eq) is called instead +#cud1 != cud2 +# +# binary and is not supported +# cud1 & cud2 +# +# binary lshift is not supported +# cud1<<1 +# +# modulus is not supported +# cud1 % 2 +# +# binary or is not supported +# cud1 | cud2 +# +# pow is not supported +# cud1**2 +# +# rshift is not suported +# cud1>>1 +# +# xor is not supported +# cud1^cud2 +# +# in the followin test, cpython still calls __eq__ +# cud3=cud1 +# cud3==cud1 diff --git a/tests/basics/string_center.py b/tests/basics/string_center.py index a2739201a..40e8af4b8 100644 --- a/tests/basics/string_center.py +++ b/tests/basics/string_center.py @@ -1,9 +1,8 @@ try: str.center except: - import sys print("SKIP") - sys.exit() + raise SystemExit print("foo".center(0)) print("foo".center(1)) diff --git a/tests/basics/string_format2.py b/tests/basics/string_format2.py index e211535be..881ff4f80 100644 --- a/tests/basics/string_format2.py +++ b/tests/basics/string_format2.py @@ -1,6 +1,6 @@ # comprehensive functionality test for {} format string -int_tests = False # these take a while, and some give wrong results +int_tests = False # these take a while char_tests = True str_tests = True diff --git a/tests/basics/string_format_modulo.py b/tests/basics/string_format_modulo.py index 2e4909220..77bbcfbe3 100644 --- a/tests/basics/string_format_modulo.py +++ b/tests/basics/string_format_modulo.py @@ -33,38 +33,11 @@ print("%c" % 48) print("%c" % 'a') print("%10s" % 'abc') print("%-10s" % 'abc') -print("%d" % 10) -print("%+d" % 10) -print("% d" % 10) -print("%d" % -10) -print("%d" % True) -print("%i" % -10) -print("%i" % True) -print("%u" % -10) -print("%u" % True) -print("%x" % 18) -print("%o" % 18) -print("%X" % 18) -print("%#x" % 18) -print("%#X" % 18) -print("%#6o" % 18) -print("%#6x" % 18) -print("%#06x" % 18) - -print("%*d" % (5, 10)) -print("%*.*d" % (2, 2, 20)) -print("%*.*d" % (5, 8, 20)) - -print(">%8.4d<" % -12) -print(">% 8.4d<" % -12) -print(">%+8.4d<" % 12) -print(">%+8.4d<" % -12) -print(">%08.4d<" % -12) -print(">%08.4d<" % 12) -print(">%-8.4d<" % -12) -print(">%-08.4d<" % -12) -print(">%-+08.4d<" % -12) -print(">%-+08.4d<" % 12) + +# Should be able to print dicts; in this case they aren't used +# to lookup keywords in formats like %(foo)s +print('%s' % {}) +print('%s' % ({},)) # Cases when "*" used and there's not enough values total try: @@ -77,6 +50,7 @@ except TypeError: print("TypeError") print("%(foo)s" % {"foo": "bar", "baz": False}) +print("%s %(foo)s %(foo)s" % {"foo": 1}) try: print("%(foo)s" % {}) except KeyError: @@ -87,6 +61,16 @@ try: except TypeError: print("TypeError") +# When using %(foo)s format the single argument must be a dict +try: + '%(foo)s' % 1 +except TypeError: + print('TypeError') +try: + '%(foo)s' % ({},) +except TypeError: + print('TypeError') + try: '%(a' % {'a':1} except ValueError: diff --git a/tests/basics/string_format_modulo_int.py b/tests/basics/string_format_modulo_int.py new file mode 100644 index 000000000..d1f29db22 --- /dev/null +++ b/tests/basics/string_format_modulo_int.py @@ -0,0 +1,41 @@ +# test string modulo formatting with int values + +# basic cases +print("%d" % 10) +print("%+d" % 10) +print("% d" % 10) +print("%d" % -10) +print("%d" % True) +print("%i" % -10) +print("%i" % True) +print("%u" % -10) +print("%u" % True) +print("%x" % 18) +print("%o" % 18) +print("%X" % 18) +print("%#x" % 18) +print("%#X" % 18) +print("%#6o" % 18) +print("%#6x" % 18) +print("%#06x" % 18) + +# with * +print("%*d" % (5, 10)) +print("%*.*d" % (2, 2, 20)) +print("%*.*d" % (5, 8, 20)) + +# precision +for val in (-12, 12): + print(">%8.4d<" % val) + print(">% 8.4d<" % val) + print(">%+8.4d<" % val) + print(">%08.4d<" % val) + print(">%-8.4d<" % val) + print(">%-08.4d<" % val) + print(">%-+08.4d<" % val) + +# test + option with various amount of padding +for pad in ('', ' ', '0'): + for n in (1, 2, 3): + for val in (-1, 0, 1): + print(('%+' + pad + str(n) + 'd') % val) diff --git a/tests/basics/string_join.py b/tests/basics/string_join.py index b8694c01e..82f1b799a 100644 --- a/tests/basics/string_join.py +++ b/tests/basics/string_join.py @@ -14,6 +14,11 @@ print(','.join('abc' for i in range(5))) print(b','.join([b'abc', b'123'])) try: + ''.join(None) +except TypeError: + print("TypeError") + +try: print(b','.join(['abc', b'123'])) except TypeError: print("TypeError") @@ -25,3 +30,13 @@ except TypeError: # joined by the compiler print("a" "b") +print("a" '''b''') +print("a" # inline comment + "b") +print("a" \ + "b") + +# the following should not be joined by the compiler +x = 'a' +'b' +print(x) diff --git a/tests/basics/string_partition.py b/tests/basics/string_partition.py index b3b2f0907..bc36388fd 100644 --- a/tests/basics/string_partition.py +++ b/tests/basics/string_partition.py @@ -2,8 +2,7 @@ try: str.partition except AttributeError: print("SKIP") - import sys - sys.exit() + raise SystemExit print("asdf".partition('g')) print("asdf".partition('a')) diff --git a/tests/basics/string_rpartition.py b/tests/basics/string_rpartition.py index 84e0031fb..6d65dfaf2 100644 --- a/tests/basics/string_rpartition.py +++ b/tests/basics/string_rpartition.py @@ -2,8 +2,7 @@ try: str.partition except AttributeError: print("SKIP") - import sys - sys.exit() + raise SystemExit print("asdf".rpartition('g')) print("asdf".rpartition('a')) diff --git a/tests/basics/string_rsplit.py b/tests/basics/string_rsplit.py index 563b64f1c..b92b8f359 100644 --- a/tests/basics/string_rsplit.py +++ b/tests/basics/string_rsplit.py @@ -52,3 +52,7 @@ print("/*10/*11/*12/*".rsplit("/*", 4)) print("/*10/*11/*12/*".rsplit("/*", 5)) print(b"abcabc".rsplit(b"bc", 2)) + +# negative "maxsplit" should delegate to .split() +print('abaca'.rsplit('a', -1)) +print('abaca'.rsplit('a', -2)) diff --git a/tests/basics/string_splitlines.py b/tests/basics/string_splitlines.py index 1d08f6e6d..c4c3fcb80 100644 --- a/tests/basics/string_splitlines.py +++ b/tests/basics/string_splitlines.py @@ -3,9 +3,8 @@ try: str.splitlines except: - import sys print("SKIP") - sys.exit() + raise SystemExit # test \n as newline print("foo\nbar".splitlines()) diff --git a/tests/basics/struct1.py b/tests/basics/struct1.py index d89519a2f..a442beb1e 100644 --- a/tests/basics/struct1.py +++ b/tests/basics/struct1.py @@ -4,9 +4,8 @@ except: try: import struct except ImportError: - import sys print("SKIP") - sys.exit() + raise SystemExit print(struct.calcsize("<bI")) print(struct.unpack("<bI", b"\x80\0\0\x01\0")) @@ -37,34 +36,6 @@ s = struct.pack("BHBI", 10, 100, 200, 300) v = struct.unpack("BHBI", s) print(v == (10, 100, 200, 300)) -# check maximum pack on 32-bit machine -print(struct.pack("<I", 2**32 - 1)) -print(struct.pack("<I", 0xffffffff)) - -# long long ints -print(struct.pack("<Q", 2**64 - 1)) -print(struct.pack(">Q", 2**64 - 1)) -print(struct.pack("<Q", 0xffffffffffffffff)) -print(struct.pack(">Q", 0xffffffffffffffff)) -print(struct.pack("<q", -1)) -print(struct.pack(">q", -1)) -print(struct.pack("<Q", 1234567890123456789)) -print(struct.pack("<q", -1234567890123456789)) -print(struct.pack(">Q", 1234567890123456789)) -print(struct.pack(">q", -1234567890123456789)) -print(struct.unpack("<Q", b"\x12\x34\x56\x78\x90\x12\x34\x56")) -print(struct.unpack(">Q", b"\x12\x34\x56\x78\x90\x12\x34\x56")) -print(struct.unpack("<q", b"\x12\x34\x56\x78\x90\x12\x34\xf6")) -print(struct.unpack(">q", b"\xf2\x34\x56\x78\x90\x12\x34\x56")) - -# check maximum unpack -print(struct.unpack("<I", b"\xff\xff\xff\xff")) -print(struct.unpack("<Q", b"\xff\xff\xff\xff\xff\xff\xff\xff")) - -# check small int overflow -print(struct.unpack("<i", b'\xff\xff\xff\x7f')) -print(struct.unpack("<q", b'\xff\xff\xff\xff\xff\xff\xff\x7f')) - # network byte order print(struct.pack('!i', 123)) diff --git a/tests/basics/struct1_intbig.py b/tests/basics/struct1_intbig.py new file mode 100644 index 000000000..b1fec527e --- /dev/null +++ b/tests/basics/struct1_intbig.py @@ -0,0 +1,36 @@ +try: + import ustruct as struct +except: + try: + import struct + except ImportError: + print("SKIP") + raise SystemExit + +# check maximum pack on 32-bit machine +print(struct.pack("<I", 2**32 - 1)) +print(struct.pack("<I", 0xffffffff)) + +# long long ints +print(struct.pack("<Q", 2**64 - 1)) +print(struct.pack(">Q", 2**64 - 1)) +print(struct.pack("<Q", 0xffffffffffffffff)) +print(struct.pack(">Q", 0xffffffffffffffff)) +print(struct.pack("<q", -1)) +print(struct.pack(">q", -1)) +print(struct.pack("<Q", 1234567890123456789)) +print(struct.pack("<q", -1234567890123456789)) +print(struct.pack(">Q", 1234567890123456789)) +print(struct.pack(">q", -1234567890123456789)) +print(struct.unpack("<Q", b"\x12\x34\x56\x78\x90\x12\x34\x56")) +print(struct.unpack(">Q", b"\x12\x34\x56\x78\x90\x12\x34\x56")) +print(struct.unpack("<q", b"\x12\x34\x56\x78\x90\x12\x34\xf6")) +print(struct.unpack(">q", b"\xf2\x34\x56\x78\x90\x12\x34\x56")) + +# check maximum unpack +print(struct.unpack("<I", b"\xff\xff\xff\xff")) +print(struct.unpack("<Q", b"\xff\xff\xff\xff\xff\xff\xff\xff")) + +# check small int overflow +print(struct.unpack("<i", b'\xff\xff\xff\x7f')) +print(struct.unpack("<q", b'\xff\xff\xff\xff\xff\xff\xff\x7f')) diff --git a/tests/basics/struct2.py b/tests/basics/struct2.py index 6dd963260..d8234d0d3 100644 --- a/tests/basics/struct2.py +++ b/tests/basics/struct2.py @@ -6,9 +6,8 @@ except: try: import struct except ImportError: - import sys print("SKIP") - sys.exit() + raise SystemExit print(struct.calcsize('0s')) print(struct.unpack('0s', b'')) @@ -26,7 +25,17 @@ print(struct.calcsize('0s1s0H2H')) print(struct.unpack('<0s1s0H2H', b'01234')) print(struct.pack('<0s1s0H2H', b'abc', b'abc', 258, 515)) -# check that zero of an unknown type raises an exception +# check that unknown types raise an exception +try: + struct.unpack('z', b'1') +except: + print('Exception') + +try: + struct.pack('z', (b'1',)) +except: + print('Exception') + try: struct.calcsize('0z') except: diff --git a/tests/basics/struct_micropython.py b/tests/basics/struct_micropython.py index e3b0ea508..4b9dfe137 100644 --- a/tests/basics/struct_micropython.py +++ b/tests/basics/struct_micropython.py @@ -6,9 +6,8 @@ except: try: import struct except ImportError: - import sys print("SKIP") - sys.exit() + raise SystemExit class A(): pass @@ -18,3 +17,16 @@ o = A() s = struct.pack("<O", o) o2 = struct.unpack("<O", s) print(o is o2[0]) + +# pack and unpack pointer to a string +# This requires uctypes to get the address of the string and instead of +# putting this in a dedicated test that can be skipped we simply pass +# if the import fails. +try: + import uctypes + o = uctypes.addressof('abc') + s = struct.pack("<S", o) + o2 = struct.unpack("<S", s) + assert o2[0] == 'abc' +except ImportError: + pass diff --git a/tests/basics/subclass_classmethod.py b/tests/basics/subclass_classmethod.py index ae5fbd1aa..00a2ebd7c 100644 --- a/tests/basics/subclass_classmethod.py +++ b/tests/basics/subclass_classmethod.py @@ -5,6 +5,12 @@ class Base: def foo(cls): print(cls.__name__) +try: + Base.__name__ +except AttributeError: + print("SKIP") + raise SystemExit + class Sub(Base): pass diff --git a/tests/basics/syntaxerror.py b/tests/basics/syntaxerror.py index e5cbbac06..4161de017 100644 --- a/tests/basics/syntaxerror.py +++ b/tests/basics/syntaxerror.py @@ -46,9 +46,6 @@ test_syntax("f**2 = 1") # can't assign to power of composite test_syntax("f[0]**2 = 1") -# can't assign to empty tuple -test_syntax("() = 1") - # can't have *x on RHS test_syntax("x = *x") @@ -66,7 +63,6 @@ test_syntax("[a, b] += c") test_syntax("def f(a=1, b): pass") # can't delete these things -test_syntax("del ()") test_syntax("del f()") test_syntax("del f[0]**2") test_syntax("del (a for a in a)") diff --git a/tests/basics/sys1.py b/tests/basics/sys1.py index 702cf1aeb..da11c88d3 100644 --- a/tests/basics/sys1.py +++ b/tests/basics/sys1.py @@ -6,11 +6,21 @@ print(sys.__name__) print(type(sys.path)) print(type(sys.argv)) print(sys.byteorder in ('little', 'big')) -print(sys.maxsize > 100) -print(sys.implementation.name in ('cpython', 'micropython', 'circuitpython')) try: - sys.exit() + print(sys.maxsize > 100) +except AttributeError: + # Effectively skip subtests + print(True) + +try: + print(sys.implementation.name in ('cpython', 'micropython', 'circuitpython')) +except AttributeError: + # Effectively skip subtests + print(True) + +try: + raise SystemExit except SystemExit as e: print("SystemExit", e.args) diff --git a/tests/basics/try_finally_loops.py b/tests/basics/try_finally_loops.py index 06a6b4a0c..a4b80196f 100644 --- a/tests/basics/try_finally_loops.py +++ b/tests/basics/try_finally_loops.py @@ -41,3 +41,28 @@ for i in [1]: break finally: print('finally 4') + +# Test unwind-jump where there is nothing in the body of the try or finally. +# This checks that the bytecode emitter allocates enough stack for the unwind. +for i in [1]: + try: + break + finally: + pass + +# The following test checks that the globals dict is valid after a call to a +# function that has an unwind jump. +# There was a bug where an unwind jump would trash the globals dict upon return +# from a function, because it used the Python-stack incorrectly. +def f(): + for i in [1]: + try: + break + finally: + pass +def g(): + global global_var + f() + print(global_var) +global_var = 'global' +g() diff --git a/tests/basics/try_reraise2.py b/tests/basics/try_reraise2.py index d9434397c..5648d2467 100644 --- a/tests/basics/try_reraise2.py +++ b/tests/basics/try_reraise2.py @@ -1,4 +1,4 @@ -# Reraise not the latest occured exception +# Reraise not the latest occurred exception def f(): try: raise ValueError("val", 3) diff --git a/tests/basics/tuple1.py b/tests/basics/tuple1.py index 2993391d5..a7956c107 100644 --- a/tests/basics/tuple1.py +++ b/tests/basics/tuple1.py @@ -17,6 +17,10 @@ print(x[2:3]) print(x + (10, 100, 10000)) +# inplace add operator +x += (10, 11, 12) +print(x) + # construction of tuple from large iterator (tests implementation detail of uPy) print(tuple(range(20))) diff --git a/tests/basics/unpack1.py b/tests/basics/unpack1.py index 0e8ec592c..1e8b53aa1 100644 --- a/tests/basics/unpack1.py +++ b/tests/basics/unpack1.py @@ -41,7 +41,7 @@ a, *b, c = 24, 25, 26, 27 ; print(a, b) a = [28, 29] *b, = a -print(a, b, a == b) +print(a, b, a == b, a is b) [*a] = [1, 2, 3] print(a) diff --git a/tests/basics/zip.py b/tests/basics/zip.py index c0109094f..66f2544e5 100644 --- a/tests/basics/zip.py +++ b/tests/basics/zip.py @@ -1,2 +1,9 @@ +try: + zip + set +except NameError: + print("SKIP") + raise SystemExit + print(list(zip())) -print(list(zip([1], {2,3}))) +print(list(zip([1], set([2, 3])))) |
