Compare commits

...
Author SHA1 Message Date
David Lechner f664757ef3 npm/jedi: new js package
This adds a new javascript package for distributing the pybricks-jedi
Python package and it's dependencies via the npm ecosystem for use in
Pybricks Code.
2022-09-07 20:10:34 -05:00
David Lechner b747520d1c jedi: add LICENSE file
This adds a LICENSE file to the jedi directory specifically for the
pybricks-jedi Python package. Poetry will automatically pick up this
file and include it in the distributed package.
2022-09-07 19:41:23 -05:00
The Vinh Luong (Lương Thế Vinh) dcddf15d15 flake8: Update VSCode settings and suppress some Flake8 linting warnings.
* update VSCode settings to exclude __pycache__

* suppress some Flake8 linting warnings

* minor fix: SPHINX_BUILD env var may not be set

* decorate _PybricksEnumMeta.__dir__() with @classmethod

* flake8-ignore E501
2022-09-05 18:40:39 -05:00
The Vinh Luong (Lương Thế Vinh) c64458d3b9 parameters: Fix wrong typing in pybricks.parameters.Stop. 2022-09-05 18:38:29 -05:00
David Lechner 2a963b2a0b poetry: update dependencies
This fixes:

    Invalid PEP 440 version: '5.1.0.dev20220527.dev-20220527'
2022-09-05 16:58:56 -05:00
Laurens Valk 6df509b66e pybricks.hubs.EssentialHub: Fix duplicate example.
Also delete reference image with the light consistent with other small hubs.
2022-07-04 15:00:41 +02:00
Laurens Valk ac9585b7a5 ubuiltins: Fix broken classmethod decorator.
Since classmethod is being redefined here, it broke Sphinx.

Fixes https://github.com/pybricks/pybricks-api/issues/86
2022-07-04 14:33:17 +02:00
Laurens Valk 0982d5d65b ubuiltins: Document int. 2022-07-04 14:33:17 +02:00
Laurens Valk 8e7f8c619e ubuiltins: Document float. 2022-07-04 14:33:17 +02:00
Laurens Valk a0b3ba1d74 ubuiltins: Document dict.
This just adds a direct reference to the Python docs.
2022-07-04 14:33:17 +02:00
Laurens Valk 3dc28579ef ubuiltins: Document bool, complex. 2022-07-04 14:33:17 +02:00
Laurens Valk 923f9df3da ubuiltins: Document input, print. 2022-07-04 14:33:17 +02:00
Laurens Valk 1665b77847 ubuiltins: Start converting signatures to new standard.
Also clarify description wherever applicable.
2022-07-04 14:33:17 +02:00
Laurens Valk 96e7e5f3d0 umath: Convert signatures to new standard. 2022-07-04 14:33:17 +02:00
Laurens Valk 1b51d71061 examples: Generate hub examples while building.
This way we don't have to commit the generated scripts.

While we do this, rename ExampleHub to ThisHub so that the common scripts can actually run.
2022-07-04 14:29:33 +02:00
Laurens Valk 9d706d719a .gitignore: Ignore .python-version. 2022-07-04 08:40:28 +02:00
David Lechner 7c62a2833a doc/main/images: add temporary essentialhub images
We don't have proper images yet, so we are adding copies of the Prime
hub images for now to not take up space in git history with temporary
images and to at least have something so the docs will build.
2022-06-29 12:08:33 -05:00
David Lechner 03ee7f74e8 doc/pup/essentialhub: fix bit rot
This fixes bitrot for PR #96. Also fixes a few minor issues where
changes were missed.
2022-06-29 12:08:33 -05:00
Pavel Lobodinský 025147680c pybricks.hubs.EssentialHub: Added missing Hub 2022-06-29 12:08:33 -05:00
David Lechner e467bb57c9 pybricks_jedi/v1.1.0 2022-06-26 00:10:04 -05:00
David Lechner 33d0c9fa49 v3.2.0b1-r3 2022-06-26 00:00:11 -05:00
David Lechner e95386e23e jedi: improve signature information
This fixes numerous issues where jedi provided incomplete or poorly
formatted signatures and docstrings.

Issue: https://github.com/pybricks/pybricks-code/issues/932
2022-06-25 23:54:49 -05:00
David Lechner a758eaa1db github/build: don't run build on tags
This is almost always redundant.
2022-06-24 15:37:59 -05:00
David Lechner 470eebd1c5 github/jedi: fix working directory in publish job
This was building the pybricks package instead of the pybricks_jedi
package because it was using the wrong directory.
2022-06-24 15:29:02 -05:00
David Lechner 37cdd2a83b v3.2.0b1-r2 2022-06-24 15:14:42 -05:00
David Lechner a2d9c33eb5 jedi: add new pybricks_jedi package
This package will be used in Pybricks Code to provide some intellesense
operations.
2022-06-24 14:52:45 -05:00
Laurens Valk 6d0de1effa doc/main: Drop beta tag.
Less variants is better. Now we'll just have to add beta support for SPIKE in the next release.

Fixes https://github.com/pybricks/pybricks-api/issues/102
2022-06-10 11:31:08 +02:00
Laurens Valk 8e7fc53974 doc/main: Disable NXT and EV3 pages again.
Now that all typehints have been added, we can
revert commit 4c583a9d4e again.
2022-06-10 11:20:32 +02:00
Laurens Valk e456c8ef91 pybricks: Drop underscores on imports.
Fixes https://github.com/pybricks/pybricks-api/issues/101
2022-06-10 11:10:20 +02:00
Laurens Valk 6500440031 pybricks: Drop most ellipsis and pass instances.
See [1]: "I still prefer ... over pass. This clarifies to the readers that they are reading a stub. But if there's a docstring we need neither."

[1] https://github.com/srittau/type-stub-pep/issues/88#issuecomment-758843441

Fixes https://github.com/pybricks/pybricks-api/issues/101#issuecomment-1148780369
2022-06-10 10:46:44 +02:00
Laurens Valk 8ec1b18629 pybricks.parameters: Add typing, part 2. 2022-06-10 10:33:33 +02:00
Laurens Valk 26908040eb pybricks.common: Add CommonColorSensor class.
Fixes https://github.com/pybricks/pybricks-api/issues/103
2022-06-10 10:05:13 +02:00
Laurens Valk f67c98105a pybricks.parameters: Add typing, part 1. 2022-06-10 10:05:13 +02:00
Laurens Valk 877391dea7 pybricks.parameters: Add typing. 2022-06-10 10:05:13 +02:00
Laurens Valk fb3446ad0d pybricks.robotics: Add typing. 2022-06-10 10:05:12 +02:00
Laurens Valk 31256d70c1 pybricks.tools: Add typing. 2022-06-10 10:05:12 +02:00
Laurens Valk f87e1b48ac pybricks.messaging: Add typing. 2022-06-10 10:05:12 +02:00
Laurens Valk 6bcf6117c3 pybricks.hubs: Add typing. 2022-06-10 10:05:11 +02:00
Laurens Valk c77682f50d pybricks.iodevices: Add typing. 2022-06-10 10:05:11 +02:00
Laurens Valk 4c583a9d4e doc/main: Enable NXT and EV3 pages.
This will help us review the pages as we add typing to the documentation. Then they will be hidden again.

This commit can be cherry-picked later on if we ever enable NXT and EV3 content again.
2022-06-10 10:05:10 +02:00
Laurens Valk 0688b8dded doc/common/conf.py: Add missing units.
These are used for NXT sensors.
2022-06-10 10:05:10 +02:00
Laurens Valk d1a4327751 pybricks.ev3dev.media: Type file classes. 2022-06-10 10:05:10 +02:00
Laurens Valk 4aec24a051 pybricks.ev3dev.media: Type Font class. 2022-06-10 10:05:09 +02:00
Laurens Valk 7bc995d0b6 pybricks.ev3dev.media: Type Image class. 2022-06-10 10:05:09 +02:00
Laurens Valk 725a07e6e1 pybricks.ev3dev._speaker: Add typing. 2022-06-10 10:05:09 +02:00
120 changed files with 5270 additions and 2874 deletions
+13 -1
View File
@@ -3,7 +3,19 @@
name: Build Python package and docs
on: [ push, pull_request ]
on:
push:
tags-ignore:
- "*"
pull_request:
paths:
- doc/**
- src/**
- poetry.lock
- poetry.toml
- pyproject.toml
- setup.cfg
jobs:
build:
+36
View File
@@ -0,0 +1,36 @@
name: pybricks_jedi
on: [push, pull_request]
jobs:
test:
if: github.ref_type != 'tag'
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v2
- uses: actions/setup-python@v2
with:
python-version: "3.10"
- run: pipx install poetry
- run: poetry install
working-directory: ./jedi
- run: poetry run pytest -vv
working-directory: ./jedi
publish:
if: github.ref_type == 'tag' && startsWith(github.ref_name, 'pybricks_jedi/')
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v2
- uses: actions/setup-python@v2
with:
python-version: "3.10"
- run: pipx install poetry
- run: poetry install
working-directory: ./jedi
- run: poetry build
working-directory: ./jedi
- run: poetry publish
working-directory: ./jedi
env:
POETRY_PYPI_TOKEN_PYPI: ${{ secrets.PYPI_PYBRICKS_JEDI_TOKEN }}
+23
View File
@@ -0,0 +1,23 @@
name: Release @pybricks/jedi
on:
push:
tags:
- '@pybricks/jedi/**'
jobs:
publish_ide_docs:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v2
# Setup .npmrc file to publish to npm
- uses: actions/setup-node@v3
with:
node-version: '16.x'
registry-url: 'https://registry.npmjs.org'
- run: ./build.py
working-directory: npm/jedi
- run: yarn publish
working-directory: npm/jedi/build
env:
NODE_AUTH_TOKEN: ${{ secrets.NODE_AUTH_TOKEN }}
+3 -1
View File
@@ -26,8 +26,9 @@ build/
build-*/
_build/
# Test failure outputs
# Tests
######################
.pytest_cache/
tests/*.exp
tests/*.out
@@ -57,3 +58,4 @@ genrst/
# Virtual environment
######################
.venv/
.python-version
+16
View File
@@ -1,4 +1,9 @@
{
"files.exclude": {
"**/__pycache__": true,
},
"python.autoComplete.extraPaths": ["jedi/src"],
"python.formatting.provider": "black",
"python.linting.pylintEnabled": false,
"python.linting.flake8Enabled": true,
@@ -9,6 +14,11 @@
"editor.defaultFormatter": "ms-python.python"
},
"python.languageServer": "Pylance",
"python.testing.pytestArgs": [
"jedi/tests"
],
"python.testing.unittestEnabled": false,
"python.testing.pytestEnabled": true,
"files.associations": {"*.inc": "restructuredtext"},
"restructuredtext.confPath": "${workspaceFolder}/doc/main",
"spellright.language": [
@@ -40,4 +50,10 @@
"restructuredtext",
],
"rewrap.wrappingColumn": 78,
"python.analysis.extraPaths": [
"jedi/src"
],
"yaml.schemas": {
"https://json.schemastore.org/github-workflow.json": "file:///home/david/work/pybricks/pybricks-api/.github/workflows/build.yml"
},
}
+17
View File
@@ -4,6 +4,23 @@
## Unreleased
### Added
- Code auto-completion for `EssentialHub`.
### Fixed
- Fixed some type hints in `parameters` submodule.
## 3.2.0b1-r3 - 2022-06-26
### Fixed
- Fixed more type hints and improved compatibility with jedi.
## 3.2.0b1-r2 - 2022-06-24
### Changed
- Moved remaining type hints from `.pyi` files to the python stub modules, and
fixed numerous errors in the type hints throughout.
## 3.2.0b1-r1 - 2022-06-09
## Added
+2 -5
View File
@@ -8,13 +8,10 @@ SPHINXPROJ = Pybricks
SOURCEDIR = main
BUILDDIR = "$(SOURCEDIR)"/build
TAG = main
ifeq ($(BETA),1)
BETATAG = "-tbeta"
endif
# Put it first so that "make" without argument is like "make help".
help:
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(TAG) $(BETATAG) $(O)
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(TAG) $(O)
.PHONY: help Makefile
@@ -25,4 +22,4 @@ diagrams:
# Catch-all target: route all unknown targets to Sphinx using the new
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
%: Makefile
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) -t $(TAG) $(BETATAG) $(O)
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) -t $(TAG) $(O)
+17 -1
View File
@@ -27,6 +27,9 @@ from docutils import nodes
from docutils.parsers.rst.directives import flag
from docutils.parsers.rst import Directive
from sphinx.application import Sphinx
from sphinx.addnodes import pending_xref
from sphinx.environment import BuildEnvironment
from sphinx.util.nodes import make_refnode
import toml
TOP_DIR = os.path.abspath(os.path.join("..", ".."))
@@ -307,7 +310,16 @@ class AvailabilityDirective(Directive):
]
def on_missing_reference(app, env, node, contnode):
def on_missing_reference(
app: Sphinx, env: BuildEnvironment, node: pending_xref, contnode: nodes.Element
) -> nodes.Element:
# The Number type alias is on the Signals and Units page instead of on the
# pybricks.parameters page so normal resolution doesn't work
if node["reftype"] == "class" and node["reftarget"] == "Number":
return make_refnode(
app.builder, node["refdoc"], "signaltypes", "numbers", contnode
)
# References with special characters can't exist, so we have to supress
# warnings when Sphinx tries to cross reference units like deg/s. For
# consistency, we also treat units without special characters this way.
@@ -324,6 +336,10 @@ def on_missing_reference(app, env, node, contnode):
"ms",
"mNm",
"Hz",
"°C",
"J",
"Ω",
"N",
]:
# If they match on raw source, we are dealing with argument types.
@@ -26,6 +26,7 @@ HUB_FEATURES = {
"technichub": {"technichub"} | FEATURES_MEDIUM,
"primehub": {"primehub", "inventorhub"} | FEATURES_LARGE,
"inventorhub": {"primehub", "inventorhub"} | FEATURES_LARGE,
"essentialhub": {"essentialhub"} | FEATURES_LARGE,
}
+7 -3
View File
@@ -4,6 +4,7 @@
# Pybricks documentation build configuration file
#
import os
import sys
# General information about the project.
project = "pybricks"
@@ -25,9 +26,8 @@ latex_logo = "../common/images/pybricks-logo-large.png"
if os.environ.get("READTHEDOCS", None) == "True":
tags.add("main") # noqa F821
# On https://docs.pybricks.com/en/latest/, show features tagged as beta.
if os.environ.get("READTHEDOCS_VERSION_NAME", None) == "latest":
tags.add("beta") # noqa F821
# HACK: this allows Number type alias to be imported by Sphinx
os.environ["SPHINX_BUILD"] = "True"
# Addtional configuration of the IDE docs
if "ide" in tags.tags: # noqa F821
@@ -51,3 +51,7 @@ if "ide" in tags.tags: # noqa F821
extensions.remove("sphinx.ext.mathjax") # noqa F821
extensions.append("sphinx.ext.imgmath") # noqa F821
html_theme_options["prev_next_buttons_location"] = None # noqa F821
# Build hub specific example scripts.
sys.path.append(os.path.abspath("../../examples/pup/hub_common"))
import make_examples # noqa F401, E402
+6 -6
View File
@@ -44,25 +44,25 @@ Turning the light on and off
****************************
.. literalinclude::
../../../examples/pup/hub_cityhub/light_off.py
../../../examples/pup/hub_common/build/light_off_cityhub.py
Changing brightness and using custom colors
*******************************************
.. literalinclude::
../../../examples/pup/hub_cityhub/light_hsv.py
../../../examples/pup/hub_common/build/light_hsv_cityhub.py
Making the light blink
**********************
.. literalinclude::
../../../examples/pup/hub_cityhub/light_blink.py
../../../examples/pup/hub_common/build/light_blink_cityhub.py
Creating light animations
*************************
.. literalinclude::
../../../examples/pup/hub_cityhub/light_animate.py
../../../examples/pup/hub_common/build/light_animate_cityhub.py
Button and system examples
----------------------------------
@@ -71,10 +71,10 @@ Using the stop button during your program
*****************************************
.. literalinclude::
../../../examples/pup/hub_cityhub/button_single.py
../../../examples/pup/hub_common/build/button_single_cityhub.py
Turning the hub off
*****************************************
.. literalinclude::
../../../examples/pup/hub_cityhub/system_shutdown.py
../../../examples/pup/hub_common/build/system_shutdown_cityhub.py
+146
View File
@@ -0,0 +1,146 @@
.. pybricks-requirements:: essentialhub
Essential Hub
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. figure:: ../../main/images/essentialhub.png
:height: 15 em
.. note:: Pybricks support for this hub is in beta.
Check the `installation instructions`_ to try it out.
The following functions may change before the final release.
.. _installation instructions: https://pybricks.com/install/
.. autoclass:: pybricks.hubs.EssentialHub
:no-members:
.. rubric:: Using the hub status light
.. automethod:: pybricks.hubs::EssentialHub.light.on
.. automethod:: pybricks.hubs::EssentialHub.light.off
.. automethod:: pybricks.hubs::EssentialHub.light.blink
.. automethod:: pybricks.hubs::EssentialHub.light.animate
.. rubric:: Using the button
.. automethod:: pybricks.hubs::EssentialHub.button.pressed
.. rubric:: Using the IMU
.. automethod:: pybricks.hubs::EssentialHub.imu.up
.. automethod:: pybricks.hubs::EssentialHub.imu.tilt
.. automethod:: pybricks.hubs::EssentialHub.imu.acceleration
.. automethod:: pybricks.hubs::EssentialHub.imu.angular_velocity
.. automethod:: pybricks.hubs::EssentialHub.imu.heading
.. automethod:: pybricks.hubs::EssentialHub.imu.reset_heading
.. rubric:: Using the battery
.. automethod:: pybricks.hubs::EssentialHub.battery.voltage
.. automethod:: pybricks.hubs::EssentialHub.battery.current
.. rubric:: Getting the charger status
.. automethod:: pybricks.hubs::EssentialHub.charger.connected
.. automethod:: pybricks.hubs::EssentialHub.charger.current
.. automethod:: pybricks.hubs::EssentialHub.charger.status
.. rubric:: System control
.. automethod:: pybricks.hubs::EssentialHub.system.set_stop_button
.. automethod:: pybricks.hubs::EssentialHub.system.name
.. automethod:: pybricks.hubs::EssentialHub.system.shutdown
.. automethod:: pybricks.hubs::EssentialHub.system.reset_reason
Status light examples
---------------------
Turning the light on and off
****************************
.. literalinclude::
../../../examples/pup/hub_common/build/light_off_essentialhub.py
Changing brightness and using custom colors
*******************************************
.. literalinclude::
../../../examples/pup/hub_common/build/light_hsv_essentialhub.py
Making the light blink
**********************
.. literalinclude::
../../../examples/pup/hub_common/build/light_blink_essentialhub.py
Creating light animations
*************************
.. literalinclude::
../../../examples/pup/hub_common/build/light_animate_essentialhub.py
IMU examples
---------------
Testing which way is up
********************************
.. literalinclude::
../../../examples/pup/hub_common/build/imu_up_essentialhub.py
Reading the tilt value
********************************
.. literalinclude::
../../../examples/pup/hub_common/build/imu_tilt_essentialhub.py
Using a custom hub orientation
**************************************************
.. literalinclude::
../../../examples/pup/hub_common/build/imu_tilt_blast_essentialhub.py
Reading acceleration and angular velocity vectors
**************************************************
.. literalinclude::
../../../examples/pup/hub_common/build/imu_read_vector_essentialhub.py
Reading acceleration and angular velocity on one axis
*****************************************************
.. literalinclude::
../../../examples/pup/hub_common/build/imu_read_scalar_essentialhub.py
System examples
----------------------------------
Using the stop button during your program
*****************************************
.. literalinclude::
../../../examples/pup/hub_common/build/button_single_essentialhub.py
Turning the hub off
*****************************************
.. literalinclude::
../../../examples/pup/hub_common/build/system_shutdown_essentialhub.py
+6
View File
@@ -13,6 +13,7 @@
cityhub
technichub
primehub
essentialhub
.. pybricks-classlink:: MoveHub
@@ -44,3 +45,8 @@
:height: 10 em
:target: primehub.html
.. pybricks-classlink:: EssentialHub
.. figure:: ../../main/images/essentialhub.png
:height: 10 em
:target: essentialhub.html
+5 -5
View File
@@ -56,13 +56,13 @@ Turning the light on and off
******************************
.. literalinclude::
../../../examples/pup/hub_movehub/light_off.py
../../../examples/pup/hub_common/build/light_off_movehub.py
Making the light blink
******************************
.. literalinclude::
../../../examples/pup/hub_movehub/light_blink.py
../../../examples/pup/hub_common/build/light_blink_movehub.py
IMU examples
---------------
@@ -71,7 +71,7 @@ Testing which way is up
********************************
.. literalinclude::
../../../examples/pup/hub_movehub/imu_up.py
../../../examples/pup/hub_common/build/imu_up_movehub.py
Reading acceleration
**************************************************
@@ -86,10 +86,10 @@ Using the stop button during your program
*****************************************
.. literalinclude::
../../../examples/pup/hub_movehub/button_single.py
../../../examples/pup/hub_common/build/button_single_movehub.py
Turning the hub off
*****************************************
.. literalinclude::
../../../examples/pup/hub_movehub/system_shutdown.py
../../../examples/pup/hub_common/build/system_shutdown_movehub.py
+149 -155
View File
@@ -6,256 +6,250 @@ Prime Hub / Inventor Hub
.. figure:: ../../main/images/primeinventorhub.png
:height: 15 em
.. only:: not beta
.. note:: Pybricks support for these hubs is currently in development.
Please check back later!
.. note:: Pybricks support for these hubs is in beta.
Check the `installation instructions`_ to try it out.
The following functions may change before the final release.
.. only:: beta
.. class:: InventorHub
.. note:: Pybricks support for these hubs is in beta.
Check the `installation instructions`_ to try it out.
The following functions may change before the final release.
This class is the same as the ``PrimeHub`` class, shown below. Both classes
work on both hubs.
.. class:: InventorHub
These hubs are completely identical. They use the same Pybricks firmware.
This class is the same as the ``PrimeHub`` class, shown below. Both classes
work on both hubs.
.. autoclass:: pybricks.hubs.PrimeHub
:no-members:
These hubs are completely identical. They use the same Pybricks firmware.
.. rubric:: Using the hub status light
.. autoclass:: pybricks.hubs.PrimeHub
:no-members:
.. figure:: ../../main/images/primehub_light_label.png
:width: 22 em
.. rubric:: Using the hub status light
.. automethod:: pybricks.hubs::PrimeHub.light.on
.. figure:: ../../main/images/primehub_light_label.png
:width: 22 em
.. automethod:: pybricks.hubs::PrimeHub.light.off
.. automethod:: pybricks.hubs::PrimeHub.light.on
.. automethod:: pybricks.hubs::PrimeHub.light.blink
.. automethod:: pybricks.hubs::PrimeHub.light.off
.. automethod:: pybricks.hubs::PrimeHub.light.animate
.. automethod:: pybricks.hubs::PrimeHub.light.blink
.. rubric:: Using the light matrix display
.. automethod:: pybricks.hubs::PrimeHub.light.animate
.. figure:: ../../main/images/primehub_display_label.png
:width: 22 em
.. rubric:: Using the light matrix display
.. automethod:: pybricks.hubs::PrimeHub.display.orientation
.. figure:: ../../main/images/primehub_display_label.png
:width: 22 em
.. automethod:: pybricks.hubs::PrimeHub.display.off
.. automethod:: pybricks.hubs::PrimeHub.display.orientation
.. automethod:: pybricks.hubs::PrimeHub.display.pixel
.. automethod:: pybricks.hubs::PrimeHub.display.off
.. automethod:: pybricks.hubs::PrimeHub.display.image
.. automethod:: pybricks.hubs::PrimeHub.display.pixel
.. automethod:: pybricks.hubs::PrimeHub.display.animate
.. automethod:: pybricks.hubs::PrimeHub.display.image
.. automethod:: pybricks.hubs::PrimeHub.display.number
.. automethod:: pybricks.hubs::PrimeHub.display.animate
.. automethod:: pybricks.hubs::PrimeHub.display.char
.. automethod:: pybricks.hubs::PrimeHub.display.number
.. automethod:: pybricks.hubs::PrimeHub.display.text
.. automethod:: pybricks.hubs::PrimeHub.display.char
.. rubric:: Using the buttons
.. automethod:: pybricks.hubs::PrimeHub.display.text
.. figure:: ../../main/images/primehub_buttons_label.png
:width: 22 em
.. rubric:: Using the buttons
.. automethod:: pybricks.hubs::PrimeHub.buttons.pressed
.. figure:: ../../main/images/primehub_buttons_label.png
:width: 22 em
.. rubric:: Using the IMU
.. automethod:: pybricks.hubs::PrimeHub.buttons.pressed
.. automethod:: pybricks.hubs::PrimeHub.imu.up
.. rubric:: Using the IMU
.. automethod:: pybricks.hubs::PrimeHub.imu.tilt
.. automethod:: pybricks.hubs::PrimeHub.imu.up
.. automethod:: pybricks.hubs::PrimeHub.imu.acceleration
.. automethod:: pybricks.hubs::PrimeHub.imu.tilt
.. automethod:: pybricks.hubs::PrimeHub.imu.angular_velocity
.. automethod:: pybricks.hubs::PrimeHub.imu.acceleration
.. automethod:: pybricks.hubs::PrimeHub.imu.heading
.. automethod:: pybricks.hubs::PrimeHub.imu.angular_velocity
.. automethod:: pybricks.hubs::PrimeHub.imu.reset_heading
.. automethod:: pybricks.hubs::PrimeHub.imu.heading
.. rubric:: Using the speaker
.. automethod:: pybricks.hubs::PrimeHub.imu.reset_heading
.. automethod:: pybricks.hubs::PrimeHub.speaker.volume
.. rubric:: Using the speaker
.. automethod:: pybricks.hubs::PrimeHub.speaker.beep
.. automethod:: pybricks.hubs::PrimeHub.speaker.volume
.. automethod:: pybricks.hubs::PrimeHub.speaker.play_notes
.. automethod:: pybricks.hubs::PrimeHub.speaker.beep
.. rubric:: Using the battery
.. automethod:: pybricks.hubs::PrimeHub.speaker.play_notes
.. automethod:: pybricks.hubs::PrimeHub.battery.voltage
.. rubric:: Using the battery
.. automethod:: pybricks.hubs::PrimeHub.battery.current
.. automethod:: pybricks.hubs::PrimeHub.battery.voltage
.. rubric:: Getting the charger status
.. automethod:: pybricks.hubs::PrimeHub.battery.current
.. automethod:: pybricks.hubs::PrimeHub.charger.connected
.. rubric:: Getting the charger status
.. automethod:: pybricks.hubs::PrimeHub.charger.current
.. automethod:: pybricks.hubs::PrimeHub.charger.connected
.. automethod:: pybricks.hubs::PrimeHub.charger.status
.. automethod:: pybricks.hubs::PrimeHub.charger.current
.. rubric:: System control
.. automethod:: pybricks.hubs::PrimeHub.charger.status
.. automethod:: pybricks.hubs::PrimeHub.system.set_stop_button
.. rubric:: System control
.. automethod:: pybricks.hubs::PrimeHub.system.name
.. automethod:: pybricks.hubs::PrimeHub.system.set_stop_button
.. automethod:: pybricks.hubs::PrimeHub.system.shutdown
.. automethod:: pybricks.hubs::PrimeHub.system.name
.. automethod:: pybricks.hubs::PrimeHub.system.reset_reason
.. automethod:: pybricks.hubs::PrimeHub.system.shutdown
.. note:: The examples below use the ``PrimeHub`` class. The examples work fine
on both hubs because they are the identical. If you prefer, you can
change this to ``InventorHub``.
.. automethod:: pybricks.hubs::PrimeHub.system.reset_reason
Status light examples
---------------------
.. note:: The examples below use the ``PrimeHub`` class. The examples work fine
on both hubs because they are the identical. If you prefer, you can
change this to ``InventorHub``.
Turning the light on and off
****************************
Status light examples
---------------------
.. literalinclude::
../../../examples/pup/hub_common/build/light_off_primehub.py
Turning the light on and off
****************************
Changing brightness and using custom colors
*******************************************
.. literalinclude::
../../../examples/pup/hub_primehub/light_off.py
.. literalinclude::
../../../examples/pup/hub_common/build/light_hsv_primehub.py
Changing brightness and using custom colors
*******************************************
Making the light blink
**********************
.. literalinclude::
../../../examples/pup/hub_primehub/light_hsv.py
.. literalinclude::
../../../examples/pup/hub_common/build/light_blink_primehub.py
Making the light blink
**********************
Creating light animations
*************************
.. literalinclude::
../../../examples/pup/hub_primehub/light_blink.py
.. literalinclude::
../../../examples/pup/hub_common/build/light_animate_primehub.py
Creating light animations
*************************
Matrix display examples
-----------------------
.. literalinclude::
../../../examples/pup/hub_primehub/light_animate.py
Displaying images
*****************
Matrix display examples
-----------------------
.. literalinclude::
../../../examples/pup/hub_primehub/display_image.py
Displaying images
*****************
Displaying numbers
******************
.. literalinclude::
../../../examples/pup/hub_primehub/display_image.py
.. literalinclude::
../../../examples/pup/hub_primehub/display_number.py
Displaying numbers
******************
Displaying text
***************
.. literalinclude::
../../../examples/pup/hub_primehub/display_number.py
.. literalinclude::
../../../examples/pup/hub_primehub/display_text.py
Displaying text
***************
Displaying individual pixels
****************************
.. literalinclude::
../../../examples/pup/hub_primehub/display_text.py
.. literalinclude::
../../../examples/pup/hub_primehub/display_pixel.py
Displaying individual pixels
****************************
Changing the display orientation
********************************
.. literalinclude::
../../../examples/pup/hub_primehub/display_pixel.py
.. literalinclude::
../../../examples/pup/hub_primehub/display_orientation.py
Changing the display orientation
********************************
.. literalinclude::
../../../examples/pup/hub_primehub/display_orientation_imu.py
.. literalinclude::
../../../examples/pup/hub_primehub/display_orientation.py
Making your own images
**********************
.. literalinclude::
../../../examples/pup/hub_primehub/display_orientation_imu.py
.. literalinclude::
../../../examples/pup/hub_primehub/display_matrix.py
Making your own images
**********************
Combining images to make expressions
************************************
.. literalinclude::
../../../examples/pup/hub_primehub/display_matrix.py
.. literalinclude::
../../../examples/pup/hub_primehub/display_expression.py
Combining images to make expressions
************************************
Displaying animations
*********************
.. literalinclude::
../../../examples/pup/hub_primehub/display_expression.py
.. literalinclude::
../../../examples/pup/hub_primehub/display_animate.py
Displaying animations
*********************
Button examples
---------------
.. literalinclude::
../../../examples/pup/hub_primehub/display_animate.py
Detecting button presses
************************
Button examples
---------------
.. literalinclude::
../../../examples/pup/hub_primehub/button_main.py
Detecting button presses
************************
IMU examples
---------------
.. literalinclude::
../../../examples/pup/hub_primehub/button_main.py
Testing which way is up
********************************
IMU examples
---------------
.. literalinclude::
../../../examples/pup/hub_common/build/imu_up_primehub.py
Testing which way is up
********************************
.. literalinclude::
../../../examples/pup/hub_primehub/imu_up.py
Reading the tilt value
********************************
.. literalinclude::
../../../examples/pup/hub_common/build/imu_tilt_primehub.py
Reading the tilt value
********************************
Using a custom hub orientation
**************************************************
.. literalinclude::
../../../examples/pup/hub_primehub/imu_tilt.py
.. literalinclude::
../../../examples/pup/hub_common/build/imu_tilt_blast_primehub.py
Using a custom hub orientation
**************************************************
Reading acceleration and angular velocity vectors
**************************************************
.. literalinclude::
../../../examples/pup/hub_primehub/imu_tilt_blast.py
.. literalinclude::
../../../examples/pup/hub_common/build/imu_read_vector_primehub.py
Reading acceleration and angular velocity vectors
**************************************************
Reading acceleration and angular velocity on one axis
*****************************************************
.. literalinclude::
../../../examples/pup/hub_primehub/imu_read_vector.py
.. literalinclude::
../../../examples/pup/hub_common/build/imu_read_scalar_primehub.py
Reading acceleration and angular velocity on one axis
*****************************************************
System examples
----------------------------------
.. literalinclude::
../../../examples/pup/hub_primehub/imu_read_scalar.py
Changing the stop button combination
*****************************************
System examples
----------------------------------
.. literalinclude::
../../../examples/pup/hub_primehub/button_stop.py
Changing the stop button combination
*****************************************
Turning the hub off
*****************************************
.. literalinclude::
../../../examples/pup/hub_primehub/button_stop.py
Turning the hub off
*****************************************
.. literalinclude::
../../../examples/pup/hub_primehub/system_shutdown.py
.. literalinclude::
../../../examples/pup/hub_common/build/system_shutdown_primehub.py
.. _installation instructions: https://pybricks.com/install/
+11 -11
View File
@@ -58,25 +58,25 @@ Turning the light on and off
****************************
.. literalinclude::
../../../examples/pup/hub_technichub/light_off.py
../../../examples/pup/hub_common/build/light_off_technichub.py
Changing brightness and using custom colors
*******************************************
.. literalinclude::
../../../examples/pup/hub_technichub/light_hsv.py
../../../examples/pup/hub_common/build/light_hsv_technichub.py
Making the light blink
**********************
.. literalinclude::
../../../examples/pup/hub_technichub/light_blink.py
../../../examples/pup/hub_common/build/light_blink_technichub.py
Creating light animations
*************************
.. literalinclude::
../../../examples/pup/hub_technichub/light_animate.py
../../../examples/pup/hub_common/build/light_animate_technichub.py
IMU examples
---------------
@@ -85,32 +85,32 @@ Testing which way is up
********************************
.. literalinclude::
../../../examples/pup/hub_technichub/imu_up.py
../../../examples/pup/hub_common/build/imu_up_technichub.py
Reading the tilt value
********************************
.. literalinclude::
../../../examples/pup/hub_technichub/imu_tilt.py
../../../examples/pup/hub_common/build/imu_tilt_technichub.py
Using a custom hub orientation
**************************************************
.. literalinclude::
../../../examples/pup/hub_technichub/imu_tilt_blast.py
../../../examples/pup/hub_common/build/imu_tilt_blast_technichub.py
Reading acceleration and angular velocity vectors
**************************************************
.. literalinclude::
../../../examples/pup/hub_technichub/imu_read_vector.py
../../../examples/pup/hub_common/build/imu_read_vector_technichub.py
Reading acceleration and angular velocity on one axis
*****************************************************
.. literalinclude::
../../../examples/pup/hub_technichub/imu_read_scalar.py
../../../examples/pup/hub_common/build/imu_read_scalar_technichub.py
Button and system examples
----------------------------------
@@ -119,10 +119,10 @@ Using the stop button during your program
*****************************************
.. literalinclude::
../../../examples/pup/hub_technichub/button_single.py
../../../examples/pup/hub_common/build/button_single_technichub.py
Turning the hub off
*****************************************
.. literalinclude::
../../../examples/pup/hub_technichub/system_shutdown.py
../../../examples/pup/hub_common/build/system_shutdown_technichub.py
Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 142 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 79 KiB

