diff options
24 files changed, 815 insertions, 740 deletions
diff --git a/.gitignore b/.gitignore index 403fcc299..f5edb89f0 100644 --- a/.gitignore +++ b/.gitignore @@ -52,7 +52,7 @@ _build # Generated rst files ###################### genrst/ -autoapi/ +/autoapi/ # ctags and similar ################### @@ -67,6 +67,7 @@ help: clean: rm -rf $(BUILDDIR)/* + rm -rf autoapi rm -rf $(STUBDIR) $(DISTDIR) *.egg-info html: stubs @@ -213,10 +214,10 @@ check-translate: locale/circuitpython.pot $(wildcard locale/*.po) $(PYTHON) tools/check_translations.py $^ stubs: - mkdir -p circuitpython-stubs - python tools/extract_pyi.py shared-bindings/ $(STUBDIR) - python tools/extract_pyi.py ports/atmel-samd/bindings $(STUBDIR) - python setup.py sdist + @mkdir -p circuitpython-stubs + @$(PYTHON) tools/extract_pyi.py shared-bindings/ $(STUBDIR) + @$(PYTHON) tools/extract_pyi.py ports/atmel-samd/bindings $(STUBDIR) + @$(PYTHON) setup.py -q sdist update-frozen-libraries: @echo "Updating all frozen libraries to latest tagged version." @@ -71,11 +71,12 @@ extensions.append('autoapi.extension') autoapi_type = 'python' # Uncomment this if debugging autoapi -# autoapi_keep_files = True -autoapi_dirs = ['circuitpython-stubs'] +autoapi_keep_files = True +autoapi_dirs = [os.path.join('circuitpython-stubs', x) for x in os.listdir('circuitpython-stubs')] autoapi_add_toctree_entry = False autoapi_options = ['members', 'undoc-members', 'private-members', 'show-inheritance', 'special-members', 'show-module-summary'] autoapi_template_dir = 'docs/autoapi/templates' +autoapi_python_use_implicit_namespaces = True # The encoding of source files. #source_encoding = 'utf-8-sig' diff --git a/docs/autoapi/templates/python/module.rst b/docs/autoapi/templates/python/module.rst new file mode 100644 index 000000000..7ede6bdfd --- /dev/null +++ b/docs/autoapi/templates/python/module.rst @@ -0,0 +1,93 @@ +{% if not obj.display %} +:orphan: + +{% endif %} +:mod:`{{ obj.name }}` +======={{ "=" * obj.name|length }} + +.. py:module:: {{ obj.name }} + +{% if obj.docstring %} +.. autoapi-nested-parse:: + + {{ obj.docstring|prepare_docstring|indent(3) }} + +{% endif %} + +{% block subpackages %} +{% set visible_subpackages = obj.subpackages|selectattr("display")|list %} +{% if visible_subpackages %} +.. toctree:: + :titlesonly: + :maxdepth: 3 + +{% for subpackage in visible_subpackages %} + {{ subpackage.short_name }}/index.rst +{% endfor %} + + +{% endif %} +{% endblock %} +{% block submodules %} +{% set visible_submodules = obj.submodules|selectattr("display")|list %} +{% if visible_submodules %} + +.. toctree:: + :titlesonly: + :maxdepth: 1 + +{% for submodule in visible_submodules %} + {{ submodule.short_name }}/index.rst +{% endfor %} + + +{% endif %} +{% endblock %} +{% block content %} +{% if obj.all is not none %} +{% set visible_children = obj.children|selectattr("short_name", "in", obj.all)|list %} +{% elif obj.type is equalto("package") %} +{% set visible_children = obj.children|selectattr("display")|list %} +{% else %} +{% set visible_children = obj.children|selectattr("display")|rejectattr("imported")|list %} +{% endif %} +{% if visible_children %} + +{% set visible_classes = visible_children|selectattr("type", "equalto", "class")|list %} +{% set visible_functions = visible_children|selectattr("type", "equalto", "function")|list %} +{% if "show-module-summary" in autoapi_options and (visible_classes or visible_functions) %} +{% block classes %} +{% if visible_classes %} +Classes +~~~~~~~ + +.. autoapisummary:: + +{% for klass in visible_classes %} + {{ klass.id }} +{% endfor %} + + +{% endif %} +{% endblock %} + +{% block functions %} +{% if visible_functions %} +Functions +~~~~~~~~~ + +.. autoapisummary:: + +{% for function in visible_functions %} + {{ function.id }} +{% endfor %} + + +{% endif %} +{% endblock %} +{% endif %} +{% for obj_item in visible_children %} +{{ obj_item.rendered|indent(0) }} +{% endfor %} +{% endif %} +{% endblock %} diff --git a/locale/sv.po b/locale/sv.po index 493245dbf..5708b6642 100644 --- a/locale/sv.po +++ b/locale/sv.po @@ -3,25 +3,28 @@ # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. # -#, fuzzy msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2020-05-12 14:37+1000\n" -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" +"PO-Revision-Date: 2020-05-14 12:41+0000\n" +"Last-Translator: Jonny Bergdahl <jonny@bergdahl.it>\n" "Language-Team: LANGUAGE <LL@li.org>\n" -"Language: \n" +"Language: sv\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 4.1-dev\n" #: main.c msgid "" "\n" "Code done running. Waiting for reload.\n" msgstr "" +"\n" +"Koden har kört klart. Väntar på omladdning.\n" #: supervisor/shared/safe_mode.c msgid "" @@ -35,23 +38,26 @@ msgid "" "\n" "To exit, please reset the board without " msgstr "" +"\n" +"För att avsluta, resetta kortet utan " #: py/obj.c msgid " File \"%q\"" -msgstr "" +msgstr " Filen \"%q\"" #: py/obj.c msgid " File \"%q\", line %d" -msgstr "" +msgstr " Fil \"%q\", rad %d" #: main.c +#, fuzzy msgid " output:\n" -msgstr "" +msgstr " utdata:\n" #: py/objstr.c #, c-format msgid "%%c requires int or char" -msgstr "" +msgstr "%%c kräver int eller char" #: shared-bindings/rgbmatrix/RGBMatrix.c #, c-format @@ -60,100 +66,101 @@ msgstr "" #: shared-bindings/microcontroller/Pin.c msgid "%q in use" -msgstr "" +msgstr "%q används redan" #: py/obj.c msgid "%q index out of range" -msgstr "" +msgstr "Index %q ligger utanför intervallet" #: py/obj.c msgid "%q indices must be integers, not %s" -msgstr "" +msgstr "Indexet %q måste vara ett heltal, inte %s" #: shared-bindings/vectorio/Polygon.c +#, fuzzy msgid "%q list must be a list" -msgstr "" +msgstr "%q-listan måste vara en lista" #: shared-bindings/_bleio/CharacteristicBuffer.c #: shared-bindings/_bleio/PacketBuffer.c shared-bindings/displayio/Group.c #: shared-bindings/displayio/Shape.c shared-bindings/vectorio/Circle.c #: shared-bindings/vectorio/Rectangle.c msgid "%q must be >= 1" -msgstr "" +msgstr "%q måste vara >= 1" #: shared-bindings/vectorio/Polygon.c msgid "%q must be a tuple of length 2" -msgstr "" +msgstr "%q måste vara en tuple av längd 2" #: shared-bindings/fontio/BuiltinFont.c msgid "%q should be an int" -msgstr "" +msgstr "%q ska vara en int" #: py/bc.c py/objnamedtuple.c msgid "%q() takes %d positional arguments but %d were given" -msgstr "" +msgstr "%q() kräver %d positionsargument men %d gavs" #: py/argcheck.c msgid "'%q' argument required" -msgstr "" +msgstr "'%q' argument krävs" #: py/emitinlinethumb.c py/emitinlinextensa.c #, c-format msgid "'%s' expects a label" -msgstr "" +msgstr "'%s' förväntar sig en etikett" #: py/emitinlinethumb.c py/emitinlinextensa.c #, c-format msgid "'%s' expects a register" -msgstr "" +msgstr "'%s' förväntar sig ett register" #: py/emitinlinethumb.c #, c-format msgid "'%s' expects a special register" -msgstr "" +msgstr "'%s' förväntar sig ett specialregister" #: py/emitinlinethumb.c #, c-format msgid "'%s' expects an FPU register" -msgstr "" +msgstr "'%s' förväntar sig ett FPU-register" #: py/emitinlinethumb.c #, c-format msgid "'%s' expects an address of the form [a, b]" -msgstr "" +msgstr "'%s' förväntar sig en adress i formen [a, b]" #: py/emitinlinethumb.c py/emitinlinextensa.c #, c-format msgid "'%s' expects an integer" -msgstr "" +msgstr "'%s' förväntar sig ett heltal" #: py/emitinlinethumb.c #, c-format msgid "'%s' expects at most r%d" -msgstr "" +msgstr "'%s' förväntar sig högst r%d" #: py/emitinlinethumb.c #, c-format msgid "'%s' expects {r0, r1, ...}" -msgstr "" +msgstr "'%s' förväntar sig {r0, r1, ...}" #: py/emitinlinextensa.c #, c-format msgid "'%s' integer %d is not within range %d..%d" -msgstr "" +msgstr "'%s' heltal %d ligger inte inom intervallet %d..%d" #: py/emitinlinethumb.c #, c-format msgid "'%s' integer 0x%x does not fit in mask 0x%x" -msgstr "" +msgstr "'%s' heltal 0x%x får inte plats i mask 0x%x" #: py/runtime.c msgid "'%s' object cannot assign attribute '%q'" -msgstr "" +msgstr "Objektet '%s' kan inte tilldela attributet '%q'" #: py/proto.c msgid "'%s' object does not support '%q'" -msgstr "" +msgstr "Objektet '%s' har inte stöd för '%q'" #: py/obj.c #, c-format @@ -167,17 +174,17 @@ msgstr "" #: py/runtime.c msgid "'%s' object has no attribute '%q'" -msgstr "" +msgstr "Objektet '%s' har inget attribut '%q'" #: py/runtime.c #, c-format msgid "'%s' object is not an iterator" -msgstr "" +msgstr "Objektet '%s' är inte en iterator" #: py/objtype.c py/runtime.c #, c-format msgid "'%s' object is not callable" -msgstr "" +msgstr "Objektet '%s' kan inte anropas" #: py/runtime.c #, c-format diff --git a/ports/atmel-samd/audio_dma.c b/ports/atmel-samd/audio_dma.c index 352af8980..93cd96b98 100644 --- a/ports/atmel-samd/audio_dma.c +++ b/ports/atmel-samd/audio_dma.c @@ -31,6 +31,7 @@ #include "shared-bindings/audiocore/RawSample.h" #include "shared-bindings/audiocore/WaveFile.h" +#include "supervisor/shared/tick.h" #include "py/mpstate.h" #include "py/runtime.h" @@ -60,6 +61,7 @@ void audio_dma_free_channel(uint8_t channel) { assert(audio_dma_allocated[channel]); audio_dma_disable_channel(channel); audio_dma_allocated[channel] = false; + supervisor_disable_tick(); } void audio_dma_disable_channel(uint8_t channel) { @@ -71,6 +73,7 @@ void audio_dma_disable_channel(uint8_t channel) { void audio_dma_enable_channel(uint8_t channel) { if (channel >= AUDIO_DMA_CHANNEL_COUNT) return; + supervisor_enable_tick(); dma_enable_channel(channel); } @@ -318,6 +321,9 @@ void audio_dma_reset(void) { for (uint8_t i = 0; i < AUDIO_DMA_CHANNEL_COUNT; i++) { audio_dma_state[i] = NULL; audio_dma_pending[i] = false; + if (audio_dma_allocated[i]) { + supervisor_disable_tick(); + } audio_dma_allocated[i] = false; audio_dma_disable_channel(i); dma_descriptor(i)->BTCTRL.bit.VALID = false; diff --git a/shared-bindings/aesio/aes.c b/shared-bindings/aesio/aes.c index 7a559b0bb..f6a0a89b8 100644 --- a/shared-bindings/aesio/aes.c +++ b/shared-bindings/aesio/aes.c @@ -99,9 +99,10 @@ STATIC mp_obj_t aesio_aes_make_new(const mp_obj_type_t *type, size_t n_args, STATIC mp_obj_t aesio_aes_rekey(size_t n_args, const mp_obj_t *pos_args) { aesio_aes_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); - size_t key_length = 0; - const uint8_t *key = - (const uint8_t *)mp_obj_str_get_data(pos_args[1], &key_length); + mp_buffer_info_t bufinfo; + mp_get_buffer_raise(pos_args[1], &bufinfo, MP_BUFFER_READ); + const uint8_t *key = bufinfo.buf; + size_t key_length = bufinfo.len; if (key == NULL) { mp_raise_ValueError(translate("No key was specified")); } @@ -111,8 +112,9 @@ STATIC mp_obj_t aesio_aes_rekey(size_t n_args, const mp_obj_t *pos_args) { const uint8_t *iv = NULL; if (n_args > 2) { - size_t iv_length = 0; - iv = (const uint8_t *)mp_obj_str_get_data(pos_args[2], &iv_length); + mp_get_buffer_raise(pos_args[2], &bufinfo, MP_BUFFER_READ); + size_t iv_length = bufinfo.len; + iv = (const uint8_t *)bufinfo.buf; if (iv_length != AES_BLOCKLEN) { mp_raise_TypeError_varg(translate("IV must be %d bytes long"), AES_BLOCKLEN); @@ -168,7 +170,7 @@ STATIC mp_obj_t aesio_aes_encrypt_into(mp_obj_t aesio_obj, mp_obj_t src, mp_buffer_info_t srcbufinfo, destbufinfo; mp_get_buffer_raise(src, &srcbufinfo, MP_BUFFER_READ); - mp_get_buffer_raise(dest, &destbufinfo, MP_BUFFER_READ); + mp_get_buffer_raise(dest, &destbufinfo, MP_BUFFER_WRITE); validate_length(aes, srcbufinfo.len, destbufinfo.len); memcpy(destbufinfo.buf, srcbufinfo.buf, srcbufinfo.len); @@ -199,7 +201,7 @@ STATIC mp_obj_t aesio_aes_decrypt_into(mp_obj_t aesio_obj, mp_obj_t src, mp_buffer_info_t srcbufinfo, destbufinfo; mp_get_buffer_raise(src, &srcbufinfo, MP_BUFFER_READ); - mp_get_buffer_raise(dest, &destbufinfo, MP_BUFFER_READ); + mp_get_buffer_raise(dest, &destbufinfo, MP_BUFFER_WRITE); validate_length(aes, srcbufinfo.len, destbufinfo.len); memcpy(destbufinfo.buf, srcbufinfo.buf, srcbufinfo.len); @@ -244,11 +246,8 @@ MP_DEFINE_CONST_FUN_OBJ_2(aesio_aes_set_mode_obj, aesio_aes_set_mode); const mp_obj_property_t aesio_aes_mode_obj = { .base.type = &mp_type_property, - .proxy = { - (mp_obj_t)&aesio_aes_get_mode_obj, - (mp_obj_t)&aesio_aes_set_mode_obj, - (mp_obj_t)&mp_const_none_obj - }, + .proxy = {(mp_obj_t)&aesio_aes_get_mode_obj, + (mp_obj_t)&aesio_aes_set_mode_obj, (mp_obj_t)&mp_const_none_obj}, }; STATIC const mp_rom_map_elem_t aesio_locals_dict_table[] = { diff --git a/shared-bindings/gamepad/GamePad.c b/shared-bindings/gamepad/GamePad.c index a750892fe..9a23344b3 100644 --- a/shared-bindings/gamepad/GamePad.c +++ b/shared-bindings/gamepad/GamePad.c @@ -33,6 +33,7 @@ #include "shared-bindings/gamepad/__init__.h" #include "shared-bindings/digitalio/DigitalInOut.h" #include "supervisor/shared/translate.h" +#include "supervisor/shared/tick.h" //| class GamePad: //| """Scan buttons for presses @@ -102,9 +103,11 @@ STATIC mp_obj_t gamepad_make_new(const mp_obj_type_t *type, size_t n_args, gamepad_obj_t* gamepad_singleton = MP_STATE_VM(gamepad_singleton); if (!gamepad_singleton || !MP_OBJ_IS_TYPE(MP_OBJ_FROM_PTR(gamepad_singleton), &gamepad_type)) { - gamepad_singleton = m_new_obj(gamepad_obj_t); + gamepad_singleton = m_new_ll_obj(gamepad_obj_t); gamepad_singleton->base.type = &gamepad_type; - gamepad_singleton = gc_make_long_lived(gamepad_singleton); + if (!MP_STATE_VM(gamepad_singleton)) { + supervisor_enable_tick(); + } MP_STATE_VM(gamepad_singleton) = gamepad_singleton; } common_hal_gamepad_gamepad_init(gamepad_singleton, args, n_args); diff --git a/shared-bindings/gamepadshift/GamePadShift.c b/shared-bindings/gamepadshift/GamePadShift.c index 48b579457..854f092ad 100644 --- a/shared-bindings/gamepadshift/GamePadShift.c +++ b/shared-bindings/gamepadshift/GamePadShift.c @@ -31,6 +31,7 @@ #include "shared-bindings/gamepadshift/GamePadShift.h" #include "shared-bindings/gamepadshift/__init__.h" #include "supervisor/shared/translate.h" +#include "supervisor/shared/tick.h" //| class GamePadShift: //| """Scan buttons for presses through a shift register""" @@ -70,9 +71,11 @@ STATIC mp_obj_t gamepadshift_make_new(const mp_obj_type_t *type, size_t n_args, if (!gamepad_singleton || !MP_OBJ_IS_TYPE(MP_OBJ_FROM_PTR(gamepad_singleton), &gamepadshift_type)) { - gamepad_singleton = m_new_obj(gamepadshift_obj_t); + gamepad_singleton = m_new_ll_obj(gamepadshift_obj_t); gamepad_singleton->base.type = &gamepadshift_type; - gamepad_singleton = gc_make_long_lived(gamepad_singleton); + if (!MP_STATE_VM(gamepad_singleton)) { + supervisor_enable_tick(); + } MP_STATE_VM(gamepad_singleton) = gamepad_singleton; } common_hal_gamepadshift_gamepadshift_init(gamepad_singleton, clock_pin, data_pin, latch_pin); diff --git a/shared-bindings/help.rst b/shared-bindings/help.rst index 63991bff2..f6d72a556 100644 --- a/shared-bindings/help.rst +++ b/shared-bindings/help.rst @@ -1,26 +1,26 @@ -# This file is part of the MicroPython project, http://micropython.org/ -# -# The MIT License (MIT) -# -# Copyright (c) 2016 Scott Shawcroft for Adafruit Industries -# -# 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. +.. This file is part of the MicroPython project, http://micropython.org/ + + The MIT License (MIT) + + Copyright (c) 2016 Scott Shawcroft for Adafruit Industries + + 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. :func:`help` - Built-in method to provide helpful information ============================================================== diff --git a/shared-bindings/math/__init__.c b/shared-bindings/math/__init__.c index 56155306f..8226a08ec 100644 --- a/shared-bindings/math/__init__.c +++ b/shared-bindings/math/__init__.c @@ -78,178 +78,170 @@ STATIC NORETURN void math_error(void) { // 1.442695040888963407354163704 is 1/_M_LN2 #define log2(x) (log(x) * 1.442695040888963407354163704) #endif - //| Constants - //| --------- - //| - //| e: Any = ... - //| """base of the natural logarithm""" - //| - //| pi: Any = ... - //| """the ratio of a circle's circumference to its diameter""" - //| - - //| Functions - //| --------- - //| - //| def acos(x: Any) -> Any: - //| """Return the inverse cosine of ``x``.""" - //| ... - //| - //| def asin(x: Any) -> Any: - //| """Return the inverse sine of ``x``.""" - //| ... - //| - //| def atan(x: Any) -> Any: - //| """Return the inverse tangent of ``x``.""" - //| ... - //| - //| def atan2(y: Any, x: Any) -> Any: - //| """Return the principal value of the inverse tangent of ``y/x``.""" - //| ... - //| - //| def ceil(x: Any) -> Any: - //| """Return an integer, being ``x`` rounded towards positive infinity.""" - //| ... - //| - //| def copysign(x: Any, y: Any) -> Any: - //| """Return ``x`` with the sign of ``y``.""" - //| ... - //| - //| def cos(x: Any) -> Any: - //| """Return the cosine of ``x``.""" - //| ... - //| - //| def degrees(x: Any) -> Any: - //| """Return radians ``x`` converted to degrees.""" - //| ... - //| - //| def exp(x: Any) -> Any: - //| """Return the exponential of ``x``.""" - //| ... - //| - //| def fabs(x: Any) -> Any: - //| """Return the absolute value of ``x``.""" - //| ... - //| - //| def floor(x: Any) -> Any: - //| """Return an integer, being ``x`` rounded towards negative infinity.""" - //| ... - //| - //| def fmod(x: Any, y: Any) -> Any: - //| """Return the remainder of ``x/y``.""" - //| ... - //| - //| def frexp(x: Any) -> Any: - //| """Decomposes a floating-point number into its mantissa and exponent. - //| The returned value is the tuple ``(m, e)`` such that ``x == m * 2**e`` - //| exactly. If ``x == 0`` then the function returns ``(0.0, 0)``, otherwise - //| the relation ``0.5 <= abs(m) < 1`` holds.""" - //| ... - //| - //| def isfinite(x: Any) -> Any: - //| """Return ``True`` if ``x`` is finite.""" - //| ... - //| - //| def isinf(x: Any) -> Any: - //| """Return ``True`` if ``x`` is infinite.""" - //| ... - //| - //| def isnan(x: Any) -> Any: - //| """Return ``True`` if ``x`` is not-a-number""" - //| ... - //| - //| def ldexp(x: Any, exp: Any) -> Any: - //| """Return ``x * (2**exp)``.""" - //| ... - //| - //| def modf(x: Any) -> Any: - //| """Return a tuple of two floats, being the fractional and integral parts of - //| ``x``. Both return values have the same sign as ``x``.""" - //| ... - //| - //| def pow(x: Any, y: Any) -> Any: - //| """Returns ``x`` to the power of ``y``.""" - //| - //| def radians(x: Any) -> Any: - //| """Return degrees ``x`` converted to radians.""" - //| - //| def sin(x: Any) -> Any: - //| """Return the sine of ``x``.""" - //| ... - //| - //| def sqrt(x: Any) -> Any: - //| """Returns the square root of ``x``.""" - //| ... - //| - //| def tan(x: Any) -> Any: ... - //| """Return the tangent of ``x``.""" - //| ... - //| - //| def trunc(x: Any) -> Any: - //| """Return an integer, being ``x`` rounded towards 0.""" - //| ... - //| + +//| e: Any = ... +//| """base of the natural logarithm""" +//| +//| pi: Any = ... +//| """the ratio of a circle's circumference to its diameter""" +//| + +//| def acos(x: Any) -> Any: +//| """Return the inverse cosine of ``x``.""" +//| ... +//| +//| def asin(x: Any) -> Any: +//| """Return the inverse sine of ``x``.""" +//| ... +//| +//| def atan(x: Any) -> Any: +//| """Return the inverse tangent of ``x``.""" +//| ... +//| +//| def atan2(y: Any, x: Any) -> Any: +//| """Return the principal value of the inverse tangent of ``y/x``.""" +//| ... +//| +//| def ceil(x: Any) -> Any: +//| """Return an integer, being ``x`` rounded towards positive infinity.""" +//| ... +//| +//| def copysign(x: Any, y: Any) -> Any: +//| """Return ``x`` with the sign of ``y``.""" +//| ... +//| +//| def cos(x: Any) -> Any: +//| """Return the cosine of ``x``.""" +//| ... +//| +//| def degrees(x: Any) -> Any: +//| """Return radians ``x`` converted to degrees.""" +//| ... +//| +//| def exp(x: Any) -> Any: +//| """Return the exponential of ``x``.""" +//| ... +//| +//| def fabs(x: Any) -> Any: +//| """Return the absolute value of ``x``.""" +//| ... +//| +//| def floor(x: Any) -> Any: +//| """Return an integer, being ``x`` rounded towards negative infinity.""" +//| ... +//| +//| def fmod(x: Any, y: Any) -> Any: +//| """Return the remainder of ``x/y``.""" +//| ... +//| +//| def frexp(x: Any) -> Any: +//| """Decomposes a floating-point number into its mantissa and exponent. +//| The returned value is the tuple ``(m, e)`` such that ``x == m * 2**e`` +//| exactly. If ``x == 0`` then the function returns ``(0.0, 0)``, otherwise +//| the relation ``0.5 <= abs(m) < 1`` holds.""" +//| ... +//| +//| def isfinite(x: Any) -> Any: +//| """Return ``True`` if ``x`` is finite.""" +//| ... +//| +//| def isinf(x: Any) -> Any: +//| """Return ``True`` if ``x`` is infinite.""" +//| ... +//| +//| def isnan(x: Any) -> Any: +//| """Return ``True`` if ``x`` is not-a-number""" +//| ... +//| +//| def ldexp(x: Any, exp: Any) -> Any: +//| """Return ``x * (2**exp)``.""" +//| ... +//| +//| def modf(x: Any) -> Any: +//| """Return a tuple of two floats, being the fractional and integral parts of +//| ``x``. Both return values have the same sign as ``x``.""" +//| ... +//| +//| def pow(x: Any, y: Any) -> Any: +//| """Returns ``x`` to the power of ``y``.""" +//| +//| def radians(x: Any) -> Any: +//| """Return degrees ``x`` converted to radians.""" +//| +//| def sin(x: Any) -> Any: +//| """Return the sine of ``x``.""" +//| ... +//| +//| def sqrt(x: Any) -> Any: +//| """Returns the square root of ``x``.""" +//| ... +//| +//| def tan(x: Any) -> Any: +//| """Return the tangent of ``x``.""" +//| ... +//| +//| def trunc(x: Any) -> Any: +//| """Return an integer, being ``x`` rounded towards 0.""" +//| ... +//| MATH_FUN_1_ERRCOND(sqrt, sqrt, (x < (mp_float_t)0.0)) MATH_FUN_2(pow, pow) MATH_FUN_1(exp, exp) #if MICROPY_PY_MATH_SPECIAL_FUNCTIONS -// Special functions -// ----------------- -// -// .. function:: expm1(x) -// -// Return ``exp(x) - 1``. -// +//| def expm1(x): +//| """Return ``exp(x) - 1``.""" +//| ... +//| MATH_FUN_1(expm1, expm1) -// .. function:: log2(x) -// -// Return the base-2 logarithm of ``x``. -// +//| def log2(x): +//| """Return the base-2 logarithm of ``x``.""" +//| ... +//| MATH_FUN_1_ERRCOND(log2, log2, (x <= (mp_float_t)0.0)) -// .. function:: log10(x) -// -// Return the base-10 logarithm of ``x``. -// +//| def log10(x): +//| """Return the base-10 logarithm of ``x``.""" +//| ... +//| MATH_FUN_1_ERRCOND(log10, log10, (x <= (mp_float_t)0.0)) -// .. function:: cosh(x) -// -// Return the hyperbolic cosine of ``x``. -// +//| def cosh(x): +//| """Return the hyperbolic cosine of ``x``.""" +//| ... +//| MATH_FUN_1(cosh, cosh) -// .. function:: sinh(x) -// -// Return the hyperbolic sine of ``x``. -// +//| def sinh(x): +//| """Return the hyperbolic sine of ``x``.""" +//| ... +//| MATH_FUN_1(sinh, sinh) -// .. function:: tanh(x) -// -// Return the hyperbolic tangent of ``x``. -// +//| def tanh(x): +//| """Return the hyperbolic tangent of ``x``.""" +//| ... +//| MATH_FUN_1(tanh, tanh) -// .. function:: acosh(x) -// -// Return the inverse hyperbolic cosine of ``x``. -// +//| def acosh(x): +//| """Return the inverse hyperbolic cosine of ``x``.""" +//| ... +//| MATH_FUN_1(acosh, acosh) -// .. function:: asinh(x) -// -// Return the inverse hyperbolic sine of ``x``. -// +//| def asinh(x): +//| """Return the inverse hyperbolic sine of ``x``.""" +//| ... +//| MATH_FUN_1(asinh, asinh) -// .. function:: atanh(x) -// -// Return the inverse hyperbolic tangent of ``x``. -// +//| def atanh(x): +//| """Return the inverse hyperbolic tangent of ``x``.""" +//| ... +//| MATH_FUN_1(atanh, atanh) #endif @@ -288,28 +280,28 @@ MATH_FUN_1_TO_INT(trunc, trunc) MATH_FUN_2(ldexp, ldexp) #if MICROPY_PY_MATH_SPECIAL_FUNCTIONS -// .. function:: erf(x) -// -// Return the error function of ``x``. -// +//| def erf(x): +//| """Return the error function of ``x``.""" +//| ... +//| MATH_FUN_1(erf, erf) -// .. function:: erfc(x) -// -// Return the complementary error function of ``x``. -// +//| def erfc(x): +//| """Return the complementary error function of ``x``.""" +//| ... +//| MATH_FUN_1(erfc, erfc) -// .. function:: gamma(x) -// -// Return the gamma function of ``x``. -// +//| def gamma(x): +//| """Return the gamma function of ``x``.""" +//| ... +//| MATH_FUN_1(gamma, tgamma) -// .. function:: lgamma(x) -// -// Return the natural logarithm of the gamma function of ``x``. -// +//| def lgamma(x): +//| """Return the natural logarithm of the gamma function of ``x``.""" +//| ... +//| MATH_FUN_1(lgamma, lgamma) #endif //TODO: factorial, fsum diff --git a/shared-bindings/ulab/__init__.pyi b/shared-bindings/ulab/__init__.pyi index d2ff7eb80..e5de1391b 100644 --- a/shared-bindings/ulab/__init__.pyi +++ b/shared-bindings/ulab/__init__.pyi @@ -1,9 +1,4 @@ - -:mod:`ulab` --- Manipulate numeric data similar to numpy -======================================================== - -.. module:: ulab - :synopsis: Manipulate numeric data similar to numpy +"""Manipulate numeric data similar to numpy `ulab` is a numpy-like module for micropython, meant to simplify and speed up common mathematical operations on arrays. The primary goal was to @@ -17,507 +12,158 @@ https://micropython-ulab.readthedocs.io/en/latest/ `ulab` is modeled after numpy, and aims to be a compatible subset where possible. Numpy's documentation can be found at -https://docs.scipy.org/doc/numpy/index.html - -.. contents:: - -.. attribute:: __version__ - -The closest corresponding version of micropython-ulab - -ulab.array -- 1- and 2- dimensional array ------------------------------------------ - -.. class:: ulab.array(values, \*, dtype=float) - - :param sequence values: Sequence giving the initial content of the array. - :param dtype: The type of array values, ``int8``, ``uint8``, ``int16``, ``uint16``, or ``float`` - - The `values` sequence can either be another ~ulab.array, sequence of numbers - (in which case a 1-dimensional array is created), or a sequence where each - subsequence has the same length (in which case a 2-dimensional array is - created). - - Passing a ~ulab.array and a different dtype can be used to convert an array - from one dtype to another. - - In many cases, it is more convenient to create an array from a function - like `zeros` or `linspace`. - - `ulab.array` implements the buffer protocol, so it can be used in many - places an `array.array` can be used. - - .. attribute:: shape - - The size of the array, a tuple of length 1 or 2 - - .. attribute:: size - - The number of elements in the array - - .. attribute:: itemsize - - The number of elements in the array - - .. method:: flatten(\*, order='C') - - :param order: Whether to flatten by rows ('C') or columns ('F') - - Returns a new `ulab.array` object which is always 1 dimensional. - If order is 'C' (the default", then the data is ordered in rows; - If it is 'F', then the data is ordered in columns. "C" and "F" refer - to the typical storage organization of the C and Fortran languages. - - .. method:: sort(\*, axis=1) +https://docs.scipy.org/doc/numpy/index.html""" - :param axis: Whether to sort elements within rows (0), columns (1), or elements (None) - .. method:: transpose() +class array: + """1- and 2- dimensional array""" + def __init__(self, values, *, dtype=float): + """:param sequence values: Sequence giving the initial content of the array. + :param dtype: The type of array values, ``int8``, ``uint8``, ``int16``, ``uint16``, or ``float`` - Swap the rows and columns of a 2-dimensional array + The `values` sequence can either be another ~ulab.array, sequence of numbers + (in which case a 1-dimensional array is created), or a sequence where each + subsequence has the same length (in which case a 2-dimensional array is + created). - .. method:: __add__() + Passing a ~ulab.array and a different dtype can be used to convert an array + from one dtype to another. - Adds corresponding elements of the two arrays, or adds a number to all - elements of the array. If both arguments are arrays, their sizes must match. + In many cases, it is more convenient to create an array from a function + like `zeros` or `linspace`. - .. method:: __sub__() + `ulab.array` implements the buffer protocol, so it can be used in many + places an `array.array` can be used.""" + ... - Subtracts corresponding elements of the two arrays, or adds a number to all - elements of the array. If both arguments are arrays, their sizes must match. + shape: tuple = ... + """The size of the array, a tuple of length 1 or 2""" - .. method:: __mul__() + size: int = ... + """The number of elements in the array""" - Multiplies corresponding elements of the two arrays, or multiplies - all elements of the array by a number. If both arguments are arrays, - their sizes must match. + itemsize: int = ... + """The number of elements in the array""" - .. method:: __div__() + def flatten(self, *, order='C'): + """:param order: Whether to flatten by rows ('C') or columns ('F') - Multiplies corresponding elements of the two arrays, or divides - all elements of the array by a number. If both arguments are arrays, - their sizes must match. + Returns a new `ulab.array` object which is always 1 dimensional. + If order is 'C' (the default", then the data is ordered in rows; + If it is 'F', then the data is ordered in columns. "C" and "F" refer + to the typical storage organization of the C and Fortran languages.""" + ... - .. method:: __pow__() + def sort(self, *, axis=1): + """:param axis: Whether to sort elements within rows (0), columns (1), or elements (None)""" + ... - Computes the power (x**y) of corresponding elements of the the two arrays, - or one number and one array. If both arguments are arrays, their sizes - must match. + def transpose(self): + """Swap the rows and columns of a 2-dimensional array""" + ... - .. method:: __getitem__() + def __add__(self): + """Adds corresponding elements of the two arrays, or adds a number to all + elements of the array. If both arguments are arrays, their sizes must match.""" + ... - Retrieve an element of the array. + def __sub__(self): + """Subtracts corresponding elements of the two arrays, or adds a number to all + elements of the array. If both arguments are arrays, their sizes must match.""" + ... - .. method:: __setitem__() + def __mul__(self): + """Multiplies corresponding elements of the two arrays, or multiplies + all elements of the array by a number. If both arguments are arrays, + their sizes must match.""" + ... - Set an element of the array. + def __div__(self): + """Multiplies corresponding elements of the two arrays, or divides + all elements of the array by a number. If both arguments are arrays, + their sizes must match.""" + ... -Array type codes ----------------- -.. attribute:: int8 + def __pow__(): + """Computes the power (x**y) of corresponding elements of the the two arrays, + or one number and one array. If both arguments are arrays, their sizes + must match.""" + ... - Type code for signed integers in the range -128 .. 127 inclusive, like the 'b' typecode of `array.array` + def __getitem__(): + """Retrieve an element of the array.""" + ... -.. attribute:: int16 + def __setitem__(): + """Set an element of the array.""" + ... - Type code for signed integers in the range -32768 .. 32767 inclusive, like the 'h' typecode of `array.array` +int8 = ... +"""Type code for signed integers in the range -128 .. 127 inclusive, like the 'b' typecode of `array.array`""" -.. attribute:: float +int16 = ... +"""Type code for signed integers in the range -32768 .. 32767 inclusive, like the 'h' typecode of `array.array`""" - Type code for floating point values, like the 'f' typecode of `array.array` +float = ... +"""Type code for floating point values, like the 'f' typecode of `array.array`""" -.. attribute:: uint8 +uint8 = ... +"""Type code for unsigned integers in the range 0 .. 255 inclusive, like the 'H' typecode of `array.array`""" - Type code for unsigned integers in the range 0 .. 255 inclusive, like the 'H' typecode of `array.array` +uint16 = ... +"""Type code for unsigned integers in the range 0 .. 65535 inclusive, like the 'h' typecode of `array.array`""" -.. attribute:: uint16 +def ones(shape, *, dtype=float): + """ + .. param: shape + Shape of the array, either an integer (for a 1-D array) or a tuple of 2 integers (for a 2-D array) - Type code for unsigned integers in the range 0 .. 65535 inclusive, like the 'h' typecode of `array.array` + .. param: dtype + Type of values in the array + Return a new array of the given shape with all elements set to 1.""" + ... -Basic Array defining functions ------------------------------- +def zeros(shape, *, dtype): + """ + .. param: shape + Shape of the array, either an integer (for a 1-D array) or a tuple of 2 integers (for a 2-D array) -.. method:: ones(shape, \*, dtype=float) + .. param: dtype + Type of values in the array - .. param: shape - Shape of the array, either an integer (for a 1-D array) or a tuple of 2 integers (for a 2-D array) + Return a new array of the given shape with all elements set to 0.""" + ... - .. param: dtype - Type of values in the array - - Return a new array of the given shape with all elements set to 1. - -.. method:: zeros - - .. param: shape - Shape of the array, either an integer (for a 1-D array) or a tuple of 2 integers (for a 2-D array) - - .. param: dtype - Type of values in the array - Return a new array of the given shape with all elements set to 0. +def eye(size, *, dtype=float): + """Return a new square array of size, with the diagonal elements set to 1 + and the other elements set to 0.""" + ... - -.. method:: eye(size, \*, dtype=float) - - Return a new square array of size, with the diagonal elements set to 1 - and the other elements set to 0. - -.. method:: linspace(start, stop, \*, dtype=float, num=50, endpoint=True) - - .. param: start +def linspace(start, stop, *, dtype=float, num=50, endpoint=True): + """ + .. param: start First value in the array - .. param: stop + .. param: stop Final value in the array - .. param int: num + .. param int: num Count of values in the array - .. param: dtype + .. param: dtype Type of values in the array - .. param bool: endpoint + .. param bool: endpoint Whether the ``stop`` value is included. Note that even when endpoint=True, the exact ``stop`` value may not be included due to the inaccuracy of floating point arithmetic. - Return a new 1-D array with ``num`` elements ranging from ``start`` to ``stop`` linearly. - - -:mod:`ulab.compare` --- Comparison functions -============================================ - -.. module::ulab.compare - -.. method:: clip(x1, x2, x3) - - Constrain the values from ``x1`` to be between ``x2`` and ``x3``. - ``x2`` is assumed to be less than or equal to ``x3``. - - Arguments may be ulab arrays or numbers. All array arguments - must be the same size. If the inputs are all scalars, a 1-element - array is returned. - - Shorthand for ``ulab.maximum(x2, ulab.minimum(x1, x3))`` - -.. method:: maximum(x1, x2) - - Compute the element by element maximum of the arguments. - - Arguments may be ulab arrays or numbers. All array arguments - must be the same size. If the inputs are both scalars, a number is - returned - -.. method:: minimum(x1, x2) - - Compute the element by element minimum of the arguments. - - Arguments may be ulab arrays or numbers. All array arguments - must be the same size. If the inputs are both scalars, a number is - returned - - -:mod:`ulab.vector` --- Element-by-element functions -=================================================== - -.. module:: ulab.vector - -These functions can operate on numbers, 1-D arrays, or 2-D arrays by -applying the function to every element in the array. This is typically -much more efficient than expressing the same operation as a Python loop. - -.. method:: acos - - Computes the inverse cosine function - -.. method:: acosh - - Computes the inverse hyperbolic cosine function - -.. method:: asin - - Computes the inverse sine function - -.. method:: asinh - - Computes the inverse hyperbolic sine function - -.. method:: around(a, \*, decimals) - - Returns a new float array in which each element is rounded to - ``decimals`` places. - -.. method:: atan - - Computes the inverse tangent function; the return values are in the - range [-pi/2,pi/2]. - -.. method:: atan2(y,x) - - Computes the inverse tangent function of y/x; the return values are in - the range [-pi, pi]. - -.. method:: atanh - - Computes the inverse hyperbolic tangent function - -.. method:: ceil - - Rounds numbers up to the next whole number - -.. method:: cos - - Computes the cosine function - -.. method:: erf - - Computes the error function, which has applications in statistics - -.. method:: erfc - - Computes the complementary error function, which has applications in statistics - -.. method:: exp - - Computes the exponent function. - -.. method:: expm1 - - Computes $e^x-1$. In certain applications, using this function preserves numeric accuracy better than the `exp` function. - -.. method:: floor - - Rounds numbers up to the next whole number - -.. method:: gamma - - Computes the gamma function - -.. method:: lgamma - - Computes the natural log of the gamma function - -.. method:: log - - Computes the natural log - -.. method:: log10 - - Computes the log base 10 - -.. method:: log2 - - Computes the log base 2 - -.. method:: sin - - Computes the sine - -.. method:: sinh - - Computes the hyperbolic sine - -.. method:: sqrt - - Computes the square root - -.. method:: tan - - Computes the tangent - -.. method:: tanh - - Computes the hyperbolic tangent - -:mod:`ulab.linalg` - Linear algebra functions -============================================= - -.. module:: ulab.linalg - -.. method:: cholesky(A) - - :param ~ulab.array A: a positive definite, symmetric square matrix - :return ~ulab.array L: a square root matrix in the lower triangular form - :raises ValueError: If the input does not fulfill the necessary conditions - - The returned matrix satisfies the equation m=LL* - -.. method:: det - - :param: m, a square matrix - :return float: The determinant of the matrix - - Computes the eigenvalues and eigenvectors of a square matrix - -.. method:: dot(m1, m2) - - :param ~ulab.array m1: a matrix - :param ~ulab.array m2: a matrix - - Computes the matrix product of two matrices - - **WARNING:** Unlike ``numpy``, this function cannot be used to compute the dot product of two vectors - -.. method:: eig(m) - - :param m: a square matrix - :return tuple (eigenvectors, eigenvalues): - - Computes the eigenvalues and eigenvectors of a square matrix - -.. method:: inv(m) - - :param ~ulab.array m: a square matrix - :return: The inverse of the matrix, if it exists - :raises ValueError: if the matrix is not invertible - - Computes the inverse of a square matrix - -.. method:: size(array) - - Return the total number of elements in the array, as an integer. - -.. method:: trace(m) - - :param m: a square matrix - - Compute the trace of the matrix, the sum of its diagonal elements. - -:mod:`ulab.filter` --- Filtering functions -========================================== - -.. module:: ulab.filter - -.. method:: convolve(r, c=None) - - :param ulab.array a: - :param ulab.array v: - - Returns the discrete, linear convolution of two one-dimensional sequences. - The result is always an array of float. Only the ``full`` mode is supported, - and the ``mode`` named parameter of numpy is not accepted. Note that all other - modes can be had by slicing a ``full`` result. - - Convolution filters can implement high pass, low pass, band pass, etc., - filtering operations. Convolution filters are typically constructed ahead - of time. This can be done using desktop python with scipy, or on web pages - such as https://fiiir.com/ - - Convolution is most time-efficient when both inputs are of float type. - -:mod:`ulab.fft` --- Frequency-domain functions -============================================== - -.. module:: ulab.fft - -.. method:: fft(r, c=None) - - :param ulab.array r: A 1-dimension array of values whose size is a power of 2 - :param ulab.array c: An optional 1-dimension array of values whose size is a power of 2, giving the complex part of the value - :return tuple (r, c): The real and complex parts of the FFT - - Perform a Fast Fourier Transform from the time domain into the frequency domain - - See also ~ulab.extras.spectrum, which computes the magnitude of the fft, - rather than separately returning its real and imaginary parts. - -.. method:: ifft(r, c=None) - - :param ulab.array r: A 1-dimension array of values whose size is a power of 2 - :param ulab.array c: An optional 1-dimension array of values whose size is a power of 2, giving the complex part of the value - :return tuple (r, c): The real and complex parts of the inverse FFT - - Perform an Inverse Fast Fourier Transform from the frequeny domain into the time domain - -:mod:`ulab.numerical` --- Numerical and Statistical functions -============================================================= - -.. module:: ulab.numerical - -Most of these functions take an "axis" argument, which indicates whether to -operate over the flattened array (None), rows (0), or columns (1). - -.. method:: argmax(array, \*, axis=None) - - Return the index of the maximum element of the 1D array - -.. method:: argmin(array, \*, axis=None) - - Return the index of the minimum element of the 1D array - -.. method:: argsort(array, \*, axis=None) - - Returns an array which gives indices into the input array from least to greatest. - -.. method:: diff(array, \*, axis=1) - - Return the numerical derivative of successive elements of the array, as - an array. axis=None is not supported. - -.. method:: flip(array, \*, axis=None) - - Returns a new array that reverses the order of the elements along the - given axis, or along all axes if axis is None. - -.. method:: max(array, \*, axis=None) - - Return the maximum element of the 1D array - -.. method:: mean(array, \*, axis=None) - - Return the mean element of the 1D array, as a number if axis is None, otherwise as an array. - -.. method:: min(array, \*, axis=None) - - Return the minimum element of the 1D array - -.. method:: roll(array, distance, \*, axis=None) - - Shift the content of a vector by the positions given as the second - argument. If the ``axis`` keyword is supplied, the shift is applied to - the given axis. The array is modified in place. - -.. method:: std(array, \*, axis=None) - - Return the standard deviation of the array, as a number if axis is None, otherwise as an array. - -.. method:: sum(array, \*, axis=None) - - Return the sum of the array, as a number if axis is None, otherwise as an array. - -.. method:: sort(array, \*, axis=0) - - Sort the array along the given axis, or along all axes if axis is None. - The array is modified in place. - -:mod:`ulab.poly` --- Polynomial functions -========================================= - -.. module:: ulab.poly - -.. method:: polyfit([x, ] y, degree) - - Return a polynomial of given degree that approximates the function - f(x)=y. If x is not supplied, it is the range(len(y)). - -.. method:: polyval(p, x) - - Evaluate the polynomial p at the points x. x must be an array. - -:mod:`ulab.extras` --- Additional functions not in numpy -======================================================== - -.. method:: spectrum(r): - - :param ulab.array r: A 1-dimension array of values whose size is a power of 2 - - Computes the spectrum of the input signal. This is the absolute value of the (complex-valued) fft of the signal. - - This function is similar to scipy's ``scipy.signal.spectrogram``. + Return a new 1-D array with ``num`` elements ranging from ``start`` to ``stop`` linearly.""" + ... diff --git a/shared-bindings/ulab/compare/__init__.pyi b/shared-bindings/ulab/compare/__init__.pyi new file mode 100644 index 000000000..00a9eae1e --- /dev/null +++ b/shared-bindings/ulab/compare/__init__.pyi @@ -0,0 +1,30 @@ +"""Comparison functions""" + +def clip(x1, x2, x3): + """ + Constrain the values from ``x1`` to be between ``x2`` and ``x3``. + ``x2`` is assumed to be less than or equal to ``x3``. + + Arguments may be ulab arrays or numbers. All array arguments + must be the same size. If the inputs are all scalars, a 1-element + array is returned. + + Shorthand for ``ulab.maximum(x2, ulab.minimum(x1, x3))``""" + ... + +def maximum(x1, x2): + """ + Compute the element by element maximum of the arguments. + + Arguments may be ulab arrays or numbers. All array arguments + must be the same size. If the inputs are both scalars, a number is + returned""" + ... + +def minimum(x1, x2): + """Compute the element by element minimum of the arguments. + + Arguments may be ulab arrays or numbers. All array arguments + must be the same size. If the inputs are both scalars, a number is + returned""" + ... diff --git a/shared-bindings/ulab/extras/__init__.pyi b/shared-bindings/ulab/extras/__init__.pyi new file mode 100644 index 000000000..4da56a582 --- /dev/null +++ b/shared-bindings/ulab/extras/__init__.pyi @@ -0,0 +1,10 @@ +"""Additional functions not in numpy""" + +def spectrum(r): + """ + :param ulab.array r: A 1-dimension array of values whose size is a power of 2 + + Computes the spectrum of the input signal. This is the absolute value of the (complex-valued) fft of the signal. + + This function is similar to scipy's ``scipy.signal.spectrogram``.""" + ... diff --git a/shared-bindings/ulab/fft/__init__.pyi b/shared-bindings/ulab/fft/__init__.pyi new file mode 100644 index 000000000..401ecb644 --- /dev/null +++ b/shared-bindings/ulab/fft/__init__.pyi @@ -0,0 +1,22 @@ +"""Frequency-domain functions""" + +def fft(r, c=None): + """ + :param ulab.array r: A 1-dimension array of values whose size is a power of 2 + :param ulab.array c: An optional 1-dimension array of values whose size is a power of 2, giving the complex part of the value + :return tuple (r, c): The real and complex parts of the FFT + + Perform a Fast Fourier Transform from the time domain into the frequency domain + + See also ~ulab.extras.spectrum, which computes the magnitude of the fft, + rather than separately returning its real and imaginary parts.""" + ... + +def ifft(r, c=None): + """ + :param ulab.array r: A 1-dimension array of values whose size is a power of 2 + :param ulab.array c: An optional 1-dimension array of values whose size is a power of 2, giving the complex part of the value + :return tuple (r, c): The real and complex parts of the inverse FFT + + Perform an Inverse Fast Fourier Transform from the frequeny domain into the time domain""" + ... diff --git a/shared-bindings/ulab/filter/__init__.pyi b/shared-bindings/ulab/filter/__init__.pyi new file mode 100644 index 000000000..fff404300 --- /dev/null +++ b/shared-bindings/ulab/filter/__init__.pyi @@ -0,0 +1,19 @@ +"""Filtering functions""" + +def convolve(r, c=None): + """ + :param ulab.array a: + :param ulab.array v: + + Returns the discrete, linear convolution of two one-dimensional sequences. + The result is always an array of float. Only the ``full`` mode is supported, + and the ``mode`` named parameter of numpy is not accepted. Note that all other + modes can be had by slicing a ``full`` result. + + Convolution filters can implement high pass, low pass, band pass, etc., + filtering operations. Convolution filters are typically constructed ahead + of time. This can be done using desktop python with scipy, or on web pages + such as https://fiiir.com/ + + Convolution is most time-efficient when both inputs are of float type.""" + ... diff --git a/shared-bindings/ulab/linalg/__init__.pyi b/shared-bindings/ulab/linalg/__init__.pyi new file mode 100644 index 000000000..d16e61807 --- /dev/null +++ b/shared-bindings/ulab/linalg/__init__.pyi @@ -0,0 +1,57 @@ +"""Linear algebra functions""" + + +def cholesky(A): + """ + :param ~ulab.array A: a positive definite, symmetric square matrix + :return ~ulab.array L: a square root matrix in the lower triangular form + :raises ValueError: If the input does not fulfill the necessary conditions + + The returned matrix satisfies the equation m=LL*""" + ... + +def det(): + """ + :param: m, a square matrix + :return float: The determinant of the matrix + + Computes the eigenvalues and eigenvectors of a square matrix""" + ... + +def dot(m1, m2): + """ + :param ~ulab.array m1: a matrix + :param ~ulab.array m2: a matrix + + Computes the matrix product of two matrices + + **WARNING:** Unlike ``numpy``, this function cannot be used to compute the dot product of two vectors""" + ... + +def eig(m): + """ + :param m: a square matrix + :return tuple (eigenvectors, eigenvalues): + + Computes the eigenvalues and eigenvectors of a square matrix""" + ... + +def inv(m): + """ + :param ~ulab.array m: a square matrix + :return: The inverse of the matrix, if it exists + :raises ValueError: if the matrix is not invertible + + Computes the inverse of a square matrix""" + ... + +def size(array): + """Return the total number of elements in the array, as an integer.""" + ... + +def trace(m): + """ + :param m: a square matrix + + Compute the trace of the matrix, the sum of its diagonal elements.""" + ... diff --git a/shared-bindings/ulab/numerical/__init__.pyi b/shared-bindings/ulab/numerical/__init__.pyi new file mode 100644 index 000000000..759678921 --- /dev/null +++ b/shared-bindings/ulab/numerical/__init__.pyi @@ -0,0 +1,57 @@ +"""Numerical and Statistical functions + +Most of these functions take an "axis" argument, which indicates whether to +operate over the flattened array (None), rows (0), or columns (1).""" + +def argmax(array, *, axis=None): + """Return the index of the maximum element of the 1D array""" + ... + +def argmin(array, *, axis=None): + """Return the index of the minimum element of the 1D array""" + ... + +def argsort(array, *, axis=None): + """Returns an array which gives indices into the input array from least to greatest.""" + ... + +def diff(array, *, axis=1): + """Return the numerical derivative of successive elements of the array, as + an array. axis=None is not supported.""" + ... + +def flip(array, *, axis=None): + """Returns a new array that reverses the order of the elements along the + given axis, or along all axes if axis is None.""" + ... + +def max(array, *, axis=None): + """Return the maximum element of the 1D array""" + ... + +def mean(array, *, axis=None): + """Return the mean element of the 1D array, as a number if axis is None, otherwise as an array.""" + ... + +def min(array, *, axis=None): + """Return the minimum element of the 1D array""" + ... + +def roll(array, distance, *, axis=None): + """Shift the content of a vector by the positions given as the second + argument. If the ``axis`` keyword is supplied, the shift is applied to + the given axis. The array is modified in place.""" + ... + +def std(array, *, axis=None): + """Return the standard deviation of the array, as a number if axis is None, otherwise as an array.""" + ... + +def sum(array, *, axis=None): + """Return the sum of the array, as a number if axis is None, otherwise as an array.""" + ... + +def sort(array, *, axis=0): + """Sort the array along the given axis, or along all axes if axis is None. + The array is modified in place.""" + ... diff --git a/shared-bindings/ulab/poly/__init__.pyi b/shared-bindings/ulab/poly/__init__.pyi new file mode 100644 index 000000000..d051bbded --- /dev/null +++ b/shared-bindings/ulab/poly/__init__.pyi @@ -0,0 +1,10 @@ +"""Polynomial functions""" + +def polyfit(x, y, degree): + """Return a polynomial of given degree that approximates the function + f(x)=y. If x is not supplied, it is the range(len(y)).""" + ... + +def polyval(p, x): + """Evaluate the polynomial p at the points x. x must be an array.""" + ... diff --git a/shared-bindings/ulab/vector/__init__.pyi b/shared-bindings/ulab/vector/__init__.pyi new file mode 100644 index 000000000..2c7a80446 --- /dev/null +++ b/shared-bindings/ulab/vector/__init__.pyi @@ -0,0 +1,108 @@ +"""Element-by-element functions + +These functions can operate on numbers, 1-D arrays, or 2-D arrays by +applying the function to every element in the array. This is typically +much more efficient than expressing the same operation as a Python loop.""" + +def acos(): + """Computes the inverse cosine function""" + ... + +def acosh(): + """Computes the inverse hyperbolic cosine function""" + ... + +def asin(): + """Computes the inverse sine function""" + ... + +def asinh(): + """Computes the inverse hyperbolic sine function""" + ... + +def around(a, *, decimals): + """Returns a new float array in which each element is rounded to + ``decimals`` places.""" + ... + +def atan(): + """Computes the inverse tangent function; the return values are in the + range [-pi/2,pi/2].""" + ... + +def atan2(y,x): + """Computes the inverse tangent function of y/x; the return values are in + the range [-pi, pi].""" + ... + +def atanh(): + """Computes the inverse hyperbolic tangent function""" + ... + +def ceil(): + """Rounds numbers up to the next whole number""" + ... + +def cos(): + """Computes the cosine function""" + ... + +def erf(): + """Computes the error function, which has applications in statistics""" + ... + +def erfc(): + """Computes the complementary error function, which has applications in statistics""" + ... + +def exp(): + """Computes the exponent function.""" + ... + +def expm1(): + """Computes $e^x-1$. In certain applications, using this function preserves numeric accuracy better than the `exp` function.""" + ... + +def floor(): + """Rounds numbers up to the next whole number""" + ... + +def gamma(): + """Computes the gamma function""" + ... + +def lgamma(): + """Computes the natural log of the gamma function""" + ... + +def log(): + """Computes the natural log""" + ... + +def log10(): + """Computes the log base 10""" + ... + +def log2(): + """Computes the log base 2""" + ... + +def sin(): + """Computes the sine""" + ... + +def sinh(): + """Computes the hyperbolic sine""" + ... + +def sqrt(): + """Computes the square root""" + ... + +def tan(): + """Computes the tangent""" + ... + +def tanh(): + """Computes the hyperbolic tangent""" + ... diff --git a/shared-module/gamepad/GamePad.c b/shared-module/gamepad/GamePad.c index fdce0caab..7b4108eb2 100644 --- a/shared-module/gamepad/GamePad.c +++ b/shared-module/gamepad/GamePad.c @@ -27,6 +27,7 @@ #include "py/mpstate.h" #include "shared-bindings/digitalio/DigitalInOut.h" #include "shared-bindings/gamepad/GamePad.h" +#include "supervisor/shared/tick.h" void common_hal_gamepad_gamepad_init(gamepad_obj_t *gamepad, const mp_obj_t pins[], size_t n_pins) { @@ -54,4 +55,5 @@ void common_hal_gamepad_gamepad_init(gamepad_obj_t *gamepad, void common_hal_gamepad_gamepad_deinit(gamepad_obj_t *self) { MP_STATE_VM(gamepad_singleton) = NULL; + supervisor_disable_tick(); } diff --git a/shared-module/gamepad/__init__.c b/shared-module/gamepad/__init__.c index 3e17a0fb5..9874b2752 100644 --- a/shared-module/gamepad/__init__.c +++ b/shared-module/gamepad/__init__.c @@ -29,6 +29,7 @@ #include "py/mpstate.h" #include "shared-bindings/gamepad/__init__.h" #include "shared-bindings/gamepad/GamePad.h" +#include "supervisor/shared/tick.h" #include "shared-bindings/digitalio/DigitalInOut.h" @@ -59,5 +60,8 @@ void gamepad_tick(void) { } void gamepad_reset(void) { + if (MP_STATE_VM(gamepad_singleton)) { + supervisor_disable_tick(); + } MP_STATE_VM(gamepad_singleton) = NULL; } diff --git a/shared-module/gamepadshift/GamePadShift.c b/shared-module/gamepadshift/GamePadShift.c index b8fb4d3f4..51da61702 100644 --- a/shared-module/gamepadshift/GamePadShift.c +++ b/shared-module/gamepadshift/GamePadShift.c @@ -27,6 +27,7 @@ #include "py/mpstate.h" #include "shared-bindings/digitalio/DigitalInOut.h" #include "shared-module/gamepadshift/GamePadShift.h" +#include "supervisor/shared/tick.h" void common_hal_gamepadshift_gamepadshift_init(gamepadshift_obj_t *gamepadshift, digitalio_digitalinout_obj_t *clock_pin, @@ -46,4 +47,5 @@ void common_hal_gamepadshift_gamepadshift_init(gamepadshift_obj_t *gamepadshift, void common_hal_gamepadshift_gamepadshift_deinit(gamepadshift_obj_t *gamepadshift) { MP_STATE_VM(gamepad_singleton) = NULL; + supervisor_disable_tick(); } diff --git a/tools/extract_pyi.py b/tools/extract_pyi.py index 7c664d965..3b30e1ac3 100644 --- a/tools/extract_pyi.py +++ b/tools/extract_pyi.py @@ -6,47 +6,46 @@ import traceback top_level = sys.argv[1].strip("/") stub_directory = sys.argv[2] -if top_level.count("/") == 1: - top_level, module = top_level.split("/") - modules = [module] -else: - modules = os.listdir(top_level) - modules = sorted(modules) - -ok = 0 -total = 0 -for module in modules: - module_path = os.path.join(top_level, module) - if not os.path.isdir(module_path): - continue +def convert_folder(top_level, stub_directory): + ok = 0 + total = 0 + filenames = sorted(os.listdir(top_level)) pyi_lines = [] - classes = os.listdir(module_path) - classes = [x for x in sorted(classes) if x.endswith(".c")] - if classes and classes[-1] == "__init__.c": - classes.insert(0, classes.pop()) - for class_file in classes: - class_path = os.path.join(module_path, class_file) - with open(class_path, "r") as f: - for line in f: - if line.startswith("//|"): - if line[3] == " ": - line = line[4:] - elif line[3] == "\n": - line = line[3:] - else: - continue - pyi_lines.append(line) + for filename in filenames: + full_path = os.path.join(top_level, filename) + file_lines = [] + if os.path.isdir(full_path): + mok, mtotal = convert_folder(full_path, os.path.join(stub_directory, filename)) + ok += mok + total += mtotal + elif filename.endswith(".c"): + with open(full_path, "r") as f: + for line in f: + if line.startswith("//|"): + if line[3] == " ": + line = line[4:] + elif line[3] == "\n": + line = line[3:] + else: + continue + file_lines.append(line) + elif filename.endswith(".pyi"): + with open(full_path, "r") as f: + file_lines.extend(f.readlines()) + + # Always put the contents from an __init__ first. + if filename.startswith("__init__."): + pyi_lines = file_lines + pyi_lines + else: + pyi_lines.extend(file_lines) - raw_stubs = [x for x in sorted(classes) if x.endswith(".pyi")] - if raw_stubs and raw_stubs[-1] == "__init__.pyi": - raw_stubs.insert(0, raw_stubs.pop()) - for raw_stub in raw_stubs: - raw_stub_path = os.path.join(module_path, raw_stub) - with open(raw_stub_path, "r") as f: - pyi_lines.extend(f.readlines()) - stub_filename = os.path.join(stub_directory, module + ".pyi") + if not pyi_lines: + return ok, total + + stub_filename = os.path.join(stub_directory, "__init__.pyi") print(stub_filename) stub_contents = "".join(pyi_lines) + os.makedirs(stub_directory, exist_ok=True) with open(stub_filename, "w") as f: f.write(stub_contents) @@ -74,6 +73,10 @@ for module in modules: except astroid.exceptions.AstroidSyntaxError as e: e = e.__cause__ traceback.print_exception(type(e), e, e.__traceback__) + print() + return ok, total + +ok, total = convert_folder(top_level, stub_directory) print(f"{ok} ok out of {total}") |
