From 4614403f63cad9f5eac09046a70e332b29584c9c Mon Sep 17 00:00:00 2001 From: Paul Sokolovsky Date: Fri, 27 Jan 2017 01:19:36 +0300 Subject: tools/tinytest-codegen.py: Blacklist heapalloc_str.py test for qemu-arm. --- tools/tinytest-codegen.py | 1 + 1 file changed, 1 insertion(+) (limited to 'tools') diff --git a/tools/tinytest-codegen.py b/tools/tinytest-codegen.py index 3436d0f45..4c245e85e 100755 --- a/tools/tinytest-codegen.py +++ b/tools/tinytest-codegen.py @@ -49,6 +49,7 @@ testgroup_member = ( test_dirs = ('basics', 'micropython', 'float', 'extmod', 'inlineasm') # 'import', 'io', 'misc') exclude_tests = ( 'float/float2int_doubleprec.py', # requires double precision floating point to work + 'micropython/heapalloc_str.py', # unknown 'inlineasm/asmfpaddsub.py', 'inlineasm/asmfpcmp.py', 'inlineasm/asmfpldrstr.py', 'inlineasm/asmfpmuldiv.py', 'inlineasm/asmfpsqrt.py', 'extmod/ticks_diff.py', 'extmod/time_ms_us.py', 'extmod/uheapq_timeq.py', 'extmod/machine_pinbase.py', 'extmod/machine_pulse.py', -- cgit v1.2.3 From f1db8a3097f74aa5499c95a2625bd0bfa285579a Mon Sep 17 00:00:00 2001 From: Damien George Date: Fri, 27 Jan 2017 12:35:46 +1100 Subject: qemu-arm: Don't compile tests in "REPL" mode. Previous to this patch the qemu-arm tests were compiled with is_relp=true meaning that the __repl_print__ function was called for all lines of code in the outer scope. This is not the right behaviour for scripts that are executed as though they were a file (eg tests). With this fix the micropython/heapalloc_str.py test now works so it is removed from the test blacklist. --- qemu-arm/test_main.c | 2 +- tools/tinytest-codegen.py | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) (limited to 'tools') diff --git a/qemu-arm/test_main.c b/qemu-arm/test_main.c index ae2beabcd..5c0c915c4 100644 --- a/qemu-arm/test_main.c +++ b/qemu-arm/test_main.c @@ -32,7 +32,7 @@ inline void do_str(const char *src) { if (nlr_push(&nlr) == 0) { qstr source_name = lex->source_name; mp_parse_tree_t parse_tree = mp_parse(lex, MP_PARSE_FILE_INPUT); - mp_obj_t module_fun = mp_compile(&parse_tree, source_name, MP_EMIT_OPT_NONE, true); + mp_obj_t module_fun = mp_compile(&parse_tree, source_name, MP_EMIT_OPT_NONE, false); mp_call_function_0(module_fun); nlr_pop(); } else { diff --git a/tools/tinytest-codegen.py b/tools/tinytest-codegen.py index 4c245e85e..3436d0f45 100755 --- a/tools/tinytest-codegen.py +++ b/tools/tinytest-codegen.py @@ -49,7 +49,6 @@ testgroup_member = ( test_dirs = ('basics', 'micropython', 'float', 'extmod', 'inlineasm') # 'import', 'io', 'misc') exclude_tests = ( 'float/float2int_doubleprec.py', # requires double precision floating point to work - 'micropython/heapalloc_str.py', # unknown 'inlineasm/asmfpaddsub.py', 'inlineasm/asmfpcmp.py', 'inlineasm/asmfpldrstr.py', 'inlineasm/asmfpmuldiv.py', 'inlineasm/asmfpsqrt.py', 'extmod/ticks_diff.py', 'extmod/time_ms_us.py', 'extmod/uheapq_timeq.py', 'extmod/machine_pinbase.py', 'extmod/machine_pulse.py', -- cgit v1.2.3 From aac2db9aafbaaa7cea82be5683b69833859200f5 Mon Sep 17 00:00:00 2001 From: Paul Sokolovsky Date: Fri, 10 Feb 2017 20:18:05 +0300 Subject: tools/upip: Update to 1.1.5. Better and more user-friendly error handling. --- tools/upip.py | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) (limited to 'tools') diff --git a/tools/upip.py b/tools/upip.py index db18a7427..0070fd619 100644 --- a/tools/upip.py +++ b/tools/upip.py @@ -105,7 +105,10 @@ warn_ussl = True def url_open(url): global warn_ussl proto, _, host, urlpath = url.split('/', 3) - ai = usocket.getaddrinfo(host, 443) + try: + ai = usocket.getaddrinfo(host, 443) + except OSError as e: + fatal("Unable to resolve %s (no Internet?)" % host, e) #print("Address infos:", ai) addr = ai[0][4] @@ -124,13 +127,16 @@ def url_open(url): l = s.readline() protover, status, msg = l.split(None, 2) if status != b"200": + s.close() + exc = ValueError(status) if status == b"404": - print("Package not found") - raise ValueError(status) + fatal("Package not found", exc) + fatal("Unexpected error querying for package", exc) while 1: l = s.readline() if not l: - raise ValueError("Unexpected EOF") + s.close() + fatal("Unexpected EOF in HTTP headers", ValueError()) if l == b'\r\n': break @@ -144,8 +150,10 @@ def get_pkg_metadata(name): return json.loads(s) -def fatal(msg): - print(msg) +def fatal(msg, exc=None): + print("Error:", msg) + if exc and debug: + raise exc sys.exit(1) def install_pkg(pkg_spec, install_path): -- cgit v1.2.3 From 6a11048af1d01c78bdacddadd1b72dc7ba7c6478 Mon Sep 17 00:00:00 2001 From: Damien George Date: Fri, 17 Feb 2017 00:19:34 +1100 Subject: py/persistentcode: Bump .mpy version due to change in bytecode. --- py/persistentcode.c | 13 ++++++++----- tools/mpy-tool.py | 5 +++-- 2 files changed, 11 insertions(+), 7 deletions(-) (limited to 'tools') diff --git a/py/persistentcode.c b/py/persistentcode.c index 07395b304..5cb511709 100644 --- a/py/persistentcode.c +++ b/py/persistentcode.c @@ -38,6 +38,9 @@ #include "py/smallint.h" +// The current version of .mpy files +#define MPY_VERSION (1) + // The feature flags byte encodes the compile-time config options that // affect the generate bytecode. #define MPY_FEATURE_FLAGS ( \ @@ -209,10 +212,10 @@ STATIC mp_raw_code_t *load_raw_code(mp_reader_t *reader) { mp_raw_code_t *mp_raw_code_load(mp_reader_t *reader) { byte header[4]; read_bytes(reader, header, sizeof(header)); - if (strncmp((char*)header, "M\x00", 2) != 0) { - mp_raise_ValueError("invalid .mpy file"); - } - if (header[2] != MPY_FEATURE_FLAGS || header[3] > mp_small_int_bits()) { + if (header[0] != 'M' + || header[1] != MPY_VERSION + || header[2] != MPY_FEATURE_FLAGS + || header[3] > mp_small_int_bits()) { mp_raise_ValueError("incompatible .mpy file"); } mp_raw_code_t *rc = load_raw_code(reader); @@ -359,7 +362,7 @@ void mp_raw_code_save(mp_raw_code_t *rc, mp_print_t *print) { // byte version // byte feature flags // byte number of bits in a small int - byte header[4] = {'M', 0, MPY_FEATURE_FLAGS_DYNAMIC, + byte header[4] = {'M', MPY_VERSION, MPY_FEATURE_FLAGS_DYNAMIC, #if MICROPY_DYNAMIC_COMPILER mp_dynamic_compiler.small_int_bits, #else diff --git a/tools/mpy-tool.py b/tools/mpy-tool.py index ce373a4f5..d14e0f4ea 100755 --- a/tools/mpy-tool.py +++ b/tools/mpy-tool.py @@ -57,6 +57,7 @@ class FreezeError(Exception): return 'error while freezing %s: %s' % (self.rawcode.source_file, self.msg) class Config: + MPY_VERSION = 1 MICROPY_LONGINT_IMPL_NONE = 0 MICROPY_LONGINT_IMPL_LONGLONG = 1 MICROPY_LONGINT_IMPL_MPZ = 2 @@ -438,8 +439,8 @@ def read_mpy(filename): header = bytes_cons(f.read(4)) if header[0] != ord('M'): raise Exception('not a valid .mpy file') - if header[1] != 0: - raise Exception('incompatible version') + if header[1] != config.MPY_VERSION: + raise Exception('incompatible .mpy version') feature_flags = header[2] config.MICROPY_OPT_CACHE_MAP_LOOKUP_IN_BYTECODE = (feature_flags & 1) != 0 config.MICROPY_PY_BUILTINS_STR_UNICODE = (feature_flags & 2) != 0 -- cgit v1.2.3 From b7fa63c7ced460fd2d3aceb35257a62ff08831c1 Mon Sep 17 00:00:00 2001 From: Rami Ali Date: Tue, 7 Feb 2017 16:43:41 +1100 Subject: tools: Add gen-cpydiff.py to generate docs differences. This patch introduces the a small framework to track differences between uPy and CPython. The framework consists of: - A set of "tests" which test for an individual feature that differs between uPy and CPy. Each test is like a normal uPy test in the test suite, but has a special comment at the start with some meta-data: a category (eg syntax, core language), a human-readable description of the difference, a cause, and a workaround. Following the meta-data there is a short code snippet which demonstrates the difference. See tests/cpydiff directory for the initial set of tests. - A program (this patch) which runs all the tests (on uPy and CPy) and generates nicely-formated .rst documenting the differences. - Integration into the docs build so that everything is automatic, and the differences appear in a way that is easy for users to read/reference (see latter commits). The idea with using this new framework is: - When a new difference is found it's easy to write a short test for it, along with a description, and add it to the existing ones. It's also easy for contributors to submit tests for differences they find. - When something is no longer different the tool will give an error and difference can be removed (or promoted to a proper feature test). --- docs/differences/index_template.txt | 8 ++ tools/gen-cpydiff.py | 213 ++++++++++++++++++++++++++++++++++++ 2 files changed, 221 insertions(+) create mode 100644 docs/differences/index_template.txt create mode 100644 tools/gen-cpydiff.py (limited to 'tools') diff --git a/docs/differences/index_template.txt b/docs/differences/index_template.txt new file mode 100644 index 000000000..6ade2c2da --- /dev/null +++ b/docs/differences/index_template.txt @@ -0,0 +1,8 @@ +MicroPython Differences from CPython +==================================== + +The operations listed in this section produce conflicting results in MicroPython when compared to standard Python. + +.. toctree:: + :maxdepth: 2 + diff --git a/tools/gen-cpydiff.py b/tools/gen-cpydiff.py new file mode 100644 index 000000000..6f83bb6e8 --- /dev/null +++ b/tools/gen-cpydiff.py @@ -0,0 +1,213 @@ +# This file is part of the MicroPython project, http://micropython.org/ +# +# The MIT License (MIT) +# +# Copyright (c) 2016 Rami Ali +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +""" gen-cpydiff generates documentation which outlines operations that differ between MicroPython + and CPython. This script is called by the docs Makefile for html and Latex and may be run + manually using the command make gen-cpydiff. """ + +import os +import errno +import subprocess +import time +import re +from collections import namedtuple + +TESTPATH = '../tests/cpydiff/' +UPYPATH = '../unix/micropython' +DOCPATH = '../docs/genrst/' +INDEXTEMPLATE = '../docs/differences/index_template.txt' +INDEX = 'index.rst' + +HEADER = '.. This document was generated by tools/gen-cpydiff.py\n\n' +UIMPORTLIST = {'struct', 'collections', 'json'} +CLASSMAP = {'Core': 'Core Language', 'Types': 'Builtin Types'} +INDEXPRIORITY = ['syntax', 'core_language', 'builtin_types', 'modules'] +RSTCHARS = ['=', '-', '~', '`', ':'] +SPLIT = '"""\n|categories: |description: |cause: |workaround: ' +TAB = ' ' + +Output = namedtuple('output', ['name', 'class_', 'desc', 'cause', 'workaround', 'code', + 'output_cpy', 'output_upy', 'status']) + +def readfiles(): + """ Reads test files """ + tests = list(filter(lambda x: x.endswith('.py'), os.listdir(TESTPATH))) + tests.sort() + files = [] + + for test in tests: + text = open(TESTPATH + test, 'r').read() + + try: + class_, desc, cause, workaround, code = [x.rstrip() for x in \ + list(filter(None, re.split(SPLIT, text)))] + output = Output(test, class_, desc, cause, workaround, code, '', '', '') + files.append(output) + except IndexError: + print('Incorrect format in file ' + TESTPATH + test) + + return files + +def uimports(code): + """ converts CPython module names into MicroPython equivalents """ + for uimport in UIMPORTLIST: + uimport = bytes(uimport, 'utf8') + code = code.replace(uimport, b'u' + uimport) + return code + +def run_tests(tests): + """ executes all tests """ + results = [] + for test in tests: + with open(TESTPATH + test.name, 'rb') as f: + input_cpy = f.read() + input_upy = uimports(input_cpy) + + process = subprocess.Popen('python', shell=True, stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE) + output_cpy = [com.decode('utf8') for com in process.communicate(input_cpy)] + + process = subprocess.Popen(UPYPATH, shell=True, stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE) + output_upy = [com.decode('utf8') for com in process.communicate(input_upy)] + + if output_cpy[0] == output_upy[0] and output_cpy[1] == output_upy[1]: + status = 'Supported' + print('Supported operation!\nFile: ' + TESTPATH + test.name) + else: + status = 'Unsupported' + + output = Output(test.name, test.class_, test.desc, test.cause, + test.workaround, test.code, output_cpy, output_upy, status) + results.append(output) + + results.sort(key=lambda x: x.class_) + return results + +def indent(block, spaces): + """ indents paragraphs of text for rst formatting """ + new_block = '' + for line in block.split('\n'): + new_block += spaces + line + '\n' + return new_block + +def gen_table(contents): + """ creates a table given any set of columns """ + xlengths = [] + ylengths = [] + for column in contents: + col_len = 0 + for entry in column: + lines = entry.split('\n') + for line in lines: + col_len = max(len(line) + 2, col_len) + xlengths.append(col_len) + for i in range(len(contents[0])): + ymax = 0 + for j in range(len(contents)): + ymax = max(ymax, len(contents[j][i].split('\n'))) + ylengths.append(ymax) + + table_divider = '+' + ''.join(['-' * i + '+' for i in xlengths]) + '\n' + table = table_divider + for i in range(len(ylengths)): + row = [column[i] for column in contents] + row = [entry + '\n' * (ylengths[i]-len(entry.split('\n'))) for entry in row] + row = [entry.split('\n') for entry in row] + for j in range(ylengths[i]): + k = 0 + for entry in row: + width = xlengths[k] + table += ''.join(['| {:{}}'.format(entry[j], width - 1)]) + k += 1 + table += '|\n' + table += table_divider + return table + '\n' + +def gen_rst(results): + """ creates restructured text documents to display tests """ + + # make sure the destination directory exists + try: + os.mkdir(DOCPATH) + except OSError as e: + if e.args[0] != errno.EEXIST and e.args[0] != errno.EISDIR: + raise + + toctree = [] + class_ = [] + for output in results: + section = output.class_.split(',') + for i in range(len(section)): + section[i] = section[i].rstrip() + if section[i] in CLASSMAP: + section[i] = CLASSMAP[section[i]] + if i >= len(class_) or section[i] != class_[i]: + if i == 0: + filename = section[i].replace(' ', '_').lower() + rst = open(DOCPATH + filename + '.rst', 'w') + rst.write(HEADER) + rst.write(section[i] + '\n') + rst.write(RSTCHARS[0] * len(section[i])) + rst.write(time.strftime("\nGenerated %a %d %b %Y %X UTC\n\n", time.gmtime())) + toctree.append(filename) + else: + rst.write(section[i] + '\n') + rst.write(RSTCHARS[min(i, len(RSTCHARS)-1)] * len(section[i])) + rst.write('\n\n') + class_ = section + rst.write('**' + output.desc + '**\n\n') + if output.cause != 'Unknown': + rst.write('**Cause:** ' + output.cause + '\n\n') + if output.workaround != 'Unknown': + rst.write('**Workaround:** ' + output.workaround + '\n\n') + + rst.write('Sample code::\n\n' + indent(output.code, TAB) + '\n') + output_cpy = indent(''.join(output.output_cpy[0:2]), TAB).rstrip() + output_cpy = ('::\n\n' if output_cpy != '' else '') + output_cpy + output_upy = indent(''.join(output.output_upy[0:2]), TAB).rstrip() + output_upy = ('::\n\n' if output_upy != '' else '') + output_upy + table = gen_table([['CPy output:', output_cpy], ['uPy output:', output_upy]]) + rst.write(table) + + template = open(INDEXTEMPLATE, 'r') + index = open(DOCPATH + INDEX, 'w') + index.write(HEADER) + index.write(template.read()) + for section in INDEXPRIORITY: + if section in toctree: + index.write(indent(section + '.rst', TAB)) + toctree.remove(section) + for section in toctree: + index.write(indent(section + '.rst', TAB)) + +def main(): + """ Main function """ + + # clear search path to make sure tests use only builtin modules + os.environ['MICROPYPATH'] = '' + + files = readfiles() + results = run_tests(files) + gen_rst(results) + +main() -- cgit v1.2.3 From 1034d9acc84317b21b953d3e9fd6ad5519d1c570 Mon Sep 17 00:00:00 2001 From: Damien George Date: Wed, 22 Feb 2017 15:50:58 +1100 Subject: tools/gen-cpydiff.py: Set the Python import path to find test modules. --- tools/gen-cpydiff.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/gen-cpydiff.py b/tools/gen-cpydiff.py index 6f83bb6e8..93c8e3719 100644 --- a/tools/gen-cpydiff.py +++ b/tools/gen-cpydiff.py @@ -203,8 +203,9 @@ def gen_rst(results): def main(): """ Main function """ - # clear search path to make sure tests use only builtin modules - os.environ['MICROPYPATH'] = '' + # set search path so that test scripts find the test modules (and no other ones) + os.environ['PYTHONPATH'] = TESTPATH + os.environ['MICROPYPATH'] = TESTPATH files = readfiles() results = run_tests(files) -- cgit v1.2.3 From 23ccb3e12e3b7fe6b56785d1e17e9d990d1da86c Mon Sep 17 00:00:00 2001 From: Krzysztof Blazewicz Date: Sat, 25 Feb 2017 13:53:56 +0100 Subject: tools/gen-cpydiff.py: configurable CPython and micropython executables --- tools/gen-cpydiff.py | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) (limited to 'tools') diff --git a/tools/gen-cpydiff.py b/tools/gen-cpydiff.py index 93c8e3719..4b273d97f 100644 --- a/tools/gen-cpydiff.py +++ b/tools/gen-cpydiff.py @@ -33,8 +33,18 @@ import time import re from collections import namedtuple +# Micropython supports syntax of CPython 3.4 with some features from 3.5, and +# such version should be used to test for differences. If your default python3 +# executable is of lower version, you can point MICROPY_CPYTHON3 environment var +# to the correct executable. +if os.name == 'nt': + CPYTHON3 = os.getenv('MICROPY_CPYTHON3', 'python3.exe') + MICROPYTHON = os.getenv('MICROPY_MICROPYTHON', '../windows/micropython.exe') +else: + CPYTHON3 = os.getenv('MICROPY_CPYTHON3', 'python3') + MICROPYTHON = os.getenv('MICROPY_MICROPYTHON', '../unix/micropython') + TESTPATH = '../tests/cpydiff/' -UPYPATH = '../unix/micropython' DOCPATH = '../docs/genrst/' INDEXTEMPLATE = '../docs/differences/index_template.txt' INDEX = 'index.rst' @@ -84,10 +94,10 @@ def run_tests(tests): input_cpy = f.read() input_upy = uimports(input_cpy) - process = subprocess.Popen('python', shell=True, stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE) + process = subprocess.Popen(CPYTHON3, shell=True, stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE) output_cpy = [com.decode('utf8') for com in process.communicate(input_cpy)] - process = subprocess.Popen(UPYPATH, shell=True, stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE) + process = subprocess.Popen(MICROPYTHON, shell=True, stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE) output_upy = [com.decode('utf8') for com in process.communicate(input_upy)] if output_cpy[0] == output_upy[0] and output_cpy[1] == output_upy[1]: -- cgit v1.2.3 From e4be56a0ea20df9252fbe35b55823594681cff72 Mon Sep 17 00:00:00 2001 From: Damien George Date: Thu, 2 Mar 2017 16:39:58 +1100 Subject: qemu-arm: Enable machine module and associated tests. --- qemu-arm/Makefile | 2 ++ qemu-arm/modmachine.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++ qemu-arm/mpconfigport.h | 4 ++++ tools/tinytest-codegen.py | 1 - 4 files changed, 53 insertions(+), 1 deletion(-) create mode 100644 qemu-arm/modmachine.c (limited to 'tools') diff --git a/qemu-arm/Makefile b/qemu-arm/Makefile index 0af2fc901..dce739fc9 100644 --- a/qemu-arm/Makefile +++ b/qemu-arm/Makefile @@ -36,9 +36,11 @@ LDFLAGS= --specs=nano.specs --specs=rdimon.specs -Wl,--gc-sections -Wl,-Map=$(@: SRC_C = \ main.c \ + modmachine.c \ SRC_TEST_C = \ test_main.c \ + modmachine.c \ LIB_SRC_C = $(addprefix lib/,\ libm/math.c \ diff --git a/qemu-arm/modmachine.c b/qemu-arm/modmachine.c new file mode 100644 index 000000000..0f66349a8 --- /dev/null +++ b/qemu-arm/modmachine.c @@ -0,0 +1,47 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Damien P. George + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "extmod/machine_mem.h" +#include "extmod/machine_pinbase.h" +#include "extmod/machine_signal.h" + +STATIC const mp_rom_map_elem_t machine_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_umachine) }, + + { MP_ROM_QSTR(MP_QSTR_mem8), MP_ROM_PTR(&machine_mem8_obj) }, + { MP_ROM_QSTR(MP_QSTR_mem16), MP_ROM_PTR(&machine_mem16_obj) }, + { MP_ROM_QSTR(MP_QSTR_mem32), MP_ROM_PTR(&machine_mem32_obj) }, + + { MP_ROM_QSTR(MP_QSTR_PinBase), MP_ROM_PTR(&machine_pinbase_type) }, + { MP_ROM_QSTR(MP_QSTR_Signal), MP_ROM_PTR(&machine_signal_type) }, +}; + +STATIC MP_DEFINE_CONST_DICT(machine_module_globals, machine_module_globals_table); + +const mp_obj_module_t mp_module_machine = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t*)&machine_module_globals, +}; diff --git a/qemu-arm/mpconfigport.h b/qemu-arm/mpconfigport.h index 853385d6a..3452266f4 100644 --- a/qemu-arm/mpconfigport.h +++ b/qemu-arm/mpconfigport.h @@ -33,6 +33,7 @@ #define MICROPY_PY_URE (1) #define MICROPY_PY_UHEAPQ (1) #define MICROPY_PY_UHASHLIB (1) +#define MICROPY_PY_MACHINE (1) #define MICROPY_USE_INTERNAL_PRINTF (0) // type definitions for the specific machine @@ -57,5 +58,8 @@ typedef long mp_off_t; #define MICROPY_PORT_BUILTINS \ { MP_OBJ_NEW_QSTR(MP_QSTR_open), (mp_obj_t)&mp_builtin_open_obj }, +#define MICROPY_PORT_BUILTIN_MODULES \ + { MP_ROM_QSTR(MP_QSTR_umachine), MP_ROM_PTR(&mp_module_machine) }, \ + // We need to provide a declaration/definition of alloca() #include diff --git a/tools/tinytest-codegen.py b/tools/tinytest-codegen.py index 3436d0f45..099e2ecce 100755 --- a/tools/tinytest-codegen.py +++ b/tools/tinytest-codegen.py @@ -51,7 +51,6 @@ exclude_tests = ( 'float/float2int_doubleprec.py', # requires double precision floating point to work 'inlineasm/asmfpaddsub.py', 'inlineasm/asmfpcmp.py', 'inlineasm/asmfpldrstr.py', 'inlineasm/asmfpmuldiv.py', 'inlineasm/asmfpsqrt.py', 'extmod/ticks_diff.py', 'extmod/time_ms_us.py', 'extmod/uheapq_timeq.py', - 'extmod/machine_pinbase.py', 'extmod/machine_pulse.py', 'extmod/vfs_fat_ramdisk.py', 'extmod/vfs_fat_fileio.py', 'extmod/vfs_fat_fsusermount.py', 'extmod/vfs_fat_oldproto.py', ) -- cgit v1.2.3 From 320099aab931ba7c2657671c069781a4ac853151 Mon Sep 17 00:00:00 2001 From: Paul Sokolovsky Date: Mon, 6 Mar 2017 22:40:04 +0100 Subject: tools/tinytest-codegen: Update for recent test renaming ("intbig" suffix). --- tools/tinytest-codegen.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/tinytest-codegen.py b/tools/tinytest-codegen.py index 099e2ecce..dadfea1cc 100755 --- a/tools/tinytest-codegen.py +++ b/tools/tinytest-codegen.py @@ -48,7 +48,7 @@ testgroup_member = ( # currently these tests are selected because they pass on qemu-arm test_dirs = ('basics', 'micropython', 'float', 'extmod', 'inlineasm') # 'import', 'io', 'misc') exclude_tests = ( - 'float/float2int_doubleprec.py', # requires double precision floating point to work + 'float/float2int_doubleprec_intbig.py', # requires double precision floating point to work 'inlineasm/asmfpaddsub.py', 'inlineasm/asmfpcmp.py', 'inlineasm/asmfpldrstr.py', 'inlineasm/asmfpmuldiv.py', 'inlineasm/asmfpsqrt.py', 'extmod/ticks_diff.py', 'extmod/time_ms_us.py', 'extmod/uheapq_timeq.py', 'extmod/vfs_fat_ramdisk.py', 'extmod/vfs_fat_fileio.py', 'extmod/vfs_fat_fsusermount.py', 'extmod/vfs_fat_oldproto.py', -- cgit v1.2.3 From 9b3f423c14af65f8f273d8ab3f3db68b191c3794 Mon Sep 17 00:00:00 2001 From: Paul Sokolovsky Date: Sun, 2 Apr 2017 20:46:32 +0300 Subject: tools/pyboard: Tighten up Pyboard object closure on errors. Some "device" implementations may be sensitive to this. --- tools/pyboard.py | 2 ++ 1 file changed, 2 insertions(+) (limited to 'tools') diff --git a/tools/pyboard.py b/tools/pyboard.py index d4ce8b788..f368455f5 100755 --- a/tools/pyboard.py +++ b/tools/pyboard.py @@ -300,6 +300,7 @@ def main(): pyb.enter_raw_repl() except PyboardError as er: print(er) + pyb.close() sys.exit(1) def execbuffer(buf): @@ -307,6 +308,7 @@ def main(): ret, ret_err = pyb.exec_raw(buf, timeout=None, data_consumer=stdout_write_bytes) except PyboardError as er: print(er) + pyb.close() sys.exit(1) except KeyboardInterrupt: sys.exit(1) -- cgit v1.2.3 From 647e72ca63a345a5d6de16fe359bbc3b7c6615ec Mon Sep 17 00:00:00 2001 From: Paul Sokolovsky Date: Tue, 4 Apr 2017 17:46:02 +0300 Subject: tools/pyboard: Add "exec" and "execpty" pseudo-devices support. This allows to execute a command and communicate with its stdin/stdout via pipes ("exec") or with command-created pseudo-terminal ("execpty"), to emulate serial access. Immediate usecase is controlling a QEMU process which emulates board's serial via normal console, but it could be used e.g. with helper binaries to access real board over other hadware protocols, etc. An example of device specification for these cases is: --device exec:../zephyr/qemu.sh --device execpty:../zephyr/qemu2.sh Where qemu.sh contains long-long qemu startup line, or calls another command. There's a special support in this patch for running the command in a new terminal session, to support shell wrappers like that (without new terminal session, only wrapper script would be terminated, but its child processes would continue to run). --- tools/pyboard.py | 85 +++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 84 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/pyboard.py b/tools/pyboard.py index f368455f5..131634c90 100755 --- a/tools/pyboard.py +++ b/tools/pyboard.py @@ -39,6 +39,7 @@ Or: import sys import time +import os try: stdout = sys.stdout.buffer @@ -116,9 +117,91 @@ class TelnetToSerial: else: return n_waiting + +class ProcessToSerial: + "Execute a process and emulate serial connection using its stdin/stdout." + + def __init__(self, cmd): + import subprocess + self.subp = subprocess.Popen(cmd.split(), bufsize=0, shell=True, preexec_fn=os.setsid, + stdin=subprocess.PIPE, stdout=subprocess.PIPE) + + # Initially was implemented with selectors, but that adds Python3 + # dependency. However, there can be race conditions communicating + # with a particular child process (like QEMU), and selectors may + # still work better in that case, so left inplace for now. + # + #import selectors + #self.sel = selectors.DefaultSelector() + #self.sel.register(self.subp.stdout, selectors.EVENT_READ) + + import select + self.poll = select.poll() + self.poll.register(self.subp.stdout.fileno()) + + def close(self): + import signal + os.killpg(os.getpgid(self.subp.pid), signal.SIGTERM) + + def read(self, size=1): + data = b"" + while len(data) < size: + data += self.subp.stdout.read(size - len(data)) + return data + + def write(self, data): + self.subp.stdin.write(data) + return len(data) + + def inWaiting(self): + #res = self.sel.select(0) + res = self.poll.poll(0) + if res: + return 1 + return 0 + + +class ProcessPtyToTerminal: + """Execute a process which creates a PTY and prints slave PTY as + first line of its output, and emulate serial connection using + this PTY.""" + + def __init__(self, cmd): + import subprocess + import re + import serial + self.subp = subprocess.Popen(cmd.split(), bufsize=0, shell=True, preexec_fn=os.setsid, + stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + pty_line = self.subp.stderr.readline().decode("utf-8") + m = re.search(r"/dev/pts/[0-9]+", pty_line) + if not m: + print("Error: unable to find PTY device in startup line:", pty_line) + self.close() + sys.exit(1) + pty = m.group() + self.ser = serial.Serial(pty, interCharTimeout=1) + + def close(self): + import signal + os.killpg(os.getpgid(self.subp.pid), signal.SIGTERM) + + def read(self, size=1): + return self.ser.read(size) + + def write(self, data): + return self.ser.write(data) + + def inWaiting(self): + return self.ser.inWaiting() + + class Pyboard: def __init__(self, device, baudrate=115200, user='micro', password='python', wait=0): - if device and device[0].isdigit() and device[-1].isdigit() and device.count('.') == 3: + if device.startswith("exec:"): + self.serial = ProcessToSerial(device[len("exec:"):]) + elif device.startswith("execpty:"): + self.serial = ProcessPtyToTerminal(device[len("qemupty:"):]) + elif device and device[0].isdigit() and device[-1].isdigit() and device.count('.') == 3: # device looks like an IP address self.serial = TelnetToSerial(device, user, password, read_timeout=10) else: -- cgit v1.2.3 From 546ef301a12ccd6015137964637983432c64d11f Mon Sep 17 00:00:00 2001 From: Paul Sokolovsky Date: Wed, 5 Apr 2017 00:44:59 +0300 Subject: tools/pyboard: execpty: Use shell=False to workaround some curdir issues. Without this, Zephyr's port "make test" doesn't work. --- tools/pyboard.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/pyboard.py b/tools/pyboard.py index 131634c90..b7babdc30 100755 --- a/tools/pyboard.py +++ b/tools/pyboard.py @@ -170,7 +170,7 @@ class ProcessPtyToTerminal: import subprocess import re import serial - self.subp = subprocess.Popen(cmd.split(), bufsize=0, shell=True, preexec_fn=os.setsid, + self.subp = subprocess.Popen(cmd.split(), bufsize=0, shell=False, preexec_fn=os.setsid, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE) pty_line = self.subp.stderr.readline().decode("utf-8") m = re.search(r"/dev/pts/[0-9]+", pty_line) -- cgit v1.2.3 From 2cbe99783432b29bc303dc2e2cfe6823fe4a6c4f Mon Sep 17 00:00:00 2001 From: Paul Sokolovsky Date: Wed, 5 Apr 2017 12:30:39 +0300 Subject: tools/pyboard: ProcessPtyToTerminal: Add workaround for PySerial bug. When working with a "virtual" port, like PTY. The issue described in http://stackoverflow.com/questions/34831131/pyserial-does-not-play-well-with-virtual-port --- tools/pyboard.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/pyboard.py b/tools/pyboard.py index b7babdc30..d96ccc328 100755 --- a/tools/pyboard.py +++ b/tools/pyboard.py @@ -179,7 +179,9 @@ class ProcessPtyToTerminal: self.close() sys.exit(1) pty = m.group() - self.ser = serial.Serial(pty, interCharTimeout=1) + # rtscts, dsrdtr params are to workaround pyserial bug: + # http://stackoverflow.com/questions/34831131/pyserial-does-not-play-well-with-virtual-port + self.ser = serial.Serial(pty, interCharTimeout=1, rtscts=True, dsrdtr=True) def close(self): import signal -- cgit v1.2.3 From 3e1310d6e23777d7322016d7390a00da3284afbb Mon Sep 17 00:00:00 2001 From: Paul Sokolovsky Date: Fri, 7 Apr 2017 01:04:47 +0300 Subject: tools/pyboard: Provide more details when expected reply not received. When trying to execute a command via raw REPL and expected "OK" reply not received, show what was received instead. --- tools/pyboard.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/pyboard.py b/tools/pyboard.py index d96ccc328..5eac030bd 100755 --- a/tools/pyboard.py +++ b/tools/pyboard.py @@ -319,7 +319,7 @@ class Pyboard: # check if we could exec command data = self.serial.read(2) if data != b'OK': - raise PyboardError('could not exec command') + raise PyboardError('could not exec command (response: %s)' % data) def exec_raw(self, command, timeout=10, data_consumer=None): self.exec_raw_no_follow(command); -- cgit v1.2.3 From dd11af209d226b7d18d5148b239662e30ed60bad Mon Sep 17 00:00:00 2001 From: Damien George Date: Wed, 19 Apr 2017 09:45:59 +1000 Subject: py: Add LOAD_SUPER_METHOD bytecode to allow heap-free super meth calls. This patch allows the following code to run without allocating on the heap: super().foo(...) Before this patch such a call would allocate a super object on the heap and then load the foo method and call it right away. The super object is only needed to perform the lookup of the method and not needed after that. This patch makes an optimisation to allocate the super object on the C stack and discard it right after use. Changes in code size due to this patch are: bare-arm: +128 minimal: +232 unix x64: +416 unix nanbox: +364 stmhal: +184 esp8266: +340 cc3200: +128 --- minimal/frozentest.mpy | Bin 255 -> 255 bytes py/bc.c | 2 +- py/bc0.h | 13 +++++++------ py/compile.c | 23 +++++++++++++++++------ py/emit.h | 4 ++-- py/emitbc.c | 6 +++--- py/emitnative.c | 19 +++++++++++++------ py/nativeglue.c | 1 + py/objtype.c | 5 +++++ py/persistentcode.c | 2 +- py/runtime.h | 1 + py/runtime0.h | 1 + py/showbc.c | 5 +++++ py/vm.c | 8 ++++++++ py/vmentrytable.h | 1 + tools/mpy-tool.py | 4 ++-- 16 files changed, 68 insertions(+), 27 deletions(-) (limited to 'tools') diff --git a/minimal/frozentest.mpy b/minimal/frozentest.mpy index 5cb356d61..87f9581bf 100644 Binary files a/minimal/frozentest.mpy and b/minimal/frozentest.mpy differ diff --git a/py/bc.c b/py/bc.c index 4c0eb5391..fc1794683 100644 --- a/py/bc.c +++ b/py/bc.c @@ -304,7 +304,7 @@ STATIC const byte opcode_format_table[64] = { OC4(U, U, U, U), // 0x0c-0x0f OC4(B, B, B, U), // 0x10-0x13 OC4(V, U, Q, V), // 0x14-0x17 - OC4(B, U, V, V), // 0x18-0x1b + OC4(B, V, V, Q), // 0x18-0x1b OC4(Q, Q, Q, Q), // 0x1c-0x1f OC4(B, B, V, V), // 0x20-0x23 OC4(Q, Q, Q, B), // 0x24-0x27 diff --git a/py/bc0.h b/py/bc0.h index c2b019f1a..b5650abe4 100644 --- a/py/bc0.h +++ b/py/bc0.h @@ -37,12 +37,13 @@ #define MP_BC_LOAD_CONST_OBJ (0x17) // ptr #define MP_BC_LOAD_NULL (0x18) -#define MP_BC_LOAD_FAST_N (0x1a) // uint -#define MP_BC_LOAD_DEREF (0x1b) // uint -#define MP_BC_LOAD_NAME (0x1c) // qstr -#define MP_BC_LOAD_GLOBAL (0x1d) // qstr -#define MP_BC_LOAD_ATTR (0x1e) // qstr -#define MP_BC_LOAD_METHOD (0x1f) // qstr +#define MP_BC_LOAD_FAST_N (0x19) // uint +#define MP_BC_LOAD_DEREF (0x1a) // uint +#define MP_BC_LOAD_NAME (0x1b) // qstr +#define MP_BC_LOAD_GLOBAL (0x1c) // qstr +#define MP_BC_LOAD_ATTR (0x1d) // qstr +#define MP_BC_LOAD_METHOD (0x1e) // qstr +#define MP_BC_LOAD_SUPER_METHOD (0x1f) // qstr #define MP_BC_LOAD_BUILD_CLASS (0x20) #define MP_BC_LOAD_SUBSCR (0x21) diff --git a/py/compile.c b/py/compile.c index 42c2cc3a2..8533e0528 100644 --- a/py/compile.c +++ b/py/compile.c @@ -1694,7 +1694,7 @@ STATIC void compile_yield_from(compiler_t *comp) { #if MICROPY_PY_ASYNC_AWAIT STATIC void compile_await_object_method(compiler_t *comp, qstr method) { - EMIT_ARG(load_method, method); + EMIT_ARG(load_method, method, false); EMIT_ARG(call_method, 0, 0, 0); compile_yield_from(comp); } @@ -1785,7 +1785,7 @@ STATIC void compile_async_with_stmt_helper(compiler_t *comp, int n, mp_parse_nod } compile_load_id(comp, context); - EMIT_ARG(load_method, MP_QSTR___aexit__); + EMIT_ARG(load_method, MP_QSTR___aexit__, false); EMIT_ARG(setup_except, try_exception_label); compile_increase_except_level(comp); @@ -2219,9 +2219,20 @@ STATIC void compile_atom_expr_normal(compiler_t *comp, mp_parse_node_struct_t *p return; } - // a super() call - EMIT_ARG(call_function, 2, 0, 0); - i = 1; + if (num_trail >= 3 + && MP_PARSE_NODE_STRUCT_KIND(pns_trail[1]) == PN_trailer_period + && MP_PARSE_NODE_STRUCT_KIND(pns_trail[2]) == PN_trailer_paren) { + // optimisation for method calls super().f(...), to eliminate heap allocation + mp_parse_node_struct_t *pns_period = pns_trail[1]; + mp_parse_node_struct_t *pns_paren = pns_trail[2]; + EMIT_ARG(load_method, MP_PARSE_NODE_LEAF_ARG(pns_period->nodes[0]), true); + compile_trailer_paren_helper(comp, pns_paren->nodes[0], true, 0); + i = 3; + } else { + // a super() call + EMIT_ARG(call_function, 2, 0, 0); + i = 1; + } } // compile the remaining trailers @@ -2232,7 +2243,7 @@ STATIC void compile_atom_expr_normal(compiler_t *comp, mp_parse_node_struct_t *p // optimisation for method calls a.f(...), following PyPy mp_parse_node_struct_t *pns_period = pns_trail[i]; mp_parse_node_struct_t *pns_paren = pns_trail[i + 1]; - EMIT_ARG(load_method, MP_PARSE_NODE_LEAF_ARG(pns_period->nodes[0])); + EMIT_ARG(load_method, MP_PARSE_NODE_LEAF_ARG(pns_period->nodes[0]), false); compile_trailer_paren_helper(comp, pns_paren->nodes[0], true, 0); i += 1; } else { diff --git a/py/emit.h b/py/emit.h index 64bb957f6..0236a9b8d 100644 --- a/py/emit.h +++ b/py/emit.h @@ -88,7 +88,7 @@ typedef struct _emit_method_table_t { void (*load_const_obj)(emit_t *emit, mp_obj_t obj); void (*load_null)(emit_t *emit); void (*load_attr)(emit_t *emit, qstr qst); - void (*load_method)(emit_t *emit, qstr qst); + void (*load_method)(emit_t *emit, qstr qst, bool is_super); void (*load_build_class)(emit_t *emit); void (*load_subscr)(emit_t *emit); void (*store_attr)(emit_t *emit, qstr qst); @@ -205,7 +205,7 @@ void mp_emit_bc_load_const_str(emit_t *emit, qstr qst); void mp_emit_bc_load_const_obj(emit_t *emit, mp_obj_t obj); void mp_emit_bc_load_null(emit_t *emit); void mp_emit_bc_load_attr(emit_t *emit, qstr qst); -void mp_emit_bc_load_method(emit_t *emit, qstr qst); +void mp_emit_bc_load_method(emit_t *emit, qstr qst, bool is_super); void mp_emit_bc_load_build_class(emit_t *emit); void mp_emit_bc_load_subscr(emit_t *emit); void mp_emit_bc_store_attr(emit_t *emit, qstr qst); diff --git a/py/emitbc.c b/py/emitbc.c index 673cd405f..6d8db81bc 100644 --- a/py/emitbc.c +++ b/py/emitbc.c @@ -594,9 +594,9 @@ void mp_emit_bc_load_attr(emit_t *emit, qstr qst) { } } -void mp_emit_bc_load_method(emit_t *emit, qstr qst) { - emit_bc_pre(emit, 1); - emit_write_bytecode_byte_qstr(emit, MP_BC_LOAD_METHOD, qst); +void mp_emit_bc_load_method(emit_t *emit, qstr qst, bool is_super) { + emit_bc_pre(emit, 1 - 2 * is_super); + emit_write_bytecode_byte_qstr(emit, is_super ? MP_BC_LOAD_SUPER_METHOD : MP_BC_LOAD_METHOD, qst); } void mp_emit_bc_load_build_class(emit_t *emit) { diff --git a/py/emitnative.c b/py/emitnative.c index 3ab001f8d..99adc809c 100644 --- a/py/emitnative.c +++ b/py/emitnative.c @@ -85,6 +85,7 @@ STATIC byte mp_f_n_args[MP_F_NUMBER_OF] = { [MP_F_LOAD_BUILD_CLASS] = 0, [MP_F_LOAD_ATTR] = 2, [MP_F_LOAD_METHOD] = 3, + [MP_F_LOAD_SUPER_METHOD] = 2, [MP_F_STORE_NAME] = 2, [MP_F_STORE_GLOBAL] = 2, [MP_F_STORE_ATTR] = 3, @@ -1065,12 +1066,18 @@ STATIC void emit_native_load_attr(emit_t *emit, qstr qst) { emit_post_push_reg(emit, VTYPE_PYOBJ, REG_RET); } -STATIC void emit_native_load_method(emit_t *emit, qstr qst) { - vtype_kind_t vtype_base; - emit_pre_pop_reg(emit, &vtype_base, REG_ARG_1); // arg1 = base - assert(vtype_base == VTYPE_PYOBJ); - emit_get_stack_pointer_to_reg_for_push(emit, REG_ARG_3, 2); // arg3 = dest ptr - emit_call_with_imm_arg(emit, MP_F_LOAD_METHOD, qst, REG_ARG_2); // arg2 = method name +STATIC void emit_native_load_method(emit_t *emit, qstr qst, bool is_super) { + if (is_super) { + emit_get_stack_pointer_to_reg_for_pop(emit, REG_ARG_2, 3); // arg2 = dest ptr + emit_get_stack_pointer_to_reg_for_push(emit, REG_ARG_2, 2); // arg2 = dest ptr + emit_call_with_imm_arg(emit, MP_F_LOAD_SUPER_METHOD, qst, REG_ARG_1); // arg1 = method name + } else { + vtype_kind_t vtype_base; + emit_pre_pop_reg(emit, &vtype_base, REG_ARG_1); // arg1 = base + assert(vtype_base == VTYPE_PYOBJ); + emit_get_stack_pointer_to_reg_for_push(emit, REG_ARG_3, 2); // arg3 = dest ptr + emit_call_with_imm_arg(emit, MP_F_LOAD_METHOD, qst, REG_ARG_2); // arg2 = method name + } } STATIC void emit_native_load_build_class(emit_t *emit) { diff --git a/py/nativeglue.c b/py/nativeglue.c index 694dfca74..c75e5ec04 100644 --- a/py/nativeglue.c +++ b/py/nativeglue.c @@ -133,6 +133,7 @@ void *const mp_fun_table[MP_F_NUMBER_OF] = { mp_load_build_class, mp_load_attr, mp_load_method, + mp_load_super_method, mp_store_name, mp_store_global, mp_store_attr, diff --git a/py/objtype.c b/py/objtype.c index de1ee8c42..2a119e40f 100644 --- a/py/objtype.c +++ b/py/objtype.c @@ -1070,6 +1070,11 @@ const mp_obj_type_t mp_type_super = { .attr = super_attr, }; +void mp_load_super_method(qstr attr, mp_obj_t *dest) { + mp_obj_super_t super = {{&mp_type_super}, dest[1], dest[2]}; + mp_load_method(MP_OBJ_FROM_PTR(&super), attr, dest); +} + /******************************************************************************/ // subclassing and built-ins specific to types diff --git a/py/persistentcode.c b/py/persistentcode.c index 2a9a5b7cc..a71045a29 100644 --- a/py/persistentcode.c +++ b/py/persistentcode.c @@ -39,7 +39,7 @@ #include "py/smallint.h" // The current version of .mpy files -#define MPY_VERSION (1) +#define MPY_VERSION (2) // The feature flags byte encodes the compile-time config options that // affect the generate bytecode. diff --git a/py/runtime.h b/py/runtime.h index 177869145..d75d23ff1 100644 --- a/py/runtime.h +++ b/py/runtime.h @@ -131,6 +131,7 @@ mp_obj_t mp_load_attr(mp_obj_t base, qstr attr); void mp_convert_member_lookup(mp_obj_t obj, const mp_obj_type_t *type, mp_obj_t member, mp_obj_t *dest); void mp_load_method(mp_obj_t base, qstr attr, mp_obj_t *dest); void mp_load_method_maybe(mp_obj_t base, qstr attr, mp_obj_t *dest); +void mp_load_super_method(qstr attr, mp_obj_t *dest); void mp_store_attr(mp_obj_t base, qstr attr, mp_obj_t val); mp_obj_t mp_getiter(mp_obj_t o, mp_obj_iter_buf_t *iter_buf); diff --git a/py/runtime0.h b/py/runtime0.h index b1ed71026..720fe6a23 100644 --- a/py/runtime0.h +++ b/py/runtime0.h @@ -107,6 +107,7 @@ typedef enum { MP_F_LOAD_BUILD_CLASS, MP_F_LOAD_ATTR, MP_F_LOAD_METHOD, + MP_F_LOAD_SUPER_METHOD, MP_F_STORE_NAME, MP_F_STORE_GLOBAL, MP_F_STORE_ATTR, diff --git a/py/showbc.c b/py/showbc.c index b52905f67..0bccf8427 100644 --- a/py/showbc.c +++ b/py/showbc.c @@ -245,6 +245,11 @@ const byte *mp_bytecode_print_str(const byte *ip) { printf("LOAD_METHOD %s", qstr_str(qst)); break; + case MP_BC_LOAD_SUPER_METHOD: + DECODE_QSTR; + printf("LOAD_SUPER_METHOD %s", qstr_str(qst)); + break; + case MP_BC_LOAD_BUILD_CLASS: printf("LOAD_BUILD_CLASS"); break; diff --git a/py/vm.c b/py/vm.c index 8ce635ca8..469528df4 100644 --- a/py/vm.c +++ b/py/vm.c @@ -376,6 +376,14 @@ dispatch_loop: DISPATCH(); } + ENTRY(MP_BC_LOAD_SUPER_METHOD): { + MARK_EXC_IP_SELECTIVE(); + DECODE_QSTR; + sp -= 1; + mp_load_super_method(qst, sp - 1); + DISPATCH(); + } + ENTRY(MP_BC_LOAD_BUILD_CLASS): MARK_EXC_IP_SELECTIVE(); PUSH(mp_load_build_class()); diff --git a/py/vmentrytable.h b/py/vmentrytable.h index 8731c3d4c..dd9789e34 100644 --- a/py/vmentrytable.h +++ b/py/vmentrytable.h @@ -44,6 +44,7 @@ static const void *const entry_table[256] = { [MP_BC_LOAD_GLOBAL] = &&entry_MP_BC_LOAD_GLOBAL, [MP_BC_LOAD_ATTR] = &&entry_MP_BC_LOAD_ATTR, [MP_BC_LOAD_METHOD] = &&entry_MP_BC_LOAD_METHOD, + [MP_BC_LOAD_SUPER_METHOD] = &&entry_MP_BC_LOAD_SUPER_METHOD, [MP_BC_LOAD_BUILD_CLASS] = &&entry_MP_BC_LOAD_BUILD_CLASS, [MP_BC_LOAD_SUBSCR] = &&entry_MP_BC_LOAD_SUBSCR, [MP_BC_STORE_FAST_N] = &&entry_MP_BC_STORE_FAST_N, diff --git a/tools/mpy-tool.py b/tools/mpy-tool.py index d14e0f4ea..d2a1c67ad 100755 --- a/tools/mpy-tool.py +++ b/tools/mpy-tool.py @@ -57,7 +57,7 @@ class FreezeError(Exception): return 'error while freezing %s: %s' % (self.rawcode.source_file, self.msg) class Config: - MPY_VERSION = 1 + MPY_VERSION = 2 MICROPY_LONGINT_IMPL_NONE = 0 MICROPY_LONGINT_IMPL_LONGLONG = 1 MICROPY_LONGINT_IMPL_MPZ = 2 @@ -94,7 +94,7 @@ def make_opcode_format(): OC4(U, U, U, U), # 0x0c-0x0f OC4(B, B, B, U), # 0x10-0x13 OC4(V, U, Q, V), # 0x14-0x17 - OC4(B, U, V, V), # 0x18-0x1b + OC4(B, V, V, Q), # 0x18-0x1b OC4(Q, Q, Q, Q), # 0x1c-0x1f OC4(B, B, V, V), # 0x20-0x23 OC4(Q, Q, Q, B), # 0x24-0x27 -- cgit v1.2.3 From 473e85e2da847ade98d728a17c339f5c75a19369 Mon Sep 17 00:00:00 2001 From: Paul Sokolovsky Date: Mon, 1 May 2017 00:01:30 +0300 Subject: tools/mpy-tool: Make work if run from another directory. By making sure we don't add relative paths to sys.path. --- tools/mpy-tool.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/mpy-tool.py b/tools/mpy-tool.py index d2a1c67ad..aff4fd210 100755 --- a/tools/mpy-tool.py +++ b/tools/mpy-tool.py @@ -45,7 +45,7 @@ import sys import struct from collections import namedtuple -sys.path.append('../py') +sys.path.append(sys.path[0] + '/../py') import makeqstrdata as qstrutil class FreezeError(Exception): -- cgit v1.2.3 From e81f46940e005e07502e3952f5b0feb23037235b Mon Sep 17 00:00:00 2001 From: Paul Sokolovsky Date: Mon, 1 May 2017 00:03:45 +0300 Subject: tools/upip: Upgrade to 1.1.6, supports commented lines in requirements.txt. --- tools/upip.py | 2 ++ 1 file changed, 2 insertions(+) (limited to 'tools') diff --git a/tools/upip.py b/tools/upip.py index 0070fd619..a156340b2 100644 --- a/tools/upip.py +++ b/tools/upip.py @@ -275,6 +275,8 @@ def main(): l = f.readline() if not l: break + if l[0] == "#": + continue to_install.append(l.rstrip()) elif opt == "--debug": debug = True -- cgit v1.2.3 From d4c070415a3ec8ea06ab99b48ecf6976b7c93289 Mon Sep 17 00:00:00 2001 From: Paul Sokolovsky Date: Fri, 5 May 2017 13:12:19 +0300 Subject: tools/upip: Upgrade to 1.2. Memory optimizations and error handling improvements. --- tools/upip.py | 79 +++++++++++++++++++++++++++++++++-------------------------- 1 file changed, 44 insertions(+), 35 deletions(-) (limited to 'tools') diff --git a/tools/upip.py b/tools/upip.py index a156340b2..7b85c718f 100644 --- a/tools/upip.py +++ b/tools/upip.py @@ -104,6 +104,10 @@ import usocket warn_ussl = True def url_open(url): global warn_ussl + + if debug: + print(url) + proto, _, host, urlpath = url.split('/', 3) try: ai = usocket.getaddrinfo(host, 443) @@ -113,41 +117,43 @@ def url_open(url): addr = ai[0][4] s = usocket.socket(ai[0][0]) - #print("Connect address:", addr) - s.connect(addr) - - if proto == "https:": - s = ussl.wrap_socket(s) - if warn_ussl: - print("Warning: %s SSL certificate is not validated" % host) - warn_ussl = False - - # MicroPython rawsocket module supports file interface directly - s.write("GET /%s HTTP/1.0\r\nHost: %s\r\n\r\n" % (urlpath, host)) - l = s.readline() - protover, status, msg = l.split(None, 2) - if status != b"200": - s.close() - exc = ValueError(status) - if status == b"404": - fatal("Package not found", exc) - fatal("Unexpected error querying for package", exc) - while 1: + try: + #print("Connect address:", addr) + s.connect(addr) + + if proto == "https:": + s = ussl.wrap_socket(s) + if warn_ussl: + print("Warning: %s SSL certificate is not validated" % host) + warn_ussl = False + + # MicroPython rawsocket module supports file interface directly + s.write("GET /%s HTTP/1.0\r\nHost: %s\r\n\r\n" % (urlpath, host)) l = s.readline() - if not l: - s.close() - fatal("Unexpected EOF in HTTP headers", ValueError()) - if l == b'\r\n': - break + protover, status, msg = l.split(None, 2) + if status != b"200": + if status == b"404" or status == b"301": + raise NotFoundError("Package not found") + raise ValueError(status) + while 1: + l = s.readline() + if not l: + raise ValueError("Unexpected EOF in HTTP headers") + if l == b'\r\n': + break + except Exception as e: + s.close() + raise e return s def get_pkg_metadata(name): f = url_open("https://pypi.python.org/pypi/%s/json" % name) - s = f.read() - f.close() - return json.loads(s) + try: + return json.load(f) + finally: + f.close() def fatal(msg, exc=None): @@ -168,10 +174,12 @@ def install_pkg(pkg_spec, install_path): print("Installing %s %s from %s" % (pkg_spec, latest_ver, package_url)) package_fname = op_basename(package_url) f1 = url_open(package_url) - f2 = uzlib.DecompIO(f1, gzdict_sz) - f3 = tarfile.TarFile(fileobj=f2) - meta = install_tar(f3, install_path) - f1.close() + try: + f2 = uzlib.DecompIO(f1, gzdict_sz) + f3 = tarfile.TarFile(fileobj=f2) + meta = install_tar(f3, install_path) + finally: + f1.close() del f3 del f2 gc.collect() @@ -208,9 +216,10 @@ def install(to_install, install_path=None): if deps: deps = deps.decode("utf-8").split("\n") to_install.extend(deps) - except NotFoundError: - print("Error: cannot find '%s' package (or server error), packages may be partially installed" \ - % pkg_spec, file=sys.stderr) + except Exception as e: + print("Error installing '{}': {}, packages may be partially installed".format( + pkg_spec, e), + file=sys.stderr) def get_install_path(): global install_path -- cgit v1.2.3 From ec534609f665cb791b8fc1eae1a44e514c297659 Mon Sep 17 00:00:00 2001 From: Damien George Date: Sat, 13 May 2017 10:08:13 +1000 Subject: tools/mpy-tool.py: Use MP_ROM_xxx macros to support nanbox builds. --- tools/mpy-tool.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'tools') diff --git a/tools/mpy-tool.py b/tools/mpy-tool.py index aff4fd210..483a992db 100755 --- a/tools/mpy-tool.py +++ b/tools/mpy-tool.py @@ -332,25 +332,25 @@ class RawCode: raise FreezeError(self, 'freezing of object %r is not implemented' % (obj,)) # generate constant table - print('STATIC const mp_uint_t const_table_data_%s[%u] = {' + print('STATIC const mp_rom_obj_t const_table_data_%s[%u] = {' % (self.escaped_name, len(self.qstrs) + len(self.objs) + len(self.raw_codes))) for qst in self.qstrs: - print(' (mp_uint_t)MP_OBJ_NEW_QSTR(%s),' % global_qstrs[qst].qstr_id) + print(' MP_ROM_QSTR(%s),' % global_qstrs[qst].qstr_id) for i in range(len(self.objs)): if type(self.objs[i]) is float: print('#if MICROPY_OBJ_REPR == MICROPY_OBJ_REPR_A || MICROPY_OBJ_REPR == MICROPY_OBJ_REPR_B') - print(' (mp_uint_t)&const_obj_%s_%u,' % (self.escaped_name, i)) + print(' MP_ROM_PTR(&const_obj_%s_%u),' % (self.escaped_name, i)) print('#elif MICROPY_OBJ_REPR == MICROPY_OBJ_REPR_C') n = struct.unpack(' Date: Sun, 14 May 2017 17:51:12 +0300 Subject: tools/mpy_cross_all.py: Helper tool to run mpy-cross on the entire project. --- tools/mpy_cross_all.py | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100755 tools/mpy_cross_all.py (limited to 'tools') diff --git a/tools/mpy_cross_all.py b/tools/mpy_cross_all.py new file mode 100755 index 000000000..2bda71e9b --- /dev/null +++ b/tools/mpy_cross_all.py @@ -0,0 +1,38 @@ +#!/usr/bin/env python3 +import argparse +import os +import os.path + +argparser = argparse.ArgumentParser(description="Compile all .py files to .mpy recursively") +argparser.add_argument("-o", "--out", help="output directory (default: input dir)") +argparser.add_argument("--target", help="select MicroPython target config") +argparser.add_argument("-mcache-lookup-bc", action="store_true", help="cache map lookups in the bytecode") +argparser.add_argument("dir", help="input directory") +args = argparser.parse_args() + +TARGET_OPTS = { + "unix": "-mcache-lookup-bc", + "baremetal": "", +} + +args.dir = args.dir.rstrip("/") + +if not args.out: + args.out = args.dir + +path_prefix_len = len(args.dir) + 1 + +for path, subdirs, files in os.walk(args.dir): + for f in files: + if f.endswith(".py"): + fpath = path + "/" + f + #print(fpath) + out_fpath = args.out + "/" + fpath[path_prefix_len:-3] + ".mpy" + out_dir = os.path.dirname(out_fpath) + if not os.path.isdir(out_dir): + os.makedirs(out_dir) + cmd = "mpy-cross -v -v %s -s %s %s -o %s" % (TARGET_OPTS.get(args.target, ""), + fpath[path_prefix_len:], fpath, out_fpath) + #print(cmd) + res = os.system(cmd) + assert res == 0 -- cgit v1.2.3 From 88c51c3592edc6c29fb0aad57c91e535793aa31b Mon Sep 17 00:00:00 2001 From: Damien George Date: Tue, 16 May 2017 18:53:02 +1000 Subject: tools/mpy-tool.py: Fix regression with freezing floats in obj repr C. Regression was introduced by ec534609f665cb791b8fc1eae1a44e514c297659 --- tools/mpy-tool.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/mpy-tool.py b/tools/mpy-tool.py index 483a992db..544f90cc8 100755 --- a/tools/mpy-tool.py +++ b/tools/mpy-tool.py @@ -343,7 +343,7 @@ class RawCode: print('#elif MICROPY_OBJ_REPR == MICROPY_OBJ_REPR_C') n = struct.unpack(' Date: Mon, 29 May 2017 10:08:14 +0300 Subject: various: Spelling fixes --- cc3200/README.md | 2 +- docs/library/btree.rst | 2 +- docs/library/machine.SD.rst | 2 +- docs/library/machine.UART.rst | 2 +- docs/library/uhashlib.rst | 4 ++-- docs/library/utime.rst | 4 ++-- docs/sphinx_selective_exclude/README.md | 2 +- docs/sphinx_selective_exclude/modindex_exclude.py | 2 +- esp8266/README.md | 2 +- esp8266/machine_rtc.c | 2 +- examples/conwaylife.py | 4 ++-- examples/embedding/Makefile.upylib | 2 +- examples/embedding/README.md | 2 +- extmod/modlwip.c | 4 ++-- extmod/modwebsocket.c | 2 +- lib/timeutils/timeutils.c | 2 +- lib/utils/stdout_helpers.c | 2 +- py/asmthumb.c | 2 +- py/builtinimport.c | 4 ++-- py/compile.c | 4 ++-- py/misc.h | 2 +- py/mkenv.mk | 2 +- py/mpconfig.h | 2 +- py/obj.c | 2 +- py/objstr.c | 4 ++-- py/py.mk | 2 +- py/ringbuf.h | 2 +- py/stream.c | 2 +- py/vm.c | 4 ++-- qemu-arm/README.md | 2 +- tests/basics/namedtuple1.py | 2 +- tests/basics/try_reraise2.py | 2 +- tests/pyb/can.py | 2 +- tests/thread/stress_aes.py | 2 +- tests/wipy/uart.py | 2 +- tools/insert-usb-ids.py | 2 +- tools/pyboard.py | 2 +- unix/Makefile | 2 +- unix/modsocket.c | 2 +- windows/windows_mphal.c | 2 +- zephyr/modutime.c | 2 +- 41 files changed, 49 insertions(+), 49 deletions(-) (limited to 'tools') diff --git a/cc3200/README.md b/cc3200/README.md index 753fd450a..53cad3ba0 100644 --- a/cc3200/README.md +++ b/cc3200/README.md @@ -138,7 +138,7 @@ If `WIPY_IP`, `WIPY_USER` or `WIPY_PWD` are omitted the default values (the ones ## Regarding old revisions of the CC3200-LAUNCHXL First silicon (pre-release) revisions of the CC3200 had issues with the ram blocks, and MicroPython cannot run -there. Make sure to use a **v4.1 (or higer) LAUNCHXL board** when trying this port, otherwise it won't work. +there. Make sure to use a **v4.1 (or higher) LAUNCHXL board** when trying this port, otherwise it won't work. ### Note regarding FileZilla diff --git a/docs/library/btree.rst b/docs/library/btree.rst index aebcbc160..bd7890586 100644 --- a/docs/library/btree.rst +++ b/docs/library/btree.rst @@ -69,7 +69,7 @@ Functions Open a database from a random-access `stream` (like an open file). All other parameters are optional and keyword-only, and allow to tweak advanced - paramters of the database operation (most users will not need them): + parameters of the database operation (most users will not need them): * `flags` - Currently unused. * `cachesize` - Suggested maximum memory cache size in bytes. For a diff --git a/docs/library/machine.SD.rst b/docs/library/machine.SD.rst index 0eb024602..608e95831 100644 --- a/docs/library/machine.SD.rst +++ b/docs/library/machine.SD.rst @@ -34,7 +34,7 @@ Methods .. method:: SD.init(id=0, pins=('GP10', 'GP11', 'GP15')) - Enable the SD card. In order to initalize the card, give it a 3-tuple: + Enable the SD card. In order to initialize the card, give it a 3-tuple: ``(clk_pin, cmd_pin, dat0_pin)``. .. method:: SD.deinit() diff --git a/docs/library/machine.UART.rst b/docs/library/machine.UART.rst index f9c8efef7..64ff28e1a 100644 --- a/docs/library/machine.UART.rst +++ b/docs/library/machine.UART.rst @@ -16,7 +16,7 @@ UART objects can be created and initialised using:: uart = UART(1, 9600) # init with given baudrate uart.init(9600, bits=8, parity=None, stop=1) # init with given parameters -Supported paramters differ on a board: +Supported parameters differ on a board: Pyboard: Bits can be 7, 8 or 9. Stop can be 1 or 2. With `parity=None`, only 8 and 9 bits are supported. With parity enabled, only 7 and 8 bits diff --git a/docs/library/uhashlib.rst b/docs/library/uhashlib.rst index cd0216dae..6b9a764ba 100644 --- a/docs/library/uhashlib.rst +++ b/docs/library/uhashlib.rst @@ -15,11 +15,11 @@ be implemented: * SHA1 - A previous generation algorithm. Not recommended for new usages, but SHA1 is a part of number of Internet standards and existing - applications, so boards targetting network connectivity and + applications, so boards targeting network connectivity and interoperatiability will try to provide this. * MD5 - A legacy algorithm, not considered cryptographically secure. Only - selected boards, targetting interoperatibility with legacy applications, + selected boards, targeting interoperatibility with legacy applications, will offer this. Constructors diff --git a/docs/library/utime.rst b/docs/library/utime.rst index 871f6c678..f3a067cde 100644 --- a/docs/library/utime.rst +++ b/docs/library/utime.rst @@ -146,8 +146,8 @@ Functions too distant inbetween, see below). The function returns **signed** value in the range [``-TICKS_PERIOD/2`` .. ``TICKS_PERIOD/2-1``] (that's a typical range definition for two's-complement signed binary integers). If the result is negative, it means that - ``ticks1`` occured earlier in time than ``ticks2``. Otherwise, it means that - ``ticks1`` occured after ``ticks2``. This holds ``only`` if ``ticks1`` and ``ticks2`` + ``ticks1`` occurred earlier in time than ``ticks2``. Otherwise, it means that + ``ticks1`` occurred after ``ticks2``. This holds ``only`` if ``ticks1`` and ``ticks2`` are apart from each other for no more than ``TICKS_PERIOD/2-1`` ticks. If that does not hold, incorrect result will be returned. Specifically, if two tick values are apart for ``TICKS_PERIOD/2-1`` ticks, that value will be returned by the function. diff --git a/docs/sphinx_selective_exclude/README.md b/docs/sphinx_selective_exclude/README.md index cc9725c21..dab140739 100644 --- a/docs/sphinx_selective_exclude/README.md +++ b/docs/sphinx_selective_exclude/README.md @@ -66,7 +66,7 @@ index for PDF, just the same as for HTML. search_auto_exclude ------------------- -Even if you exclude soem documents from toctree:: using only:: +Even if you exclude some documents from toctree:: using only:: directive, they will be indexed for full-text search, so user may find them and get confused. This plugin follows very simple idea that if you didn't include some documents in the toctree, then diff --git a/docs/sphinx_selective_exclude/modindex_exclude.py b/docs/sphinx_selective_exclude/modindex_exclude.py index 18b49cc80..bf8db795e 100644 --- a/docs/sphinx_selective_exclude/modindex_exclude.py +++ b/docs/sphinx_selective_exclude/modindex_exclude.py @@ -2,7 +2,7 @@ # This is a Sphinx documentation tool extension which allows to # exclude some Python modules from the generated indexes. Modules # are excluded both from "modindex" and "genindex" index tables -# (in the latter case, all members of a module are exlcuded). +# (in the latter case, all members of a module are excluded). # To control exclusion, set "modindex_exclude" variable in Sphinx # conf.py to the list of modules to exclude. Note: these should be # modules (as defined by py:module directive, not just raw filenames). diff --git a/esp8266/README.md b/esp8266/README.md index 897bb4737..d717d26fe 100644 --- a/esp8266/README.md +++ b/esp8266/README.md @@ -100,7 +100,7 @@ programming). __WiFi__ -Initally, the device configures itself as a WiFi access point (AP). +Initially, the device configures itself as a WiFi access point (AP). - ESSID: MicroPython-xxxxxx (x’s are replaced with part of the MAC address). - Password: micropythoN (note the upper-case N). - IP address of the board: 192.168.4.1. diff --git a/esp8266/machine_rtc.c b/esp8266/machine_rtc.c index 019b705ba..b17bcb261 100644 --- a/esp8266/machine_rtc.c +++ b/esp8266/machine_rtc.c @@ -93,7 +93,7 @@ void pyb_rtc_set_us_since_2000(uint64_t nowus) { int64_t delta = nowus - (((uint64_t)rtc_last_ticks * cal) >> 12); // As the calibration value jitters quite a bit, to make the - // clock at least somewhat practially usable, we need to store it + // clock at least somewhat practically usable, we need to store it system_rtc_mem_write(MEM_CAL_ADDR, &cal, sizeof(cal)); system_rtc_mem_write(MEM_DELTA_ADDR, &delta, sizeof(delta)); }; diff --git a/examples/conwaylife.py b/examples/conwaylife.py index f99796175..323f42e85 100644 --- a/examples/conwaylife.py +++ b/examples/conwaylife.py @@ -8,7 +8,7 @@ lcd.light(1) def conway_step(): for x in range(128): # loop over x coordinates for y in range(32): # loop over y coordinates - # count number of neigbours + # count number of neighbours num_neighbours = (lcd.get(x - 1, y - 1) + lcd.get(x, y - 1) + lcd.get(x + 1, y - 1) + @@ -25,7 +25,7 @@ def conway_step(): if self and not (2 <= num_neighbours <= 3): lcd.pixel(x, y, 0) # not enough, or too many neighbours: cell dies elif not self and num_neighbours == 3: - lcd.pixel(x, y, 1) # exactly 3 neigbours around an empty cell: cell is born + lcd.pixel(x, y, 1) # exactly 3 neighbours around an empty cell: cell is born # randomise the start def conway_rand(): diff --git a/examples/embedding/Makefile.upylib b/examples/embedding/Makefile.upylib index 873c0fd34..4663ad30a 100644 --- a/examples/embedding/Makefile.upylib +++ b/examples/embedding/Makefile.upylib @@ -170,7 +170,7 @@ SRC_QSTR_AUTO_DEPS += include $(MPTOP)/py/mkrules.mk # Value of configure's --host= option (required for cross-compilation). -# Deduce it from CROSS_COMPILE by default, but can be overriden. +# Deduce it from CROSS_COMPILE by default, but can be overridden. ifneq ($(CROSS_COMPILE),) CROSS_COMPILE_HOST = --host=$(patsubst %-,%,$(CROSS_COMPILE)) else diff --git a/examples/embedding/README.md b/examples/embedding/README.md index 989ce1fc8..804dfede6 100644 --- a/examples/embedding/README.md +++ b/examples/embedding/README.md @@ -18,7 +18,7 @@ Building the example is as simple as running: It's worth to trace what's happening behind the scenes though: 1. As a first step, a MicroPython library is built. This is handled by a -seperate makefile, Makefile.upylib. It is more or less complex, but the +separate makefile, Makefile.upylib. It is more or less complex, but the good news is that you won't need to change anything in it, just use it as is, the main Makefile shows how. What may require editing though is a MicroPython configuration file. MicroPython is highly configurable, so diff --git a/extmod/modlwip.c b/extmod/modlwip.c index c72849cf9..47669cb3a 100644 --- a/extmod/modlwip.c +++ b/extmod/modlwip.c @@ -373,7 +373,7 @@ STATIC err_t _lwip_tcp_recv(void *arg, struct tcp_pcb *tcpb, struct pbuf *p, err } /*******************************************************************************/ -// Functions for socket send/recieve operations. Socket send/recv and friends call +// Functions for socket send/receive operations. Socket send/recv and friends call // these to do the work. // Helper function for send/sendto to handle UDP packets. @@ -805,7 +805,7 @@ STATIC mp_obj_t lwip_socket_connect(mp_obj_t self_in, mp_obj_t addr_in) { mp_raise_OSError(MP_EINPROGRESS); } } - // Register our recieve callback. + // Register our receive callback. tcp_recv(socket->pcb.tcp, _lwip_tcp_recv); socket->state = STATE_CONNECTING; err = tcp_connect(socket->pcb.tcp, &dest, port, _lwip_tcp_connected); diff --git a/extmod/modwebsocket.c b/extmod/modwebsocket.c index 8200ea708..9e17d6a6d 100644 --- a/extmod/modwebsocket.c +++ b/extmod/modwebsocket.c @@ -132,7 +132,7 @@ STATIC mp_uint_t websocket_read(mp_obj_t self_in, void *buf, mp_uint_t size, int self->buf_pos = 0; self->to_recv = to_recv; - self->msg_sz = sz; // May be overriden by FRAME_OPT + self->msg_sz = sz; // May be overridden by FRAME_OPT if (to_recv != 0) { self->state = FRAME_OPT; } else { diff --git a/lib/timeutils/timeutils.c b/lib/timeutils/timeutils.c index 0af39a295..06915f25a 100644 --- a/lib/timeutils/timeutils.c +++ b/lib/timeutils/timeutils.c @@ -165,7 +165,7 @@ mp_uint_t timeutils_mktime(mp_uint_t year, mp_int_t month, mp_int_t mday, // // tm_tomorrow = list(time.localtime()) // tm_tomorrow[2] += 1 # Adds 1 to mday - // tomorrow = time.mktime(tm_tommorrow) + // tomorrow = time.mktime(tm_tomorrow) // // And not have to worry about all the weird overflows. // diff --git a/lib/utils/stdout_helpers.c b/lib/utils/stdout_helpers.c index 5f7a17d32..3de119757 100644 --- a/lib/utils/stdout_helpers.c +++ b/lib/utils/stdout_helpers.c @@ -9,7 +9,7 @@ * implementation below can be used. */ -// Send "cooked" string of given length, where every occurance of +// Send "cooked" string of given length, where every occurrence of // LF character is replaced with CR LF. void mp_hal_stdout_tx_strn_cooked(const char *str, size_t len) { while (len--) { diff --git a/py/asmthumb.c b/py/asmthumb.c index 749c1e405..7e92e4de4 100644 --- a/py/asmthumb.c +++ b/py/asmthumb.c @@ -52,7 +52,7 @@ void asm_thumb_end_pass(asm_thumb_t *as) { #if defined(MCU_SERIES_F7) if (as->base.pass == MP_ASM_PASS_EMIT) { - // flush D-cache, so the code emited is stored in memory + // flush D-cache, so the code emitted is stored in memory SCB_CleanDCache_by_Addr((uint32_t*)as->base.code_base, as->base.code_size); // invalidate I-cache SCB_InvalidateICache(); diff --git a/py/builtinimport.c b/py/builtinimport.c index d01ebbe73..6994fc48f 100644 --- a/py/builtinimport.c +++ b/py/builtinimport.c @@ -271,7 +271,7 @@ mp_obj_t mp_builtin___import__(size_t n_args, const mp_obj_t *args) { if (level != 0) { // What we want to do here is to take name of current module, // chop trailing components, and concatenate with passed-in - // module name, thus resolving relative import name into absolue. + // module name, thus resolving relative import name into absolute. // This even appears to be correct per // http://legacy.python.org/dev/peps/pep-0328/#relative-imports-and-name // "Relative imports use a module's __name__ attribute to determine that @@ -441,7 +441,7 @@ mp_obj_t mp_builtin___import__(size_t n_args, const mp_obj_t *args) { #if MICROPY_CPYTHON_COMPAT // Store module as "__main__" in the dictionary of loaded modules (returned by sys.modules). mp_obj_dict_store(MP_OBJ_FROM_PTR(&MP_STATE_VM(mp_loaded_modules_dict)), MP_OBJ_NEW_QSTR(MP_QSTR___main__), module_obj); - // Store real name in "__main__" attribute. Choosen semi-randonly, to reuse existing qstr's. + // Store real name in "__main__" attribute. Chosen semi-randonly, to reuse existing qstr's. mp_obj_dict_store(MP_OBJ_FROM_PTR(o->globals), MP_OBJ_NEW_QSTR(MP_QSTR___main__), MP_OBJ_NEW_QSTR(mod_name)); #endif } diff --git a/py/compile.c b/py/compile.c index 8533e0528..3b6a264d6 100644 --- a/py/compile.c +++ b/py/compile.c @@ -939,7 +939,7 @@ STATIC void c_del_stmt(compiler_t *comp, mp_parse_node_t pn) { } } } else { - // some arbitrary statment that we can't delete (eg del 1) + // some arbitrary statement that we can't delete (eg del 1) goto cannot_delete; } @@ -1090,7 +1090,7 @@ STATIC void compile_import_name(compiler_t *comp, mp_parse_node_struct_t *pns) { STATIC void compile_import_from(compiler_t *comp, mp_parse_node_struct_t *pns) { mp_parse_node_t pn_import_source = pns->nodes[0]; - // extract the preceeding .'s (if any) for a relative import, to compute the import level + // extract the preceding .'s (if any) for a relative import, to compute the import level uint import_level = 0; do { mp_parse_node_t pn_rel; diff --git a/py/misc.h b/py/misc.h index 146b9a8e4..caa5945bf 100644 --- a/py/misc.h +++ b/py/misc.h @@ -197,7 +197,7 @@ int DEBUG_printf(const char *fmt, ...); extern mp_uint_t mp_verbose_flag; // This is useful for unicode handling. Some CPU archs has -// special instructions for efficient implentation of this +// special instructions for efficient implementation of this // function (e.g. CLZ on ARM). // NOTE: this function is unused at the moment #ifndef count_lead_ones diff --git a/py/mkenv.mk b/py/mkenv.mk index eb1e44fef..b167b2533 100644 --- a/py/mkenv.mk +++ b/py/mkenv.mk @@ -32,7 +32,7 @@ ifeq ($(BUILD_VERBOSE),0) $(info Use make V=1 or set BUILD_VERBOSE in your environment to increase build verbosity.) endif -# default settings; can be overriden in main Makefile +# default settings; can be overridden in main Makefile PY_SRC ?= $(TOP)/py BUILD ?= build diff --git a/py/mpconfig.h b/py/mpconfig.h index a61d431e5..78e346d73 100644 --- a/py/mpconfig.h +++ b/py/mpconfig.h @@ -32,7 +32,7 @@ // mpconfigport.h is a file containing configuration settings for a // particular port. mpconfigport.h is actually a default name for -// such config, and it can be overriden using MP_CONFIGFILE preprocessor +// such config, and it can be overridden using MP_CONFIGFILE preprocessor // define (you can do that by passing CFLAGS_EXTRA='-DMP_CONFIGFILE=""' // argument to make when using standard MicroPython makefiles). // This is useful to have more than one config per port, for example, diff --git a/py/obj.c b/py/obj.c index 98ffa930b..493945a22 100644 --- a/py/obj.c +++ b/py/obj.c @@ -401,7 +401,7 @@ mp_obj_t mp_obj_id(mp_obj_t o_in) { return MP_OBJ_NEW_SMALL_INT(id); } else { // If that didn't work, well, let's return long int, just as - // a (big) positve value, so it will never clash with the range + // a (big) positive value, so it will never clash with the range // of small int returned in previous case. return mp_obj_new_int_from_uint((mp_uint_t)id); } diff --git a/py/objstr.c b/py/objstr.c index 70de0a693..a1e223572 100644 --- a/py/objstr.c +++ b/py/objstr.c @@ -798,7 +798,7 @@ STATIC mp_obj_t str_uni_strip(int type, size_t n_args, const mp_obj_t *args) { } assert(last_good_char_pos >= first_good_char_pos); - //+1 to accomodate the last character + //+1 to accommodate the last character size_t stripped_len = last_good_char_pos - first_good_char_pos + 1; if (stripped_len == orig_str_len) { // If nothing was stripped, don't bother to dup original string @@ -1811,7 +1811,7 @@ STATIC mp_obj_t str_islower(mp_obj_t self_in) { } #if MICROPY_CPYTHON_COMPAT -// These methods are superfluous in the presense of str() and bytes() +// These methods are superfluous in the presence of str() and bytes() // constructors. // TODO: should accept kwargs too STATIC mp_obj_t bytes_decode(size_t n_args, const mp_obj_t *args) { diff --git a/py/py.mk b/py/py.mk index 5ff1fd6a6..70891677d 100644 --- a/py/py.mk +++ b/py/py.mk @@ -25,7 +25,7 @@ ifeq ($(MICROPY_SSL_AXTLS),1) CFLAGS_MOD += -DMICROPY_SSL_AXTLS=1 -I../lib/axtls/ssl -I../lib/axtls/crypto -I../lib/axtls/config LDFLAGS_MOD += -Lbuild -laxtls else ifeq ($(MICROPY_SSL_MBEDTLS),1) -# Can be overriden by ports which have "builtin" mbedTLS +# Can be overridden by ports which have "builtin" mbedTLS MICROPY_SSL_MBEDTLS_INCLUDE ?= ../lib/mbedtls/include CFLAGS_MOD += -DMICROPY_SSL_MBEDTLS=1 -I$(MICROPY_SSL_MBEDTLS_INCLUDE) LDFLAGS_MOD += -L../lib/mbedtls/library -lmbedx509 -lmbedtls -lmbedcrypto diff --git a/py/ringbuf.h b/py/ringbuf.h index 5662594f7..5e108afad 100644 --- a/py/ringbuf.h +++ b/py/ringbuf.h @@ -33,7 +33,7 @@ typedef struct _ringbuf_t { uint16_t iput; } ringbuf_t; -// Static initalization: +// Static initialization: // byte buf_array[N]; // ringbuf_t buf = {buf_array, sizeof(buf_array)}; diff --git a/py/stream.c b/py/stream.c index c915110e0..d3fc767bb 100644 --- a/py/stream.c +++ b/py/stream.c @@ -51,7 +51,7 @@ STATIC mp_obj_t stream_readall(mp_obj_t self_in); #define STREAM_CONTENT_TYPE(stream) (((stream)->is_text) ? &mp_type_str : &mp_type_bytes) // Returns error condition in *errcode, if non-zero, return value is number of bytes written -// before error condition occured. If *errcode == 0, returns total bytes written (which will +// before error condition occurred. If *errcode == 0, returns total bytes written (which will // be equal to input size). mp_uint_t mp_stream_rw(mp_obj_t stream, void *buf_, mp_uint_t size, int *errcode, byte flags) { byte *buf = buf_; diff --git a/py/vm.c b/py/vm.c index 5094e3e45..ad3d9e29c 100644 --- a/py/vm.c +++ b/py/vm.c @@ -947,7 +947,7 @@ unwind_jump:; DECODE_UINT; // unum & 0xff == n_positional // (unum >> 8) & 0xff == n_keyword - // We have folowing stack layout here: + // We have following stack layout here: // fun arg0 arg1 ... kw0 val0 kw1 val1 ... seq dict <- TOS sp -= (unum & 0xff) + ((unum >> 7) & 0x1fe) + 2; #if MICROPY_STACKLESS @@ -1018,7 +1018,7 @@ unwind_jump:; DECODE_UINT; // unum & 0xff == n_positional // (unum >> 8) & 0xff == n_keyword - // We have folowing stack layout here: + // We have following stack layout here: // fun self arg0 arg1 ... kw0 val0 kw1 val1 ... seq dict <- TOS sp -= (unum & 0xff) + ((unum >> 7) & 0x1fe) + 3; #if MICROPY_STACKLESS diff --git a/qemu-arm/README.md b/qemu-arm/README.md index 329ae4d92..0cf93c7d5 100644 --- a/qemu-arm/README.md +++ b/qemu-arm/README.md @@ -4,7 +4,7 @@ provided by QEMU (http://qemu.org). The purposes of this port are to enable: 1. Continuous integration - - run tests agains architecture-specific parts of code base + - run tests against architecture-specific parts of code base 2. Experimentation - simulation & prototyping of anything that has architecture-specific code diff --git a/tests/basics/namedtuple1.py b/tests/basics/namedtuple1.py index 132dcf96b..70372f7ca 100644 --- a/tests/basics/namedtuple1.py +++ b/tests/basics/namedtuple1.py @@ -76,7 +76,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/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/pyb/can.py b/tests/pyb/can.py index 617eb7ccc..7f2d070ec 100644 --- a/tests/pyb/can.py +++ b/tests/pyb/can.py @@ -158,7 +158,7 @@ print(can.recv(1)) del can -# Testing asyncronous send +# Testing asynchronous send can = CAN(1, CAN.LOOPBACK) can.setfilter(0, CAN.MASK16, 0, (0, 0, 0, 0)) diff --git a/tests/thread/stress_aes.py b/tests/thread/stress_aes.py index ecc963c92..df75e616c 100644 --- a/tests/thread/stress_aes.py +++ b/tests/thread/stress_aes.py @@ -8,7 +8,7 @@ # # The AES code comes first (code originates from a C version authored by D.P.George) # and then the test harness at the bottom. It can be tuned to be more/less -# agressive by changing the amount of data to encrypt, the number of loops and +# aggressive by changing the amount of data to encrypt, the number of loops and # the number of threads. # # MIT license; Copyright (c) 2016 Damien P. George on behalf of Pycom Ltd diff --git a/tests/wipy/uart.py b/tests/wipy/uart.py index a3a1c14e8..8e794015d 100644 --- a/tests/wipy/uart.py +++ b/tests/wipy/uart.py @@ -95,7 +95,7 @@ print(uart1.read() == None) print(uart1.write(b'123') == 3) print(uart0.read() == b'123') -# no pin assignemnt +# no pin assignment uart0 = UART(0, 1000000, pins=(None, None)) print(uart0.write(b'123456789') == 9) print(uart1.read() == None) diff --git a/tools/insert-usb-ids.py b/tools/insert-usb-ids.py index 420db34c5..cdccd3be9 100644 --- a/tools/insert-usb-ids.py +++ b/tools/insert-usb-ids.py @@ -1,4 +1,4 @@ -# Reads the USB VID and PID from the file specifed by sys.arg[1] and then +# Reads the USB VID and PID from the file specified by sys.argv[1] and then # inserts those values into the template file specified by sys.argv[2], # printing the result to stdout diff --git a/tools/pyboard.py b/tools/pyboard.py index 5eac030bd..921ffc52d 100755 --- a/tools/pyboard.py +++ b/tools/pyboard.py @@ -69,7 +69,7 @@ class TelnetToSerial: self.tn.write(bytes(password, 'ascii') + b"\r\n") if b'for more information.' in self.tn.read_until(b'Type "help()" for more information.', timeout=read_timeout): - # login succesful + # login successful from collections import deque self.fifo = deque() return diff --git a/unix/Makefile b/unix/Makefile index 837ddf2b7..006bce0ef 100644 --- a/unix/Makefile +++ b/unix/Makefile @@ -262,7 +262,7 @@ coverage_test: coverage gcov -o build-coverage/extmod ../extmod/*.c # Value of configure's --host= option (required for cross-compilation). -# Deduce it from CROSS_COMPILE by default, but can be overriden. +# Deduce it from CROSS_COMPILE by default, but can be overridden. ifneq ($(CROSS_COMPILE),) CROSS_COMPILE_HOST = --host=$(patsubst %-,%,$(CROSS_COMPILE)) else diff --git a/unix/modsocket.c b/unix/modsocket.c index 9ca04b88b..c7be6461e 100644 --- a/unix/modsocket.c +++ b/unix/modsocket.c @@ -58,7 +58,7 @@ from socket_more_funcs2 import * ------------------- I.e. this module should stay lean, and more functions (if needed) - should be add to seperate modules (C or Python level). + should be add to separate modules (C or Python level). */ #define MICROPY_SOCKET_EXTRA (0) diff --git a/windows/windows_mphal.c b/windows/windows_mphal.c index 1dd3105d8..a73140e54 100644 --- a/windows/windows_mphal.c +++ b/windows/windows_mphal.c @@ -72,7 +72,7 @@ void mp_hal_stdio_mode_orig(void) { // Previous versions of the mp_hal code would install a handler whenever Ctrl-C input is // allowed and remove the handler again when it is not. That is not necessary though (1), // and it might introduce problems (2) because console notifications are delivered to the -// application in a seperate thread. +// application in a separate thread. // (1) mp_hal_set_interrupt_char effectively enables/disables processing of Ctrl-C via the // ENABLE_PROCESSED_INPUT flag so in raw mode console_sighandler won't be called. // (2) if mp_hal_set_interrupt_char would remove the handler while Ctrl-C was issued earlier, diff --git a/zephyr/modutime.c b/zephyr/modutime.c index 378068bb3..0c268046a 100644 --- a/zephyr/modutime.c +++ b/zephyr/modutime.c @@ -36,7 +36,7 @@ #include "extmod/utime_mphal.h" STATIC mp_obj_t mod_time_time(void) { - /* The absense of FP support is deliberate. The Zephyr port uses + /* The absence of FP support is deliberate. The Zephyr port uses * single precision floats so the fraction component will start to * lose precision on devices with a long uptime. */ -- cgit v1.2.3