+2 -2
View File
@@ -28,8 +28,8 @@ Pybricks Documentation
.. list-table::
* - **Technic Hub, City Hub, BOOST Move Hub**
- **SPIKE Prime Hub / MINDSTORMS Inventor Hub**
* - **Technic, City, and BOOST Move Hubs**
- **SPIKE Essential/Prime, and MINDSTORMS Inventor Hubs**
* - .. figure:: ../main/images/powereduphubs.png
:target: https://pybricks.com/install/technic-boost-city/
+3 -3
View File
@@ -9,12 +9,12 @@ EV3 DC Motor
.. figure:: ../../main/images/rcxmotor.png
:width: 40 %
.. autoclass:: pybricks._common.DCMotor
.. autoclass:: pybricks.iodevices.DCMotor
:noindex:
:no-members:
.. automethod:: pybricks._common.DCMotor.dc
.. automethod:: pybricks.iodevices.DCMotor.dc
:noindex:
.. automethod:: pybricks._common.DCMotor.stop
.. automethod:: pybricks.iodevices.DCMotor.stop
:noindex:
+1 -15
View File
@@ -36,26 +36,12 @@ Basic types
.. pybricks-requirements::
..
_comment: The int class is defined manually because otherwise the classmethod is hidden, see https://github.com/pybricks/pybricks-api/issues/86
.. autoclass:: ubuiltins.int
:no-members:
.. automethod:: ubuiltins.int.to_bytes
.. classmethod:: from_bytes(bytes: Union[bytes, bytearray], byteorder: Literal["little", "big"]) -> int
Returns the integer represented by the given bytes.
:param bytes: The bytes to convert.
:param byteorder: Determines the byte order used to represent the
integer. If byteorder is ``"big"``, the most significant byte is at
the beginning of the byte sequence. If byteorder is ``"little"``,
the most significant byte is at the end of the byte sequence.
:returns: The integer represented by the bytes.
.. automethod:: ubuiltins.int.from_bytes
.. pybricks-requirements::
+6
View File
@@ -45,6 +45,12 @@ NXT Color Sensor
.. automethod:: pybricks.nxtdevices.ColorSensor.rgb
.. rubric:: Advanced color sensing
.. automethod:: pybricks.nxtdevices.ColorSensor.hsv
.. automethod:: pybricks.nxtdevices.ColorSensor.detectable_colors
.. rubric:: Built-in light
This sensor has a built-in light. You can make it red, green, blue, or turn
+5
View File
@@ -41,6 +41,11 @@ Side
.. figure:: ../../main/images/orientation_inventorhub_label.png
:height: 17 em
**Essential Hub**
.. figure:: ../../main/images/orientation_essentialhub_label.png
:height: 17 em
**Move Hub**
.. figure:: ../../main/images/orientation_movehub_label.png
+2 -16
View File
@@ -7,22 +7,8 @@ quantities. This page gives an overview of each quantity and its unit.
Numbers
~~~~~~~
.. class:: Number
Numbers can be represented as integers or floating point values:
* Integers (:class:`int <ubuiltins.int>`) are whole numbers
like ``15`` or ``-123``.
* Floating point values (:class:`float <ubuiltins.float>`) are decimal
numbers like ``3.14`` or ``-123.45``.
If you see :class:`Number <Number>` as the argument type, both
:class:`int <ubuiltins.int>` and :class:`float <ubuiltins.float>` may be used.
For example, :func:`wait(15) <pybricks.tools.wait>` and
:func:`wait(15.75) <pybricks.tools.wait>` are both allowed. In most functions,
however, your input value will be truncated to a whole number anyway. In this
example, either command makes the program pause for just 15 milliseconds.
.. autodata:: pybricks.parameters.Number
:noindex:
Time
~~~~~~
+2 -6
View File
@@ -15,10 +15,6 @@ if "%TAG%" == "" (
set TAG=main
)
if "%BETA%" == "1" (
set BETATAG=-tbeta
)
if "%1" == "" goto help
%SPHINXBUILD% >NUL 2>NUL
@@ -34,11 +30,11 @@ if errorlevel 9009 (
exit /b 1
)
%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% -t %TAG% %BETATAG%
%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% -t %TAG%
goto end
:help
%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% -t %TAG% %BETATAG%
%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% -t %TAG%
:end
popd
-22
View File
@@ -1,22 +0,0 @@
from pybricks.hubs import CityHub
from pybricks.parameters import Color
from pybricks.tools import wait
from umath import sin, pi
# Initialize the hub.
hub = CityHub()
# Make an animation with multiple colors.
hub.light.animate([Color.RED, Color.GREEN, Color.NONE], interval=500)
wait(10000)
# Make the color RED grow faint and bright using a sine pattern.
hub.light.animate([Color.RED * (0.5 * sin(i / 15 * pi) + 0.5) for i in range(30)], 40)
wait(10000)
# Cycle through a rainbow of colors.
hub.light.animate([Color(h=i * 8) for i in range(45)], interval=40)
wait(10000)
-16
View File
@@ -1,16 +0,0 @@
from pybricks.hubs import CityHub
from pybricks.parameters import Color
from pybricks.tools import wait
# Initialize the hub
hub = CityHub()
# Keep blinking red on and off.
hub.light.blink(Color.RED, [500, 500])
wait(10000)
# Keep blinking green slowly and then quickly.
hub.light.blink(Color.GREEN, [500, 500, 50, 900])
wait(10000)
-21
View File
@@ -1,21 +0,0 @@
from pybricks.hubs import CityHub
from pybricks.parameters import Color
from pybricks.tools import wait
# Initialize the hub.
hub = CityHub()
# Show the color at 30% brightness.
hub.light.on(Color.RED * 0.3)
wait(2000)
# Use your own custom color.
hub.light.on(Color(h=30, s=100, v=50))
wait(2000)
# Go through all the colors.
for hue in range(360):
hub.light.on(Color(hue))
wait(10)
@@ -1,12 +0,0 @@
from pybricks.hubs import CityHub
from pybricks.tools import wait
# Initialize the hub.
hub = CityHub()
# Say goodbye and give some time to send it.
print("Goodbye!")
wait(100)
# Shut the hub down.
hub.system.shutdown()
@@ -1,9 +1,10 @@
from pybricks.hubs import CityHub
# ThisHub = MoveHub CityHub TechnicHub EssentialHub
from pybricks.hubs import ThisHub
from pybricks.parameters import Color, Button
from pybricks.tools import wait, StopWatch
# Initialize the hub.
hub = CityHub()
hub = ThisHub()
# Disable the stop button.
hub.system.set_stop_button(None)
@@ -1,9 +1,10 @@
from pybricks.hubs import PrimeHub
# ThisHub = TechnicHub PrimeHub EssentialHub
from pybricks.hubs import ThisHub
from pybricks.tools import wait
from pybricks.geometry import Axis
# Initialize the hub.
hub = PrimeHub()
hub = ThisHub()
# Get the acceleration or angular_velocity along a single axis.
# If you need only one value, this is more memory efficient.
@@ -1,9 +1,9 @@
# ExampleHub = TechnicHub PrimeHub
from pybricks.hubs import ExampleHub
# ThisHub = TechnicHub PrimeHub EssentialHub
from pybricks.hubs import ThisHub
from pybricks.tools import wait
# Initialize the hub.
hub = ExampleHub()
hub = ThisHub()
# Get the acceleration vector in g's.
print(hub.imu.acceleration() / 9810)
@@ -1,8 +1,9 @@
from pybricks.hubs import PrimeHub
# ThisHub = TechnicHub PrimeHub EssentialHub
from pybricks.hubs import ThisHub
from pybricks.tools import wait
# Initialize the hub.
hub = PrimeHub()
hub = ThisHub()
while True:
# Read the tilt values.
@@ -1,11 +1,12 @@
from pybricks.hubs import TechnicHub
# ThisHub = TechnicHub PrimeHub EssentialHub
from pybricks.hubs import ThisHub
from pybricks.tools import wait
from pybricks.geometry import Axis
# Initialize the hub. In this case, specify that the hub is mounted with the
# top side facing forward and the front side facing to the right.
# For example, this is how the hub is mounted in BLAST in the 51515 set.
hub = TechnicHub(top_side=Axis.X, front_side=-Axis.Y)
hub = ThisHub(top_side=Axis.X, front_side=-Axis.Y)
while True:
# Read the tilt values. Now, the values are 0 when BLAST stands upright.
@@ -1,9 +1,10 @@
from pybricks.hubs import MoveHub
# ThisHub = TechnicHub PrimeHub MoveHub EssentialHub
from pybricks.hubs import ThisHub
from pybricks.parameters import Color, Side
from pybricks.tools import wait
# Initialize the hub.
hub = MoveHub()
hub = ThisHub()
# Define colors for each side in a dictionary.
SIDE_COLORS = {
@@ -1,11 +1,11 @@
# ExampleHub = CityHub TechnicHub PrimeHub
from pybricks.hubs import ExampleHub
# ThisHub = CityHub TechnicHub PrimeHub EssentialHub
from pybricks.hubs import ThisHub
from pybricks.parameters import Color
from pybricks.tools import wait
from umath import sin, pi
# Initialize the hub.
hub = ExampleHub()
hub = ThisHub()
# Make an animation with multiple colors.
hub.light.animate([Color.RED, Color.GREEN, Color.NONE], interval=500)
@@ -1,9 +1,10 @@
from pybricks.hubs import PrimeHub
# ThisHub = MoveHub CityHub TechnicHub PrimeHub EssentialHub
from pybricks.hubs import ThisHub
from pybricks.parameters import Color
from pybricks.tools import wait
# Initialize the hub
hub = PrimeHub()
hub = ThisHub()
# Keep blinking red on and off.
hub.light.blink(Color.RED, [500, 500])
@@ -1,10 +1,10 @@
# ExampleHub = CityHub TechnicHub PrimeHub
from pybricks.hubs import ExampleHub
# ThisHub = CityHub TechnicHub PrimeHub EssentialHub
from pybricks.hubs import ThisHub
from pybricks.parameters import Color
from pybricks.tools import wait
# Initialize the hub.
hub = ExampleHub()
hub = ThisHub()
# Show the color at 30% brightness.
hub.light.on(Color.RED * 0.3)
@@ -1,9 +1,10 @@
from pybricks.hubs import CityHub
# ThisHub = MoveHub CityHub TechnicHub PrimeHub EssentialHub
from pybricks.hubs import ThisHub
from pybricks.parameters import Color
from pybricks.tools import wait
# Initialize the hub.
hub = CityHub()
hub = ThisHub()
# Turn the light on and off 5 times.
for i in range(5):
+39
View File
@@ -0,0 +1,39 @@
#!/usr/bin/env python3
"""Generates hub-specific examples from common template script."""
import pathlib
# Make build directory.
dir_path = pathlib.Path(__file__).parent
build_path = dir_path / "build"
build_path.mkdir(exist_ok=True)
# Get list of scripts to be parsed.
file_paths = [f for f in dir_path.glob("*.py") if f.stem != "make_examples"]
# Go through all template scripts
for file_path in file_paths:
with open(file_path) as template:
# First line contains hub info
hubs = template.readline().strip().split()[3:]
print("Converting", template.name, "to", hubs)
for hub in hubs:
# Path to hub-specific output script.
gen_path = build_path / (file_path.stem + "_" + hub.lower() + ".py")
# Reset source script and skip over header.
template.seek(0)
template.readline()
# Open destination script:
with open(gen_path, "w") as dest_file:
# Read script line by line.
for line in template.readlines():
# Replace hub name if present.
dest_file.writelines(line.replace("ThisHub", hub))
@@ -1,8 +1,9 @@
from pybricks.hubs import PrimeHub
# ThisHub = MoveHub CityHub TechnicHub PrimeHub EssentialHub
from pybricks.hubs import ThisHub
from pybricks.tools import wait
# Initialize the hub.
hub = PrimeHub()
hub = ThisHub()
# Say goodbye and give some time to send it.
print("Goodbye!")
-25
View File
@@ -1,25 +0,0 @@
from pybricks.hubs import MoveHub
from pybricks.parameters import Color, Button
from pybricks.tools import wait, StopWatch
# Initialize the hub.
hub = MoveHub()
# Disable the stop button.
hub.system.set_stop_button(None)
# Check the button for 5 seconds.
watch = StopWatch()
while watch.time() < 5000:
# Set light to green if pressed, else red.
if hub.button.pressed():
hub.light.on(Color.GREEN)
else:
hub.light.on(Color.RED)
# Enable the stop button again.
hub.system.set_stop_button(Button.CENTER)
# Now you can press the stop button as usual.
wait(5000)
-16
View File
@@ -1,16 +0,0 @@
from pybricks.hubs import MoveHub
from pybricks.parameters import Color
from pybricks.tools import wait
# Initialize the hub
hub = MoveHub()
# Keep blinking red on and off.
hub.light.blink(Color.RED, [500, 500])
wait(10000)
# Keep blinking green slowly and then quickly.
hub.light.blink(Color.GREEN, [500, 500, 50, 900])
wait(10000)
-15
View File
@@ -1,15 +0,0 @@
from pybricks.hubs import MoveHub
from pybricks.parameters import Color
from pybricks.tools import wait
# Initialize the hub.
hub = MoveHub()
# Turn the light on and off 5 times.
for i in range(5):
hub.light.on(Color.RED)
wait(1000)
hub.light.off()
wait(500)
@@ -1,12 +0,0 @@
from pybricks.hubs import MoveHub
from pybricks.tools import wait
# Initialize the hub.
hub = MoveHub()
# Say goodbye and give some time to send it.
print("Goodbye!")
wait(100)
# Shut the hub down.
hub.system.shutdown()
@@ -1,14 +0,0 @@
from pybricks.hubs import PrimeHub
from pybricks.tools import wait
# Initialize the hub.
hub = PrimeHub()
# Get the acceleration vector in g's.
print(hub.imu.acceleration() / 9810)
# Get the angular velocity vector.
print(hub.imu.angular_velocity())
# Wait so we can see what we printed
wait(5000)
@@ -1,17 +0,0 @@
from pybricks.hubs import PrimeHub
from pybricks.tools import wait
from pybricks.geometry import Axis
# Initialize the hub. In this case, specify that the hub is mounted with the
# top side facing forward and the front side facing to the right.
# For example, this is how the hub is mounted in BLAST in the 51515 set.
hub = PrimeHub(top_side=Axis.X, front_side=-Axis.Y)
while True:
# Read the tilt values. Now, the values are 0 when BLAST stands upright.
# Leaning forward gives positive pitch. Leaning right gives positive roll.
pitch, roll = hub.imu.tilt()
# Print the result.
print(pitch, roll)
wait(200)
-29
View File
@@ -1,29 +0,0 @@
from pybricks.hubs import PrimeHub
from pybricks.parameters import Color, Side
from pybricks.tools import wait
# Initialize the hub.
hub = PrimeHub()
# Define colors for each side in a dictionary.
SIDE_COLORS = {
Side.TOP: Color.RED,
Side.BOTTOM: Color.BLUE,
Side.LEFT: Color.GREEN,
Side.RIGHT: Color.YELLOW,
Side.FRONT: Color.MAGENTA,
Side.BACK: Color.BLACK,
}
# Keep updating the color based on detected up side.
while True:
# Check which side of the hub is up.
up_side = hub.imu.up()
# Change the color based on the side.
hub.light.on(SIDE_COLORS[up_side])
# Also print the result.
print(up_side)
wait(50)
@@ -1,22 +0,0 @@
from pybricks.hubs import PrimeHub
from pybricks.parameters import Color
from pybricks.tools import wait
from umath import sin, pi
# Initialize the hub.
hub = PrimeHub()
# Make an animation with multiple colors.
hub.light.animate([Color.RED, Color.GREEN, Color.NONE], interval=500)
wait(10000)
# Make the color RED grow faint and bright using a sine pattern.
hub.light.animate([Color.RED * (0.5 * sin(i / 15 * pi) + 0.5) for i in range(30)], 40)
wait(10000)
# Cycle through a rainbow of colors.
hub.light.animate([Color(h=i * 8) for i in range(45)], interval=40)
wait(10000)
-21
View File
@@ -1,21 +0,0 @@
from pybricks.hubs import PrimeHub
from pybricks.parameters import Color
from pybricks.tools import wait
# Initialize the hub.
hub = PrimeHub()
# Show the color at 30% brightness.
hub.light.on(Color.RED * 0.3)
wait(2000)
# Use your own custom color.
hub.light.on(Color(h=30, s=100, v=50))
wait(2000)
# Go through all the colors.
for hue in range(360):
hub.light.on(Color(hue))
wait(10)
-15
View File
@@ -1,15 +0,0 @@
from pybricks.hubs import PrimeHub
from pybricks.parameters import Color
from pybricks.tools import wait
# Initialize the hub.
hub = PrimeHub()
# Turn the light on and off 5 times.
for i in range(5):
hub.light.on(Color.RED)
wait(1000)
hub.light.off()
wait(500)
-26
View File
@@ -1,26 +0,0 @@
# ExampleHub = MoveHub CityHub TechnicHub
from pybricks.hubs import ExampleHub
from pybricks.parameters import Color, Button
from pybricks.tools import wait, StopWatch
# Initialize the hub.
hub = ExampleHub()
# Disable the stop button.
hub.system.set_stop_button(None)
# Check the button for 5 seconds.
watch = StopWatch()
while watch.time() < 5000:
# Set light to green if pressed, else red.
if hub.button.pressed():
hub.light.on(Color.GREEN)
else:
hub.light.on(Color.RED)
# Enable the stop button again.
hub.system.set_stop_button(Button.CENTER)
# Now you can press the stop button as usual.
wait(5000)
@@ -1,21 +0,0 @@
# ExampleHub = TechnicHub PrimeHub
from pybricks.hubs import ExampleHub
from pybricks.tools import wait
from pybricks.geometry import Axis
# Initialize the hub.
hub = ExampleHub()
# Get the acceleration or angular_velocity along a single axis.
# If you need only one value, this is more memory efficient.
while True:
# Read the forward acceleration.
forward_acceleration = hub.imu.acceleration(Axis.X)
# Read the yaw rate.
yaw_rate = hub.imu.angular_velocity(Axis.Z)
# Print the yaw rate.
print(yaw_rate)
wait(100)
-14
View File
@@ -1,14 +0,0 @@
# ExampleHub = TechnicHub PrimeHub
from pybricks.hubs import ExampleHub
from pybricks.tools import wait
# Initialize the hub.
hub = ExampleHub()
while True:
# Read the tilt values.
pitch, roll = hub.imu.tilt()
# Print the result.
print(pitch, roll)
wait(200)
-18
View File
@@ -1,18 +0,0 @@
# ExampleHub = TechnicHub PrimeHub
from pybricks.hubs import ExampleHub
from pybricks.tools import wait
from pybricks.geometry import Axis
# Initialize the hub. In this case, specify that the hub is mounted with the
# top side facing forward and the front side facing to the right.
# For example, this is how the hub is mounted in BLAST in the 51515 set.
hub = ExampleHub(top_side=Axis.X, front_side=-Axis.Y)
while True:
# Read the tilt values. Now, the values are 0 when BLAST stands upright.
# Leaning forward gives positive pitch. Leaning right gives positive roll.
pitch, roll = hub.imu.tilt()
# Print the result.
print(pitch, roll)
wait(200)
-30
View File
@@ -1,30 +0,0 @@
# ExampleHub = TechnicHub PrimeHub MoveHub
from pybricks.hubs import ExampleHub
from pybricks.parameters import Color, Side
from pybricks.tools import wait
# Initialize the hub.
hub = ExampleHub()
# Define colors for each side in a dictionary.
SIDE_COLORS = {
Side.TOP: Color.RED,
Side.BOTTOM: Color.BLUE,
Side.LEFT: Color.GREEN,
Side.RIGHT: Color.YELLOW,
Side.FRONT: Color.MAGENTA,
Side.BACK: Color.BLACK,
}
# Keep updating the color based on detected up side.
while True:
# Check which side of the hub is up.
up_side = hub.imu.up()
# Change the color based on the side.
hub.light.on(SIDE_COLORS[up_side])
# Also print the result.
print(up_side)
wait(50)
-17
View File
@@ -1,17 +0,0 @@
# ExampleHub = MoveHub CityHub TechnicHub PrimeHub
from pybricks.hubs import ExampleHub
from pybricks.parameters import Color
from pybricks.tools import wait
# Initialize the hub
hub = ExampleHub()
# Keep blinking red on and off.
hub.light.blink(Color.RED, [500, 500])
wait(10000)
# Keep blinking green slowly and then quickly.
hub.light.blink(Color.GREEN, [500, 500, 50, 900])
wait(10000)
-16
View File
@@ -1,16 +0,0 @@
# ExampleHub = MoveHub CityHub TechnicHub PrimeHub
from pybricks.hubs import ExampleHub
from pybricks.parameters import Color
from pybricks.tools import wait
# Initialize the hub.
hub = ExampleHub()
# Turn the light on and off 5 times.
for i in range(5):
hub.light.on(Color.RED)
wait(1000)
hub.light.off()
wait(500)
@@ -1,31 +0,0 @@
#!/usr/bin/env python3
"""Replaces all instances of ExampleHub in template with actual hub names."""
import os
# Get list of scripts to be parsed
script_names = [f for f in os.listdir(".") if f != "make_shared_examples.py"]
# Go through all template scripts
for script in (open(f, "r") for f in script_names):
# First line contains hub info
hubs = script.readline().strip().split()[3:]
print("Converting", script.name, "for", hubs)
for hub in hubs:
# Determine path to the hub
hub_path = os.path.join("..", "hub_" + hub.lower())
# Reset source script
script.seek(0)
script.readline()
# Open destination script:
with open(os.path.join(hub_path, script.name), "w") as dest_file:
# Read script line by line
for line in script.readlines():
# Replace hub name if present
dest_file.writelines(line.replace("ExampleHub", hub))
@@ -1,13 +0,0 @@
# ExampleHub = MoveHub CityHub TechnicHub PrimeHub
from pybricks.hubs import ExampleHub
from pybricks.tools import wait
# Initialize the hub.
hub = ExampleHub()
# Say goodbye and give some time to send it.
print("Goodbye!")
wait(100)
# Shut the hub down.
hub.system.shutdown()
@@ -1,25 +0,0 @@
from pybricks.hubs import TechnicHub
from pybricks.parameters import Color, Button
from pybricks.tools import wait, StopWatch
# Initialize the hub.
hub = TechnicHub()
# Disable the stop button.
hub.system.set_stop_button(None)
# Check the button for 5 seconds.
watch = StopWatch()
while watch.time() < 5000:
# Set light to green if pressed, else red.
if hub.button.pressed():
hub.light.on(Color.GREEN)
else:
hub.light.on(Color.RED)
# Enable the stop button again.
hub.system.set_stop_button(Button.CENTER)
# Now you can press the stop button as usual.
wait(5000)
@@ -1,20 +0,0 @@
from pybricks.hubs import TechnicHub
from pybricks.tools import wait
from pybricks.geometry import Axis
# Initialize the hub.
hub = TechnicHub()
# Get the acceleration or angular_velocity along a single axis.
# If you need only one value, this is more memory efficient.
while True:
# Read the forward acceleration.
forward_acceleration = hub.imu.acceleration(Axis.X)
# Read the yaw rate.
yaw_rate = hub.imu.angular_velocity(Axis.Z)
# Print the yaw rate.
print(yaw_rate)
wait(100)
@@ -1,14 +0,0 @@
from pybricks.hubs import TechnicHub
from pybricks.tools import wait
# Initialize the hub.
hub = TechnicHub()
# Get the acceleration vector in g's.
print(hub.imu.acceleration() / 9810)
# Get the angular velocity vector.
print(hub.imu.angular_velocity())
# Wait so we can see what we printed
wait(5000)
-13
View File
@@ -1,13 +0,0 @@
from pybricks.hubs import TechnicHub
from pybricks.tools import wait
# Initialize the hub.
hub = TechnicHub()
while True:
# Read the tilt values.
pitch, roll = hub.imu.tilt()
# Print the result.
print(pitch, roll)
wait(200)
-29
View File
@@ -1,29 +0,0 @@
from pybricks.hubs import TechnicHub
from pybricks.parameters import Color, Side
from pybricks.tools import wait
# Initialize the hub.
hub = TechnicHub()
# Define colors for each side in a dictionary.
SIDE_COLORS = {
Side.TOP: Color.RED,
Side.BOTTOM: Color.BLUE,
Side.LEFT: Color.GREEN,
Side.RIGHT: Color.YELLOW,
Side.FRONT: Color.MAGENTA,
Side.BACK: Color.BLACK,
}
# Keep updating the color based on detected up side.
while True:
# Check which side of the hub is up.
up_side = hub.imu.up()
# Change the color based on the side.
hub.light.on(SIDE_COLORS[up_side])
# Also print the result.
print(up_side)
wait(50)
@@ -1,22 +0,0 @@
from pybricks.hubs import TechnicHub
from pybricks.parameters import Color
from pybricks.tools import wait
from umath import sin, pi
# Initialize the hub.
hub = TechnicHub()
# Make an animation with multiple colors.
hub.light.animate([Color.RED, Color.GREEN, Color.NONE], interval=500)
wait(10000)
# Make the color RED grow faint and bright using a sine pattern.
hub.light.animate([Color.RED * (0.5 * sin(i / 15 * pi) + 0.5) for i in range(30)], 40)
wait(10000)
# Cycle through a rainbow of colors.
hub.light.animate([Color(h=i * 8) for i in range(45)], interval=40)
wait(10000)
@@ -1,16 +0,0 @@
from pybricks.hubs import TechnicHub
from pybricks.parameters import Color
from pybricks.tools import wait
# Initialize the hub
hub = TechnicHub()
# Keep blinking red on and off.
hub.light.blink(Color.RED, [500, 500])
wait(10000)
# Keep blinking green slowly and then quickly.
hub.light.blink(Color.GREEN, [500, 500, 50, 900])
wait(10000)
-21
View File
@@ -1,21 +0,0 @@
from pybricks.hubs import TechnicHub
from pybricks.parameters import Color
from pybricks.tools import wait
# Initialize the hub.
hub = TechnicHub()
# Show the color at 30% brightness.
hub.light.on(Color.RED * 0.3)
wait(2000)
# Use your own custom color.
hub.light.on(Color(h=30, s=100, v=50))
wait(2000)
# Go through all the colors.
for hue in range(360):
hub.light.on(Color(hue))
wait(10)
-15
View File
@@ -1,15 +0,0 @@
from pybricks.hubs import TechnicHub
from pybricks.parameters import Color
from pybricks.tools import wait
# Initialize the hub.
hub = TechnicHub()
# Turn the light on and off 5 times.
for i in range(5):
hub.light.on(Color.RED)
wait(1000)
hub.light.off()
wait(500)
@@ -1,12 +0,0 @@
from pybricks.hubs import TechnicHub
from pybricks.tools import wait
# Initialize the hub.
hub = TechnicHub()
# Say goodbye and give some time to send it.
print("Goodbye!")
wait(100)
# Shut the hub down.
hub.system.shutdown()
+25
View File
@@ -0,0 +1,25 @@
# Changelog
<!-- refer to https://keepachangelog.com/en/1.0.0/ for guidance -->
## Unreleased
### Added
- Added LICENSE file.
## 1.1.0 - 2022-06-26
### Added
- Added this changelog.
- Added support for parameter documentation in signatures.
### Changed
- Updated to pybricks API package v3.2.0b1-r3.
- Documentation is now treated as markdown.
### Fixed
- Fixed including docstring for `__init__` on classes.
## 1.0.0 - 2022-06-24
Initial release.
+21
View File
@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2022 The Pybricks Authors
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.
+382
View File
@@ -0,0 +1,382 @@
[[package]]
name = "atomicwrites"
version = "1.4.0"
description = "Atomic file writes."
category = "dev"
optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
[[package]]
name = "attrs"
version = "21.4.0"
description = "Classes Without Boilerplate"
category = "dev"
optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
[package.extras]
dev = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "zope-interface", "furo", "sphinx", "sphinx-notfound-page", "pre-commit", "cloudpickle"]
docs = ["furo", "sphinx", "zope-interface", "sphinx-notfound-page"]
tests = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "zope-interface", "cloudpickle"]
tests_no_zope = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "cloudpickle"]
[[package]]
name = "black"
version = "22.3.0"
description = "The uncompromising code formatter."
category = "dev"
optional = false
python-versions = ">=3.6.2"
[package.dependencies]
click = ">=8.0.0"
mypy-extensions = ">=0.4.3"
pathspec = ">=0.9.0"
platformdirs = ">=2"
tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""}
[package.extras]
colorama = ["colorama (>=0.4.3)"]
d = ["aiohttp (>=3.7.4)"]
jupyter = ["ipython (>=7.8.0)", "tokenize-rt (>=3.2.0)"]
uvloop = ["uvloop (>=0.15.2)"]
[[package]]
name = "click"
version = "8.1.3"
description = "Composable command line interface toolkit"
category = "dev"
optional = false
python-versions = ">=3.7"
[package.dependencies]
colorama = {version = "*", markers = "platform_system == \"Windows\""}
[[package]]
name = "colorama"
version = "0.4.5"
description = "Cross-platform colored terminal text."
category = "dev"
optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
[[package]]
name = "docstring-parser"
version = "0.14.1"
description = "Parse Python docstrings in reST, Google and Numpydoc format"
category = "main"
optional = false
python-versions = ">=3.6,<4.0"
[[package]]
name = "flake8"
version = "4.0.1"
description = "the modular source code checker: pep8 pyflakes and co"
category = "dev"
optional = false
python-versions = ">=3.6"
[package.dependencies]
mccabe = ">=0.6.0,<0.7.0"
pycodestyle = ">=2.8.0,<2.9.0"
pyflakes = ">=2.4.0,<2.5.0"
[[package]]
name = "iniconfig"
version = "1.1.1"
description = "iniconfig: brain-dead simple config-ini parsing"
category = "dev"
optional = false
python-versions = "*"
[[package]]
name = "jedi"
version = "0.18.1"
description = "An autocompletion tool for Python that can be used for text editors."
category = "main"
optional = false
python-versions = ">=3.6"
[package.dependencies]
parso = ">=0.8.0,<0.9.0"
[package.extras]
qa = ["flake8 (==3.8.3)", "mypy (==0.782)"]
testing = ["Django (<3.1)", "colorama", "docopt", "pytest (<7.0.0)"]
[[package]]
name = "mccabe"
version = "0.6.1"
description = "McCabe checker, plugin for flake8"
category = "dev"
optional = false
python-versions = "*"
[[package]]
name = "mypy-extensions"
version = "0.4.3"
description = "Experimental type system extensions for programs checked with the mypy typechecker."
category = "dev"
optional = false
python-versions = "*"
[[package]]
name = "packaging"
version = "21.3"
description = "Core utilities for Python packages"
category = "dev"
optional = false
python-versions = ">=3.6"
[package.dependencies]
pyparsing = ">=2.0.2,<3.0.5 || >3.0.5"
[[package]]
name = "parso"
version = "0.8.3"
description = "A Python Parser"
category = "main"
optional = false
python-versions = ">=3.6"
[package.extras]
qa = ["flake8 (==3.8.3)", "mypy (==0.782)"]
testing = ["docopt", "pytest (<6.0.0)"]
[[package]]
name = "pathspec"
version = "0.9.0"
description = "Utility library for gitignore style pattern matching of file paths."
category = "dev"
optional = false
python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7"
[[package]]
name = "platformdirs"
version = "2.5.2"
description = "A small Python module for determining appropriate platform-specific dirs, e.g. a \"user data dir\"."
category = "dev"
optional = false
python-versions = ">=3.7"
[package.extras]
docs = ["furo (>=2021.7.5b38)", "proselint (>=0.10.2)", "sphinx-autodoc-typehints (>=1.12)", "sphinx (>=4)"]
test = ["appdirs (==1.4.4)", "pytest-cov (>=2.7)", "pytest-mock (>=3.6)", "pytest (>=6)"]
[[package]]
name = "pluggy"
version = "1.0.0"
description = "plugin and hook calling mechanisms for python"
category = "dev"
optional = false
python-versions = ">=3.6"
[package.extras]
dev = ["pre-commit", "tox"]
testing = ["pytest", "pytest-benchmark"]
[[package]]
name = "py"
version = "1.11.0"
description = "library with cross-python path, ini-parsing, io, code, log facilities"
category = "dev"
optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
[[package]]
name = "pybricks"
version = "3.2.0b1-r3"
description = "Documentation and user-API stubs for Pybricks MicroPython"
category = "main"
optional = false
python-versions = "^3.8"
develop = true
[package.source]
type = "directory"
url = ".."
[[package]]
name = "pycodestyle"
version = "2.8.0"
description = "Python style guide checker"
category = "dev"
optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
[[package]]
name = "pyflakes"
version = "2.4.0"
description = "passive checker of Python programs"
category = "dev"
optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
[[package]]
name = "pyparsing"
version = "3.0.9"
description = "pyparsing module - Classes and methods to define and execute parsing grammars"
category = "dev"
optional = false
python-versions = ">=3.6.8"
[package.extras]
diagrams = ["railroad-diagrams", "jinja2"]
[[package]]
name = "pytest"
version = "7.1.2"
description = "pytest: simple powerful testing with Python"
category = "dev"
optional = false
python-versions = ">=3.7"
[package.dependencies]
atomicwrites = {version = ">=1.0", markers = "sys_platform == \"win32\""}
attrs = ">=19.2.0"
colorama = {version = "*", markers = "sys_platform == \"win32\""}
iniconfig = "*"
packaging = "*"
pluggy = ">=0.12,<2.0"
py = ">=1.8.2"
tomli = ">=1.0.0"
[package.extras]
testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "pygments (>=2.7.2)", "requests", "xmlschema"]
[[package]]
name = "tomli"
version = "2.0.1"
description = "A lil' TOML parser"
category = "dev"
optional = false
python-versions = ">=3.7"
[[package]]
name = "typing-extensions"
version = "4.2.0"
description = "Backported and Experimental Type Hints for Python 3.7+"
category = "main"
optional = false
python-versions = ">=3.7"
[metadata]
lock-version = "1.1"
python-versions = ">= 3.10, < 3.11"
content-hash = "acab2fb183ac5598666cfb333e1dfc1e8a06eb73c7d3297de36b199e9277508c"
[metadata.files]
atomicwrites = [
{file = "atomicwrites-1.4.0-py2.py3-none-any.whl", hash = "sha256:6d1784dea7c0c8d4a5172b6c620f40b6e4cbfdf96d783691f2e1302a7b88e197"},
{file = "atomicwrites-1.4.0.tar.gz", hash = "sha256:ae70396ad1a434f9c7046fd2dd196fc04b12f9e91ffb859164193be8b6168a7a"},
]
attrs = [
{file = "attrs-21.4.0-py2.py3-none-any.whl", hash = "sha256:2d27e3784d7a565d36ab851fe94887c5eccd6a463168875832a1be79c82828b4"},
{file = "attrs-21.4.0.tar.gz", hash = "sha256:626ba8234211db98e869df76230a137c4c40a12d72445c45d5f5b716f076e2fd"},
]
black = [
{file = "black-22.3.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:2497f9c2386572e28921fa8bec7be3e51de6801f7459dffd6e62492531c47e09"},
{file = "black-22.3.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:5795a0375eb87bfe902e80e0c8cfaedf8af4d49694d69161e5bd3206c18618bb"},
{file = "black-22.3.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e3556168e2e5c49629f7b0f377070240bd5511e45e25a4497bb0073d9dda776a"},
{file = "black-22.3.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:67c8301ec94e3bcc8906740fe071391bce40a862b7be0b86fb5382beefecd968"},
{file = "black-22.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:fd57160949179ec517d32ac2ac898b5f20d68ed1a9c977346efbac9c2f1e779d"},
{file = "black-22.3.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:cc1e1de68c8e5444e8f94c3670bb48a2beef0e91dddfd4fcc29595ebd90bb9ce"},
{file = "black-22.3.0-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6d2fc92002d44746d3e7db7cf9313cf4452f43e9ea77a2c939defce3b10b5c82"},
{file = "black-22.3.0-cp36-cp36m-win_amd64.whl", hash = "sha256:a6342964b43a99dbc72f72812bf88cad8f0217ae9acb47c0d4f141a6416d2d7b"},
{file = "black-22.3.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:328efc0cc70ccb23429d6be184a15ce613f676bdfc85e5fe8ea2a9354b4e9015"},
{file = "black-22.3.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:06f9d8846f2340dfac80ceb20200ea5d1b3f181dd0556b47af4e8e0b24fa0a6b"},
{file = "black-22.3.0-cp37-cp37m-win_amd64.whl", hash = "sha256:ad4efa5fad66b903b4a5f96d91461d90b9507a812b3c5de657d544215bb7877a"},
{file = "black-22.3.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:e8477ec6bbfe0312c128e74644ac8a02ca06bcdb8982d4ee06f209be28cdf163"},
{file = "black-22.3.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:637a4014c63fbf42a692d22b55d8ad6968a946b4a6ebc385c5505d9625b6a464"},
{file = "black-22.3.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:863714200ada56cbc366dc9ae5291ceb936573155f8bf8e9de92aef51f3ad0f0"},
{file = "black-22.3.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:10dbe6e6d2988049b4655b2b739f98785a884d4d6b85bc35133a8fb9a2233176"},
{file = "black-22.3.0-cp38-cp38-win_amd64.whl", hash = "sha256:cee3e11161dde1b2a33a904b850b0899e0424cc331b7295f2a9698e79f9a69a0"},
{file = "black-22.3.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:5891ef8abc06576985de8fa88e95ab70641de6c1fca97e2a15820a9b69e51b20"},
{file = "black-22.3.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:30d78ba6bf080eeaf0b7b875d924b15cd46fec5fd044ddfbad38c8ea9171043a"},
{file = "black-22.3.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ee8f1f7228cce7dffc2b464f07ce769f478968bfb3dd1254a4c2eeed84928aad"},
{file = "black-22.3.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6ee227b696ca60dd1c507be80a6bc849a5a6ab57ac7352aad1ffec9e8b805f21"},
{file = "black-22.3.0-cp39-cp39-win_amd64.whl", hash = "sha256:9b542ced1ec0ceeff5b37d69838106a6348e60db7b8fdd245294dc1d26136265"},
{file = "black-22.3.0-py3-none-any.whl", hash = "sha256:bc58025940a896d7e5356952228b68f793cf5fcb342be703c3a2669a1488cb72"},
{file = "black-22.3.0.tar.gz", hash = "sha256:35020b8886c022ced9282b51b5a875b6d1ab0c387b31a065b84db7c33085ca79"},
]
click = [
{file = "click-8.1.3-py3-none-any.whl", hash = "sha256:bb4d8133cb15a609f44e8213d9b391b0809795062913b383c62be0ee95b1db48"},
{file = "click-8.1.3.tar.gz", hash = "sha256:7682dc8afb30297001674575ea00d1814d808d6a36af415a82bd481d37ba7b8e"},
]
colorama = [
{file = "colorama-0.4.5-py2.py3-none-any.whl", hash = "sha256:854bf444933e37f5824ae7bfc1e98d5bce2ebe4160d46b5edf346a89358e99da"},
{file = "colorama-0.4.5.tar.gz", hash = "sha256:e6c6b4334fc50988a639d9b98aa429a0b57da6e17b9a44f0451f930b6967b7a4"},
]
docstring-parser = [
{file = "docstring_parser-0.14.1-py3-none-any.whl", hash = "sha256:14ac6ec1f1ba6905c4d8cb90fd0bc55394f5678183752c90e44812bf28d7a515"},
{file = "docstring_parser-0.14.1.tar.gz", hash = "sha256:2c77522e31b7c88b1ab457a1f3c9ae38947ad719732260ba77ee8a3deb58622a"},
]
flake8 = [
{file = "flake8-4.0.1-py2.py3-none-any.whl", hash = "sha256:479b1304f72536a55948cb40a32dce8bb0ffe3501e26eaf292c7e60eb5e0428d"},
{file = "flake8-4.0.1.tar.gz", hash = "sha256:806e034dda44114815e23c16ef92f95c91e4c71100ff52813adf7132a6ad870d"},
]
iniconfig = [
{file = "iniconfig-1.1.1-py2.py3-none-any.whl", hash = "sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3"},
{file = "iniconfig-1.1.1.tar.gz", hash = "sha256:bc3af051d7d14b2ee5ef9969666def0cd1a000e121eaea580d4a313df4b37f32"},
]
jedi = [
{file = "jedi-0.18.1-py2.py3-none-any.whl", hash = "sha256:637c9635fcf47945ceb91cd7f320234a7be540ded6f3e99a50cb6febdfd1ba8d"},
{file = "jedi-0.18.1.tar.gz", hash = "sha256:74137626a64a99c8eb6ae5832d99b3bdd7d29a3850fe2aa80a4126b2a7d949ab"},
]
mccabe = [
{file = "mccabe-0.6.1-py2.py3-none-any.whl", hash = "sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42"},
{file = "mccabe-0.6.1.tar.gz", hash = "sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f"},
]
mypy-extensions = [
{file = "mypy_extensions-0.4.3-py2.py3-none-any.whl", hash = "sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d"},
{file = "mypy_extensions-0.4.3.tar.gz", hash = "sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8"},
]
packaging = [
{file = "packaging-21.3-py3-none-any.whl", hash = "sha256:ef103e05f519cdc783ae24ea4e2e0f508a9c99b2d4969652eed6a2e1ea5bd522"},
{file = "packaging-21.3.tar.gz", hash = "sha256:dd47c42927d89ab911e606518907cc2d3a1f38bbd026385970643f9c5b8ecfeb"},
]
parso = [
{file = "parso-0.8.3-py2.py3-none-any.whl", hash = "sha256:c001d4636cd3aecdaf33cbb40aebb59b094be2a74c556778ef5576c175e19e75"},
{file = "parso-0.8.3.tar.gz", hash = "sha256:8c07be290bb59f03588915921e29e8a50002acaf2cdc5fa0e0114f91709fafa0"},
]
pathspec = [
{file = "pathspec-0.9.0-py2.py3-none-any.whl", hash = "sha256:7d15c4ddb0b5c802d161efc417ec1a2558ea2653c2e8ad9c19098201dc1c993a"},
{file = "pathspec-0.9.0.tar.gz", hash = "sha256:e564499435a2673d586f6b2130bb5b95f04a3ba06f81b8f895b651a3c76aabb1"},
]
platformdirs = [
{file = "platformdirs-2.5.2-py3-none-any.whl", hash = "sha256:027d8e83a2d7de06bbac4e5ef7e023c02b863d7ea5d079477e722bb41ab25788"},
{file = "platformdirs-2.5.2.tar.gz", hash = "sha256:58c8abb07dcb441e6ee4b11d8df0ac856038f944ab98b7be6b27b2a3c7feef19"},
]
pluggy = [
{file = "pluggy-1.0.0-py2.py3-none-any.whl", hash = "sha256:74134bbf457f031a36d68416e1509f34bd5ccc019f0bcc952c7b909d06b37bd3"},
{file = "pluggy-1.0.0.tar.gz", hash = "sha256:4224373bacce55f955a878bf9cfa763c1e360858e330072059e10bad68531159"},
]
py = [
{file = "py-1.11.0-py2.py3-none-any.whl", hash = "sha256:607c53218732647dff4acdfcd50cb62615cedf612e72d1724fb1a0cc6405b378"},
{file = "py-1.11.0.tar.gz", hash = "sha256:51c75c4126074b472f746a24399ad32f6053d1b34b68d2fa41e558e6f4a98719"},
]
pybricks = []
pycodestyle = [
{file = "pycodestyle-2.8.0-py2.py3-none-any.whl", hash = "sha256:720f8b39dde8b293825e7ff02c475f3077124006db4f440dcbc9a20b76548a20"},
{file = "pycodestyle-2.8.0.tar.gz", hash = "sha256:eddd5847ef438ea1c7870ca7eb78a9d47ce0cdb4851a5523949f2601d0cbbe7f"},
]
pyflakes = [
{file = "pyflakes-2.4.0-py2.py3-none-any.whl", hash = "sha256:3bb3a3f256f4b7968c9c788781e4ff07dce46bdf12339dcda61053375426ee2e"},
{file = "pyflakes-2.4.0.tar.gz", hash = "sha256:05a85c2872edf37a4ed30b0cce2f6093e1d0581f8c19d7393122da7e25b2b24c"},
]
pyparsing = [
{file = "pyparsing-3.0.9-py3-none-any.whl", hash = "sha256:5026bae9a10eeaefb61dab2f09052b9f4307d44aee4eda64b309723d8d206bbc"},
{file = "pyparsing-3.0.9.tar.gz", hash = "sha256:2b020ecf7d21b687f219b71ecad3631f644a47f01403fa1d1036b0c6416d70fb"},
]
pytest = [
{file = "pytest-7.1.2-py3-none-any.whl", hash = "sha256:13d0e3ccfc2b6e26be000cb6568c832ba67ba32e719443bfe725814d3c42433c"},
{file = "pytest-7.1.2.tar.gz", hash = "sha256:a06a0425453864a270bc45e71f783330a7428defb4230fb5e6a731fde06ecd45"},
]
tomli = [
{file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"},
{file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"},
]
typing-extensions = [
{file = "typing_extensions-4.2.0-py3-none-any.whl", hash = "sha256:6657594ee297170d19f67d55c05852a874e7eb634f4f753dbd667855e07c1708"},
{file = "typing_extensions-4.2.0.tar.gz", hash = "sha256:f1c24655a0da0d1b67f07e17a5e6b2a105894e6824b92096378bb3668ef02376"},
]
+27
View File
@@ -0,0 +1,27 @@
[tool.poetry]
name = "pybricks_jedi"
version = "1.1.0"
description = "Code completion for Pybricks."
authors = ["The Pybricks Authors"]
license = "MIT"
[tool.poetry.dependencies]
python = ">= 3.10, < 3.11"
pybricks = "3.2.0b1-r3"
jedi = "0.18.1"
typing-extensions = "4.2.0"
docstring-parser = "0.14.1"
[tool.poetry.dev-dependencies]
pytest = "^7.1.2"
black = "^22.3.0"
flake8 = "^4.0.1"
pybricks = { path = "../", develop = true }
[build-system]
requires = ["poetry-core>=1.0.0"]
build-backend = "poetry.core.masonry.api"
[tool.pytest.ini_options]
pythonpath = ["src"]
testpaths = ["tests"]
+473
View File
@@ -0,0 +1,473 @@
import io
import json
import re
from enum import IntEnum
import docstring_parser
import jedi
from jedi.api.classes import BaseName, Completion, Name, ParamName, Signature
from typing_extensions import NotRequired, TypedDict
# Packages included in Pybricks firmware that ships with Pybricks Code.
PYBRICKS_CODE_PACKAGES = {
"micropython",
"pybricks",
"pybricks.geometry",
"pybricks.hubs",
"pybricks.iodevices",
"pybricks.parameters",
"pybricks.pupdevices",
"pybricks.robotics",
"pybricks.tools",
"uerrno",
"uio",
"umath",
"urandom",
"uselect",
"usys",
}
# Subset of Python builtins included in Pybricks MicroPython.
PYBRICKS_BUILTINS = {
"abs",
"all",
"any",
"ArithmeticError",
"AssertionError",
"AttributeError",
"BaseException",
"bin",
"bool",
"bytearray",
"bytes",
"callable",
"chr",
"classmethod",
"complex",
"dict",
"dir",
"divmod",
"enumerate",
"EOFError",
"eval",
"Exception",
"exec",
"float",
"GeneratorExit",
"getattr",
"globals",
"hasattr",
"hash",
"help",
"hex",
"id",
"ImportError",
"IndentationError",
"IndexError",
"input",
"int",
"isinstance",
"issubclass",
"iter",
"KeyboardInterrupt",
"KeyError",
"len",
"list",
"locals",
"LookupError",
"map",
"max",
"MemoryError",
"min",
"NameError",
"next",
"NotImplementedError",
"object",
"oct",
"ord",
"OSError",
"OverflowError",
"pow",
"print",
"range",
"repr",
"reversed",
"round",
"RuntimeError",
"set",
"setattr",
"slice",
"sorted",
"staticmethod",
"StopIteration",
"str",
"sum",
"super",
"SyntaxError",
"SystemExit",
"tuple",
"type",
"TypeError",
"ValueError",
"ZeroDivisionError",
"zip",
}
# Types from monaco editor
class IRange(TypedDict):
startLineNumber: int
startColumn: int
endLineNumber: int
endColumn: int
class ISingleEditOperation(TypedDict):
range: IRange
text: str # TODO: can also be JavaScript null
forceMoveMarkers: NotRequired[bool]
class Command(TypedDict):
id: str
title: str
tooltip: NotRequired[str]
arguments: NotRequired[list]
class UriComponents(TypedDict):
scheme: str
authority: str
path: str
query: str
fragment: str
class IMarkdownString(TypedDict):
value: str
isTrusted: NotRequired[bool]
supportThemeIcons: NotRequired[bool]
supportHtml: NotRequired[bool]
baseUri: NotRequired[UriComponents]
uris: NotRequired[dict[str, UriComponents]]
class CompletionItemKind(IntEnum):
Method = 0
Function = 1
Constructor = 2
Field = 3
Variable = 4
Class = 5
Struct = 6
Interface = 7
Module = 8
Property = 9
Event = 10
Operator = 11
Unit = 12
Value = 13
Constant = 14
Enum = 15
EnumMember = 16
Keyword = 17
Text = 18
Color = 19
File = 20
Reference = 21
Customcolor = 22
Folder = 23
TypeParameter = 24
User = 25
Issue = 26
Snippet = 27
class CompletionItemTag(IntEnum):
Deprecated = 1
class CompletionItemInsertTextRule(IntEnum):
KeepWhitespace = 1
InsertAsSnippet = 4
class CompletionItemLabel(TypedDict):
label: str
detail: NotRequired[str]
description: NotRequired[str]
class CompletionItemRanges(TypedDict):
insert: IRange
replace: IRange
class CompletionItem(TypedDict):
label: str | CompletionItemLabel
kind: CompletionItemKind
tags: NotRequired[list[CompletionItemTag]]
detail: NotRequired[str]
documentation: NotRequired[str]
sortText: NotRequired[str]
filterText: NotRequired[str]
preselect: NotRequired[bool]
insertText: str
insertTextRules: NotRequired[CompletionItemInsertTextRule]
range: IRange | CompletionItemRanges
commitCharacters: NotRequired[list[str]]
additionalTextEdits: NotRequired[list[ISingleEditOperation]]
command: NotRequired[Command]
class ParameterInformation(TypedDict):
label: str | tuple[int, int]
documentation: NotRequired[str]
class SignatureInformation(TypedDict):
label: str
documentation: NotRequired[str]
parameters: list[ParameterInformation]
activeParameter: NotRequired[int]
class SignatureHelp(TypedDict):
signatures: list[SignatureInformation]
activeSignature: int
activeParameter: int
def _is_pybricks(c: Completion) -> bool:
# filter all "private" names (leading underscore)
if (isinstance(c.name, str)) and c.name.startswith("_"):
return False
if isinstance(c.full_name, str):
# this catches things like `from __future__ import annotations`
if c.full_name.startswith("_") and c.module_name != "__main__":
return False
# filter out enum types
if c.full_name.startswith("enum."):
return False
# filter out typing types
if c.full_name.startswith("typing."):
return False
# filter out packages/modules that are not included in Pybricks firmware
if c.type == "module" or c.type == "namespace":
return c.full_name in PYBRICKS_CODE_PACKAGES
# filter subset of builtins
if c.module_name == "builtins" and c.type != "keyword":
return c.name in PYBRICKS_BUILTINS
# this is a type alias, not a real type
if c.full_name == "pybricks.parameters.Number":
return False
return True
def _get_docstring(name: BaseName) -> str:
"""
Gets the docstring for a name.
"""
docstring = name.docstring(raw=True)
# jedi does not appear to be smart enough to use __init__ docstring for class
if name.type == "class" and isinstance(name, Name):
n: Name
for n in name.defined_names():
if n.name == "__init__":
docstring = "\n".join([docstring, _get_docstring(n)])
return docstring
def _parse_docstring(text: str) -> tuple[IMarkdownString, list[IMarkdownString]]:
"""
Parses a doc string, removes the overload declarations, performs some
fixups and extracts the individual parameter strings.
Args:
The raw docstring.
Returns:
A tuple with the fixed up doc string and a list of parameter doc strings.
"""
# docstring_parser does not support signatures at the beginning of the
# docstring, so we have to remove them
# https://www.sphinx-doc.org/en/master/usage/extensions/autodoc.html#confval-autodoc_docstring_signature
lines, end_of_signatures = [], False
for line in io.StringIO(text).readlines():
# signatures look like: "name(params...)"
if not end_of_signatures and re.match(r"^\w+\(.*\)", line):
continue
end_of_signatures = True
# TODO: we may want to do some restructured text to markdown fixes,
# e.g. strip off ":class:" from ":class:`SomeClass`" and replace
# ".. some-directive::" with an appropriate header
lines.append(line)
text = "".join(lines)
doc = docstring_parser.parse(text, docstring_parser.DocstringStyle.GOOGLE)
# convert to numpy doc for better markdown rendering (section names are underlined)
numpy_doc = docstring_parser.compose(doc, docstring_parser.Style.NUMPYDOC)
docstring = IMarkdownString(value=numpy_doc)
param_docstrings = [IMarkdownString(value=p.description) for p in doc.params]
return docstring, param_docstrings
def _map_completion_kind(type: str) -> CompletionItemKind:
match type:
case "module":
return CompletionItemKind.Module
case "class":
return CompletionItemKind.Class
case "instance":
return CompletionItemKind.Variable
case "function":
return CompletionItemKind.Function
case "param":
return CompletionItemKind.Variable
case "path":
return CompletionItemKind.File
case "keyword":
return CompletionItemKind.Keyword
case "property":
return CompletionItemKind.Property
case "statement":
return CompletionItemKind.Variable
case _:
return CompletionItemKind.User
def _map_completion_item(
completion: Completion, line: int, column: int
) -> CompletionItem:
"""
Maps a Jedi completion to a Monaco editor CompletionItem.
Note: All members of the CompletionItem must be directly mappable without
PyProxy in Pyodide.
"""
return CompletionItem(
insertText=completion.name_with_symbols,
kind=_map_completion_kind(completion.type),
label=completion.name_with_symbols,
range=IRange(
startLineNumber=line,
startColumn=column - completion.get_completion_prefix_length(),
endLineNumber=line,
endColumn=column,
),
documentation=_parse_docstring(_get_docstring(completion))[0],
)
def _map_parameter(param: ParamName, docstr: str) -> ParameterInformation:
return ParameterInformation(label=param.to_string(), documentation=docstr)
def _map_signature(signature: Signature) -> SignatureInformation:
optional = {} if signature.index is None else dict(activeParameter=signature.index)
docstr, param_docstr = _parse_docstring(_get_docstring(signature))
return SignatureInformation(
label=signature.to_string(),
documentation=docstr,
parameters=[_map_parameter(*p) for p in zip(signature.params, param_docstr)],
**optional,
)
def _map_signatures(signatures: list[Signature]) -> SignatureHelp:
return SignatureHelp(
signatures=[_map_signature(s) for s in signatures],
activeSignature=0,
activeParameter=0,
)
def initialize():
"""
Initialize jedi with Pybricks-specific config.
"""
jedi.preload_module(
"typing",
"enum",
"micropython",
"pybricks._common",
"pybricks.ev3dev",
"pybricks.ev3dev.speaker",
"pybricks.geometry",
"pybricks.hubs",
"pybricks.iodevices",
"pybricks.parameters",
"pybricks.pupdevices",
"pybricks.robotics",
"pybricks.tools",
"pybricks",
"ubuiltins",
"uerrno",
"uio",
"ujson",
"umath",
"urandom",
"uselect",
"ustruct",
"usys",
)
# also preload "everything" in builtins
jedi.Script("").complete()
def complete(code: str, line: int, column: int) -> str:
"""
Calls jedi.Script().complete() and filters the results for Pybricks.
Args:
code: The Python code to parse.
line: The 1-based line number of the cursor position.
column: The 1-based column number of the cursor position.
Returns:
A json string containing a filtered list of completion items.
"""
completions = jedi.Script(code).complete(line, column - 1, fuzzy=True)
return json.dumps(
[_map_completion_item(c, line, column) for c in completions if _is_pybricks(c)]
)
def get_signatures(code: str, line: int, column: int) -> str:
"""
Calls jedi.Script().get_signatures().
Args:
code: The Python code to parse.
line: The 1-based line number of the cursor position.
column: The 1-based column number of the cursor position.
Returns:
A json string containing the signature help.
"""
signatures = jedi.Script(code).get_signatures(line, column - 1)
return json.dumps(_map_signatures(signatures))
+30
View File
@@ -0,0 +1,30 @@
import pybricks_jedi
def pytest_configure(config):
"""
Allows plugins and conftest files to perform initial configuration.
This hook is called for every plugin and initial conftest
file after command line options have been parsed.
"""
def pytest_sessionstart(session):
"""
Called after the Session object has been created and
before performing collection and entering the run test loop.
"""
pybricks_jedi.initialize()
def pytest_sessionfinish(session, exitstatus):
"""
Called after whole test run finished, right before
returning the exit status to the system.
"""
def pytest_unconfigure(config):
"""
called before test process is exited.
"""
+126
View File
@@ -0,0 +1,126 @@
# SPDX-License-Identifier: MIT
# Copyright (c) 2022 The Pybricks Authors
"""
Tests for correct code completion of builtins.
"""
import json
from pybricks_jedi import CompletionItem, complete
def test_empty_code():
code = ""
completions: list[CompletionItem] = json.loads(complete(code, 1, 1))
# since nothing has been imported, this is just all builtins and keywords
assert [c["insertText"] for c in completions] == [
"abs",
"all",
"any",
"ArithmeticError",
"assert",
"AssertionError",
"async",
"AttributeError",
"await",
"BaseException",
"bin",
"bool",
"break",
"bytearray",
"bytes",
"callable",
"chr",
"class",
"classmethod",
"complex",
"continue",
"def",
"del",
"dict",
"dir",
"divmod",
"enumerate",
"EOFError",
"eval",
"Exception",
"exec",
"False",
"float",
"for",
"from",
"GeneratorExit",
"getattr",
"global",
"globals",
"hasattr",
"hash",
"help",
"hex",
"id",
"if",
"import",
"ImportError",
"IndentationError",
"IndexError",
"input",
"int",
"isinstance",
"issubclass",
"iter",
"KeyboardInterrupt",
"KeyError",
"lambda",
"len",
"list",
"locals",
"LookupError",
"map",
"max",
"MemoryError",
"min",
"NameError",
"next",
"None",
"nonlocal",
"not",
"NotImplementedError",
"object",
"oct",
"ord",
"OSError",
"OverflowError",
"pass",
"pow",
"print",
"raise",
"range",
"repr",
"return",
"reversed",
"round",
"RuntimeError",
"set",
"setattr",
"slice",
"sorted",
"staticmethod",
"StopIteration",
"str",
"sum",
"super",
"SyntaxError",
"SystemExit",
"True",
"try",
"tuple",
"type",
"TypeError",
"ValueError",
"while",
"with",
"yield",
"ZeroDivisionError",
"zip",
]
+82
View File
@@ -0,0 +1,82 @@
# SPDX-License-Identifier: MIT
# Copyright (c) 2022 The Pybricks Authors
"""
Tests for correct code completion of the CityHub class.
"""
import json
from pybricks_jedi import CompletionItem, complete
IMPORT = "from pybricks.hubs import CityHub"
CREATE_INSTANCE = "hub = CityHub()"
def _create_snippet(line: str) -> str:
"""
Creates a code snippet::
from pybricks.hubs import CityHub
hub = CityHub()
{line}
Args:
line: The value substituted for ``{line}``
"""
return "\n".join((IMPORT, CREATE_INSTANCE, line))
def test_hub_dot():
line = "hub."
code = _create_snippet(line)
completions: list[CompletionItem] = json.loads(complete(code, 3, len(line) + 1))
assert [c["insertText"] for c in completions] == [
"battery",
"button",
"light",
"system",
]
def test_hub_dot_battery_dot():
line = "hub.battery."
code = _create_snippet(line)
completions: list[CompletionItem] = json.loads(complete(code, 3, len(line) + 1))
assert [c["insertText"] for c in completions] == [
"current",
"voltage",
]
def test_hub_dot_button_dot():
line = "hub.button."
code = _create_snippet(line)
completions: list[CompletionItem] = json.loads(complete(code, 3, len(line) + 1))
assert [c["insertText"] for c in completions] == [
"pressed",
]
def test_hub_dot_light_dot():
line = "hub.light."
code = _create_snippet(line)
completions: list[CompletionItem] = json.loads(complete(code, 3, len(line) + 1))
assert [c["insertText"] for c in completions] == [
"animate",
"blink",
"off",
"on",
]
def test_hub_dot_system_dot():
line = "hub.system."
code = _create_snippet(line)
completions: list[CompletionItem] = json.loads(complete(code, 3, len(line) + 1))
assert [c["insertText"] for c in completions] == [
"name",
"reset_reason",
"set_stop_button",
"shutdown",
]
+109
View File
@@ -0,0 +1,109 @@
# SPDX-License-Identifier: MIT
# Copyright (c) 2022 The Pybricks Authors
"""
Tests for correct code completion of the EssentialHub class.
"""
import json
from pybricks_jedi import CompletionItem, complete
IMPORT = "from pybricks.hubs import EssentialHub"
CREATE_INSTANCE = "hub = EssentialHub()"
def _create_snippet(line: str) -> str:
"""
Creates a code snippet::
from pybricks.hubs import EssentialHub
hub = EssentialHub()
{line}
Args:
line: The value substituted for ``{line}``
"""
return "\n".join((IMPORT, CREATE_INSTANCE, line))
def test_hub_dot():
line = "hub."
code = _create_snippet(line)
completions: list[CompletionItem] = json.loads(complete(code, 3, len(line) + 1))
assert [c["insertText"] for c in completions] == [
"battery",
"button",
"charger",
"imu",
"light",
"system",
]
def test_hub_dot_battery_dot():
line = "hub.battery."
code = _create_snippet(line)
completions: list[CompletionItem] = json.loads(complete(code, 3, len(line) + 1))
assert [c["insertText"] for c in completions] == [
"current",
"voltage",
]
def test_hub_dot_buttons_dot():
line = "hub.button."
code = _create_snippet(line)
completions: list[CompletionItem] = json.loads(complete(code, 3, len(line) + 1))
assert [c["insertText"] for c in completions] == [
"pressed",
]
def test_hub_dot_charger_dot():
line = "hub.charger."
code = _create_snippet(line)
completions: list[CompletionItem] = json.loads(complete(code, 3, len(line) + 1))
assert [c["insertText"] for c in completions] == [
"connected",
"current",
"status",
]
def test_hub_dot_imu_dot():
line = "hub.imu."
code = _create_snippet(line)
completions: list[CompletionItem] = json.loads(complete(code, 3, len(line) + 1))
assert [c["insertText"] for c in completions] == [
"acceleration",
"angular_velocity",
"heading",
"reset_heading",
"tilt",
"up",
]
def test_hub_dot_light_dot():
line = "hub.light."
code = _create_snippet(line)
completions: list[CompletionItem] = json.loads(complete(code, 3, len(line) + 1))
assert [c["insertText"] for c in completions] == [
"animate",
"blink",
"off",
"on",
]
def test_hub_dot_system_dot():
line = "hub.system."
code = _create_snippet(line)
completions: list[CompletionItem] = json.loads(complete(code, 3, len(line) + 1))
assert [c["insertText"] for c in completions] == [
"name",
"reset_reason",
"set_stop_button",
"shutdown",
]
+255
View File
@@ -0,0 +1,255 @@
# SPDX-License-Identifier: MIT
# Copyright (c) 2022 The Pybricks Authors
"""
Tests for correct code completion of import statements.
"""
import json
from pybricks_jedi import CompletionItem, complete
def test_from():
code = "from "
completions: list[CompletionItem] = json.loads(complete(code, 1, len(code) + 1))
# only modules included in Pybricks firmware should be listed
assert [c["insertText"] for c in completions] == [
"micropython",
"pybricks",
"uerrno",
"uio",
"umath",
"urandom",
"uselect",
"usys",
]
def test_from_pybricks_import():
code = "from pybricks import "
completions: list[CompletionItem] = json.loads(complete(code, 1, len(code) + 1))
assert [c["insertText"] for c in completions] == [
"geometry",
"hubs",
"iodevices",
"parameters",
"pupdevices",
"robotics",
"tools",
"version",
]
def test_from_pybricks_dot():
code = "from pybricks."
completions: list[CompletionItem] = json.loads(complete(code, 1, len(code) + 1))
assert [c["insertText"] for c in completions] == [
"geometry",
"hubs",
"iodevices",
"parameters",
"pupdevices",
"robotics",
"tools",
]
def test_from_pybricks_geometry_import():
code = "from pybricks.geometry import "
completions: list[CompletionItem] = json.loads(complete(code, 1, len(code) + 1))
assert [c["insertText"] for c in completions] == [
"Axis",
"Matrix",
"vector",
]
def test_from_pybricks_hubs_import():
code = "from pybricks.hubs import "
completions: list[CompletionItem] = json.loads(complete(code, 1, len(code) + 1))
assert [c["insertText"] for c in completions] == [
"CityHub",
"EssentialHub",
"EV3Brick",
"InventorHub",
"MoveHub",
"PrimeHub",
"TechnicHub",
]
def test_from_pybricks_iodevices_import():
code = "from pybricks.iodevices import "
completions: list[CompletionItem] = json.loads(complete(code, 1, len(code) + 1))
assert [c["insertText"] for c in completions] == [
"AnalogSensor",
"DCMotor",
"Ev3devSensor",
"I2CDevice",
"LUMPDevice",
"LWP3Device",
"PUPDevice",
"UARTDevice",
]
def test_from_pybricks_parameters_import():
code = "from pybricks.parameters import "
completions: list[CompletionItem] = json.loads(complete(code, 1, len(code) + 1))
assert [c["insertText"] for c in completions] == [
"Button",
"Color",
"Direction",
"Icon",
"Port",
"Side",
"Stop",
]
def test_from_pybricks_pupdevices_import():
code = "from pybricks.pupdevices import "
completions: list[CompletionItem] = json.loads(complete(code, 1, len(code) + 1))
assert [c["insertText"] for c in completions] == [
"ColorDistanceSensor",
"ColorLightMatrix",
"ColorSensor",
"DCMotor",
"ForceSensor",
"InfraredSensor",
"Light",
"Motor",
"PFMotor",
"Remote",
"TiltSensor",
"UltrasonicSensor",
]
def test_from_pybricks_robotics_import():
code = "from pybricks.robotics import "
completions: list[CompletionItem] = json.loads(complete(code, 1, len(code) + 1))
assert [c["insertText"] for c in completions] == [
"DriveBase",
]
def test_from_pybricks_tools_import():
code = "from pybricks.tools import "
completions: list[CompletionItem] = json.loads(complete(code, 1, len(code) + 1))
assert [c["insertText"] for c in completions] == [
"DataLog",
"StopWatch",
"wait",
]
def test_from_micropython_import():
code = "from micropython import "
completions: list[CompletionItem] = json.loads(complete(code, 1, len(code) + 1))
assert [c["insertText"] for c in completions] == [
"const",
"kbd_intr",
"mem_info",
"opt_level",
"qstr_info",
"stack_use",
]
def test_from_uerrno_import():
code = "from uerrno import "
completions: list[CompletionItem] = json.loads(complete(code, 1, len(code) + 1))
assert [c["insertText"] for c in completions] == [
"EAGAIN",
"EBUSY",
"ECANCELED",
"EINVAL",
"EIO",
"ENODEV",
"EOPNOTSUPP",
"EPERM",
"errorcode",
"ETIMEDOUT",
]
def test_from_uio_import():
code = "from uio import "
completions: list[CompletionItem] = json.loads(complete(code, 1, len(code) + 1))
assert [c["insertText"] for c in completions] == [
"BytesIO",
"FileIO",
"StringIO",
]
def test_from_umath_import():
code = "from umath import "
completions: list[CompletionItem] = json.loads(complete(code, 1, len(code) + 1))
assert [c["insertText"] for c in completions] == [
"acos",
"asin",
"atan",
"atan2",
"ceil",
"copysign",
"cos",
"degrees",
"e",
"exp",
"fabs",
"floor",
"fmod",
"frexp",
"isfinite",
"isinfinite",
"isnan",
"ldexp",
"log",
"modf",
"pi",
"pow",
"radians",
"sin",
"sqrt",
"tan",
"trunc",
]
def test_from_urandom_import():
code = "from urandom import "
completions: list[CompletionItem] = json.loads(complete(code, 1, len(code) + 1))
assert [c["insertText"] for c in completions] == [
"choice",
"getrandbits",
"randint",
"random",
"randrange",
"seed",
"uniform",
]
def test_from_uselect_import():
code = "from uselect import "
completions: list[CompletionItem] = json.loads(complete(code, 1, len(code) + 1))
assert [c["insertText"] for c in completions] == [
"poll",
"Poll",
"POLLERR",
"POLLHUP",
"POLLIN",
"POLLOUT",
]
def test_from_usys_import():
code = "from usys import "
completions: list[CompletionItem] = json.loads(complete(code, 1, len(code) + 1))
assert [c["insertText"] for c in completions] == [
"stderr",
"stdin",
"stdout",
]
+138
View File
@@ -0,0 +1,138 @@
# SPDX-License-Identifier: MIT
# Copyright (c) 2022 The Pybricks Authors
"""
Tests for correct code completion of the InventorHub class.
"""
import json
from pybricks_jedi import complete, CompletionItem
IMPORT = "from pybricks.hubs import InventorHub"
CREATE_INSTANCE = "hub = InventorHub()"
def _create_snippet(line: str) -> str:
"""
Creates a code snippet::
from pybricks.hubs import InventorHub
hub = InventorHub()
{line}
Args:
line: The value substituted for ``{line}``
"""
return "\n".join((IMPORT, CREATE_INSTANCE, line))
def test_hub_dot():
line = "hub."
code = _create_snippet(line)
completions: list[CompletionItem] = json.loads(complete(code, 3, len(line) + 1))
assert [c["insertText"] for c in completions] == [
"battery",
"buttons",
"charger",
"display",
"imu",
"light",
"speaker",
"system",
]
def test_hub_dot_battery_dot():
line = "hub.battery."
code = _create_snippet(line)
completions: list[CompletionItem] = json.loads(complete(code, 3, len(line) + 1))
assert [c["insertText"] for c in completions] == [
"current",
"voltage",
]
def test_hub_dot_buttons_dot():
line = "hub.buttons."
code = _create_snippet(line)
completions: list[CompletionItem] = json.loads(complete(code, 3, len(line) + 1))
assert [c["insertText"] for c in completions] == [
"pressed",
]
def test_hub_dot_charger_dot():
line = "hub.charger."
code = _create_snippet(line)
completions: list[CompletionItem] = json.loads(complete(code, 3, len(line) + 1))
assert [c["insertText"] for c in completions] == [
"connected",
"current",
"status",
]
def test_hub_dot_display_dot():
line = "hub.display."
code = _create_snippet(line)
completions: list[CompletionItem] = json.loads(complete(code, 3, len(line) + 1))
assert [c["insertText"] for c in completions] == [
"animate",
"char",
"image",
"number",
"off",
"orientation",
"pixel",
"text",
]
def test_hub_dot_imu_dot():
line = "hub.imu."
code = _create_snippet(line)
completions: list[CompletionItem] = json.loads(complete(code, 3, len(line) + 1))
assert [c["insertText"] for c in completions] == [
"acceleration",
"angular_velocity",
"heading",
"reset_heading",
"tilt",
"up",
]
def test_hub_dot_light_dot():
line = "hub.light."
code = _create_snippet(line)
completions: list[CompletionItem] = json.loads(complete(code, 3, len(line) + 1))
assert [c["insertText"] for c in completions] == [
"animate",
"blink",
"off",
"on",
]
def test_hub_dot_speaker_dot():
line = "hub.speaker."
code = _create_snippet(line)
completions: list[CompletionItem] = json.loads(complete(code, 3, len(line) + 1))
assert [c["insertText"] for c in completions] == [
"beep",
"play_notes",
"volume",
]
def test_hub_dot_system_dot():
line = "hub.system."
code = _create_snippet(line)
completions: list[CompletionItem] = json.loads(complete(code, 3, len(line) + 1))
assert [c["insertText"] for c in completions] == [
"name",
"reset_reason",
"set_stop_button",
"shutdown",
]
+93
View File
@@ -0,0 +1,93 @@
# SPDX-License-Identifier: MIT
# Copyright (c) 2022 The Pybricks Authors
"""
Tests for correct code completion of the MoveHub class.
"""
import json
from pybricks_jedi import CompletionItem, complete
IMPORT = "from pybricks.hubs import MoveHub"
CREATE_INSTANCE = "hub = MoveHub()"
def _create_snippet(line: str) -> str:
"""
Creates a code snippet::
from pybricks.hubs import MoveHub
hub = MoveHub()
{line}
Args:
line: The value substituted for ``{line}``
"""
return "\n".join((IMPORT, CREATE_INSTANCE, line))
def test_hub_dot():
line = "hub."
code = _create_snippet(line)
completions: list[CompletionItem] = json.loads(complete(code, 3, len(line) + 1))
assert [c["insertText"] for c in completions] == [
"battery",
"button",
"imu",
"light",
"system",
]
def test_hub_dot_battery_dot():
line = "hub.battery."
code = _create_snippet(line)
completions: list[CompletionItem] = json.loads(complete(code, 3, len(line) + 1))
assert [c["insertText"] for c in completions] == [
"current",
"voltage",
]
def test_hub_dot_button_dot():
line = "hub.button."
code = _create_snippet(line)
completions: list[CompletionItem] = json.loads(complete(code, 3, len(line) + 1))
assert [c["insertText"] for c in completions] == [
"pressed",
]
def test_hub_dot_imu_dot():
line = "hub.imu."
code = _create_snippet(line)
completions: list[CompletionItem] = json.loads(complete(code, 3, len(line) + 1))
assert [c["insertText"] for c in completions] == [
"acceleration",
"up",
]
def test_hub_dot_light_dot():
line = "hub.light."
code = _create_snippet(line)
completions: list[CompletionItem] = json.loads(complete(code, 3, len(line) + 1))
assert [c["insertText"] for c in completions] == [
"animate",
"blink",
"off",
"on",
]
def test_hub_dot_system_dot():
line = "hub.system."
code = _create_snippet(line)
completions: list[CompletionItem] = json.loads(complete(code, 3, len(line) + 1))
assert [c["insertText"] for c in completions] == [
"name",
"reset_reason",
"set_stop_button",
"shutdown",
]
+138
View File
@@ -0,0 +1,138 @@
# SPDX-License-Identifier: MIT
# Copyright (c) 2022 The Pybricks Authors
"""
Tests for correct code completion of the PrimeHub class.
"""
import json
from pybricks_jedi import CompletionItem, complete
IMPORT = "from pybricks.hubs import PrimeHub"
CREATE_INSTANCE = "hub = PrimeHub()"
def _create_snippet(line: str) -> str:
"""
Creates a code snippet::
from pybricks.hubs import PrimeHub
hub = PrimeHub()
{line}
Args:
line: The value substituted for ``{line}``
"""
return "\n".join((IMPORT, CREATE_INSTANCE, line))
def test_hub_dot():
line = "hub."
code = _create_snippet(line)
completions: list[CompletionItem] = json.loads(complete(code, 3, len(line) + 1))
assert [c["insertText"] for c in completions] == [
"battery",
"buttons",
"charger",
"display",
"imu",
"light",
"speaker",
"system",
]
def test_hub_dot_battery_dot():
line = "hub.battery."
code = _create_snippet(line)
completions: list[CompletionItem] = json.loads(complete(code, 3, len(line) + 1))
assert [c["insertText"] for c in completions] == [
"current",
"voltage",
]
def test_hub_dot_buttons_dot():
line = "hub.buttons."
code = _create_snippet(line)
completions: list[CompletionItem] = json.loads(complete(code, 3, len(line) + 1))
assert [c["insertText"] for c in completions] == [
"pressed",
]
def test_hub_dot_charger_dot():
line = "hub.charger."
code = _create_snippet(line)
completions: list[CompletionItem] = json.loads(complete(code, 3, len(line) + 1))
assert [c["insertText"] for c in completions] == [
"connected",
"current",
"status",
]
def test_hub_dot_display_dot():
line = "hub.display."
code = _create_snippet(line)
completions: list[CompletionItem] = json.loads(complete(code, 3, len(line) + 1))
assert [c["insertText"] for c in completions] == [
"animate",
"char",
"image",
"number",
"off",
"orientation",
"pixel",
"text",
]
def test_hub_dot_imu_dot():
line = "hub.imu."
code = _create_snippet(line)
completions: list[CompletionItem] = json.loads(complete(code, 3, len(line) + 1))
assert [c["insertText"] for c in completions] == [
"acceleration",
"angular_velocity",
"heading",
"reset_heading",
"tilt",
"up",
]
def test_hub_dot_light_dot():
line = "hub.light."
code = _create_snippet(line)
completions: list[CompletionItem] = json.loads(complete(code, 3, len(line) + 1))
assert [c["insertText"] for c in completions] == [
"animate",
"blink",
"off",
"on",
]
def test_hub_dot_speaker_dot():
line = "hub.speaker."
code = _create_snippet(line)
completions: list[CompletionItem] = json.loads(complete(code, 3, len(line) + 1))
assert [c["insertText"] for c in completions] == [
"beep",
"play_notes",
"volume",
]
def test_hub_dot_system_dot():
line = "hub.system."
code = _create_snippet(line)
completions: list[CompletionItem] = json.loads(complete(code, 3, len(line) + 1))
assert [c["insertText"] for c in completions] == [
"name",
"reset_reason",
"set_stop_button",
"shutdown",
]
+97
View File
@@ -0,0 +1,97 @@
# SPDX-License-Identifier: MIT
# Copyright (c) 2022 The Pybricks Authors
"""
Tests for correct code completion of the TechnicHub class.
"""
import json
from pybricks_jedi import CompletionItem, complete
IMPORT = "from pybricks.hubs import TechnicHub"
CREATE_INSTANCE = "hub = TechnicHub()"
def _create_snippet(line: str) -> str:
"""
Creates a code snippet::
from pybricks.hubs import TechnicHub
hub = TechnicHub()
{line}
Args:
line: The value substituted for ``{line}``
"""
return "\n".join((IMPORT, CREATE_INSTANCE, line))
def test_hub_dot():
line = "hub."
code = _create_snippet(line)
completions: list[CompletionItem] = json.loads(complete(code, 3, len(line) + 1))
assert [c["insertText"] for c in completions] == [
"battery",
"button",
"imu",
"light",
"system",
]
def test_hub_dot_battery_dot():
line = "hub.battery."
code = _create_snippet(line)
completions: list[CompletionItem] = json.loads(complete(code, 3, len(line) + 1))
assert [c["insertText"] for c in completions] == [
"current",
"voltage",
]
def test_hub_dot_button_dot():
line = "hub.button."
code = _create_snippet(line)
completions: list[CompletionItem] = json.loads(complete(code, 3, len(line) + 1))
assert [c["insertText"] for c in completions] == [
"pressed",
]
def test_hub_dot_imu_dot():
line = "hub.imu."
code = _create_snippet(line)
completions: list[CompletionItem] = json.loads(complete(code, 3, len(line) + 1))
assert [c["insertText"] for c in completions] == [
"acceleration",
"angular_velocity",
"heading",
"reset_heading",
"tilt",
"up",
]
def test_hub_dot_light_dot():
line = "hub.light."
code = _create_snippet(line)
completions: list[CompletionItem] = json.loads(complete(code, 3, len(line) + 1))
assert [c["insertText"] for c in completions] == [
"animate",
"blink",
"off",
"on",
]
def test_hub_dot_system_dot():
line = "hub.system."
code = _create_snippet(line)
completions: list[CompletionItem] = json.loads(complete(code, 3, len(line) + 1))
assert [c["insertText"] for c in completions] == [
"name",
"reset_reason",
"set_stop_button",
"shutdown",
]
+835
View File
@@ -0,0 +1,835 @@
# SPDX-License-Identifier: MIT
# Copyright (c) 2022 The Pybricks Authors
"""
Tests for correct signatures of the pupdevices.Motor class.
"""
from itertools import zip_longest
import json
import pytest
from pybricks_jedi import SignatureHelp, get_signatures
def _get_function_signature(module: str, function: str) -> SignatureHelp:
"""
Gets the signature help object for code like::
from {module} import {function}
{function}(
Args:
module: the module name
func: the function name (a function in the module)
"""
code = f"from {module} import {function}; {function}("
return json.loads(get_signatures(code, 1, len(code) + 1))
FUNCTION_PARAMS = [
pytest.param("pybricks.tools", "wait", [(["time: Number"], "None")]),
pytest.param(
"pybricks.geometry",
"vector",
[
(["x: float", "y: float"], "Matrix"),
(["x: float", "y: float", "z: float"], "Matrix"),
],
),
]
@pytest.mark.parametrize("module,function,signatures", FUNCTION_PARAMS)
def test_get_signature_for_functions(
module: str, function: str, signatures: list[tuple[list[str], str]]
):
help = _get_function_signature(module, function)
assert help["activeSignature"] == 0
assert help["activeParameter"] == 0
assert help["signatures"]
for sig, (params, returns) in zip_longest(help["signatures"], signatures):
assert sig["label"] == f"{function}({', '.join(params)}) -> {returns}"
assert sig["documentation"]["value"]
# ensure signatures are stripped from doc comment
assert not sig["documentation"]["value"].startswith(f"{function}(")
for pi, p in zip_longest(sig["parameters"], params):
assert pi["label"] == p
assert pi["documentation"]["value"]
def _get_constructor_signature(module: str, type: str) -> SignatureHelp:
"""
Gets the signature help object for code like::
from {module} import {type}
instance = {type}(
Args:
module: the module name
type: the type name (a type in the module)
"""
code = f"from {module} import {type}; {type}("
return json.loads(get_signatures(code, 1, len(code) + 1))
CONSTRUCTOR_PARAMS = [
pytest.param("pybricks.hubs", "MoveHub", [[]]),
pytest.param("pybricks.hubs", "CityHub", [[]]),
pytest.param(
"pybricks.hubs",
"TechnicHub",
[["top_side: Axis=Axis.Z", "front_side: Axis=Axis.X"]],
),
pytest.param(
"pybricks.hubs",
"PrimeHub",
[["top_side: Axis=Axis.Z", "front_side: Axis=Axis.X"]],
),
pytest.param(
"pybricks.pupdevices",
"DCMotor",
[["port: Port", "positive_direction: Direction=Direction.CLOCKWISE"]],
),
pytest.param(
"pybricks.pupdevices",
"Motor",
[
[
"port: Port",
"positive_direction: Direction=Direction.CLOCKWISE",
"gears: Optional[Union[Collection[int], Collection[Collection[int]]]]=None",
"reset_angle: bool=True",
]
],
),
pytest.param("pybricks.pupdevices", "TiltSensor", [["port: Port"]]),
pytest.param("pybricks.pupdevices", "InfraredSensor", [["port: Port"]]),
pytest.param("pybricks.pupdevices", "ColorDistanceSensor", [["port: Port"]]),
pytest.param(
"pybricks.pupdevices",
"PFMotor",
[
[
"sensor: ColorDistanceSensor",
"channel: int",
"color: Color",
"positive_direction: Direction=Direction.CLOCKWISE",
]
],
),
pytest.param("pybricks.pupdevices", "ColorSensor", [["port: Port"]]),
pytest.param("pybricks.pupdevices", "UltrasonicSensor", [["port: Port"]]),
pytest.param("pybricks.pupdevices", "ForceSensor", [["port: Port"]]),
pytest.param("pybricks.pupdevices", "ColorLightMatrix", [["port: Port"]]),
pytest.param("pybricks.pupdevices", "Light", [["port: Port"]]),
pytest.param(
"pybricks.pupdevices",
"Remote",
[["name: Optional[str]=None", "timeout: int=10000"]],
),
# TODO: iodevices go here
pytest.param(
"pybricks.parameters",
"Color",
[["h: Number", "s: Number=100", "v: Number=100"]],
),
pytest.param(
"pybricks.robotics",
"DriveBase",
[
[
"left_motor: Motor",
"right_motor: Motor",
"wheel_diameter: Number",
"axle_track: Number",
]
],
),
pytest.param(
"pybricks.geometry",
"Matrix",
[["rows: Sequence[Sequence[float]]"]],
),
]
@pytest.mark.parametrize("module,type,signatures", CONSTRUCTOR_PARAMS)
def test_get_signature_for_constructors(
module: str, type: str, signatures: list[list[str]]
):
help = _get_constructor_signature(module, type)
assert help["activeSignature"] == 0
assert help["activeParameter"] == 0
assert help["signatures"]
for sig, params in zip_longest(help["signatures"], signatures):
assert sig["label"] == f"{type}({', '.join(params)})"
assert sig["documentation"]["value"]
# ensure signatures are stripped from doc comment
assert not sig["documentation"]["value"].startswith(f"{type}(")
for pi, p in zip_longest(sig["parameters"], params):
assert pi["label"] == p
assert pi["documentation"]["value"]
def _get_method_signature(module: str, type: str, method: str) -> SignatureHelp:
"""
Gets the signature help object for code like::
from {module} import {type}
instance = {type}()
instance.{method}(
Args:
module: the module name
type: the type name (a type in the module)
method: the method name (a method of the type)
"""
code = f"from {module} import {type}; x = {type}(); x.{method}("
return json.loads(get_signatures(code, 1, len(code) + 1))
METHOD_PARAMS = [
pytest.param("pybricks.hubs", "MoveHub", "light.on", [(["color: Color"], "None")]),
pytest.param("pybricks.hubs", "MoveHub", "light.off", [([], "None")]),
pytest.param(
"pybricks.hubs",
"MoveHub",
"light.blink",
[(["color: Color", "durations: Collection[Number]"], "None")],
),
pytest.param(
"pybricks.hubs",
"MoveHub",
"light.animate",
[(["colors: Collection[Color]", "interval: Number"], "None")],
),
pytest.param("pybricks.hubs", "MoveHub", "imu.up", [([], "Side")]),
pytest.param(
"pybricks.hubs", "MoveHub", "imu.acceleration", [([], "Tuple[int, int, int]")]
),
pytest.param("pybricks.hubs", "MoveHub", "battery.voltage", [([], "int")]),
pytest.param("pybricks.hubs", "MoveHub", "battery.current", [([], "int")]),
pytest.param(
"pybricks.hubs", "MoveHub", "button.pressed", [([], "Collection[Button]")]
),
pytest.param(
"pybricks.hubs",
"MoveHub",
"system.set_stop_button",
[(["button: Optional[Union[Button, Iterable[Button]]]"], "None")],
),
pytest.param("pybricks.hubs", "MoveHub", "system.name", [([], "str")]),
pytest.param("pybricks.hubs", "MoveHub", "system.shutdown", [([], "None")]),
pytest.param("pybricks.hubs", "MoveHub", "system.reset_reason", [([], "int")]),
pytest.param("pybricks.hubs", "CityHub", "light.on", [(["color: Color"], "None")]),
pytest.param("pybricks.hubs", "CityHub", "light.off", [([], "None")]),
pytest.param(
"pybricks.hubs",
"CityHub",
"light.blink",
[(["color: Color", "durations: Collection[Number]"], "None")],
),
pytest.param(
"pybricks.hubs",
"CityHub",
"light.animate",
[(["colors: Collection[Color]", "interval: Number"], "None")],
),
pytest.param("pybricks.hubs", "CityHub", "battery.voltage", [([], "int")]),
pytest.param("pybricks.hubs", "CityHub", "battery.current", [([], "int")]),
pytest.param(
"pybricks.hubs", "CityHub", "button.pressed", [([], "Collection[Button]")]
),
pytest.param(
"pybricks.hubs",
"CityHub",
"system.set_stop_button",
[(["button: Optional[Union[Button, Iterable[Button]]]"], "None")],
),
pytest.param("pybricks.hubs", "CityHub", "system.name", [([], "str")]),
pytest.param("pybricks.hubs", "CityHub", "system.shutdown", [([], "None")]),
pytest.param("pybricks.hubs", "CityHub", "system.reset_reason", [([], "int")]),
pytest.param(
"pybricks.hubs", "TechnicHub", "light.on", [(["color: Color"], "None")]
),
pytest.param("pybricks.hubs", "TechnicHub", "light.off", [([], "None")]),
pytest.param(
"pybricks.hubs",
"TechnicHub",
"light.blink",
[(["color: Color", "durations: Collection[Number]"], "None")],
),
pytest.param(
"pybricks.hubs",
"TechnicHub",
"light.animate",
[(["colors: Collection[Color]", "interval: Number"], "None")],
),
pytest.param("pybricks.hubs", "TechnicHub", "imu.up", [([], "Side")]),
pytest.param("pybricks.hubs", "TechnicHub", "imu.tilt", [([], "Tuple[int, int]")]),
pytest.param(
"pybricks.hubs",
"TechnicHub",
"imu.acceleration",
[(["axis: Axis"], "float"), ([], "Matrix")],
),
pytest.param(
"pybricks.hubs",
"TechnicHub",
"imu.angular_velocity",
[(["axis: Axis"], "float"), ([], "Matrix")],
),
pytest.param("pybricks.hubs", "TechnicHub", "imu.heading", [([], "float")]),
pytest.param(
"pybricks.hubs",
"TechnicHub",
"imu.reset_heading",
[(["angle: Number"], "None")],
),
pytest.param("pybricks.hubs", "TechnicHub", "battery.voltage", [([], "int")]),
pytest.param("pybricks.hubs", "TechnicHub", "battery.current", [([], "int")]),
pytest.param(
"pybricks.hubs", "TechnicHub", "button.pressed", [([], "Collection[Button]")]
),
pytest.param(
"pybricks.hubs",
"TechnicHub",
"system.set_stop_button",
[(["button: Optional[Union[Button, Iterable[Button]]]"], "None")],
),
pytest.param("pybricks.hubs", "TechnicHub", "system.name", [([], "str")]),
pytest.param("pybricks.hubs", "TechnicHub", "system.shutdown", [([], "None")]),
pytest.param("pybricks.hubs", "TechnicHub", "system.reset_reason", [([], "int")]),
pytest.param("pybricks.hubs", "PrimeHub", "light.on", [(["color: Color"], "None")]),
pytest.param("pybricks.hubs", "PrimeHub", "light.off", [([], "None")]),
pytest.param(
"pybricks.hubs",
"PrimeHub",
"light.blink",
[(["color: Color", "durations: Collection[Number]"], "None")],
),
pytest.param(
"pybricks.hubs",
"PrimeHub",
"light.animate",
[(["colors: Collection[Color]", "interval: Number"], "None")],
),
pytest.param(
"pybricks.hubs", "PrimeHub", "display.orientation", [(["up: Side"], "None")]
),
pytest.param("pybricks.hubs", "PrimeHub", "display.off", [([], "None")]),
pytest.param(
"pybricks.hubs",
"PrimeHub",
"display.pixel",
[(["row: Number", "column: Number", "brightness: Number=100"], "None")],
),
pytest.param(
"pybricks.hubs", "PrimeHub", "display.image", [(["matrix: Matrix"], "None")]
),
pytest.param(
"pybricks.hubs",
"PrimeHub",
"display.animate",
[(["matrices: Collection[Matrix]", "interval: Number"], "None")],
),
pytest.param(
"pybricks.hubs", "PrimeHub", "display.number", [(["number: Number"], "None")]
),
pytest.param(
"pybricks.hubs", "PrimeHub", "display.char", [(["char: str"], "None")]
),
pytest.param(
"pybricks.hubs",
"PrimeHub",
"display.text",
[(["text: str", "on: Number=500", "off: Number=50"], "None")],
),
pytest.param(
"pybricks.hubs", "PrimeHub", "buttons.pressed", [([], "Collection[Button]")]
),
pytest.param("pybricks.hubs", "PrimeHub", "imu.up", [([], "Side")]),
pytest.param("pybricks.hubs", "PrimeHub", "imu.tilt", [([], "Tuple[int, int]")]),
pytest.param(
"pybricks.hubs",
"PrimeHub",
"imu.acceleration",
[(["axis: Axis"], "float"), ([], "Matrix")],
),
pytest.param(
"pybricks.hubs",
"PrimeHub",
"imu.angular_velocity",
[(["axis: Axis"], "float"), ([], "Matrix")],
),
pytest.param("pybricks.hubs", "PrimeHub", "imu.heading", [([], "float")]),
pytest.param(
"pybricks.hubs",
"PrimeHub",
"imu.reset_heading",
[(["angle: Number"], "None")],
),
pytest.param(
"pybricks.hubs",
"PrimeHub",
"speaker.volume",
[(["volume: Number"], "None"), ([], "int")],
),
pytest.param(
"pybricks.hubs",
"PrimeHub",
"speaker.beep",
[(["frequency: Number=500", "duration: Number=100"], "None")],
),
pytest.param(
"pybricks.hubs",
"PrimeHub",
"speaker.play_notes",
[(["notes: Iterable[str]", "tempo: Number=120"], "None")],
),
pytest.param("pybricks.hubs", "PrimeHub", "battery.voltage", [([], "int")]),
pytest.param("pybricks.hubs", "PrimeHub", "battery.current", [([], "int")]),
pytest.param("pybricks.hubs", "PrimeHub", "charger.connected", [([], "bool")]),
pytest.param("pybricks.hubs", "PrimeHub", "charger.current", [([], "int")]),
pytest.param("pybricks.hubs", "PrimeHub", "charger.status", [([], "int")]),
pytest.param(
"pybricks.hubs",
"PrimeHub",
"system.set_stop_button",
[(["button: Optional[Union[Button, Iterable[Button]]]"], "None")],
),
pytest.param("pybricks.hubs", "PrimeHub", "system.name", [([], "str")]),
pytest.param("pybricks.hubs", "PrimeHub", "system.shutdown", [([], "None")]),
pytest.param("pybricks.hubs", "PrimeHub", "system.reset_reason", [([], "int")]),
pytest.param(
"pybricks.hubs", "EssentialHub", "light.on", [(["color: Color"], "None")]
),
pytest.param("pybricks.hubs", "EssentialHub", "light.off", [([], "None")]),
pytest.param(
"pybricks.hubs",
"EssentialHub",
"light.blink",
[(["color: Color", "durations: Collection[Number]"], "None")],
),
pytest.param(
"pybricks.hubs",
"EssentialHub",
"light.animate",
[(["colors: Collection[Color]", "interval: Number"], "None")],
),
pytest.param(
"pybricks.hubs", "EssentialHub", "button.pressed", [([], "Collection[Button]")]
),
pytest.param("pybricks.hubs", "EssentialHub", "imu.up", [([], "Side")]),
pytest.param(
"pybricks.hubs", "EssentialHub", "imu.tilt", [([], "Tuple[int, int]")]
),
pytest.param(
"pybricks.hubs",
"EssentialHub",
"imu.acceleration",
[(["axis: Axis"], "float"), ([], "Matrix")],
),
pytest.param(
"pybricks.hubs",
"EssentialHub",
"imu.angular_velocity",
[(["axis: Axis"], "float"), ([], "Matrix")],
),
pytest.param("pybricks.hubs", "EssentialHub", "imu.heading", [([], "float")]),
pytest.param(
"pybricks.hubs",
"EssentialHub",
"imu.reset_heading",
[(["angle: Number"], "None")],
),
pytest.param("pybricks.hubs", "EssentialHub", "battery.voltage", [([], "int")]),
pytest.param("pybricks.hubs", "EssentialHub", "battery.current", [([], "int")]),
pytest.param("pybricks.hubs", "EssentialHub", "charger.connected", [([], "bool")]),
pytest.param("pybricks.hubs", "EssentialHub", "charger.current", [([], "int")]),
pytest.param("pybricks.hubs", "EssentialHub", "charger.status", [([], "int")]),
pytest.param(
"pybricks.hubs",
"EssentialHub",
"system.set_stop_button",
[(["button: Optional[Union[Button, Iterable[Button]]]"], "None")],
),
pytest.param("pybricks.hubs", "EssentialHub", "system.name", [([], "str")]),
pytest.param("pybricks.hubs", "EssentialHub", "system.shutdown", [([], "None")]),
pytest.param("pybricks.hubs", "EssentialHub", "system.reset_reason", [([], "int")]),
# TODO: iodevices module here
pytest.param("pybricks.pupdevices", "DCMotor", "dc", [(["duty: Number"], "None")]),
pytest.param("pybricks.pupdevices", "DCMotor", "stop", [([], "None")]),
pytest.param("pybricks.pupdevices", "DCMotor", "brake", [([], "None")]),
pytest.param(
"pybricks.pupdevices",
"DCMotor",
"settings",
[(["max_voltage: Number"], "None"), ([], "Tuple[int]")],
),
pytest.param("pybricks.pupdevices", "Motor", "speed", [([], "int")]),
pytest.param("pybricks.pupdevices", "Motor", "angle", [([], "int")]),
pytest.param(
"pybricks.pupdevices",
"Motor",
"reset_angle",
[(["angle: Optional[Number]=None"], "None")],
),
pytest.param("pybricks.pupdevices", "Motor", "stop", [([], "None")]),
pytest.param("pybricks.pupdevices", "Motor", "brake", [([], "None")]),
pytest.param("pybricks.pupdevices", "Motor", "hold", [([], "None")]),
pytest.param("pybricks.pupdevices", "Motor", "run", [(["speed: Number"], "None")]),
pytest.param(
"pybricks.pupdevices",
"Motor",
"run_time",
[
(
[
"speed: Number",
"time: Number",
"then: Stop=Stop.HOLD",
"wait: bool=True",
],
"None",
)
],
),
pytest.param(
"pybricks.pupdevices",
"Motor",
"run_angle",
[
(
[
"speed: Number",
"rotation_angle: Number",
"then: Stop=Stop.HOLD",
"wait: bool=True",
],
"None",
)
],
),
pytest.param(
"pybricks.pupdevices",
"Motor",
"run_target",
[
(
[
"speed: Number",
"target_angle: Number",
"then: Stop=Stop.HOLD",
"wait: bool=True",
],
"None",
)
],
),
pytest.param(
"pybricks.pupdevices",
"Motor",
"track_target",
[(["target_angle: Number"], "None")],
),
pytest.param(
"pybricks.pupdevices",
"Motor",
"run_until_stalled",
[
(
[
"speed: Number",
"then: Stop=Stop.COAST",
"duty_limit: Optional[Number]=None",
],
"int",
)
],
),
pytest.param("pybricks.pupdevices", "Motor", "dc", [(["duty: Number"], "None")]),
pytest.param("pybricks.pupdevices", "Motor", "control.done", [([], "bool")]),
pytest.param("pybricks.pupdevices", "Motor", "control.stalled", [([], "bool")]),
pytest.param("pybricks.pupdevices", "Motor", "control.load", [([], "int")]),
pytest.param(
"pybricks.pupdevices",
"Motor",
"settings",
[(["max_voltage: Number"], "None"), ([], "Tuple[int]")],
),
pytest.param(
"pybricks.pupdevices",
"Motor",
"control.limits",
[
(
[
"speed: Optional[Number]=None",
"acceleration: Optional[Number]=None",
"torque: Optional[Number]=None",
],
"None",
),
([], "Tuple[int, int, int]"),
],
),
pytest.param(
"pybricks.pupdevices",
"Motor",
"control.pid",
[
(
[
"kp: Optional[Number]=None",
"ki: Optional[Number]=None",
"kd: Optional[Number]=None",
"reserved: Optional[Number]=None",
"integral_rate: Optional[Number]=None",
],
"None",
),
([], "Tuple[int, int, int, None, int]"),
],
),
pytest.param(
"pybricks.pupdevices",
"Motor",
"control.target_tolerances",
[
(
[
"speed: Optional[Number]=None",
"position: Optional[Number]=None",
],
"None",
),
([], "Tuple[int, int]"),
],
),
pytest.param(
"pybricks.pupdevices",
"Motor",
"control.stall_tolerances",
[
(
[
"speed: Optional[Number]=None",
"time: Optional[Number]=None",
],
"None",
),
([], "Tuple[int, int]"),
],
),
pytest.param(
"pybricks.pupdevices", "TiltSensor", "tilt", [([], "Tuple[int, int]")]
),
pytest.param("pybricks.pupdevices", "InfraredSensor", "distance", [([], "int")]),
pytest.param("pybricks.pupdevices", "InfraredSensor", "reflection", [([], "int")]),
pytest.param("pybricks.pupdevices", "InfraredSensor", "count", [([], "int")]),
pytest.param(
"pybricks.pupdevices", "ColorDistanceSensor", "color", [([], "Color")]
),
pytest.param(
"pybricks.pupdevices", "ColorDistanceSensor", "reflection", [([], "int")]
),
pytest.param(
"pybricks.pupdevices", "ColorDistanceSensor", "ambient", [([], "int")]
),
pytest.param(
"pybricks.pupdevices", "ColorDistanceSensor", "distance", [([], "int")]
),
pytest.param("pybricks.pupdevices", "ColorDistanceSensor", "hsv", [([], "Color")]),
pytest.param(
"pybricks.pupdevices",
"ColorDistanceSensor",
"detectable_colors",
[(["colors: Collection[Color]"], "None"), ([], "Collection[Color]")],
),
pytest.param(
"pybricks.pupdevices",
"ColorDistanceSensor",
"light.on",
[(["color: Color"], "None")],
),
pytest.param(
"pybricks.pupdevices", "ColorDistanceSensor", "light.off", [([], "None")]
),
pytest.param("pybricks.pupdevices", "PFMotor", "dc", [(["duty: Number"], "None")]),
pytest.param("pybricks.pupdevices", "PFMotor", "stop", [([], "None")]),
pytest.param("pybricks.pupdevices", "PFMotor", "brake", [([], "None")]),
pytest.param(
"pybricks.pupdevices",
"ColorSensor",
"color",
[(["surface: bool=True"], "Optional[Color]")],
),
pytest.param("pybricks.pupdevices", "ColorSensor", "reflection", [([], "int")]),
pytest.param("pybricks.pupdevices", "ColorSensor", "ambient", [([], "int")]),
pytest.param(
"pybricks.pupdevices",
"ColorSensor",
"hsv",
[(["surface: bool=True"], "Color")],
),
pytest.param(
"pybricks.pupdevices",
"ColorSensor",
"detectable_colors",
[(["colors: Collection[Color]"], "None"), ([], "Collection[Color]")],
),
pytest.param(
"pybricks.pupdevices",
"ColorSensor",
"lights.on",
[(["brightness: Union[Number, Tuple[Number, Number, Number]]"], "None")],
),
pytest.param("pybricks.pupdevices", "ColorSensor", "lights.off", [([], "None")]),
pytest.param("pybricks.pupdevices", "UltrasonicSensor", "distance", [([], "int")]),
pytest.param("pybricks.pupdevices", "UltrasonicSensor", "presence", [([], "bool")]),
pytest.param(
"pybricks.pupdevices",
"UltrasonicSensor",
"lights.on",
[
(
["brightness: Union[Number, Tuple[Number, Number, Number, Number]]"],
"None",
)
],
),
pytest.param(
"pybricks.pupdevices", "UltrasonicSensor", "lights.off", [([], "None")]
),
pytest.param("pybricks.pupdevices", "ForceSensor", "force", [([], "float")]),
pytest.param("pybricks.pupdevices", "ForceSensor", "distance", [([], "float")]),
pytest.param(
"pybricks.pupdevices",
"ForceSensor",
"pressed",
[(["force: Number=3"], "bool")],
),
pytest.param("pybricks.pupdevices", "ForceSensor", "touched", [([], "bool")]),
pytest.param(
"pybricks.pupdevices",
"ColorLightMatrix",
"on",
[(["color: Union[Color, Collection[Color]]"], "None")],
),
pytest.param("pybricks.pupdevices", "ColorLightMatrix", "off", [([], "None")]),
pytest.param(
"pybricks.pupdevices", "Light", "on", [(["brightness: Number=100"], "None")]
),
pytest.param("pybricks.pupdevices", "Light", "off", [([], "None")]),
pytest.param(
"pybricks.pupdevices",
"Remote",
"name",
[(["name: str"], "None"), ([], "str")],
),
pytest.param(
"pybricks.pupdevices", "Remote", "light.on", [(["color: Color"], "None")]
),
pytest.param("pybricks.pupdevices", "Remote", "light.off", [([], "None")]),
pytest.param(
"pybricks.pupdevices",
"Remote",
"buttons.pressed",
[([], "Collection[Button]")],
),
pytest.param("pybricks.tools", "StopWatch", "time", [([], "int")]),
pytest.param("pybricks.tools", "StopWatch", "pause", [([], "None")]),
pytest.param("pybricks.tools", "StopWatch", "resume", [([], "None")]),
pytest.param("pybricks.tools", "StopWatch", "reset", [([], "None")]),
pytest.param(
"pybricks.robotics",
"DriveBase",
"straight",
[(["distance: Number", "then: Stop=Stop.HOLD", "wait: bool=True"], "None")],
),
pytest.param(
"pybricks.robotics",
"DriveBase",
"turn",
[(["angle: Number", "then: Stop=Stop.HOLD", "wait: bool=True"], "None")],
),
pytest.param(
"pybricks.robotics",
"DriveBase",
"curve",
[
(
[
"radius: Number",
"angle: Number",
"then: Stop=Stop.HOLD",
"wait: bool=True",
],
"None",
)
],
),
pytest.param(
"pybricks.robotics",
"DriveBase",
"settings",
[
(
[
"straight_speed: Optional[Number]=None",
"straight_acceleration: Optional[Number]=None",
"turn_rate: Optional[Number]=None",
"turn_acceleration: Optional[Number]=None",
],
"None",
),
([], "Tuple[int, int, int, int]"),
],
),
pytest.param(
"pybricks.robotics",
"DriveBase",
"drive",
[(["speed: Number", "turn_rate: Number"], "None")],
),
pytest.param("pybricks.robotics", "DriveBase", "stop", [([], "None")]),
pytest.param("pybricks.robotics", "DriveBase", "distance", [([], "int")]),
pytest.param("pybricks.robotics", "DriveBase", "angle", [([], "int")]),
pytest.param(
"pybricks.robotics", "DriveBase", "state", [([], "Tuple[int, int, int, int]")]
),
pytest.param("pybricks.robotics", "DriveBase", "reset", [([], "None")]),
]
@pytest.mark.parametrize("module,type,method,signatures", METHOD_PARAMS)
def test_get_signature_for_methods(
module: str, type: str, method: str, signatures: list[tuple[list[str], str]]
):
help = _get_method_signature(module, type, method)
# strip method now that code has been generated (may have leading subcomponent)
method = method.split(".")[-1]
assert help["activeSignature"] == 0
assert help["activeParameter"] == 0
assert help["signatures"]
for sig, (params, returns) in zip_longest(help["signatures"], signatures):
assert sig["label"] == f"{method}({', '.join(params)}) -> {returns}"
assert sig["documentation"]["value"]
# ensure signatures are stripped from doc comment
assert not sig["documentation"]["value"].startswith(f"{method}(")
for pi, p in zip_longest(sig["parameters"], params):
assert pi["label"] == p
assert pi["documentation"]["value"]
+2
View File
@@ -0,0 +1,2 @@
version-tag-prefix "@pybricks/jedi/v"
version-git-message "@pybricks/jedi v%s"
+8
View File
@@ -0,0 +1,8 @@
# Changelog
<!-- refer to https://keepachangelog.com/en/1.0.0/ for guidance -->
## 1.0.0 - 2022-09-07
### Added
- Added new @pybricks/jedi package.
+5
View File
@@ -0,0 +1,5 @@
@pybricks/jedi
==============
Binary distribution of the `pybricks-jedi` Python package and its dependencies
for using in JavaScript/WASM, e.g. via Pyodide.
+125
View File
@@ -0,0 +1,125 @@
#!/usr/bin/env python3
import email.parser
import json
import pathlib
import shutil
import subprocess
import sys
import zipfile
BUILD_DIR = (pathlib.Path(__file__).parent / "build").resolve()
package_json = {
"name": "@pybricks/jedi",
"version": "1.0.0",
"description": "Binary distribution of pybricks-jedi Python package and dependencies for use with Pyodide.",
"repository": {
"type": "git",
"url": "https://github.com/pybricks/pybricks-api",
"directory": "npm/jedi",
},
"publishConfig": {"registry": "https://registry.npmjs.org", "access": "public"},
}
license_identifiers: set[str] = set()
license_text: dict[str, str] = {}
whl_map: dict[str, str] = {}
# ensure empty build directory so we don't end up with stale files
shutil.rmtree(BUILD_DIR, True)
BUILD_DIR.mkdir()
# download package and depedencies (*.whl files)
subprocess.check_call(
[
sys.executable,
"-m",
"pip",
"download",
"--only-binary=any",
"pybricks-jedi==1.1.0",
],
cwd=BUILD_DIR,
)
# extract info from wheel files to generate javascript package files
for whl in BUILD_DIR.glob("*.whl"):
with zipfile.ZipFile(whl) as f:
def is_dist_info_metadata(info: zipfile.ZipInfo):
return info.filename.endswith(".dist-info/METADATA")
def is_dist_info_license(info: zipfile.ZipInfo):
return ".dist-info" in info.filename and "LICENSE" in info.filename
metadata = next(filter(is_dist_info_metadata, f.filelist))
with f.open(metadata.filename) as mf:
meta = email.parser.BytesParser().parse(mf)
# extract package name from metadata
name = meta["Name"]
if not name:
raise RuntimeError(f"missing 'Name' in {whl.name} METADATA")
whl_map[name] = whl.name
# extract license identifier from metadata
license = meta["License"]
if not license:
# some packages are missing license in metadata
if whl.name.startswith("typing_extensions-"):
license = "Python-2.0"
else:
raise RuntimeError(f"missing 'License' in {whl.name} METADATA")
license_identifiers.add(license)
# TODO: The LICENSE workaround for the pybricks-jedi package can be
# dropped after the next release of that package
if whl.name.startswith("pybricks_jedi-"):
LICENSE = (
pathlib.Path(__file__).parent.parent.parent / "jedi" / "LICENSE"
).resolve()
with open(LICENSE) as lf:
license_text[whl.name] = lf.read()
else:
try:
license = next(filter(is_dist_info_license, f.filelist))
except StopIteration:
raise RuntimeError(f"missing license for {whl.name}")
with f.open(license) as lf:
license_text[whl.name] = lf.read().decode()
# generate package.json file
# create "license" item from collected license identifiers
package_json["license"] = (
license_identifiers[0]
if len(license_identifiers) < 2
else f"({' AND '.join(license_identifiers)})"
)
# create "exports" item from collect whl map
package_json["exports"] = {k: f"./{v}" for k, v in whl_map.items()}
with open(BUILD_DIR / "package.json", "w") as f:
json.dump(package_json, f, indent=2)
# generate LICENSE file
NEWLINE = "\n"
DIVIDER = "=" * 80 + NEWLINE
with open(BUILD_DIR / "LICENSE", "w") as f:
for whl, text in license_text.items():
f.write(DIVIDER)
f.write(whl)
f.writelines([NEWLINE, DIVIDER, NEWLINE])
f.write(text)
f.write(NEWLINE)
Generated
+117 -113
View File
@@ -7,8 +7,8 @@ optional = false
python-versions = "*"
[[package]]
name = "babel"
version = "2.10.1"
name = "Babel"
version = "2.10.3"
description = "Internationalization utilities"
category = "dev"
optional = false
@@ -19,7 +19,7 @@ pytz = ">=2015.7"
[[package]]
name = "black"
version = "22.3.0"
version = "22.8.0"
description = "The uncompromising code formatter."
category = "dev"
optional = false
@@ -30,7 +30,7 @@ click = ">=8.0.0"
mypy-extensions = ">=0.4.3"
pathspec = ">=0.9.0"
platformdirs = ">=2"
tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""}
tomli = {version = ">=1.1.0", markers = "python_full_version < \"3.11.0a7\""}
typing-extensions = {version = ">=3.10.0.0", markers = "python_version < \"3.10\""}
[package.extras]
@@ -41,7 +41,7 @@ uvloop = ["uvloop (>=0.15.2)"]
[[package]]
name = "certifi"
version = "2022.5.18.1"
version = "2022.6.15"
description = "Python package for providing Mozilla's CA Bundle."
category = "dev"
optional = false
@@ -49,19 +49,19 @@ python-versions = ">=3.6"
[[package]]
name = "chardet"
version = "4.0.0"
description = "Universal encoding detector for Python 2 and 3"
version = "5.0.0"
description = "Universal encoding detector for Python 3"
category = "dev"
optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
python-versions = ">=3.6"
[[package]]
name = "charset-normalizer"
version = "2.0.12"
version = "2.1.1"
description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet."
category = "dev"
optional = false
python-versions = ">=3.5.0"
python-versions = ">=3.6.0"
[package.extras]
unicode_backport = ["unicodedata2"]
@@ -79,7 +79,7 @@ colorama = {version = "*", markers = "platform_system == \"Windows\""}
[[package]]
name = "colorama"
version = "0.4.4"
version = "0.4.5"
description = "Cross-platform colored terminal text."
category = "dev"
optional = false
@@ -132,7 +132,7 @@ python-versions = ">=3.5"
[[package]]
name = "imagesize"
version = "1.3.0"
version = "1.4.1"
description = "Getting image size from png/jpeg/jpeg2000/gif file"
category = "dev"
optional = false
@@ -140,7 +140,7 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
[[package]]
name = "importlib-metadata"
version = "4.11.4"
version = "4.12.0"
description = "Read metadata from Python packages"
category = "dev"
optional = false
@@ -150,12 +150,12 @@ python-versions = ">=3.7"
zipp = ">=0.5"
[package.extras]
docs = ["sphinx", "jaraco.packaging (>=9)", "rst.linker (>=1.9)"]
docs = ["jaraco.packaging (>=9)", "rst.linker (>=1.9)", "sphinx"]
perf = ["ipython"]
testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-cov", "pytest-enabler (>=1.0.1)", "packaging", "pyfakefs", "flufl.flake8", "pytest-perf (>=0.9.2)", "pytest-black (>=0.3.7)", "pytest-mypy (>=0.9.1)", "importlib-resources (>=1.3)"]
testing = ["flufl.flake8", "importlib-resources (>=1.3)", "packaging", "pyfakefs", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)", "pytest-perf (>=0.9.2)"]
[[package]]
name = "jinja2"
name = "Jinja2"
version = "3.1.2"
description = "A very fast and expressive template engine."
category = "dev"
@@ -169,7 +169,7 @@ MarkupSafe = ">=2.0"
i18n = ["Babel (>=2.7)"]
[[package]]
name = "markupsafe"
name = "MarkupSafe"
version = "2.1.1"
description = "Safely add untrusted strings to HTML/XML markup."
category = "dev"
@@ -205,15 +205,15 @@ pyparsing = ">=2.0.2,<3.0.5 || >3.0.5"
[[package]]
name = "pathspec"
version = "0.9.0"
version = "0.10.1"
description = "Utility library for gitignore style pattern matching of file paths."
category = "dev"
optional = false
python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7"
python-versions = ">=3.7"
[[package]]
name = "pbr"
version = "5.9.0"
version = "5.10.0"
description = "Python Build Reasonableness"
category = "dev"
optional = false
@@ -228,8 +228,8 @@ optional = false
python-versions = ">=3.7"
[package.extras]
docs = ["furo (>=2021.7.5b38)", "proselint (>=0.10.2)", "sphinx-autodoc-typehints (>=1.12)", "sphinx (>=4)"]
test = ["appdirs (1.4.4)", "pytest-cov (>=2.7)", "pytest-mock (>=3.6)", "pytest (>=6)"]
docs = ["furo (>=2021.7.5b38)", "proselint (>=0.10.2)", "sphinx (>=4)", "sphinx-autodoc-typehints (>=1.12)"]
test = ["appdirs (==1.4.4)", "pytest (>=6)", "pytest-cov (>=2.7)", "pytest-mock (>=3.6)"]
[[package]]
name = "pycodestyle"
@@ -248,13 +248,16 @@ optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
[[package]]
name = "pygments"
version = "2.12.0"
name = "Pygments"
version = "2.13.0"
description = "Pygments is a syntax highlighting package written in Python."
category = "dev"
optional = false
python-versions = ">=3.6"
[package.extras]
plugins = ["importlib-metadata"]
[[package]]
name = "pyparsing"
version = "3.0.9"
@@ -264,11 +267,11 @@ optional = false
python-versions = ">=3.6.8"
[package.extras]
diagrams = ["railroad-diagrams", "jinja2"]
diagrams = ["jinja2", "railroad-diagrams"]
[[package]]
name = "pytz"
version = "2022.1"
version = "2022.2.1"
description = "World timezone definitions, modern and historical"
category = "dev"
optional = false
@@ -276,21 +279,21 @@ python-versions = "*"
[[package]]
name = "requests"
version = "2.27.1"
version = "2.28.1"
description = "Python HTTP for Humans."
category = "dev"
optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*"
python-versions = ">=3.7, <4"
[package.dependencies]
certifi = ">=2017.4.17"
charset-normalizer = {version = ">=2.0.0,<2.1.0", markers = "python_version >= \"3\""}
idna = {version = ">=2.5,<4", markers = "python_version >= \"3\""}
charset-normalizer = ">=2,<3"
idna = ">=2.5,<4"
urllib3 = ">=1.21.1,<1.27"
[package.extras]
socks = ["PySocks (>=1.5.6,<1.5.7 || >1.5.7)", "win-inet-pton"]
use_chardet_on_py3 = ["chardet (>=3.0.2,<5)"]
socks = ["PySocks (>=1.5.6,!=1.5.7)"]
use_chardet_on_py3 = ["chardet (>=3.0.2,<6)"]
[[package]]
name = "restructuredtext-lint"
@@ -321,11 +324,12 @@ python-versions = "*"
[[package]]
name = "Sphinx"
version = "5.1.0.dev20220527.dev-20220527"
version = "5.1.0.dev20220621"
description = "Python documentation generator"
category = "dev"
optional = false
python-versions = ">=3.6"
develop = false
[package.dependencies]
alabaster = ">=0.7,<0.8"
@@ -348,8 +352,8 @@ sphinxcontrib-serializinghtml = ">=1.1.5"
[package.extras]
docs = ["sphinxcontrib-websupport"]
lint = ["flake8 (>=3.5.0)", "isort", "mypy (>=0.950)", "docutils-stubs", "types-typed-ast", "types-requests"]
test = ["pytest (>=4.6)", "html5lib", "cython", "typed-ast"]
lint = ["docutils-stubs", "flake8 (>=3.5.0)", "isort", "mypy (>=0.950)", "types-requests", "types-typed-ast"]
test = ["cython", "html5lib", "pytest (>=4.6)", "typed_ast"]
[package.source]
type = "git"
@@ -370,7 +374,7 @@ docutils = "<0.18"
sphinx = ">=1.6"
[package.extras]
dev = ["transifex-client", "sphinxcontrib-httpdomain", "bump2version"]
dev = ["bump2version", "sphinxcontrib-httpdomain", "transifex-client"]
[[package]]
name = "sphinxcontrib-applehelp"
@@ -381,7 +385,7 @@ optional = false
python-versions = ">=3.5"
[package.extras]
lint = ["flake8", "mypy", "docutils-stubs"]
lint = ["docutils-stubs", "flake8", "mypy"]
test = ["pytest"]
[[package]]
@@ -393,7 +397,7 @@ optional = false
python-versions = ">=3.5"
[package.extras]
lint = ["flake8", "mypy", "docutils-stubs"]
lint = ["docutils-stubs", "flake8", "mypy"]
test = ["pytest"]
[[package]]
@@ -405,8 +409,8 @@ optional = false
python-versions = ">=3.6"
[package.extras]
lint = ["flake8", "mypy", "docutils-stubs"]
test = ["pytest", "html5lib"]
lint = ["docutils-stubs", "flake8", "mypy"]
test = ["html5lib", "pytest"]
[[package]]
name = "sphinxcontrib-jsmath"
@@ -417,7 +421,7 @@ optional = false
python-versions = ">=3.5"
[package.extras]
test = ["pytest", "flake8", "mypy"]
test = ["flake8", "mypy", "pytest"]
[[package]]
name = "sphinxcontrib-qthelp"
@@ -428,7 +432,7 @@ optional = false
python-versions = ">=3.5"
[package.extras]
lint = ["flake8", "mypy", "docutils-stubs"]
lint = ["docutils-stubs", "flake8", "mypy"]
test = ["pytest"]
[[package]]
@@ -440,16 +444,16 @@ optional = false
python-versions = ">=3.5"
[package.extras]
lint = ["flake8", "mypy", "docutils-stubs"]
lint = ["docutils-stubs", "flake8", "mypy"]
test = ["pytest"]
[[package]]
name = "stevedore"
version = "3.5.0"
version = "4.0.0"
description = "Manage dynamic plugins for Python applications"
category = "dev"
optional = false
python-versions = ">=3.6"
python-versions = ">=3.8"
[package.dependencies]
pbr = ">=2.0.0,<2.1.0 || >2.1.0"
@@ -472,7 +476,7 @@ python-versions = ">=3.7"
[[package]]
name = "typing-extensions"
version = "4.2.0"
version = "4.3.0"
description = "Backported and Experimental Type Hints for Python 3.7+"
category = "dev"
optional = false
@@ -480,28 +484,28 @@ python-versions = ">=3.7"
[[package]]
name = "urllib3"
version = "1.26.9"
version = "1.26.12"
description = "HTTP library with thread-safe connection pooling, file post, and more."
category = "dev"
optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <4"
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*, <4"
[package.extras]
brotli = ["brotlicffi (>=0.8.0)", "brotli (>=1.0.9)", "brotlipy (>=0.6.0)"]
secure = ["pyOpenSSL (>=0.14)", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "certifi", "ipaddress"]
socks = ["PySocks (>=1.5.6,<1.5.7 || >1.5.7,<2.0)"]
brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)", "brotlipy (>=0.6.0)"]
secure = ["certifi", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "ipaddress", "pyOpenSSL (>=0.14)", "urllib3-secure-extra"]
socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"]
[[package]]
name = "zipp"
version = "3.8.0"
version = "3.8.1"
description = "Backport of pathlib-compatible object wrapper for zip files"
category = "dev"
optional = false
python-versions = ">=3.7"
[package.extras]
docs = ["sphinx", "jaraco.packaging (>=9)", "rst.linker (>=1.9)"]
testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-cov", "pytest-enabler (>=1.0.1)", "jaraco.itertools", "func-timeout", "pytest-black (>=0.3.7)", "pytest-mypy (>=0.9.1)"]
docs = ["jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx"]
testing = ["func-timeout", "jaraco.itertools", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)"]
[metadata]
lock-version = "1.1"
@@ -513,54 +517,54 @@ alabaster = [
{file = "alabaster-0.7.12-py2.py3-none-any.whl", hash = "sha256:446438bdcca0e05bd45ea2de1668c1d9b032e1a9154c2c259092d77031ddd359"},
{file = "alabaster-0.7.12.tar.gz", hash = "sha256:a661d72d58e6ea8a57f7a86e37d86716863ee5e92788398526d58b26a4e4dc02"},
]
babel = [
{file = "Babel-2.10.1-py3-none-any.whl", hash = "sha256:3f349e85ad3154559ac4930c3918247d319f21910d5ce4b25d439ed8693b98d2"},
{file = "Babel-2.10.1.tar.gz", hash = "sha256:98aeaca086133efb3e1e2aad0396987490c8425929ddbcfe0550184fdc54cd13"},
Babel = [
{file = "Babel-2.10.3-py3-none-any.whl", hash = "sha256:ff56f4892c1c4bf0d814575ea23471c230d544203c7748e8c68f0089478d48eb"},
{file = "Babel-2.10.3.tar.gz", hash = "sha256:7614553711ee97490f732126dc077f8d0ae084ebc6a96e23db1482afabdb2c51"},
]
black = [
{file = "black-22.3.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:2497f9c2386572e28921fa8bec7be3e51de6801f7459dffd6e62492531c47e09"},
{file = "black-22.3.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:5795a0375eb87bfe902e80e0c8cfaedf8af4d49694d69161e5bd3206c18618bb"},
{file = "black-22.3.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e3556168e2e5c49629f7b0f377070240bd5511e45e25a4497bb0073d9dda776a"},
{file = "black-22.3.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:67c8301ec94e3bcc8906740fe071391bce40a862b7be0b86fb5382beefecd968"},
{file = "black-22.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:fd57160949179ec517d32ac2ac898b5f20d68ed1a9c977346efbac9c2f1e779d"},
{file = "black-22.3.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:cc1e1de68c8e5444e8f94c3670bb48a2beef0e91dddfd4fcc29595ebd90bb9ce"},
{file = "black-22.3.0-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6d2fc92002d44746d3e7db7cf9313cf4452f43e9ea77a2c939defce3b10b5c82"},
{file = "black-22.3.0-cp36-cp36m-win_amd64.whl", hash = "sha256:a6342964b43a99dbc72f72812bf88cad8f0217ae9acb47c0d4f141a6416d2d7b"},
{file = "black-22.3.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:328efc0cc70ccb23429d6be184a15ce613f676bdfc85e5fe8ea2a9354b4e9015"},
{file = "black-22.3.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:06f9d8846f2340dfac80ceb20200ea5d1b3f181dd0556b47af4e8e0b24fa0a6b"},
{file = "black-22.3.0-cp37-cp37m-win_amd64.whl", hash = "sha256:ad4efa5fad66b903b4a5f96d91461d90b9507a812b3c5de657d544215bb7877a"},
{file = "black-22.3.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:e8477ec6bbfe0312c128e74644ac8a02ca06bcdb8982d4ee06f209be28cdf163"},
{file = "black-22.3.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:637a4014c63fbf42a692d22b55d8ad6968a946b4a6ebc385c5505d9625b6a464"},
{file = "black-22.3.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:863714200ada56cbc366dc9ae5291ceb936573155f8bf8e9de92aef51f3ad0f0"},
{file = "black-22.3.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:10dbe6e6d2988049b4655b2b739f98785a884d4d6b85bc35133a8fb9a2233176"},
{file = "black-22.3.0-cp38-cp38-win_amd64.whl", hash = "sha256:cee3e11161dde1b2a33a904b850b0899e0424cc331b7295f2a9698e79f9a69a0"},
{file = "black-22.3.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:5891ef8abc06576985de8fa88e95ab70641de6c1fca97e2a15820a9b69e51b20"},
{file = "black-22.3.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:30d78ba6bf080eeaf0b7b875d924b15cd46fec5fd044ddfbad38c8ea9171043a"},
{file = "black-22.3.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ee8f1f7228cce7dffc2b464f07ce769f478968bfb3dd1254a4c2eeed84928aad"},
{file = "black-22.3.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6ee227b696ca60dd1c507be80a6bc849a5a6ab57ac7352aad1ffec9e8b805f21"},
{file = "black-22.3.0-cp39-cp39-win_amd64.whl", hash = "sha256:9b542ced1ec0ceeff5b37d69838106a6348e60db7b8fdd245294dc1d26136265"},
{file = "black-22.3.0-py3-none-any.whl", hash = "sha256:bc58025940a896d7e5356952228b68f793cf5fcb342be703c3a2669a1488cb72"},
{file = "black-22.3.0.tar.gz", hash = "sha256:35020b8886c022ced9282b51b5a875b6d1ab0c387b31a065b84db7c33085ca79"},
{file = "black-22.8.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:ce957f1d6b78a8a231b18e0dd2d94a33d2ba738cd88a7fe64f53f659eea49fdd"},
{file = "black-22.8.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:5107ea36b2b61917956d018bd25129baf9ad1125e39324a9b18248d362156a27"},
{file = "black-22.8.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e8166b7bfe5dcb56d325385bd1d1e0f635f24aae14b3ae437102dedc0c186747"},
{file = "black-22.8.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd82842bb272297503cbec1a2600b6bfb338dae017186f8f215c8958f8acf869"},
{file = "black-22.8.0-cp310-cp310-win_amd64.whl", hash = "sha256:d839150f61d09e7217f52917259831fe2b689f5c8e5e32611736351b89bb2a90"},
{file = "black-22.8.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:a05da0430bd5ced89176db098567973be52ce175a55677436a271102d7eaa3fe"},
{file = "black-22.8.0-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4a098a69a02596e1f2a58a2a1c8d5a05d5a74461af552b371e82f9fa4ada8342"},
{file = "black-22.8.0-cp36-cp36m-win_amd64.whl", hash = "sha256:5594efbdc35426e35a7defa1ea1a1cb97c7dbd34c0e49af7fb593a36bd45edab"},
{file = "black-22.8.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a983526af1bea1e4cf6768e649990f28ee4f4137266921c2c3cee8116ae42ec3"},
{file = "black-22.8.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3b2c25f8dea5e8444bdc6788a2f543e1fb01494e144480bc17f806178378005e"},
{file = "black-22.8.0-cp37-cp37m-win_amd64.whl", hash = "sha256:78dd85caaab7c3153054756b9fe8c611efa63d9e7aecfa33e533060cb14b6d16"},
{file = "black-22.8.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:cea1b2542d4e2c02c332e83150e41e3ca80dc0fb8de20df3c5e98e242156222c"},
{file = "black-22.8.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:5b879eb439094751185d1cfdca43023bc6786bd3c60372462b6f051efa6281a5"},
{file = "black-22.8.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:0a12e4e1353819af41df998b02c6742643cfef58282915f781d0e4dd7a200411"},
{file = "black-22.8.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c3a73f66b6d5ba7288cd5d6dad9b4c9b43f4e8a4b789a94bf5abfb878c663eb3"},
{file = "black-22.8.0-cp38-cp38-win_amd64.whl", hash = "sha256:e981e20ec152dfb3e77418fb616077937378b322d7b26aa1ff87717fb18b4875"},
{file = "black-22.8.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:8ce13ffed7e66dda0da3e0b2eb1bdfc83f5812f66e09aca2b0978593ed636b6c"},
{file = "black-22.8.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:32a4b17f644fc288c6ee2bafdf5e3b045f4eff84693ac069d87b1a347d861497"},
{file = "black-22.8.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:0ad827325a3a634bae88ae7747db1a395d5ee02cf05d9aa7a9bd77dfb10e940c"},
{file = "black-22.8.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:53198e28a1fb865e9fe97f88220da2e44df6da82b18833b588b1883b16bb5d41"},
{file = "black-22.8.0-cp39-cp39-win_amd64.whl", hash = "sha256:bc4d4123830a2d190e9cc42a2e43570f82ace35c3aeb26a512a2102bce5af7ec"},
{file = "black-22.8.0-py3-none-any.whl", hash = "sha256:d2c21d439b2baf7aa80d6dd4e3659259be64c6f49dfd0f32091063db0e006db4"},
{file = "black-22.8.0.tar.gz", hash = "sha256:792f7eb540ba9a17e8656538701d3eb1afcb134e3b45b71f20b25c77a8db7e6e"},
]
certifi = [
{file = "certifi-2022.5.18.1-py3-none-any.whl", hash = "sha256:f1d53542ee8cbedbe2118b5686372fb33c297fcd6379b050cca0ef13a597382a"},
{file = "certifi-2022.5.18.1.tar.gz", hash = "sha256:9c5705e395cd70084351dd8ad5c41e65655e08ce46f2ec9cf6c2c08390f71eb7"},
{file = "certifi-2022.6.15-py3-none-any.whl", hash = "sha256:fe86415d55e84719d75f8b69414f6438ac3547d2078ab91b67e779ef69378412"},
{file = "certifi-2022.6.15.tar.gz", hash = "sha256:84c85a9078b11105f04f3036a9482ae10e4621616db313fe045dd24743a0820d"},
]
chardet = [
{file = "chardet-4.0.0-py2.py3-none-any.whl", hash = "sha256:f864054d66fd9118f2e67044ac8981a54775ec5b67aed0441892edb553d21da5"},
{file = "chardet-4.0.0.tar.gz", hash = "sha256:0d6f53a15db4120f2b08c94f11e7d93d2c911ee118b6b30a04ec3ee8310179fa"},
{file = "chardet-5.0.0-py3-none-any.whl", hash = "sha256:d3e64f022d254183001eccc5db4040520c0f23b1a3f33d6413e099eb7f126557"},
{file = "chardet-5.0.0.tar.gz", hash = "sha256:0368df2bfd78b5fc20572bb4e9bb7fb53e2c094f60ae9993339e8671d0afb8aa"},
]
charset-normalizer = [
{file = "charset-normalizer-2.0.12.tar.gz", hash = "sha256:2857e29ff0d34db842cd7ca3230549d1a697f96ee6d3fb071cfa6c7393832597"},
{file = "charset_normalizer-2.0.12-py3-none-any.whl", hash = "sha256:6881edbebdb17b39b4eaaa821b438bf6eddffb4468cf344f09f89def34a8b1df"},
{file = "charset-normalizer-2.1.1.tar.gz", hash = "sha256:5a3d016c7c547f69d6f81fb0db9449ce888b418b5b9952cc5e6e66843e9dd845"},
{file = "charset_normalizer-2.1.1-py3-none-any.whl", hash = "sha256:83e9a75d1911279afd89352c68b45348559d1fc0506b054b346651b5e7fee29f"},
]
click = [
{file = "click-8.1.3-py3-none-any.whl", hash = "sha256:bb4d8133cb15a609f44e8213d9b391b0809795062913b383c62be0ee95b1db48"},
{file = "click-8.1.3.tar.gz", hash = "sha256:7682dc8afb30297001674575ea00d1814d808d6a36af415a82bd481d37ba7b8e"},
]
colorama = [
{file = "colorama-0.4.4-py2.py3-none-any.whl", hash = "sha256:9f47eda37229f68eee03b24b9748937c7dc3868f906e8ba69fbcbdd3bc5dc3e2"},
{file = "colorama-0.4.4.tar.gz", hash = "sha256:5941b2b48a20143d2267e95b1c2a7603ce057ee39fd88e7329b0c292aa16869b"},
{file = "colorama-0.4.5-py2.py3-none-any.whl", hash = "sha256:854bf444933e37f5824ae7bfc1e98d5bce2ebe4160d46b5edf346a89358e99da"},
{file = "colorama-0.4.5.tar.gz", hash = "sha256:e6c6b4334fc50988a639d9b98aa429a0b57da6e17b9a44f0451f930b6967b7a4"},
]
doc8 = [
{file = "doc8-0.8.1-py2.py3-none-any.whl", hash = "sha256:4d58a5c8c56cedd2b2c9d6e3153be5d956cf72f6051128f0f2255c66227df721"},
@@ -579,18 +583,18 @@ idna = [
{file = "idna-3.3.tar.gz", hash = "sha256:9d643ff0a55b762d5cdb124b8eaa99c66322e2157b69160bc32796e824360e6d"},
]
imagesize = [
{file = "imagesize-1.3.0-py2.py3-none-any.whl", hash = "sha256:1db2f82529e53c3e929e8926a1fa9235aa82d0bd0c580359c67ec31b2fddaa8c"},
{file = "imagesize-1.3.0.tar.gz", hash = "sha256:cd1750d452385ca327479d45b64d9c7729ecf0b3969a58148298c77092261f9d"},
{file = "imagesize-1.4.1-py2.py3-none-any.whl", hash = "sha256:0d8d18d08f840c19d0ee7ca1fd82490fdc3729b7ac93f49870406ddde8ef8d8b"},
{file = "imagesize-1.4.1.tar.gz", hash = "sha256:69150444affb9cb0d5cc5a92b3676f0b2fb7cd9ae39e947a5e11a36b4497cd4a"},
]
importlib-metadata = [
{file = "importlib_metadata-4.11.4-py3-none-any.whl", hash = "sha256:c58c8eb8a762858f49e18436ff552e83914778e50e9d2f1660535ffb364552ec"},
{file = "importlib_metadata-4.11.4.tar.gz", hash = "sha256:5d26852efe48c0a32b0509ffbc583fda1a2266545a78d104a6f4aff3db17d700"},
{file = "importlib_metadata-4.12.0-py3-none-any.whl", hash = "sha256:7401a975809ea1fdc658c3aa4f78cc2195a0e019c5cbc4c06122884e9ae80c23"},
{file = "importlib_metadata-4.12.0.tar.gz", hash = "sha256:637245b8bab2b6502fcbc752cc4b7a6f6243bb02b31c5c26156ad103d3d45670"},
]
jinja2 = [
Jinja2 = [
{file = "Jinja2-3.1.2-py3-none-any.whl", hash = "sha256:6088930bfe239f0e6710546ab9c19c9ef35e29792895fed6e6e31a023a182a61"},
{file = "Jinja2-3.1.2.tar.gz", hash = "sha256:31351a702a408a9e7595a8fc6150fc3f43bb6bf7e319770cbc0db9df9437e852"},
]
markupsafe = [
MarkupSafe = [
{file = "MarkupSafe-2.1.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:86b1f75c4e7c2ac2ccdaec2b9022845dbb81880ca318bb7a0a01fbf7813e3812"},
{file = "MarkupSafe-2.1.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:f121a1420d4e173a5d96e47e9a0c0dcff965afdf1626d28de1460815f7c4ee7a"},
{file = "MarkupSafe-2.1.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a49907dd8420c5685cfa064a1335b6754b74541bbb3706c259c02ed65b644b3e"},
@@ -645,12 +649,12 @@ packaging = [
{file = "packaging-21.3.tar.gz", hash = "sha256:dd47c42927d89ab911e606518907cc2d3a1f38bbd026385970643f9c5b8ecfeb"},
]
pathspec = [
{file = "pathspec-0.9.0-py2.py3-none-any.whl", hash = "sha256:7d15c4ddb0b5c802d161efc417ec1a2558ea2653c2e8ad9c19098201dc1c993a"},
{file = "pathspec-0.9.0.tar.gz", hash = "sha256:e564499435a2673d586f6b2130bb5b95f04a3ba06f81b8f895b651a3c76aabb1"},
{file = "pathspec-0.10.1-py3-none-any.whl", hash = "sha256:46846318467efc4556ccfd27816e004270a9eeeeb4d062ce5e6fc7a87c573f93"},
{file = "pathspec-0.10.1.tar.gz", hash = "sha256:7ace6161b621d31e7902eb6b5ae148d12cfd23f4a249b9ffb6b9fee12084323d"},
]
pbr = [
{file = "pbr-5.9.0-py2.py3-none-any.whl", hash = "sha256:e547125940bcc052856ded43be8e101f63828c2d94239ffbe2b327ba3d5ccf0a"},
{file = "pbr-5.9.0.tar.gz", hash = "sha256:e8dca2f4b43560edef58813969f52a56cef023146cbb8931626db80e6c1c4308"},
{file = "pbr-5.10.0-py2.py3-none-any.whl", hash = "sha256:da3e18aac0a3c003e9eea1a81bd23e5a3a75d745670dcf736317b7d966887fdf"},
{file = "pbr-5.10.0.tar.gz", hash = "sha256:cfcc4ff8e698256fc17ea3ff796478b050852585aa5bae79ecd05b2ab7b39b9a"},
]
platformdirs = [
{file = "platformdirs-2.5.2-py3-none-any.whl", hash = "sha256:027d8e83a2d7de06bbac4e5ef7e023c02b863d7ea5d079477e722bb41ab25788"},
@@ -664,21 +668,21 @@ pyflakes = [
{file = "pyflakes-2.4.0-py2.py3-none-any.whl", hash = "sha256:3bb3a3f256f4b7968c9c788781e4ff07dce46bdf12339dcda61053375426ee2e"},
{file = "pyflakes-2.4.0.tar.gz", hash = "sha256:05a85c2872edf37a4ed30b0cce2f6093e1d0581f8c19d7393122da7e25b2b24c"},
]
pygments = [
{file = "Pygments-2.12.0-py3-none-any.whl", hash = "sha256:dc9c10fb40944260f6ed4c688ece0cd2048414940f1cea51b8b226318411c519"},
{file = "Pygments-2.12.0.tar.gz", hash = "sha256:5eb116118f9612ff1ee89ac96437bb6b49e8f04d8a13b514ba26f620208e26eb"},
Pygments = [
{file = "Pygments-2.13.0-py3-none-any.whl", hash = "sha256:f643f331ab57ba3c9d89212ee4a2dabc6e94f117cf4eefde99a0574720d14c42"},
{file = "Pygments-2.13.0.tar.gz", hash = "sha256:56a8508ae95f98e2b9bdf93a6be5ae3f7d8af858b43e02c5a2ff083726be40c1"},
]
pyparsing = [
{file = "pyparsing-3.0.9-py3-none-any.whl", hash = "sha256:5026bae9a10eeaefb61dab2f09052b9f4307d44aee4eda64b309723d8d206bbc"},
{file = "pyparsing-3.0.9.tar.gz", hash = "sha256:2b020ecf7d21b687f219b71ecad3631f644a47f01403fa1d1036b0c6416d70fb"},
]
pytz = [
{file = "pytz-2022.1-py2.py3-none-any.whl", hash = "sha256:e68985985296d9a66a881eb3193b0906246245294a881e7c8afe623866ac6a5c"},
{file = "pytz-2022.1.tar.gz", hash = "sha256:1e760e2fe6a8163bc0b3d9a19c4f84342afa0a2affebfaa84b01b978a02ecaa7"},
{file = "pytz-2022.2.1-py2.py3-none-any.whl", hash = "sha256:220f481bdafa09c3955dfbdddb7b57780e9a94f5127e35456a48589b9e0c0197"},
{file = "pytz-2022.2.1.tar.gz", hash = "sha256:cea221417204f2d1a2aa03ddae3e867921971d0d76f14d87abb4414415bbdcf5"},
]
requests = [
{file = "requests-2.27.1-py2.py3-none-any.whl", hash = "sha256:f22fa1e554c9ddfd16e6e41ac79759e17be9e492b3587efa038054674760e72d"},
{file = "requests-2.27.1.tar.gz", hash = "sha256:68d7c56fd5a8999887728ef304a6d12edc7be74f1cfa47714fc8b414525c9a61"},
{file = "requests-2.28.1-py3-none-any.whl", hash = "sha256:8fefa2a1a1365bf5520aac41836fbee479da67864514bdb821f31ce07ce65349"},
{file = "requests-2.28.1.tar.gz", hash = "sha256:7c5599b102feddaa661c826c56ab4fee28bfd17f5abca1ebbe3e7f19d7c97983"},
]
restructuredtext-lint = [
{file = "restructuredtext_lint-1.4.0.tar.gz", hash = "sha256:1b235c0c922341ab6c530390892eb9e92f90b9b75046063e047cacfb0f050c45"},
@@ -721,8 +725,8 @@ sphinxcontrib-serializinghtml = [
{file = "sphinxcontrib_serializinghtml-1.1.5-py2.py3-none-any.whl", hash = "sha256:352a9a00ae864471d3a7ead8d7d79f5fc0b57e8b3f95e9867eb9eb28999b92fd"},
]
stevedore = [
{file = "stevedore-3.5.0-py3-none-any.whl", hash = "sha256:a547de73308fd7e90075bb4d301405bebf705292fa90a90fc3bcf9133f58616c"},
{file = "stevedore-3.5.0.tar.gz", hash = "sha256:f40253887d8712eaa2bb0ea3830374416736dc8ec0e22f5a65092c1174c44335"},
{file = "stevedore-4.0.0-py3-none-any.whl", hash = "sha256:87e4d27fe96d0d7e4fc24f0cbe3463baae4ec51e81d95fbe60d2474636e0c7d8"},
{file = "stevedore-4.0.0.tar.gz", hash = "sha256:f82cc99a1ff552310d19c379827c2c64dd9f85a38bcd5559db2470161867b786"},
]
toml = [
{file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"},
@@ -733,14 +737,14 @@ tomli = [
{file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"},
]
typing-extensions = [
{file = "typing_extensions-4.2.0-py3-none-any.whl", hash = "sha256:6657594ee297170d19f67d55c05852a874e7eb634f4f753dbd667855e07c1708"},
{file = "typing_extensions-4.2.0.tar.gz", hash = "sha256:f1c24655a0da0d1b67f07e17a5e6b2a105894e6824b92096378bb3668ef02376"},
{file = "typing_extensions-4.3.0-py3-none-any.whl", hash = "sha256:25642c956049920a5aa49edcdd6ab1e06d7e5d467fc00e0506c44ac86fbfca02"},
{file = "typing_extensions-4.3.0.tar.gz", hash = "sha256:e6d2677a32f47fc7eb2795db1dd15c1f34eff616bcaf2cfb5e997f854fa1c4a6"},
]
urllib3 = [
{file = "urllib3-1.26.9-py2.py3-none-any.whl", hash = "sha256:44ece4d53fb1706f667c9bd1c648f5469a2ec925fcf3a776667042d645472c14"},
{file = "urllib3-1.26.9.tar.gz", hash = "sha256:aabaf16477806a5e1dd19aa41f8c2b7950dd3c746362d7e3223dbe6de6ac448e"},
{file = "urllib3-1.26.12-py2.py3-none-any.whl", hash = "sha256:b930dd878d5a8afb066a637fbb35144fe7901e3b209d1cd4f524bd0e9deee997"},
{file = "urllib3-1.26.12.tar.gz", hash = "sha256:3fa96cf423e6987997fc326ae8df396db2a8b7c667747d47ddd8ecba91f4a74e"},
]
zipp = [
{file = "zipp-3.8.0-py3-none-any.whl", hash = "sha256:c4f6e5bbf48e74f7a38e7cc5b0480ff42b0ae5178957d564d18932525d5cf099"},
{file = "zipp-3.8.0.tar.gz", hash = "sha256:56bf8aadb83c24db6c4b577e13de374ccfb67da2078beba1d037c17980bf43ad"},
{file = "zipp-3.8.1-py3-none-any.whl", hash = "sha256:47c40d7fe183a6f21403a199b3e4192cca5774656965b0a4988ad2f8feb5f009"},
{file = "zipp-3.8.1.tar.gz", hash = "sha256:05b45f1ee8f807d0cc928485ca40a07cb491cf092ff587c0df9cb1fd154848d2"},
]
+1 -1
View File
@@ -1,6 +1,6 @@
[tool.poetry]
name = "pybricks"
version = "3.2.0b1-r1"
version = "3.2.0b1-r3"
description = "Documentation and user-API stubs for Pybricks MicroPython"
authors = ["The Pybricks Authors <dev@pybricks.com>"]
maintainers = ["Laurens Valk <laurens@pybricks.com>", "David Lechner <david@pybricks.com>" ]
+2 -2
View File
@@ -1,8 +1,8 @@
[flake8]
exclude = .venv/,*.pyi
exclude = .venv/,*.pyi,jedi/
max-line-length = 88
ignore = E203,W503
ignore = E203,E501,W503
[doc8]
ignore-path = .venv/,doc/main/build/,doc/api/build/,pybricks.egg-info/,npm/
+192 -112
View File
@@ -4,20 +4,23 @@
"""Generic cross-platform module for typical devices like lights, displays,
speakers, and batteries."""
from .parameters import Direction, Stop, Button, Port, Color, Side
from __future__ import annotations
from typing import Union, Iterable, overload, Optional, Tuple, Collection, TYPE_CHECKING
from .geometry import Matrix, Axis
from .parameters import Direction, Stop, Button, Port, Color, Side
from typing import Union, Iterable, overload, Optional, Tuple, Collection
Number = Union[int, float]
if TYPE_CHECKING:
from .parameters import Number
class System:
"""System control actions for a hub."""
def set_stop_button(self, button: Union[Button, Iterable[Button]]) -> None:
def set_stop_button(
self, button: Optional[Union[Button, Iterable[Button]]]
) -> None:
"""
set_stop_button(button)
@@ -33,13 +36,11 @@ class System:
or a tuple of multiple buttons. Choose ``None`` to disable the
stop button altogether.
"""
pass
def shutdown(self) -> None:
"""shutdown()
Stops your program and shuts the hub down."""
pass
def reset_reason(self) -> int:
"""reset_reason() -> int
@@ -56,7 +57,6 @@ class System:
crashed due to a watchdog timeout, which indicates a firmware
issue.
"""
pass
def name(self) -> str:
"""name() -> str
@@ -67,7 +67,6 @@ class System:
Returns:
The hub name.
"""
pass
class DCMotor:
@@ -75,14 +74,13 @@ class DCMotor:
as train motors."""
def __init__(self, port: Port, positive_direction: Direction = Direction.CLOCKWISE):
"""DCMotor(port, positive_direction=Direction.CLOCKWISE)
"""__init__(port, positive_direction=Direction.CLOCKWISE)
Arguments:
port (Port): Port to which the motor is connected.
positive_direction (Direction): Which direction the motor should
turn when you give a positive duty cycle value.
"""
pass
def dc(self, duty: Number) -> None:
"""dc(duty)
@@ -92,7 +90,6 @@ class DCMotor:
Arguments:
duty (Number, %): The duty cycle (-100.0 to 100).
"""
pass
def stop(self) -> None:
"""stop()
@@ -100,7 +97,6 @@ class DCMotor:
Stops the motor and lets it spin freely.
The motor gradually stops due to friction."""
pass
def brake(self) -> None:
"""brake()
@@ -109,10 +105,9 @@ class DCMotor:
The motor stops due to friction, plus the voltage that
is generated while the motor is still moving."""
pass
@overload
def settings(self, max_voltage: Optional[int] = None) -> None:
def settings(self, max_voltage: Number) -> None:
...
@overload
@@ -131,7 +126,6 @@ class DCMotor:
max_voltage (Number, mV):
Maximum voltage applied to the motor during all motor commands.
"""
pass
class Control:
@@ -146,16 +140,16 @@ class Control:
"""
@overload
def limits(self) -> Tuple[int, int, int]:
def limits(
self,
speed: Optional[Number] = None,
acceleration: Optional[Number] = None,
torque: Optional[Number] = None,
) -> None:
...
@overload
def limits(
self,
speed: Optional[int] = None,
acceleration: Optional[int] = None,
torque: Optional[int] = None,
) -> None:
def limits(self) -> Tuple[int, int, int]:
...
def limits(self, *args):
@@ -177,23 +171,22 @@ class Control:
torque (:ref:`torque`):
Maximum feedback torque during control.
"""
pass
@overload
def pid(self) -> Tuple[int, int, int, None, int]:
...
@overload
def pid(
self,
kp: Optional[int] = None,
ki: Optional[int] = None,
kd: Optional[int] = None,
reserved: Optional[int] = None,
integral_rate: Optional[int] = None,
kp: Optional[Number] = None,
ki: Optional[Number] = None,
kd: Optional[Number] = None,
reserved: Optional[Number] = None,
integral_rate: Optional[Number] = None,
) -> None:
...
@overload
def pid(self) -> Tuple[int, int, int, None, int]:
...
def pid(self, *args):
"""pid(kp, ki, kd, reserved, integral_rate)
pid() -> Tuple[int, int, int, None, int]
@@ -215,18 +208,17 @@ class Control:
integral_rate (Number, deg/s or Number, mm/s): Maximum rate at
which the error integral is allowed to grow.
"""
pass
@overload
def target_tolerances(self) -> Tuple[int, int]:
...
@overload
def target_tolerances(
self, speed: Optional[int] = None, position: Optional[int] = None
self, speed: Optional[Number] = None, position: Optional[Number] = None
) -> None:
...
@overload
def target_tolerances(self) -> Tuple[int, int]:
...
def target_tolerances(self, *args):
"""target_tolerances(speed, position)
target_tolerances() -> Tuple[int, int]
@@ -242,18 +234,17 @@ class Control:
deviation from the target before motion is considered
complete.
"""
pass
@overload
def stall_tolerances(self) -> Tuple[int, int]:
...
@overload
def stall_tolerances(
self, speed: Optional[int] = None, time: Optional[int] = None
self, speed: Optional[Number] = None, time: Optional[Number] = None
) -> None:
...
@overload
def stall_tolerances(self) -> Tuple[int, int]:
...
def stall_tolerances(self, speed, time):
"""stall_tolerances(speed, time)
stall_tolerances() -> Tuple[int, int]
@@ -269,7 +260,6 @@ class Control:
time (Number, ms): How long the controller has to be below this
minimum ``speed`` before we say it is stalled.
"""
pass
def stalled(self) -> bool:
"""stalled() -> bool
@@ -282,7 +272,6 @@ class Control:
Returns:
``True`` if the controller is stalled, ``False`` if not.
"""
pass
def done(self) -> bool:
"""done() -> bool
@@ -292,7 +281,6 @@ class Control:
Returns:
``True`` if the command is done, ``False`` if not.
"""
pass
def load(self) -> int:
"""load() -> int: mNm
@@ -306,7 +294,6 @@ class Control:
Returns:
The load torque. It returns 0 if control is not active.
"""
pass
class Motor(DCMotor):
@@ -325,7 +312,7 @@ class Motor(DCMotor):
gears: Optional[Union[Collection[int], Collection[Collection[int]]]] = None,
reset_angle: bool = True,
):
"""Motor(port, positive_direction=Direction.CLOCKWISE, gears=None, reset_angle=True)
"""__init__(port, positive_direction=Direction.CLOCKWISE, gears=None, reset_angle=True)
Arguments:
port (Port): Port to which the motor is connected.
@@ -349,7 +336,6 @@ class Motor(DCMotor):
current value, so your program knows where it left off last
time.
"""
pass
def angle(self) -> int:
"""angle() -> int: deg
@@ -359,7 +345,6 @@ class Motor(DCMotor):
Returns:
Motor angle.
"""
pass
def speed(self) -> int:
"""speed() -> int: deg/s
@@ -370,9 +355,8 @@ class Motor(DCMotor):
Motor speed.
"""
pass
def reset_angle(self, angle: Number) -> None:
def reset_angle(self, angle: Optional[Number]) -> None:
"""
reset_angle(angle)
@@ -381,13 +365,11 @@ class Motor(DCMotor):
Arguments:
angle (Number, deg): Value to which the angle should be reset.
"""
pass
def hold(self) -> None:
"""hold()
Stops the motor and actively holds it at its current angle."""
pass
def run(self, speed: Number) -> None:
"""run(speed)
@@ -400,7 +382,6 @@ class Motor(DCMotor):
Arguments:
speed (Number, deg/s): Speed of the motor.
"""
pass
def run_time(
self, speed: Number, time: Number, then: Stop = Stop.HOLD, wait: bool = True
@@ -420,7 +401,6 @@ class Motor(DCMotor):
wait (bool): Wait for the maneuver to complete before continuing
with the rest of the program.
"""
pass
def run_angle(
self,
@@ -441,7 +421,6 @@ class Motor(DCMotor):
wait (bool): Wait for the maneuver to complete before continuing
with the rest of the program.
"""
pass
def run_target(
self,
@@ -464,7 +443,6 @@ class Motor(DCMotor):
wait (bool): Wait for the motor to reach the target
before continuing with the rest of the program.
"""
pass
def run_until_stalled(
self,
@@ -488,7 +466,6 @@ class Motor(DCMotor):
Returns:
Angle at which the motor becomes stalled.
"""
pass
def track_target(self, target_angle: Number) -> None:
"""track_target(target_angle)
@@ -502,18 +479,17 @@ class Motor(DCMotor):
target_angle (Number, deg): Target angle that the motor should
rotate to.
"""
pass
class Speaker:
"""Plays beeps and sounds using a speaker."""
@overload
def volume(self) -> int:
def volume(self, volume: Number) -> None:
...
@overload
def volume(self, volume: Number) -> None:
def volume(self) -> int:
...
def volume(self, *args):
@@ -527,7 +503,6 @@ class Speaker:
Arguments:
volume (Number, %): Volume of the speaker in the 0-100 range.
"""
pass
def beep(self, frequency: Number = 500, duration: Number = 100) -> None:
"""beep(frequency=500, duration=100)
@@ -542,7 +517,6 @@ class Speaker:
than 0, then the method returns immediately and the frequency
play continues to play indefinitely.
"""
pass
def play_notes(self, notes: Iterable[str], tempo: Number = 120) -> None:
"""play_notes(notes, tempo=120)
@@ -577,7 +551,6 @@ class Speaker:
tempo (int):
Beats per minute. A quarter note is one beat.
"""
pass
class ColorLight:
@@ -591,15 +564,13 @@ class ColorLight:
Arguments:
color (Color): Color of the light.
"""
pass
def off(self) -> None:
"""off()
Turns off the light."""
pass
def blink(self, color: Color, durations: Collection[int]) -> None:
def blink(self, color: Color, durations: Collection[Number]) -> None:
"""blink(color, durations)
Blinks the light at a given color by turning it on and off for given
@@ -628,7 +599,7 @@ class ColorLight:
keeps running. When the animation completes, it repeats.
Arguments:
colors (iter): Sequence of :class:`Color <.parameters.Color>`
colors (list): Sequence of :class:`Color <.parameters.Color>`
values.
interval (Number, ms): Time between color updates.
"""
@@ -645,9 +616,8 @@ class LightArray:
Arguments:
n (int): Number of lights
"""
pass
def on(self, brightness: Union[int, Collection[int]]) -> None:
def on(self, brightness: Union[Number, Collection[Number]]) -> None:
"""on(brightness)
Turns on the lights at the specified brightness.
@@ -658,13 +628,11 @@ class LightArray:
If you give just one brightness value, all lights get that
brightness.
"""
pass
def off(self) -> None:
"""off()
Turns off all the lights."""
pass
class LightMatrix:
@@ -679,7 +647,6 @@ class LightMatrix:
rows (int): Number of rows in the grid
columns (int): Number of columns in the grid
"""
pass
def orientation(self, up: Side) -> None:
"""orientation(up)
@@ -694,7 +661,6 @@ class LightMatrix:
design. Choose ``Side.TOP``, ``Side.LEFT``, ``Side.RIGHT``,
or ``Side.BOTTOM``.
"""
pass
def image(self, matrix: Matrix) -> None:
"""image(matrix)
@@ -706,7 +672,6 @@ class LightMatrix:
matrix (Matrix): Matrix of intensities (:ref:`brightness`). A 2D
list is also accepted.
"""
pass
def animate(self, matrices: Collection[Matrix], interval: Number) -> None:
"""animate(matrices, interval)
@@ -722,25 +687,22 @@ class LightMatrix:
:class:`Matrix <pybricks.geometry.Matrix>` of intensities.
interval (Number, ms): Time to display each image in the list.
"""
pass
def pixel(self, row: int, column: int, brightness: Number = 100) -> None:
def pixel(self, row: Number, column: Number, brightness: Number = 100) -> None:
"""pixel(row, column, brightness=100)
Turns on one pixel at the specified brightness.
Arguments:
row (int): Vertical grid index, starting at 0 from the top.
column (int): Horizontal grid index, starting at 0 from the left.
brightness (:ref:`brightness`): Brightness of the pixel.
row (Number): Vertical grid index, starting at 0 from the top.
column (Number): Horizontal grid index, starting at 0 from the left.
brightness (Number :ref:`brightness`): Brightness of the pixel.
"""
pass
def off(self) -> None:
"""off()
Turns off all the pixels."""
pass
def number(self, number: Number) -> None:
"""number(number)
@@ -754,7 +716,6 @@ class LightMatrix:
Arguments:
number (int): The number to be displayed.
"""
pass
def char(self, char: str) -> None:
"""char(char)
@@ -766,7 +727,6 @@ class LightMatrix:
Arguments:
character (str): The character or symbol to be displayed.
"""
pass
def text(self, text: str, on: Number = 500, off: Number = 50) -> None:
"""text(text, on=500, off=50)
@@ -781,24 +741,22 @@ class LightMatrix:
off (Number, ms): For how long the display is off between
characters.
"""
pass
class Keypad:
"""Get status of buttons on a keypad layout."""
def __init__(self, active_buttons):
pass
...
def pressed(self) -> Tuple[Button]:
"""pressed() -> Tuple[Button]
def pressed(self) -> Collection[Button]:
"""pressed() -> Collection[Button]
Checks which buttons are currently pressed.
Returns:
Tuple of pressed buttons.
Set of pressed buttons.
"""
pass
class Battery:
@@ -812,7 +770,6 @@ class Battery:
Returns:
Battery voltage.
"""
pass
def current(self) -> int:
"""current() -> int: mA
@@ -822,7 +779,6 @@ class Battery:
Returns:
Battery current.
"""
pass
class Charger:
@@ -852,7 +808,6 @@ class Charger:
Returns:
Status value.
"""
pass
def current(self) -> int:
"""current() -> int: mA
@@ -862,7 +817,6 @@ class Charger:
Returns:
Charging current.
"""
pass
class SimpleAccelerometer:
@@ -876,7 +830,6 @@ class SimpleAccelerometer:
Returns:
Acceleration along all three axes.
"""
pass
def up(self) -> Side:
"""up() -> Side
@@ -887,18 +840,17 @@ class SimpleAccelerometer:
``Side.TOP``, ``Side.BOTTOM``, ``Side.LEFT``, ``Side.RIGHT``,
``Side.FRONT`` or ``Side.BACK``.
"""
pass
class Accelerometer(SimpleAccelerometer):
"""Get measurements from an accelerometer."""
@overload
def acceleration(self) -> Matrix:
def acceleration(self, axis: Axis) -> float:
...
@overload
def acceleration(self, axis: Axis) -> float:
def acceleration(self) -> Matrix:
...
def acceleration(self, *args):
@@ -917,7 +869,6 @@ class Accelerometer(SimpleAccelerometer):
Acceleration along the specified axis. If you specify no axis,
this returns a vector of accelerations along all axes.
"""
pass
def tilt(self) -> Tuple[int, int]:
"""tilt() -> Tuple[int, int]
@@ -932,7 +883,6 @@ class Accelerometer(SimpleAccelerometer):
Returns:
Tuple of pitch and roll angles.
"""
pass
class IMU(Accelerometer):
@@ -952,10 +902,9 @@ class IMU(Accelerometer):
Heading angle relative to starting orientation.
"""
pass
def reset_heading(self, angle: Number) -> None:
"""reset_heading(angle: Number)
"""reset_heading(angle)
Resets the accumulated heading angle of the robot.
@@ -964,16 +913,15 @@ class IMU(Accelerometer):
Arguments:
angle (Number, deg): Value to which the heading should be reset.
"""
pass
@overload
def angular_velocity(self) -> Matrix:
...
@overload
def angular_velocity(self, axis: Axis) -> float:
...
@overload
def angular_velocity(self) -> Matrix:
...
def angular_velocity(self, *args):
"""
angular_velocity(axis) -> float: deg/s
@@ -989,4 +937,136 @@ class IMU(Accelerometer):
Angular velocity along the specified axis. If you specify no axis,
this returns a vector of accelerations along all axes.
"""
pass
class CommonColorSensor:
"""Generic color sensor that supports Pybricks color calibration."""
def __init__(self, port: Port):
"""__init__(port)
Arguments:
port (Port): Port to which the sensor is connected.
"""
def color(self) -> Color:
"""color() -> Color
Scans the color of a surface.
You choose which colors are detected using the
``detectable_colors()`` method. By default, it detects
``Color.RED``, ``Color.YELLOW``, ``Color.GREEN``, ``Color.BLUE``,
``Color.WHITE``, or ``Color.NONE``.
Returns:
Detected color.
"""
def hsv(self) -> Color:
"""hsv() -> Color
Scans the color of a surface.
This method is similar to ``color()``, but it gives the full range
of hue, saturation and brightness values, instead of rounding it to the
nearest detectable color.
Returns:
Measured color. The color is described by a hue (0--359), a
saturation (0--100), and a brightness value (0--100).
"""
def ambient(self) -> int:
"""ambient() -> int: %
Measures the ambient light intensity.
Returns:
Ambient light intensity, ranging from 0% (dark)
to 100% (bright).
"""
def reflection(self) -> int:
"""reflection() -> int: %
Measures how much a surface reflects the light emitted by the
sensor.
Returns:
Measured reflection, ranging from 0% (no reflection) to
100% (high reflection).
"""
@overload
def detectable_colors(self, colors: Collection[Color]) -> None:
...
@overload
def detectable_colors(self) -> Collection[Color]:
...
def detectable_colors(self, *args):
"""
detectable_colors(colors)
detectable_colors() -> Collection[Color]
Configures which colors the ``color()`` method should detect.
Specify only colors that you wish to detect in your application.
This way, the full-color measurements are rounded to the nearest
desired color, and other colors are ignored. This improves reliability.
If you give no arguments, the currently chosen colors will be returned.
Arguments:
colors (list or tuple): List of :class:`Color <.parameters.Color>`
objects: the colors that you want to detect. You can pick
standard colors such as ``Color.MAGENTA``, or provide your
own colors like ``Color(h=348, s=96, v=40)`` for even
better results. You measure your own colors with the
``hsv()`` method.
"""
class AmbientColorSensor(CommonColorSensor):
"""Like CommonColorSensor, but also detects ambient colors when the sensor
light is turned off"""
def color(self, surface: bool = True) -> Optional[Color]:
"""color(surface=True) -> Color
Scans the color of a surface or an external light source.
You choose which colors are detected using the
``detectable_colors()`` method. By default, it detects
``Color.RED``, ``Color.YELLOW``, ``Color.GREEN``, ``Color.BLUE``,
``Color.WHITE``, or ``Color.NONE``.
Arguments:
surface (bool): Choose ``true`` to scan the color of objects
and surfaces. Choose ``false`` to scan the color of
screens and other external light sources.
Returns:
Detected color.`
"""
def hsv(self, surface: bool = True) -> Color:
"""hsv(surface=True) -> Color
Scans the color of a surface or an external light source.
This method is similar to ``color()``, but it gives the full range
of hue, saturation and brightness values, instead of rounding it to the
nearest detectable color.
Arguments:
surface (bool): Choose ``true`` to scan the color of objects
and surfaces. Choose ``false`` to scan the color of
screens and other external light sources.
Returns:
Measured color. The color is described by a hue (0--359), a
saturation (0--100), and a brightness value (0--100).
"""
+40 -26
View File
@@ -1,26 +1,33 @@
# SPDX-License-Identifier: MIT
# Copyright (c) 2018-2021 The Pybricks Authors
from typing import Iterable, Union, Optional
from ..media.ev3dev import SoundFile
class Speaker:
"""Plays beeps and sounds using a speaker."""
def beep(self, frequency=500, duration=100):
"""Play a beep/tone.
def beep(self, frequency: int = 500, duration: int = 100) -> None:
"""beep(frequency=500, duration=100)
Play a beep/tone.
Arguments:
frequency (:ref:`frequency`):
Frequency of the beep. Frequencies below 100
are treated as 100.
duration (:ref:`time`):
Duration of the beep. If the duration is less
than 0, then the method returns immediately and the frequency
play continues to play indefinitely.
frequency (Number, Hz):
Frequency of the beep. Frequencies below 100 Hz are treated as
100 Hz.
duration (Number, ms):
Duration of the beep. If the duration is less than 0, then the
method returns immediately and the frequency play continues to
play indefinitely.
"""
pass
def play_notes(self, notes, tempo=120):
"""Plays a sequence of musical notes. For example:
def play_notes(self, notes: Iterable[str], tempo: int = 120) -> None:
"""play_notes(notes, tempo=120)
Plays a sequence of musical notes. For example:
``['C4/4', 'C4/4', 'G4/4', 'G4/4']``.
Each note is a string with the following format:
@@ -50,20 +57,21 @@ class Speaker:
tempo (int):
Beats per minute. A quarter note is one beat.
"""
pass
def play_file(self, file):
"""Plays a sound file.
def play_file(self, file_name: Union[SoundFile, str]) -> None:
"""play_file(file_name)
Plays a sound file.
Arguments:
file (str):
Path to the sound file, including the file extension.
"""
pass
def say(self, text: str) -> None:
"""say(text)
def say(self, text):
"""Says a given text string.
Says a given text string.
You can configure the language and voice of the text using
:meth:`.set_speech_options`.
@@ -72,10 +80,16 @@ class Speaker:
text (str): What to say.
"""
pass
def set_speech_options(
self,
language: Optional[str] = None,
voice: Optional[str] = None,
speed: Optional[int] = None,
pitch: Optional[int] = None,
):
"""set_speech_options(language, voice, speed, pitch)
def set_speech_options(self, language=None, voice=None, speed=None, pitch=None):
"""Configures speech settings used by the :meth:`.say` method.
Configures speech settings used by the :meth:`.say` method.
Any option that is set to ``None`` will not be changed. If an option
is set to an invalid value :meth:`.say` will use the default value
@@ -95,13 +109,14 @@ class Speaker:
Pitch (0 to 99). Higher numbers make the voice higher pitched
and lower numbers make the voice lower pitched.
"""
pass
def set_volume(self, volume, which="_all_"):
"""Sets the speaker volume.
def set_volume(self, volume: int, which: str = "_all_") -> None:
"""set_volume(volume, which="_all_")
Sets the speaker volume.
Arguments:
volume (:ref:`percentage`):
volume (Number, %):
Volume of the speaker.
which (str):
Which volume to set. ``'Beep'`` sets the volume for
@@ -109,4 +124,3 @@ class Speaker:
volume for :meth:`.play_file` and :meth:`.say`. ``'_all_'``
sets both at the same time.
"""
pass
-20
View File
@@ -1,20 +0,0 @@
# SPDX-License-Identifier: MIT
# Copyright (c) 2020-2021 The Pybricks Authors
from typing import Iterable, Optional, Union
from pybricks.media.ev3dev import SoundFile
class Speaker:
def beep(self, frequency: int = 500, duration: int = 100) -> None: ...
def play_notes(self, notes: Iterable[str], tempo: int = 120) -> None: ...
def play_file(self, file_name: Union[SoundFile, str]) -> None: ...
def say(self, text: str) -> None: ...
def set_speech_options(
self,
language: Optional[str] = None,
voice: Optional[str] = None,
speed: Optional[int] = None,
pitch: Optional[int] = None,
): ...
def set_volume(self, volume: int, which: str = "_all_") -> None: ...
+20 -32
View File
@@ -3,26 +3,30 @@
"""LEGO® MINDSTORMS® EV3 motors and sensors."""
from .parameters import Direction, Port, Color, Button
from ._common import Motor as _Motor
from typing import Optional, Tuple, List
from . import _common
from .parameters import (
Button as _Button,
Color as _Color,
Direction as _Direction,
Port as _Port,
)
class Motor(_Motor):
pass
class Motor(_common.Motor):
"""LEGO® MINDSTORMS® EV3 Motor."""
class TouchSensor:
"""LEGO® MINDSTORMS® EV3 Touch Sensor."""
def __init__(self, port: Port):
def __init__(self, port: _Port):
"""TouchSensor(port)
Arguments:
port (Port): Port to which the sensor is connected.
"""
pass
def pressed(self) -> bool:
"""pressed() -> bool
@@ -33,21 +37,19 @@ class TouchSensor:
``True`` if the sensor is pressed, ``False`` if it is
not pressed.
"""
pass
class ColorSensor:
"""LEGO® MINDSTORMS® EV3 Color Sensor."""
def __init__(self, port: Port):
def __init__(self, port: _Port):
"""ColorSensor(port)
Arguments:
port (Port): Port to which the sensor is connected.
"""
pass
def color(self) -> Optional[Color]:
def color(self) -> Optional[_Color]:
"""color() -> Color
Measures the color of a surface.
@@ -58,7 +60,6 @@ class ColorSensor:
or ``None`` if no color is detected.
"""
pass
def ambient(self) -> int:
"""ambient() -> int: %
@@ -69,7 +70,6 @@ class ColorSensor:
Ambient light intensity, ranging from 0% (dark)
to 100% (bright).
"""
pass
def reflection(self) -> int:
"""reflection() -> int: %
@@ -81,7 +81,6 @@ class ColorSensor:
100% (high reflection).
"""
pass
def rgb(self) -> Tuple[int, int, int]:
"""rgb() -> Tuple[int, int, int]
@@ -93,20 +92,18 @@ class ColorSensor:
Tuple of reflections for red, green, and blue light, each
ranging from 0.0% (no reflection) to 100.0% (high reflection).
"""
pass
class InfraredSensor:
"""LEGO® MINDSTORMS® EV3 Infrared Sensor and Beacon."""
def __init__(self, port: Port):
def __init__(self, port: _Port):
"""InfraredSensor(port)
Arguments:
port (Port): Port to which the sensor is connected.
"""
pass
def distance(self) -> int:
"""distance() -> int: %
@@ -119,7 +116,6 @@ class InfraredSensor:
to 100% (farthest).
"""
pass
def beacon(self, channel: int) -> Tuple[Optional[int], Optional[int]]:
"""
@@ -137,9 +133,8 @@ class InfraredSensor:
(-75 to 75 degrees) between remote and infrared sensor or
a tuple of (``None``, ``None``) if no remote is detected.
"""
pass
def buttons(self, channel: int) -> List[Button]:
def buttons(self, channel: int) -> List[_Button]:
"""buttons(channel) -> List[Button]
Checks which buttons on the infrared remote are pressed.
@@ -154,9 +149,8 @@ class InfraredSensor:
List of pressed buttons on the remote on the selected channel.
"""
pass
def keypad(self) -> List[Button]:
def keypad(self) -> List[_Button]:
"""keypad() -> List[Button]
Checks which buttons on the infrared remote are pressed.
@@ -169,13 +163,14 @@ class InfraredSensor:
Returns:
List of pressed buttons.
"""
pass
class GyroSensor:
"""LEGO® MINDSTORMS® EV3 Gyro Sensor."""
def __init__(self, port: Port, positive_direction: Direction = Direction.CLOCKWISE):
def __init__(
self, port: _Port, positive_direction: _Direction = _Direction.CLOCKWISE
):
"""GyroSensor(port)
Arguments:
@@ -185,7 +180,6 @@ class GyroSensor:
of the sensor.
"""
pass
def speed(self) -> int:
"""speed() -> int: deg/s
@@ -196,7 +190,6 @@ class GyroSensor:
Angular velocity.
"""
pass
def angle(self) -> int:
"""angle() -> int: deg
@@ -207,7 +200,6 @@ class GyroSensor:
Rotation angle.
"""
pass
def reset_angle(self, angle: int) -> None:
"""reset_angle(angle)
@@ -217,20 +209,18 @@ class GyroSensor:
Arguments:
angle (Number, deg): Value to which the angle should be reset.
"""
pass
class UltrasonicSensor:
"""LEGO® MINDSTORMS® EV3 Ultrasonic Sensor."""
def __init__(self, port: Port):
def __init__(self, port: _Port):
"""UltrasonicSensor(port)
Arguments:
port (Port): Port to which the sensor is connected.
"""
pass
def distance(self, silent: bool = False) -> int:
"""distance(silent=False) -> int: mm
@@ -249,7 +239,6 @@ class UltrasonicSensor:
Measured distance.
"""
pass
def presence(self) -> bool:
"""presence() -> bool
@@ -265,4 +254,3 @@ class UltrasonicSensor:
``True`` if ultrasonic sounds are detected,
``False`` if not.
"""
pass
+24 -8
View File
@@ -5,7 +5,7 @@
from __future__ import annotations
from typing import Tuple, Collection, overload
from typing import Sequence, Tuple, overload
class Matrix:
@@ -51,7 +51,7 @@ class Matrix:
def __ifloordiv__(self, other) -> Matrix:
...
def __init__(self, rows: Collection[Collection[int]]):
def __init__(self, rows: Sequence[Sequence[float]]):
"""Matrix(rows)
Arguments:
@@ -60,27 +60,44 @@ class Matrix:
"""
@property
def T(self) -> Matrix:
def T(self) -> Matrix: # noqa: N802
"""Returns a new :class:`.Matrix` that is the transpose of the
original."""
pass
@property
def shape(self) -> Tuple[int, int]:
"""Returns a tuple (``m``, ``n``),
where ``m`` is the number of rows and ``n`` is the number of columns.
"""
pass
@overload
def vector(x: float, y: float) -> Matrix:
...
"""
Convenience function to create a :class:`.Matrix` with the shape (``2``, ``1``).
Arguments:
x (float): x-coordinate of the vector.
y (float): y-coordinate of the vector.
Returns:
A matrix with the shape of a column vector.
"""
@overload
def vector(x: float, y: float, z: float) -> Matrix:
...
"""
Convenience function to create a :class:`.Matrix` with the shape (``3``, ``1``).
Arguments:
x (float): x-coordinate of the vector.
y (float): y-coordinate of the vector.
z (float): z-coordinate of the vector.
Returns:
A matrix with the shape of a column vector.
"""
def vector(*args):
@@ -99,7 +116,6 @@ def vector(*args):
Returns:
A matrix with the shape of a column vector.
"""
pass
class Axis:
+70 -51
View File
@@ -1,20 +1,10 @@
# SPDX-License-Identifier: MIT
# Copyright (c) 2018-2020 The Pybricks Authors
# Copyright (c) 2018-2022 The Pybricks Authors
"""LEGO® Programmable Hubs."""
from ._common import (
Speaker as _Speaker,
Battery as _Battery,
ColorLight as _ColorLight,
Keypad as _Keypad,
LightMatrix as _LightMatrix,
IMU as _IMU,
Charger as _Charger,
System as _System,
SimpleAccelerometer as _SimpleAccelerometer,
)
from .ev3dev._speaker import Speaker as _EV3Speaker
from .geometry import Axis as _Axis
from . import _common
from .ev3dev import _speaker
from .geometry import Axis
from .media.ev3dev import Image as _Image
from .parameters import Button as _Button
@@ -24,19 +14,19 @@ class EV3Brick:
# These class attributes are here for auto-documentation only.
# In reality, they are instance attributes created by __init__.
buttons = _Keypad(
(
buttons = _common.Keypad(
[
_Button.LEFT,
_Button.RIGHT,
_Button.CENTER,
_Button.UP,
_Button.DOWN,
)
]
)
screen = _Image("_screen_")
speaker = _EV3Speaker()
battery = _Battery()
light = _ColorLight()
speaker = _speaker.Speaker()
battery = _common.Battery()
light = _common.ColorLight()
class MoveHub:
@@ -44,11 +34,11 @@ class MoveHub:
# These class attributes are here for auto-documentation only.
# In reality, they are instance attributes created by __init__.
battery = _Battery()
light = _ColorLight()
imu = _SimpleAccelerometer()
system = _System()
button = _Keypad((_Button.CENTER,))
battery = _common.Battery()
light = _common.ColorLight()
imu = _common.SimpleAccelerometer()
system = _common.System()
button = _common.Keypad([_Button.CENTER])
class CityHub:
@@ -56,10 +46,10 @@ class CityHub:
# These class attributes are here for auto-documentation only.
# In reality, they are instance attributes created by __init__.
battery = _Battery()
light = _ColorLight()
system = _System()
button = _Keypad((_Button.CENTER,))
battery = _common.Battery()
light = _common.ColorLight()
system = _common.System()
button = _common.Keypad([_Button.CENTER])
class TechnicHub:
@@ -67,14 +57,14 @@ class TechnicHub:
# These class attributes are here for auto-documentation only.
# In reality, they are instance attributes created by __init__.
battery = _Battery()
light = _ColorLight()
imu = _IMU()
system = _System()
button = _Keypad((_Button.CENTER,))
battery = _common.Battery()
light = _common.ColorLight()
imu = _common.IMU()
system = _common.System()
button = _common.Keypad([_Button.CENTER])
def __init__(self, top_side=_Axis.Z, front_side=_Axis.X):
"""__init__(top_side=Axis.Z, front_side=Axis.X)
def __init__(self, top_side: Axis = Axis.Z, front_side: Axis = Axis.X):
"""TechnicHub(top_side=Axis.Z, front_side=Axis.X)
Initializes the hub. Optionally, specify how the hub is
:ref:`placed in your design <robotframe>` by saying in which
@@ -87,32 +77,60 @@ class TechnicHub:
front_side (Axis): The axis that passes through the *front side* of
the hub.
"""
class EssentialHub:
"""LEGO® SPIKE Essential Hub."""
# These class attributes are here for auto-documentation only.
# In reality, they are instance attributes created by __init__.
battery = _common.Battery()
button = _common.Keypad([_Button.CENTER])
charger = _common.Charger()
light = _common.ColorLight()
imu = _common.IMU()
system = _common.System()
def __init__(self, top_side=Axis.Z, front_side=Axis.X):
"""__init__(top_side=Axis.Z, front_side=Axis.X)
Initializes the hub. Optionally, specify how the hub is
:ref:`placed in your design <robotframe>` by saying in which
direction the top side (with the button) and the front side (with the USB
port, and I/O ports A and B) are pointing.
Arguments:
top_side (Axis): The axis that passes through the *top side* of
the hub.
front_side (Axis): The axis that passes through the *front side* of
the hub.
"""
pass
class PrimeHub:
"""LEGO® SPIKE Prime Hub or LEGO® MINDSTORMS Inventor Hub."""
"""LEGO® SPIKE Prime Hub."""
# These class attributes are here for auto-documentation only.
# In reality, they are instance attributes created by __init__.
battery = _Battery()
buttons = _Keypad(
(
battery = _common.Battery()
buttons = _common.Keypad(
[
_Button.LEFT,
_Button.RIGHT,
_Button.CENTER,
_Button.BLUETOOTH,
)
]
)
charger = _Charger()
light = _ColorLight()
display = _LightMatrix(5, 5)
speaker = _Speaker()
imu = _IMU()
system = _System()
charger = _common.Charger()
light = _common.ColorLight()
display = _common.LightMatrix(5, 5)
speaker = _common.Speaker()
imu = _common.IMU()
system = _common.System()
def __init__(self, top_side=_Axis.Z, front_side=_Axis.X):
"""__init__(top_side=Axis.Z, front_side=Axis.X)
def __init__(self, top_side: Axis = Axis.Z, front_side: Axis = Axis.X):
"""PrimeHub(top_side=Axis.Z, front_side=Axis.X)
Initializes the hub. Optionally, specify how the hub is
:ref:`placed in your design <robotframe>` by saying in which
@@ -125,10 +143,11 @@ class PrimeHub:
front_side (Axis): The axis that passes through the *front side* of
the hub.
"""
pass
class InventorHub(PrimeHub):
"""LEGO® MINDSTORMS Inventor Hub."""
pass
# HACK: hide from jedi
del Axis

Some files were not shown because too many files have changed in this diff Show More