From f51ca53553b9043e7785f9dd29e3bfd10367c80e Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Tue, 22 Jun 2021 08:59:05 -0500 Subject: [PATCH 1/9] refine stubs-building procedure * so that excess files are not included in sdist, perform build down in circuitpython-stubs * This means we need to * Remove the need-pypi check * Copy a setup.py, README, and MANIFEST.in into the stubs build location * Revamp how the overall `mypy --strict` check lists its inputs * Add a new test that actually installing the stubs lets us do type checking (tools/test-stubs.sh) * Add a missing return type to a __init__ function (why was this not an error under `mypy --strict`, I wonder) --- .github/workflows/build.yml | 8 +- .gitignore | 1 + MANIFEST.in-stubs | 1 + Makefile | 12 +- README.rst-stubs | 241 ++++++++++++++++++ setup.py => setup.py-stubs | 20 +- .../imagecapture/ParallelImageCapture.c | 2 +- tools/test-stubs.sh | 12 + 8 files changed, 277 insertions(+), 20 deletions(-) create mode 100644 MANIFEST.in-stubs create mode 100644 README.rst-stubs rename setup.py => setup.py-stubs (78%) create mode 100755 tools/test-stubs.sh diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 60a9743493..7df7fc1a02 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -43,10 +43,6 @@ jobs: run: | gcc --version python3 --version - - name: Check For setup.py - id: need-pypi - run: | - echo ::set-output name=setup-py::$( find . -wholename './setup.py' ) - name: New boards check run: python3 -u ci_new_boards_check.py working-directory: tools @@ -59,7 +55,6 @@ jobs: name: stubs path: circuitpython-stubs* - name: Install pypi dependencies - if: contains(steps.need-pypi.outputs.setup-py, 'setup.py') run: | python -m pip install --upgrade pip pip install setuptools wheel twine @@ -138,8 +133,7 @@ jobs: TWINE_PASSWORD: ${{ secrets.pypi_password }} run: | echo "Uploading dev release to PyPi" - python setup.py sdist - twine upload dist/* + twine upload circuitpython-stubs/dist/* mpy-cross-mac: runs-on: macos-10.15 diff --git a/.gitignore b/.gitignore index de649ad3a0..2fdfe207a2 100644 --- a/.gitignore +++ b/.gitignore @@ -33,6 +33,7 @@ dist/ build/ bin/ circuitpython-stubs/ +test-stubs/ build-*/ # Test failure outputs diff --git a/MANIFEST.in-stubs b/MANIFEST.in-stubs new file mode 100644 index 0000000000..a5aa2aac4f --- /dev/null +++ b/MANIFEST.in-stubs @@ -0,0 +1 @@ +recursive-include . *.pyi diff --git a/Makefile b/Makefile index f1a4f84331..a925ab358c 100644 --- a/Makefile +++ b/Makefile @@ -251,17 +251,23 @@ check-translate: find $(TRANSLATE_SOURCES) -type d \( $(TRANSLATE_SOURCES_EXC) \) -prune -o -type f \( -iname "*.c" -o -iname "*.h" \) -print | (LC_ALL=C sort) | xgettext -f- -L C -s --add-location=file --keyword=translate --keyword=MP_ERROR_TEXT -o circuitpython.pot.tmp -p locale $(PYTHON) tools/check_translations.py locale/circuitpython.pot.tmp locale/circuitpython.pot; status=$$?; rm -f locale/circuitpython.pot.tmp; exit $$status +.PHONY: stubs stubs: - @mkdir -p circuitpython-stubs + @rm -rf circuitpython-stubs + @mkdir circuitpython-stubs @$(PYTHON) tools/extract_pyi.py shared-bindings/ $(STUBDIR) @$(PYTHON) tools/extract_pyi.py extmod/ulab/code/ $(STUBDIR)/ulab @$(PYTHON) tools/extract_pyi.py ports/atmel-samd/bindings $(STUBDIR) @$(PYTHON) tools/extract_pyi.py ports/raspberrypi/bindings $(STUBDIR) - @$(PYTHON) setup.py -q sdist + @cp setup.py-stubs circuitpython-stubs/setup.py + @cp README.rst-stubs circuitpython-stubs/README.rst + @cp MANIFEST.in-stubs circuitpython-stubs/MANIFEST.in + @(cd circuitpython-stubs && $(PYTHON) setup.py -q sdist) .PHONY: check-stubs check-stubs: stubs - MYPYPATH=$(STUBDIR) mypy --strict $(STUBDIR) + @(cd $(STUBDIR) && set -- */__init__.pyi && mypy --strict "$${@%/*}") + @tools/test-stubs.sh update-frozen-libraries: @echo "Updating all frozen libraries to latest tagged version." diff --git a/README.rst-stubs b/README.rst-stubs new file mode 100644 index 0000000000..7b8919db1f --- /dev/null +++ b/README.rst-stubs @@ -0,0 +1,241 @@ +CircuitPython +============= + +.. image:: https://s3.amazonaws.com/adafruit-circuit-python/CircuitPython_Repo_header_logo.png + +|Build Status| |Doc Status| |License| |Discord| |Weblate| + +`circuitpython.org `__ \| `Get CircuitPython <#get-circuitpython>`__ \| +`Documentation <#documentation>`__ \| `Contributing <#contributing>`__ \| +`Branding <#branding>`__ \| `Differences from Micropython <#differences-from-micropython>`__ \| +`Project Structure <#project-structure>`__ + +**CircuitPython** is a *beginner friendly*, open source version of Python for tiny, inexpensive +computers called microcontrollers. Microcontrollers are the brains of many electronics including a +wide variety of development boards used to build hobby projects and prototypes. CircuitPython in +electronics is one of the best ways to learn to code because it connects code to reality. Simply +install CircuitPython on a supported board via drag and drop and then edit a ``code.py`` file on +the CIRCUITPY drive. The code will automatically reload. No software installs are needed besides a +text editor (we recommend `Mu `_ for beginners.) + +CircuitPython features unified Python core APIs and a growing list of 150+ device libraries and +drivers that work with it. These libraries also work on single board computers with regular +Python via the `Adafruit Blinka Library `_. + +CircuitPython is based on `MicroPython `_. See +`below <#differences-from-micropython>`_ for differences. CircuitPython development is sponsored by +`Adafruit `_ and is available on their educational development boards. Please +support both MicroPython and Adafruit. + +Get CircuitPython +------------------ + +Official binaries for all supported boards are available through +`circuitpython.org/downloads `_. The site includes stable, unstable and +continuous builds. Full release notes and assets are available through +`GitHub releases `_ as well. + +Documentation +------------- + +Guides and videos are available through the `Adafruit Learning +System `__ under the `CircuitPython +category `__. An API +reference is also available on `Read the Docs +`__. A collection of awesome +resources can be found at `Awesome CircuitPython `__. + +Specifically useful documentation when starting out: + +- `Welcome to CircuitPython `__ +- `CircuitPython Essentials `__ +- `Example Code `__ + +Code Search +------------ +GitHub doesn't currently support code search on forks. Therefore, CircuitPython doesn't have code search through GitHub because it is a fork of MicroPython. Luckily, `SourceGraph `_ has free code search for public repos like CircuitPython. So, visit `sourcegraph.com/github.com/adafruit/circuitpython `_ to search the CircuitPython codebase online. + +Contributing +------------ + +See +`CONTRIBUTING.md `__ +for full guidelines but please be aware that by contributing to this +project you are agreeing to the `Code of +Conduct `__. +Contributors who follow the `Code of +Conduct `__ +are welcome to submit pull requests and they will be promptly reviewed +by project admins. Please join the +`Discord `__ too. + +Branding +------------ + +While we are happy to see CircuitPython forked and modified, we'd appreciate it if forked releases +not use the name "CircuitPython" or the Blinka logo. "CircuitPython" means something special to +us and those who learn about it. As a result, we'd like to make sure products referring to it meet a +common set of requirements. + +If you'd like to use the term "CircuitPython" and Blinka for your product here is what we ask: + +* Your product is supported by the primary + `"adafruit/circuitpython" `_ repo. This way we can + update any custom code as we update the CircuitPython internals. +* Your product is listed on `circuitpython.org `__ (source + `here `_). This is to ensure that a user of your + product can always download the latest version of CircuitPython from the standard place. +* Your product has a user accessible USB plug which appears as a CIRCUITPY drive when plugged in. + +If you choose not to meet these requirements, then we ask you call your version of CircuitPython +something else (for example, SuperDuperPython) and not use the Blinka logo. You can say it is +"CircuitPython-compatible" if most CircuitPython drivers will work with it. + +-------------- + +Differences from `MicroPython `__ +----------------------------------------------------------------------------- + +CircuitPython: + +- Supports native USB on all boards, allowing file editing without special tools. +- Floats (aka decimals) are enabled for all builds. +- Error messages are translated into 10+ languages. +- Does not support concurrency within Python (including interrupts and threading). Some concurrency + is achieved with native modules for tasks that require it such as audio file playback. + +Behavior +~~~~~~~~ + +- The order that files are run and the state that is shared between + them. CircuitPython's goal is to clarify the role of each file and + make each file independent from each other. +- ``boot.py`` (or ``settings.py``) runs only once on start up before + USB is initialized. This lays the ground work for configuring USB at + startup rather than it being fixed. Since serial is not available, + output is written to ``boot_out.txt``. +- ``code.py`` (or ``main.py``) is run after every reload until it + finishes or is interrupted. After it is done running, the vm and + hardware is reinitialized. **This means you cannot read state from** + ``code.py`` **in the REPL anymore, as the REPL is a fresh vm.** CircuitPython's goal for this + change includes reducing confusion about pins and memory being used. +- After the main code is finished the REPL can be entered by pressing any key. +- Autoreload state will be maintained across reload. +- Adds a safe mode that does not run user code after a hard crash or + brown out. The hope is that this will make it easier to fix code that + causes nasty crashes by making it available through mass storage + after the crash. A reset (the button) is needed after it's fixed to + get back into normal mode. +- RGB status LED indicating CircuitPython state, and errors through a sequence of colored flashes. +- Re-runs ``code.py`` or other main file after file system writes over USB mass storage. (Disable with + ``supervisor.disable_autoreload()``) +- Autoreload is disabled while the REPL is active. +- Main is one of these: ``code.txt``, ``code.py``, ``main.py``, + ``main.txt`` +- Boot is one of these: ``settings.txt``, ``settings.py``, ``boot.py``, + ``boot.txt`` + +API +~~~ + +- Unified hardware APIs. Documented on + `ReadTheDocs `_. +- API docs are rST within the C files in ``shared-bindings``. +- No ``machine`` API. + +Modules +~~~~~~~ + +- No module aliasing. (``uos`` and ``utime`` are not available as + ``os`` and ``time`` respectively.) Instead ``os``, ``time``, and + ``random`` are CPython compatible. +- New ``storage`` module which manages file system mounts. + (Functionality from ``uos`` in MicroPython.) +- Modules with a CPython counterpart, such as ``time``, ``os`` and + ``random``, are strict + `subsets `__ + of their `CPython + version `__. + Therefore, code from CircuitPython is runnable on CPython but not + necessarily the reverse. +- tick count is available as + `time.monotonic() `__ + +-------------- + +Project Structure +----------------- + +Here is an overview of the top-level source code directories. + +Core +~~~~ + +The core code of +`MicroPython `__ is shared +amongst ports including CircuitPython: + +- ``docs`` High level user documentation in Sphinx reStructuredText + format. +- ``drivers`` External device drivers written in Python. +- ``examples`` A few example Python scripts. +- ``extmod`` Shared C code used in multiple ports' modules. +- ``lib`` Shared core C code including externally developed libraries + such as FATFS. +- ``logo`` The CircuitPython logo. +- ``mpy-cross`` A cross compiler that converts Python files to byte + code prior to being run in MicroPython. Useful for reducing library + size. +- ``py`` Core Python implementation, including compiler, runtime, and + core library. +- ``shared-bindings`` Shared definition of Python modules, their docs + and backing C APIs. Ports must implement the C API to support the + corresponding module. +- ``shared-module`` Shared implementation of Python modules that may be + based on ``common-hal``. +- ``tests`` Test framework and test scripts. +- ``tools`` Various tools, including the pyboard.py module. + +Ports +~~~~~ + +Ports include the code unique to a microcontroller line. + +================ ============================================================ +Supported Support status +================ ============================================================ +atmel-samd ``SAMD21`` stable | ``SAMD51`` stable +cxd56 stable +esp32s2 stable +litex alpha +mimxrt10xx alpha +nrf stable +raspberrypi stable +stm ``F4`` stable | ``others`` beta +unix alpha +================ ============================================================ + +- ``stable`` Highly unlikely to have bugs or missing functionality. +- ``beta`` Being actively improved but may be missing functionality and have bugs. +- ``alpha`` Will have bugs and missing functionality. + +Boards +~~~~~~ + +- Each ``port`` has a ``boards`` directory containing variations of boards + which belong to a specific microcontroller line. +- A list of native modules supported by a particular board can be found + `here `__. + +`Back to Top <#circuitpython>`__ + +.. |Build Status| image:: https://github.com/adafruit/circuitpython/workflows/Build%20CI/badge.svg + :target: https://github.com/adafruit/circuitpython/actions?query=branch%3Amain +.. |Doc Status| image:: https://readthedocs.org/projects/circuitpython/badge/?version=latest + :target: http://circuitpython.readthedocs.io/ +.. |Discord| image:: https://img.shields.io/discord/327254708534116352.svg + :target: https://adafru.it/discord +.. |License| image:: https://img.shields.io/badge/License-MIT-brightgreen.svg + :target: https://choosealicense.com/licenses/mit/ +.. |Weblate| image:: https://hosted.weblate.org/widgets/circuitpython/-/svg-badge.svg + :target: https://hosted.weblate.org/engage/circuitpython/?utm_source=widget diff --git a/setup.py b/setup.py-stubs similarity index 78% rename from setup.py rename to setup.py-stubs index 4152cc0017..3604ee973e 100644 --- a/setup.py +++ b/setup.py-stubs @@ -9,18 +9,16 @@ from typing import Dict, List from setuptools import setup from pathlib import Path -STD_PACKAGES = set(('array', 'math', 'os', 'random', 'struct', 'sys', 'ssl', 'time')) - -stub_root = Path("circuitpython-stubs") -stubs = [p.relative_to(stub_root).as_posix() for p in stub_root.glob("*.pyi")] - def local_scheme(version): return "" -packages = set(os.listdir("circuitpython-stubs")) - STD_PACKAGES -package_dir = dict((f"{package}-stubs", f"circuitpython-stubs/{package}") +STD_PACKAGES = set(('array', 'math', 'os', 'random', 'struct', 'sys', 'ssl', 'time')) + +stub_root = Path(".") +stubs = [p.relative_to(stub_root) for p in stub_root.glob("*/*.pyi")] +packages = set(stub.parent.as_posix() for stub in stubs) - STD_PACKAGES +package_dir = dict((f"{package}-stubs", package) for package in packages) -print("package dir is", package_dir) def build_package_data() -> Dict[str, List[str]]: result = {} @@ -41,6 +39,10 @@ setup( package_data=package_data, package_dir = package_dir, setup_requires=["setuptools_scm", "setuptools>=38.6.0"], - use_scm_version={"local_scheme": local_scheme}, + use_scm_version = { + "root": "..", + "relative_to": __file__, + "local_scheme": local_scheme, + }, zip_safe=False, ) diff --git a/shared-bindings/imagecapture/ParallelImageCapture.c b/shared-bindings/imagecapture/ParallelImageCapture.c index 8e8991339b..59a6f256e6 100644 --- a/shared-bindings/imagecapture/ParallelImageCapture.c +++ b/shared-bindings/imagecapture/ParallelImageCapture.c @@ -43,7 +43,7 @@ //| clock: microcontroller.Pin, //| vsync: Optional[microcontroller.Pin], //| href: Optional[microcontroller.Pin], -//| ): +//| ) -> None: //| """Create a parallel image capture object //| //| :param List[microcontroller.Pin] data_pins: The data pins. diff --git a/tools/test-stubs.sh b/tools/test-stubs.sh new file mode 100755 index 0000000000..9b384bab32 --- /dev/null +++ b/tools/test-stubs.sh @@ -0,0 +1,12 @@ +#!/bin/sh -e +rm -rf test-stubs +python3 -mvenv test-stubs +. test-stubs/bin/activate +pip install mypy isort black wheel +rm -rf circuitpython-stubs .mypy_cache +make stubs +pip install --force-reinstall circuitpython-stubs/dist/circuitpython-stubs-*.tar.gz +mypy -c 'import busio; b: busio.I2C; b.writeto(0x30, b"")' +! mypy -c 'import busio; b: busio.I2C; b.readfrom_into(0x30, b"")' +! mypy -c 'import busio; b: busio.I2C; b.write(0x30, b"")' +echo "(The above two tests are expected to show type errors)" From acc6bec9dab57c1f64a207d48cb13927c2167c2c Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Tue, 22 Jun 2021 09:15:30 -0500 Subject: [PATCH 2/9] exclude test-stubs files from docs --- conf.py | 1 + 1 file changed, 1 insertion(+) diff --git a/conf.py b/conf.py index 7acc981f3d..09fbae2950 100644 --- a/conf.py +++ b/conf.py @@ -203,6 +203,7 @@ exclude_patterns = ["**/build*", "shared-module", "supervisor", "tests", + "test-stubs", "tools"] # The reST default role (used for this markup: `text`) to use for all From 95535a238eaf8c73891de6d43af3ffd37536c388 Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Tue, 22 Jun 2021 10:49:55 -0500 Subject: [PATCH 3/9] fix doc building more --- conf.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/conf.py b/conf.py index 09fbae2950..063a527244 100644 --- a/conf.py +++ b/conf.py @@ -86,7 +86,8 @@ extensions.append('autoapi.extension') autoapi_type = 'python' # Uncomment this if debugging autoapi autoapi_keep_files = True -autoapi_dirs = [os.path.join('circuitpython-stubs', x) for x in os.listdir('circuitpython-stubs')] +autoapi_dirs = [os.path.join('circuitpython-stubs', x) for x in os.listdir('circuitpython-stubs') if os.path.exists(os.path.join("circuitpython-stubs", x, "__init__.pyi"))] +print("autoapi_dirs", autoapi_dirs) 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' @@ -204,7 +205,8 @@ exclude_patterns = ["**/build*", "supervisor", "tests", "test-stubs", - "tools"] + "tools", + "circuitpython-stubs/README.rst"] # The reST default role (used for this markup: `text`) to use for all # documents. From a8e599a3def3ce813a7013052a324464ea37955b Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Tue, 22 Jun 2021 14:09:27 -0500 Subject: [PATCH 4/9] upload the 'sdist' file as an artifact / to s3, not the whole circuitpython-stubs folder --- .github/workflows/build.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 7df7fc1a02..777d3d15cb 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -53,7 +53,7 @@ jobs: - uses: actions/upload-artifact@v2 with: name: stubs - path: circuitpython-stubs* + path: circuitpython-stubs/dist/* - name: Install pypi dependencies run: | python -m pip install --upgrade pip @@ -124,7 +124,7 @@ jobs: [ -z "$AWS_ACCESS_KEY_ID" ] || aws s3 cp mpy-cross/mpy-cross.static s3://adafruit-circuit-python/bin/mpy-cross/mpy-cross.static-amd64-linux-${{ env.CP_VERSION }} --no-progress --region us-east-1 [ -z "$AWS_ACCESS_KEY_ID" ] || aws s3 cp mpy-cross/mpy-cross.static.exe s3://adafruit-circuit-python/bin/mpy-cross/mpy-cross.static-x64-windows-${{ env.CP_VERSION }}.exe --no-progress --region us-east-1 zip -9r circuitpython-stubs.zip circuitpython-stubs - [ -z "$AWS_ACCESS_KEY_ID" ] || aws s3 cp circuitpython-stubs.zip s3://adafruit-circuit-python/bin/stubs/circuitpython-stubs-${{ env.CP_VERSION }}.zip --no-progress --region us-east-1 + [ -z "$AWS_ACCESS_KEY_ID" ] || aws s3 cp circuitpython-stubs/dist/*.tar.gz s3://adafruit-circuit-python/bin/stubs/circuitpython-stubs-${{ env.CP_VERSION }}.zip --no-progress --region us-east-1 - name: Upload stubs to PyPi if: github.event_name == 'push' From 6a48c694196548640062248a49488c3d4f94543d Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Thu, 24 Jun 2021 11:08:34 -0500 Subject: [PATCH 5/9] tighten conditions under which pypi upload is attempted --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 777d3d15cb..33cd4ece2e 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -127,7 +127,7 @@ jobs: [ -z "$AWS_ACCESS_KEY_ID" ] || aws s3 cp circuitpython-stubs/dist/*.tar.gz s3://adafruit-circuit-python/bin/stubs/circuitpython-stubs-${{ env.CP_VERSION }}.zip --no-progress --region us-east-1 - name: Upload stubs to PyPi - if: github.event_name == 'push' + if: github.event_name == 'push' && github.ref == 'refs/heads/main' && github.repository_owner == 'adafruit' env: TWINE_USERNAME: ${{ secrets.pypi_username }} TWINE_PASSWORD: ${{ secrets.pypi_password }} From 6a4298991b7860a7636dbb31141393c2a9b4be96 Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Thu, 24 Jun 2021 13:37:09 -0500 Subject: [PATCH 6/9] Actually reduce the README text for the stubs package --- README.rst-stubs | 220 +---------------------------------------------- 1 file changed, 4 insertions(+), 216 deletions(-) diff --git a/README.rst-stubs b/README.rst-stubs index 7b8919db1f..00880563cb 100644 --- a/README.rst-stubs +++ b/README.rst-stubs @@ -11,223 +11,11 @@ CircuitPython `Project Structure <#project-structure>`__ **CircuitPython** is a *beginner friendly*, open source version of Python for tiny, inexpensive -computers called microcontrollers. Microcontrollers are the brains of many electronics including a -wide variety of development boards used to build hobby projects and prototypes. CircuitPython in -electronics is one of the best ways to learn to code because it connects code to reality. Simply -install CircuitPython on a supported board via drag and drop and then edit a ``code.py`` file on -the CIRCUITPY drive. The code will automatically reload. No software installs are needed besides a -text editor (we recommend `Mu `_ for beginners.) +computers called microcontrollers. -CircuitPython features unified Python core APIs and a growing list of 150+ device libraries and -drivers that work with it. These libraries also work on single board computers with regular -Python via the `Adafruit Blinka Library `_. - -CircuitPython is based on `MicroPython `_. See -`below <#differences-from-micropython>`_ for differences. CircuitPython development is sponsored by -`Adafruit `_ and is available on their educational development boards. Please -support both MicroPython and Adafruit. - -Get CircuitPython ------------------- - -Official binaries for all supported boards are available through -`circuitpython.org/downloads `_. The site includes stable, unstable and -continuous builds. Full release notes and assets are available through -`GitHub releases `_ as well. - -Documentation -------------- - -Guides and videos are available through the `Adafruit Learning -System `__ under the `CircuitPython -category `__. An API -reference is also available on `Read the Docs -`__. A collection of awesome -resources can be found at `Awesome CircuitPython `__. - -Specifically useful documentation when starting out: - -- `Welcome to CircuitPython `__ -- `CircuitPython Essentials `__ -- `Example Code `__ - -Code Search ------------- -GitHub doesn't currently support code search on forks. Therefore, CircuitPython doesn't have code search through GitHub because it is a fork of MicroPython. Luckily, `SourceGraph `_ has free code search for public repos like CircuitPython. So, visit `sourcegraph.com/github.com/adafruit/circuitpython `_ to search the CircuitPython codebase online. - -Contributing ------------- - -See -`CONTRIBUTING.md `__ -for full guidelines but please be aware that by contributing to this -project you are agreeing to the `Code of -Conduct `__. -Contributors who follow the `Code of -Conduct `__ -are welcome to submit pull requests and they will be promptly reviewed -by project admins. Please join the -`Discord `__ too. - -Branding ------------- - -While we are happy to see CircuitPython forked and modified, we'd appreciate it if forked releases -not use the name "CircuitPython" or the Blinka logo. "CircuitPython" means something special to -us and those who learn about it. As a result, we'd like to make sure products referring to it meet a -common set of requirements. - -If you'd like to use the term "CircuitPython" and Blinka for your product here is what we ask: - -* Your product is supported by the primary - `"adafruit/circuitpython" `_ repo. This way we can - update any custom code as we update the CircuitPython internals. -* Your product is listed on `circuitpython.org `__ (source - `here `_). This is to ensure that a user of your - product can always download the latest version of CircuitPython from the standard place. -* Your product has a user accessible USB plug which appears as a CIRCUITPY drive when plugged in. - -If you choose not to meet these requirements, then we ask you call your version of CircuitPython -something else (for example, SuperDuperPython) and not use the Blinka logo. You can say it is -"CircuitPython-compatible" if most CircuitPython drivers will work with it. - --------------- - -Differences from `MicroPython `__ ------------------------------------------------------------------------------ - -CircuitPython: - -- Supports native USB on all boards, allowing file editing without special tools. -- Floats (aka decimals) are enabled for all builds. -- Error messages are translated into 10+ languages. -- Does not support concurrency within Python (including interrupts and threading). Some concurrency - is achieved with native modules for tasks that require it such as audio file playback. - -Behavior -~~~~~~~~ - -- The order that files are run and the state that is shared between - them. CircuitPython's goal is to clarify the role of each file and - make each file independent from each other. -- ``boot.py`` (or ``settings.py``) runs only once on start up before - USB is initialized. This lays the ground work for configuring USB at - startup rather than it being fixed. Since serial is not available, - output is written to ``boot_out.txt``. -- ``code.py`` (or ``main.py``) is run after every reload until it - finishes or is interrupted. After it is done running, the vm and - hardware is reinitialized. **This means you cannot read state from** - ``code.py`` **in the REPL anymore, as the REPL is a fresh vm.** CircuitPython's goal for this - change includes reducing confusion about pins and memory being used. -- After the main code is finished the REPL can be entered by pressing any key. -- Autoreload state will be maintained across reload. -- Adds a safe mode that does not run user code after a hard crash or - brown out. The hope is that this will make it easier to fix code that - causes nasty crashes by making it available through mass storage - after the crash. A reset (the button) is needed after it's fixed to - get back into normal mode. -- RGB status LED indicating CircuitPython state, and errors through a sequence of colored flashes. -- Re-runs ``code.py`` or other main file after file system writes over USB mass storage. (Disable with - ``supervisor.disable_autoreload()``) -- Autoreload is disabled while the REPL is active. -- Main is one of these: ``code.txt``, ``code.py``, ``main.py``, - ``main.txt`` -- Boot is one of these: ``settings.txt``, ``settings.py``, ``boot.py``, - ``boot.txt`` - -API -~~~ - -- Unified hardware APIs. Documented on - `ReadTheDocs `_. -- API docs are rST within the C files in ``shared-bindings``. -- No ``machine`` API. - -Modules -~~~~~~~ - -- No module aliasing. (``uos`` and ``utime`` are not available as - ``os`` and ``time`` respectively.) Instead ``os``, ``time``, and - ``random`` are CPython compatible. -- New ``storage`` module which manages file system mounts. - (Functionality from ``uos`` in MicroPython.) -- Modules with a CPython counterpart, such as ``time``, ``os`` and - ``random``, are strict - `subsets `__ - of their `CPython - version `__. - Therefore, code from CircuitPython is runnable on CPython but not - necessarily the reverse. -- tick count is available as - `time.monotonic() `__ - --------------- - -Project Structure ------------------ - -Here is an overview of the top-level source code directories. - -Core -~~~~ - -The core code of -`MicroPython `__ is shared -amongst ports including CircuitPython: - -- ``docs`` High level user documentation in Sphinx reStructuredText - format. -- ``drivers`` External device drivers written in Python. -- ``examples`` A few example Python scripts. -- ``extmod`` Shared C code used in multiple ports' modules. -- ``lib`` Shared core C code including externally developed libraries - such as FATFS. -- ``logo`` The CircuitPython logo. -- ``mpy-cross`` A cross compiler that converts Python files to byte - code prior to being run in MicroPython. Useful for reducing library - size. -- ``py`` Core Python implementation, including compiler, runtime, and - core library. -- ``shared-bindings`` Shared definition of Python modules, their docs - and backing C APIs. Ports must implement the C API to support the - corresponding module. -- ``shared-module`` Shared implementation of Python modules that may be - based on ``common-hal``. -- ``tests`` Test framework and test scripts. -- ``tools`` Various tools, including the pyboard.py module. - -Ports -~~~~~ - -Ports include the code unique to a microcontroller line. - -================ ============================================================ -Supported Support status -================ ============================================================ -atmel-samd ``SAMD21`` stable | ``SAMD51`` stable -cxd56 stable -esp32s2 stable -litex alpha -mimxrt10xx alpha -nrf stable -raspberrypi stable -stm ``F4`` stable | ``others`` beta -unix alpha -================ ============================================================ - -- ``stable`` Highly unlikely to have bugs or missing functionality. -- ``beta`` Being actively improved but may be missing functionality and have bugs. -- ``alpha`` Will have bugs and missing functionality. - -Boards -~~~~~~ - -- Each ``port`` has a ``boards`` directory containing variations of boards - which belong to a specific microcontroller line. -- A list of native modules supported by a particular board can be found - `here `__. - -`Back to Top <#circuitpython>`__ +This package contains the "stubs", or type definitions for CircuitPython. With some advanced +editors and other tools, this information can be identify TypeErrors, AttributeErrors, and other +problems before you deploy your code to a device and can even help autocomplete your code. .. |Build Status| image:: https://github.com/adafruit/circuitpython/workflows/Build%20CI/badge.svg :target: https://github.com/adafruit/circuitpython/actions?query=branch%3Amain From 89f7652fca00bb096fc925a3f4dbbf98c62ac3d4 Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Sat, 26 Jun 2021 20:00:31 -0500 Subject: [PATCH 7/9] objtuple: Move mp_obj_is_tuple_compatible to obj.h. Signed-off-by: Jeff Epler --- py/obj.h | 2 ++ py/objtuple.c | 2 -- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/py/obj.h b/py/obj.h index c9135546f2..5455c81f73 100644 --- a/py/obj.h +++ b/py/obj.h @@ -764,6 +764,8 @@ extern const struct _mp_obj_exception_t mp_const_GeneratorExit_obj; #define mp_obj_is_str_or_bytes(o) (mp_obj_is_qstr(o) || (mp_obj_is_obj(o) && ((mp_obj_base_t *)MP_OBJ_TO_PTR(o))->type->binary_op == mp_obj_str_binary_op)) #define mp_obj_is_dict_or_ordereddict(o) (mp_obj_is_obj(o) && ((mp_obj_base_t *)MP_OBJ_TO_PTR(o))->type->make_new == mp_obj_dict_make_new) #define mp_obj_is_fun(o) (mp_obj_is_obj(o) && (((mp_obj_base_t *)MP_OBJ_TO_PTR(o))->type->name == MP_QSTR_function)) +// type check is done on getiter method to allow tuple, namedtuple, attrtuple +#define mp_obj_is_tuple_compatible(o) (mp_obj_get_type(o)->getiter == mp_obj_tuple_getiter) mp_obj_t mp_obj_new_type(qstr name, mp_obj_t bases_tuple, mp_obj_t locals_dict); static inline mp_obj_t mp_obj_new_bool(mp_int_t x) { diff --git a/py/objtuple.c b/py/objtuple.c index bb4f79997c..414cf65c3b 100644 --- a/py/objtuple.c +++ b/py/objtuple.c @@ -34,8 +34,6 @@ #include "supervisor/shared/translate.h" -// type check is done on getiter method to allow tuple, namedtuple, attrtuple -#define mp_obj_is_tuple_compatible(o) (mp_obj_get_type(o)->getiter == mp_obj_tuple_getiter) /******************************************************************************/ /* tuple */ From 05aa8ea40488f5bac1acd040b691f4fa1e606ea1 Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Sat, 26 Jun 2021 20:00:56 -0500 Subject: [PATCH 8/9] mp_obj_get_array: Work with namedtuple, attrtuple. Signed-off-by: Jeff Epler --- py/obj.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/py/obj.c b/py/obj.c index 616f4f2ce4..e5715d5411 100644 --- a/py/obj.c +++ b/py/obj.c @@ -444,7 +444,7 @@ void mp_obj_get_complex(mp_obj_t arg, mp_float_t *real, mp_float_t *imag) { // note: returned value in *items may point to the interior of a GC block void mp_obj_get_array(mp_obj_t o, size_t *len, mp_obj_t **items) { - if (mp_obj_is_type(o, &mp_type_tuple)) { + if (mp_obj_is_tuple_compatible(o)) { mp_obj_tuple_get(o, len, items); } else if (mp_obj_is_type(o, &mp_type_list)) { mp_obj_list_get(o, len, items); From 9449a354050fa0b674c09fefc4631180b2f1a6c8 Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Sat, 26 Jun 2021 20:01:19 -0500 Subject: [PATCH 9/9] time: Allow constructing a struct_time from another struct_time --- shared-bindings/time/__init__.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/shared-bindings/time/__init__.c b/shared-bindings/time/__init__.c index 87a40f6fc1..5e40d2774a 100644 --- a/shared-bindings/time/__init__.c +++ b/shared-bindings/time/__init__.c @@ -83,12 +83,10 @@ mp_obj_t struct_time_make_new(const mp_obj_type_t *type, size_t n_args, const mp if (n_args != 1 || (kw_args != NULL && kw_args->used > 0)) { return namedtuple_make_new(type, n_args, args, kw_args); } - if (mp_obj_get_type(args[0])->getiter != mp_obj_tuple_getiter || ((mp_obj_tuple_t *)MP_OBJ_TO_PTR(args[0]))->len != 9) { - mp_raise_TypeError(translate("time.struct_time() takes a 9-sequence")); - } - - mp_obj_tuple_t *tuple = MP_OBJ_TO_PTR(args[0]); - return namedtuple_make_new(type, 9, tuple->items, NULL); + size_t len; + mp_obj_t *items; + mp_obj_get_array(args[0], &len, &items); + return namedtuple_make_new(type, len, items, NULL); } //| class struct_time: