Commit Graph

715 Commits

Author SHA1 Message Date
Damien George
22ade2f5c4 py/vm: Fix case of handling raised StopIteration within yield from.
This patch concerns the handling of an NLR-raised StopIteration, raised
during a call to mp_resume() which is handling the yield from opcode.

Previously, commit 6738c1dded introduced code
to handle this case, along with a test.  It seems that it was lucky that
the test worked because the code did not correctly handle the stack pointer
(sp).

Furthermore, commit 79d996a57b improved the
way mp_resume() propagated certain exceptions: it changed raising an NLR
value to returning MP_VM_RETURN_EXCEPTION.  This change meant that the
test introduced in gen_yield_from_ducktype.py was no longer hitting the
code introduced in 6738c1dded.

The patch here does two things:

1. Fixes the handling of sp in the VM for the case that yield from is
   interrupted by a StopIteration raised via NLR.

2. Introduces a new test to check this handling of sp and re-covers the
   code in the VM.
2018-02-27 15:39:31 +11:00
Damien George
90da791a08 tests/basics: Add test for calling a subclass of a native class.
Adding this test gets py/objtype.c to 100% coverage.
2018-02-24 23:13:42 +11:00
Damien George
160d670868 py/objdeque: Protect against negative maxlen in deque constructor.
Otherwise passing -1 as maxlen will lead to a zero allocation and
subsequent unbound buffer overflow in deque.append() because i_put is
allowed to grow without bound.
2018-02-21 23:34:17 +11:00
Damien George
8f9b113be2 tests/basics: Add tests to improve coverage of py/objdeque.c. 2018-02-21 23:19:06 +11:00
Paul Sokolovsky
4668ec801e tests/basics/deque*: Tests for ucollections.deque. 2018-02-21 22:58:14 +11:00
Damien George
4e469085c1 py/objstr: Protect against creating bytes(n) with n negative.
Prior to this patch uPy (on a 32-bit arch) would have severe issues when
calling bytes(-1): such a call would call vstr_init_len(vstr, -1) which
would then +1 on the len and call vstr_init(vstr, 0), which would then
round this up and allocate a small amount of memory for the vstr.  The
bytes constructor would then attempt to zero out all this memory, thinking
it had allocated 2^32-1 bytes.
2018-02-19 16:25:30 +11:00
Damien George
98647e83c7 py/modbuiltins: Simplify and generalise dir() by probing qstrs.
This patch improves the builtin dir() function by probing the target object
with all possible qstrs via mp_load_method_maybe.  This is very simple (in
terms of implementation), doesn't require recursion, and allows to list all
methods of user-defined classes (without duplicates) even if they have
multiple inheritance with a common parent.  The downside is that it can be
slow because it has to iterate through all the qstrs in the system, but
the "dir()" function is anyway mostly used for testing frameworks and user
introspection of types, so speed is not considered a priority.

In addition to providing a more complete implementation of dir(), this
patch is simpler than the previous implementation and saves some code
space:

   bare-arm:   -80
minimal x86:   -80
   unix x64:   -56
unix nanbox:   -48
      stm32:   -80
     cc3200:   -80
    esp8266:  -104
      esp32:   -64
2018-02-19 16:12:44 +11:00
Mike Wadsten
a3e01d3642 py/objdict: Disallow possible modifications to fixed dicts. 2018-02-18 21:51:04 -06:00
Damien George
d77da83d55 py/objrange: Implement (in)equality comparison between range objects.
This feature is not often used so is guarded by the config option
MICROPY_PY_BUILTINS_RANGE_BINOP which is disabled by default.  With this
option disabled MicroPython will always return false when comparing two
range objects for equality (unless they are exactly the same object
instance).  This does not match CPython so if (in)equality between range
objects is needed then this option should be enabled.

Enabling this option costs between 100 and 200 bytes of code space
depending on the machine architecture.
2018-02-14 23:17:06 +11:00
Damien George
04c55f5828 tests: Rewrite some tests so they can run without needing eval/exec.
For builds without the compiler enabled (and hence without eval/exec) it is
useful to still be able to run as many tests as possible.
2018-02-14 16:50:20 +11:00
Damien George
6031957473 tests: Automatically skip tests that require eval, exec or frozenset. 2018-02-14 16:46:44 +11:00
Damien George
1f53ff61ff tests/basics: Rename remaining tests that are for built-in functions.
For consistency with all of the other tests that are named builtin_XXX.py.
2018-02-07 15:55:52 +11:00
Damien George
b45c8c17f0 py/objtype: Check and prevent delete/store on a fixed locals map.
Note that the check for elem!=NULL is removed for the
MP_MAP_LOOKUP_ADD_IF_NOT_FOUND case because mp_map_lookup will always
return non-NULL for such a case.
2018-02-07 15:44:29 +11:00
Damien George
a1d85d6199 tests/basics/memoryerror: Add test for out-of-memory using realloc. 2017-12-20 16:58:27 +11:00
Damien George
35a759dc1d tests: Add some more tests to improve coverage of py/parse.c. 2017-12-19 16:13:00 +11:00
Damien George
2bfa531798 tests/basics/builtin_pow3: Add tests for edge cases of pow3. 2017-12-19 15:44:10 +11:00
Damien George
8e6113a188 tests/basics/generator_pend_throw: Add test for just-started generator. 2017-12-19 15:02:34 +11:00
Damien George
7208cad97a tests/basics: Add more set tests to improve coverage of py/objset.c. 2017-12-19 13:59:54 +11:00
Paul Sokolovsky
6364401666 py/objgenerator: Allow to pend an exception for next execution.
This implements .pend_throw(exc) method, which sets up an exception to be
triggered on the next call to generator's .__next__() or .send() method.
This is unlike .throw(), which immediately starts to execute the generator
to process the exception. This effectively adds Future-like capabilities
to generator protocol (exception will be raised in the future).

The need for such a method arised to implement uasyncio wait_for() function
efficiently (its behavior is clearly "Future" like, and normally would
require to introduce an expensive Future wrapper around all native
couroutines, like upstream asyncio does).

py/objgenerator: pend_throw: Return previous pended value.

This effectively allows to store an additional value (not necessary an
exception) in a coroutine while it's not being executed. uasyncio has
exactly this usecase: to mark a coro waiting in I/O queue (and thus
not executed in the normal scheduling queue), for the purpose of
implementing wait_for() function (cancellation of such waiting coro
by a timeout).
2017-12-15 20:20:36 +02:00
Damien George
36f79523ab tests: Add tests to improve coverage of py/objtype.c. 2017-12-14 12:25:30 +11:00
Paul Sokolovsky
da34b6ef45 tests: Fix few test for proper "skipped" detection with qemu-arm's tinytest.
"Builtin" tinytest-based testsuite as employed by qemu-arm (and now
generalized by me to be reusable for other targets) performs simplified
detection of skipped tests, it treats as such tests which raised SystemExit
(instead of checking got "SKIP" output). Consequently, each "SKIP" must
be accompanied by SystemExit (and conversely, SystemExit should not be
used if test is not skipped, which so far seems to be true).
2017-12-12 23:45:48 +02:00
Damien George
fd0b0db873 tests/basics: Add test for overriding a native base-class's init method. 2017-12-12 16:47:38 +11:00
Damien George
c3bc8d7b2b tests/basics/builtin_locals: Add test for using locals() in class body. 2017-11-27 14:14:57 +11:00
Damien George
c7a0e1472d tests/basics/builtin_range: Add test for corner case of range slicing. 2017-11-24 15:30:12 +11:00
Damien George
505671b698 tests/basics: Add test for containment of a subclass of a native type. 2017-11-24 14:48:41 +11:00
stijn
79ed58f87b py/objnamedtuple: Add _asdict function if OrderedDict is supported 2017-11-12 14:16:54 +02:00
Damien George
dfa563c71f py/objstr: Make empty bytes object have a null-terminating byte.
Because a lot of string processing functions assume there is a null
terminating byte, so they can work in an efficient way.

Fixes issue #3334.
2017-10-04 17:59:22 +11:00
Damien George
1394258f37 py/objset: Include the failed key in a KeyError raised from set.remove. 2017-10-03 18:03:06 +11:00
Damien George
2ac1364688 py/objset: Check that RHS of a binary op is a set/frozenset.
CPython docs explicitly state that the RHS of a set/frozenset binary op
must be a set to prevent user errors.  It also preserves commutativity of
the ops, eg: "abc" & set() is a TypeError, and so should be set() & "abc".

This change actually decreases unix (x64) code by 160 bytes; it increases
stm32 by 4 bytes and esp8266 by 28 bytes (but previous patch already
introduced a much large saving).
2017-10-03 17:56:27 +11:00
Paul Sokolovsky
fc9a6dd09e py/objstr: strip: Don't strip "\0" by default.
An issue was due to incorrectly taking size of default strip characters
set.
2017-09-19 21:21:12 +03:00
Paul Sokolovsky
d6f9d64d97 tests/class_reverse_op: Test for reverse arith ops special methods.
This test should be run only if support for reverse ops is enabled, so
the corresponding feature_check is added to run-tests.
2017-09-10 17:05:57 +03:00
Paul Sokolovsky
5c603bd0fd py/objlist: Properly implement comparison with incompatible types.
Should raise TypeError, unless it's (in)equality comparison.
2017-09-07 00:10:10 +03:00
Paul Sokolovsky
1aaba5cabe py/objtuple: Properly implement comparison with incompatible types.
Should raise TypeError, unless it's (in)equality comparison.
2017-09-06 00:23:41 +03:00
Paul Sokolovsky
376618cd8a tests/class_inplace_op: Test for inplace op fallback to normal one. 2017-09-04 16:44:38 +03:00
Damien George
2daacc5cee py/modstruct: Check and prevent buffer-write overflow in struct packing.
Prior to this patch, the size of the buffer given to pack_into() was checked
for being too small by using the count of the arguments, not their actual
size.  For example, a format spec of '4I' would only check that there was 4
bytes available, not 16; and 'I' would check for 1 byte, not 4.

The pack() function is ok because its buffer is created to be exactly the
correct size.

The fix in this patch calculates the total size of the format spec at the
start of pack_into() and verifies that the buffer is large enough.  This
adds some computational overhead, to iterate through the whole format spec.
The alternative is to check during the packing, but that requires extra
code to handle alignment, and the check is anyway not needed for pack().
So to maintain minimal code size the check is done using struct_calcsize.
2017-09-01 11:11:09 +10:00
Damien George
79d5acbd01 py/modstruct: Check and prevent buffer-read overflow in struct unpacking
Prior to this patch, the size of the buffer given to unpack/unpack_from was
checked for being too small by using the count of the arguments, not their
actual size.  For example, a format spec of '4I' would only check that
there was 4 bytes available, not 16; and 'I' would check for 1 byte, not 4.

This bug is fixed in this patch by calculating the total size of the format
spec at the start of the unpacking function.  This function anyway needs to
calculate the number of items at the start, so calculating the total size
can be done at the same time.
2017-09-01 10:53:29 +10:00
Damien George
793d826d9d py/modstruct: In struct.pack, stop converting if there are no args left.
This patch makes a repeat counter behave the same as repeating the
typecode, when there are not enough args.  For example:
struct.pack('2I', 1) now behave the same as struct.pack('II', 1).
2017-09-01 10:10:51 +10:00
Paul Sokolovsky
b349479a49 tests/class_new: Add another testcase for __new__/__init__ interaction.
Similar to the existing testcase, but test that returning both value of
native type and instance of another user class from __new__ lead to
__init__ not being called, for better coverage.
2017-09-01 00:43:52 +03:00
Paul Sokolovsky
35be9e805f tests/class_new: Add checks for __init__ being called and other improvements. 2017-08-30 21:33:42 +03:00
Paul Sokolovsky
b565c36963 tests/object_new: Better messages, check user __new__() method.
Make messages more verbose and easier to follow and check that user class'
__new__() is not called by object.__new__(user_class).
2017-08-30 21:29:23 +03:00
Paul Sokolovsky
784909ce16 py/objtype: Handle NotImplemented return from binary special methods.
NotImplemented means "try other fallbacks (like calling __rop__
instead of __op__) and if nothing works, raise TypeError". As
MicroPython doesn't implement any fallbacks, signal to raise
TypeError right away.
2017-08-30 01:39:24 +03:00
Paul Sokolovsky
37379a2974 py/objstr: startswith, endswith: Check arg to be a string.
Otherwise, it will silently get incorrect result on other values types,
including CPython tuple form like "foo.png".endswith(("png", "jpg"))
(which MicroPython doesn't support for unbloatedness).
2017-08-29 00:06:21 +03:00
Damien George
025e5f2b33 py/binary: Change internal bytearray typecode from 0 to 1.
The value of 0 can't be used because otherwise mp_binary_get_size will let
a null byte through as the type code (intepreted as byterray).  This can
lead to invalid type-specifier strings being let through without an error
in the struct module, and even buffer overruns.
2017-08-17 16:19:35 +10:00
Bas van Sisseren
a14ce77b28 py/binary.c: Fix bug when packing big-endian 'Q' values.
Without bugfix:

    struct.pack('>Q', 16)
    b'\x00\x00\x00\x10\x00\x00\x00\x00'

With bugfix:

    struct.pack('>Q', 16)
    b'\x00\x00\x00\x00\x00\x00\x00\x10'
2017-08-15 11:33:43 +10:00
Damien George
3d25d9c7d9 py/objstr: Raise an exception for wrong type on RHS of str binary op.
The main case to catch is invalid types for the containment operator, of
the form str.__contains__(non-str).
2017-08-09 21:25:48 +10:00
Damien George
eb2784e8a2 py/objtuple: Allow to use inplace-multiplication operator on tuples. 2017-08-09 21:20:42 +10:00
Alexander Steffen
55f33240f3 all: Use the name MicroPython consistently in comments
There were several different spellings of MicroPython present in comments,
when there should be only one.
2017-07-31 18:35:40 +10:00
Tom Collins
6cfe737597 tests/basics/builtin_exec: Test various globals/locals args to exec(). 2017-07-21 15:17:33 +10:00
Damien George
6c1b7e008d tests: Rename exec1.py to builtin_exec.py. 2017-07-21 15:11:24 +10:00
Damien George
f69ab79ec8 py/objgenerator: Allow to hash generators and generator instances.
Adds nothing to the code size, since it uses existing empty slots in the
type structures.
2017-07-07 11:47:38 +10:00