commit b5a30adb2749c452313a4109054b8eb6d71f46ff Author: tiijay Date: Sun Oct 19 18:29:10 2025 +0200 first save diff --git a/.venv/bin/Activate.ps1 b/.venv/bin/Activate.ps1 new file mode 100644 index 0000000..b49d77b --- /dev/null +++ b/.venv/bin/Activate.ps1 @@ -0,0 +1,247 @@ +<# +.Synopsis +Activate a Python virtual environment for the current PowerShell session. + +.Description +Pushes the python executable for a virtual environment to the front of the +$Env:PATH environment variable and sets the prompt to signify that you are +in a Python virtual environment. Makes use of the command line switches as +well as the `pyvenv.cfg` file values present in the virtual environment. + +.Parameter VenvDir +Path to the directory that contains the virtual environment to activate. The +default value for this is the parent of the directory that the Activate.ps1 +script is located within. + +.Parameter Prompt +The prompt prefix to display when this virtual environment is activated. By +default, this prompt is the name of the virtual environment folder (VenvDir) +surrounded by parentheses and followed by a single space (ie. '(.venv) '). + +.Example +Activate.ps1 +Activates the Python virtual environment that contains the Activate.ps1 script. + +.Example +Activate.ps1 -Verbose +Activates the Python virtual environment that contains the Activate.ps1 script, +and shows extra information about the activation as it executes. + +.Example +Activate.ps1 -VenvDir C:\Users\MyUser\Common\.venv +Activates the Python virtual environment located in the specified location. + +.Example +Activate.ps1 -Prompt "MyPython" +Activates the Python virtual environment that contains the Activate.ps1 script, +and prefixes the current prompt with the specified string (surrounded in +parentheses) while the virtual environment is active. + +.Notes +On Windows, it may be required to enable this Activate.ps1 script by setting the +execution policy for the user. You can do this by issuing the following PowerShell +command: + +PS C:\> Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser + +For more information on Execution Policies: +https://go.microsoft.com/fwlink/?LinkID=135170 + +#> +Param( + [Parameter(Mandatory = $false)] + [String] + $VenvDir, + [Parameter(Mandatory = $false)] + [String] + $Prompt +) + +<# Function declarations --------------------------------------------------- #> + +<# +.Synopsis +Remove all shell session elements added by the Activate script, including the +addition of the virtual environment's Python executable from the beginning of +the PATH variable. + +.Parameter NonDestructive +If present, do not remove this function from the global namespace for the +session. + +#> +function global:deactivate ([switch]$NonDestructive) { + # Revert to original values + + # The prior prompt: + if (Test-Path -Path Function:_OLD_VIRTUAL_PROMPT) { + Copy-Item -Path Function:_OLD_VIRTUAL_PROMPT -Destination Function:prompt + Remove-Item -Path Function:_OLD_VIRTUAL_PROMPT + } + + # The prior PYTHONHOME: + if (Test-Path -Path Env:_OLD_VIRTUAL_PYTHONHOME) { + Copy-Item -Path Env:_OLD_VIRTUAL_PYTHONHOME -Destination Env:PYTHONHOME + Remove-Item -Path Env:_OLD_VIRTUAL_PYTHONHOME + } + + # The prior PATH: + if (Test-Path -Path Env:_OLD_VIRTUAL_PATH) { + Copy-Item -Path Env:_OLD_VIRTUAL_PATH -Destination Env:PATH + Remove-Item -Path Env:_OLD_VIRTUAL_PATH + } + + # Just remove the VIRTUAL_ENV altogether: + if (Test-Path -Path Env:VIRTUAL_ENV) { + Remove-Item -Path env:VIRTUAL_ENV + } + + # Just remove VIRTUAL_ENV_PROMPT altogether. + if (Test-Path -Path Env:VIRTUAL_ENV_PROMPT) { + Remove-Item -Path env:VIRTUAL_ENV_PROMPT + } + + # Just remove the _PYTHON_VENV_PROMPT_PREFIX altogether: + if (Get-Variable -Name "_PYTHON_VENV_PROMPT_PREFIX" -ErrorAction SilentlyContinue) { + Remove-Variable -Name _PYTHON_VENV_PROMPT_PREFIX -Scope Global -Force + } + + # Leave deactivate function in the global namespace if requested: + if (-not $NonDestructive) { + Remove-Item -Path function:deactivate + } +} + +<# +.Description +Get-PyVenvConfig parses the values from the pyvenv.cfg file located in the +given folder, and returns them in a map. + +For each line in the pyvenv.cfg file, if that line can be parsed into exactly +two strings separated by `=` (with any amount of whitespace surrounding the =) +then it is considered a `key = value` line. The left hand string is the key, +the right hand is the value. + +If the value starts with a `'` or a `"` then the first and last character is +stripped from the value before being captured. + +.Parameter ConfigDir +Path to the directory that contains the `pyvenv.cfg` file. +#> +function Get-PyVenvConfig( + [String] + $ConfigDir +) { + Write-Verbose "Given ConfigDir=$ConfigDir, obtain values in pyvenv.cfg" + + # Ensure the file exists, and issue a warning if it doesn't (but still allow the function to continue). + $pyvenvConfigPath = Join-Path -Resolve -Path $ConfigDir -ChildPath 'pyvenv.cfg' -ErrorAction Continue + + # An empty map will be returned if no config file is found. + $pyvenvConfig = @{ } + + if ($pyvenvConfigPath) { + + Write-Verbose "File exists, parse `key = value` lines" + $pyvenvConfigContent = Get-Content -Path $pyvenvConfigPath + + $pyvenvConfigContent | ForEach-Object { + $keyval = $PSItem -split "\s*=\s*", 2 + if ($keyval[0] -and $keyval[1]) { + $val = $keyval[1] + + # Remove extraneous quotations around a string value. + if ("'""".Contains($val.Substring(0, 1))) { + $val = $val.Substring(1, $val.Length - 2) + } + + $pyvenvConfig[$keyval[0]] = $val + Write-Verbose "Adding Key: '$($keyval[0])'='$val'" + } + } + } + return $pyvenvConfig +} + + +<# Begin Activate script --------------------------------------------------- #> + +# Determine the containing directory of this script +$VenvExecPath = Split-Path -Parent $MyInvocation.MyCommand.Definition +$VenvExecDir = Get-Item -Path $VenvExecPath + +Write-Verbose "Activation script is located in path: '$VenvExecPath'" +Write-Verbose "VenvExecDir Fullname: '$($VenvExecDir.FullName)" +Write-Verbose "VenvExecDir Name: '$($VenvExecDir.Name)" + +# Set values required in priority: CmdLine, ConfigFile, Default +# First, get the location of the virtual environment, it might not be +# VenvExecDir if specified on the command line. +if ($VenvDir) { + Write-Verbose "VenvDir given as parameter, using '$VenvDir' to determine values" +} +else { + Write-Verbose "VenvDir not given as a parameter, using parent directory name as VenvDir." + $VenvDir = $VenvExecDir.Parent.FullName.TrimEnd("\\/") + Write-Verbose "VenvDir=$VenvDir" +} + +# Next, read the `pyvenv.cfg` file to determine any required value such +# as `prompt`. +$pyvenvCfg = Get-PyVenvConfig -ConfigDir $VenvDir + +# Next, set the prompt from the command line, or the config file, or +# just use the name of the virtual environment folder. +if ($Prompt) { + Write-Verbose "Prompt specified as argument, using '$Prompt'" +} +else { + Write-Verbose "Prompt not specified as argument to script, checking pyvenv.cfg value" + if ($pyvenvCfg -and $pyvenvCfg['prompt']) { + Write-Verbose " Setting based on value in pyvenv.cfg='$($pyvenvCfg['prompt'])'" + $Prompt = $pyvenvCfg['prompt']; + } + else { + Write-Verbose " Setting prompt based on parent's directory's name. (Is the directory name passed to venv module when creating the virtual environment)" + Write-Verbose " Got leaf-name of $VenvDir='$(Split-Path -Path $venvDir -Leaf)'" + $Prompt = Split-Path -Path $venvDir -Leaf + } +} + +Write-Verbose "Prompt = '$Prompt'" +Write-Verbose "VenvDir='$VenvDir'" + +# Deactivate any currently active virtual environment, but leave the +# deactivate function in place. +deactivate -nondestructive + +# Now set the environment variable VIRTUAL_ENV, used by many tools to determine +# that there is an activated venv. +$env:VIRTUAL_ENV = $VenvDir + +if (-not $Env:VIRTUAL_ENV_DISABLE_PROMPT) { + + Write-Verbose "Setting prompt to '$Prompt'" + + # Set the prompt to include the env name + # Make sure _OLD_VIRTUAL_PROMPT is global + function global:_OLD_VIRTUAL_PROMPT { "" } + Copy-Item -Path function:prompt -Destination function:_OLD_VIRTUAL_PROMPT + New-Variable -Name _PYTHON_VENV_PROMPT_PREFIX -Description "Python virtual environment prompt prefix" -Scope Global -Option ReadOnly -Visibility Public -Value $Prompt + + function global:prompt { + Write-Host -NoNewline -ForegroundColor Green "($_PYTHON_VENV_PROMPT_PREFIX) " + _OLD_VIRTUAL_PROMPT + } + $env:VIRTUAL_ENV_PROMPT = $Prompt +} + +# Clear PYTHONHOME +if (Test-Path -Path Env:PYTHONHOME) { + Copy-Item -Path Env:PYTHONHOME -Destination Env:_OLD_VIRTUAL_PYTHONHOME + Remove-Item -Path Env:PYTHONHOME +} + +# Add the venv to the PATH +Copy-Item -Path Env:PATH -Destination Env:_OLD_VIRTUAL_PATH +$Env:PATH = "$VenvExecDir$([System.IO.Path]::PathSeparator)$Env:PATH" diff --git a/.venv/bin/activate b/.venv/bin/activate new file mode 100644 index 0000000..a0ce031 --- /dev/null +++ b/.venv/bin/activate @@ -0,0 +1,70 @@ +# This file must be used with "source bin/activate" *from bash* +# You cannot run it directly + +deactivate () { + # reset old environment variables + if [ -n "${_OLD_VIRTUAL_PATH:-}" ] ; then + PATH="${_OLD_VIRTUAL_PATH:-}" + export PATH + unset _OLD_VIRTUAL_PATH + fi + if [ -n "${_OLD_VIRTUAL_PYTHONHOME:-}" ] ; then + PYTHONHOME="${_OLD_VIRTUAL_PYTHONHOME:-}" + export PYTHONHOME + unset _OLD_VIRTUAL_PYTHONHOME + fi + + # Call hash to forget past commands. Without forgetting + # past commands the $PATH changes we made may not be respected + hash -r 2> /dev/null + + if [ -n "${_OLD_VIRTUAL_PS1:-}" ] ; then + PS1="${_OLD_VIRTUAL_PS1:-}" + export PS1 + unset _OLD_VIRTUAL_PS1 + fi + + unset VIRTUAL_ENV + unset VIRTUAL_ENV_PROMPT + if [ ! "${1:-}" = "nondestructive" ] ; then + # Self destruct! + unset -f deactivate + fi +} + +# unset irrelevant variables +deactivate nondestructive + +# on Windows, a path can contain colons and backslashes and has to be converted: +if [ "${OSTYPE:-}" = "cygwin" ] || [ "${OSTYPE:-}" = "msys" ] ; then + # transform D:\path\to\venv to /d/path/to/venv on MSYS + # and to /cygdrive/d/path/to/venv on Cygwin + export VIRTUAL_ENV=$(cygpath /home/tiijay/Development/Microcontroller/rapsberry_pico/micropython/weather-info/.venv) +else + # use the path as-is + export VIRTUAL_ENV=/home/tiijay/Development/Microcontroller/rapsberry_pico/micropython/weather-info/.venv +fi + +_OLD_VIRTUAL_PATH="$PATH" +PATH="$VIRTUAL_ENV/"bin":$PATH" +export PATH + +# unset PYTHONHOME if set +# this will fail if PYTHONHOME is set to the empty string (which is bad anyway) +# could use `if (set -u; : $PYTHONHOME) ;` in bash +if [ -n "${PYTHONHOME:-}" ] ; then + _OLD_VIRTUAL_PYTHONHOME="${PYTHONHOME:-}" + unset PYTHONHOME +fi + +if [ -z "${VIRTUAL_ENV_DISABLE_PROMPT:-}" ] ; then + _OLD_VIRTUAL_PS1="${PS1:-}" + PS1='(.venv) '"${PS1:-}" + export PS1 + VIRTUAL_ENV_PROMPT='(.venv) ' + export VIRTUAL_ENV_PROMPT +fi + +# Call hash to forget past commands. Without forgetting +# past commands the $PATH changes we made may not be respected +hash -r 2> /dev/null diff --git a/.venv/bin/activate.csh b/.venv/bin/activate.csh new file mode 100644 index 0000000..28bb4a7 --- /dev/null +++ b/.venv/bin/activate.csh @@ -0,0 +1,27 @@ +# This file must be used with "source bin/activate.csh" *from csh*. +# You cannot run it directly. + +# Created by Davide Di Blasi . +# Ported to Python 3.3 venv by Andrew Svetlov + +alias deactivate 'test $?_OLD_VIRTUAL_PATH != 0 && setenv PATH "$_OLD_VIRTUAL_PATH" && unset _OLD_VIRTUAL_PATH; rehash; test $?_OLD_VIRTUAL_PROMPT != 0 && set prompt="$_OLD_VIRTUAL_PROMPT" && unset _OLD_VIRTUAL_PROMPT; unsetenv VIRTUAL_ENV; unsetenv VIRTUAL_ENV_PROMPT; test "\!:*" != "nondestructive" && unalias deactivate' + +# Unset irrelevant variables. +deactivate nondestructive + +setenv VIRTUAL_ENV /home/tiijay/Development/Microcontroller/rapsberry_pico/micropython/weather-info/.venv + +set _OLD_VIRTUAL_PATH="$PATH" +setenv PATH "$VIRTUAL_ENV/"bin":$PATH" + + +set _OLD_VIRTUAL_PROMPT="$prompt" + +if (! "$?VIRTUAL_ENV_DISABLE_PROMPT") then + set prompt = '(.venv) '"$prompt" + setenv VIRTUAL_ENV_PROMPT '(.venv) ' +endif + +alias pydoc python -m pydoc + +rehash diff --git a/.venv/bin/activate.fish b/.venv/bin/activate.fish new file mode 100644 index 0000000..df5aa40 --- /dev/null +++ b/.venv/bin/activate.fish @@ -0,0 +1,69 @@ +# This file must be used with "source /bin/activate.fish" *from fish* +# (https://fishshell.com/). You cannot run it directly. + +function deactivate -d "Exit virtual environment and return to normal shell environment" + # reset old environment variables + if test -n "$_OLD_VIRTUAL_PATH" + set -gx PATH $_OLD_VIRTUAL_PATH + set -e _OLD_VIRTUAL_PATH + end + if test -n "$_OLD_VIRTUAL_PYTHONHOME" + set -gx PYTHONHOME $_OLD_VIRTUAL_PYTHONHOME + set -e _OLD_VIRTUAL_PYTHONHOME + end + + if test -n "$_OLD_FISH_PROMPT_OVERRIDE" + set -e _OLD_FISH_PROMPT_OVERRIDE + # prevents error when using nested fish instances (Issue #93858) + if functions -q _old_fish_prompt + functions -e fish_prompt + functions -c _old_fish_prompt fish_prompt + functions -e _old_fish_prompt + end + end + + set -e VIRTUAL_ENV + set -e VIRTUAL_ENV_PROMPT + if test "$argv[1]" != "nondestructive" + # Self-destruct! + functions -e deactivate + end +end + +# Unset irrelevant variables. +deactivate nondestructive + +set -gx VIRTUAL_ENV /home/tiijay/Development/Microcontroller/rapsberry_pico/micropython/weather-info/.venv + +set -gx _OLD_VIRTUAL_PATH $PATH +set -gx PATH "$VIRTUAL_ENV/"bin $PATH + +# Unset PYTHONHOME if set. +if set -q PYTHONHOME + set -gx _OLD_VIRTUAL_PYTHONHOME $PYTHONHOME + set -e PYTHONHOME +end + +if test -z "$VIRTUAL_ENV_DISABLE_PROMPT" + # fish uses a function instead of an env var to generate the prompt. + + # Save the current fish_prompt function as the function _old_fish_prompt. + functions -c fish_prompt _old_fish_prompt + + # With the original prompt function renamed, we can override with our own. + function fish_prompt + # Save the return status of the last command. + set -l old_status $status + + # Output the venv prompt; color taken from the blue of the Python logo. + printf "%s%s%s" (set_color 4B8BBE) '(.venv) ' (set_color normal) + + # Restore the return status of the previous command. + echo "exit $old_status" | . + # Output the original/"old" prompt. + _old_fish_prompt + end + + set -gx _OLD_FISH_PROMPT_OVERRIDE "$VIRTUAL_ENV" + set -gx VIRTUAL_ENV_PROMPT '(.venv) ' +end diff --git a/.venv/bin/mpremote b/.venv/bin/mpremote new file mode 100755 index 0000000..9b015cd --- /dev/null +++ b/.venv/bin/mpremote @@ -0,0 +1,8 @@ +#!/home/tiijay/Development/Microcontroller/rapsberry_pico/micropython/weather-info/.venv/bin/python3 +# -*- coding: utf-8 -*- +import re +import sys +from mpremote.main import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/.venv/bin/pip b/.venv/bin/pip new file mode 100755 index 0000000..944b610 --- /dev/null +++ b/.venv/bin/pip @@ -0,0 +1,8 @@ +#!/home/tiijay/Development/Microcontroller/rapsberry_pico/micropython/weather-info/.venv/bin/python3 +# -*- coding: utf-8 -*- +import re +import sys +from pip._internal.cli.main import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/.venv/bin/pip3 b/.venv/bin/pip3 new file mode 100755 index 0000000..944b610 --- /dev/null +++ b/.venv/bin/pip3 @@ -0,0 +1,8 @@ +#!/home/tiijay/Development/Microcontroller/rapsberry_pico/micropython/weather-info/.venv/bin/python3 +# -*- coding: utf-8 -*- +import re +import sys +from pip._internal.cli.main import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/.venv/bin/pip3.12 b/.venv/bin/pip3.12 new file mode 100755 index 0000000..944b610 --- /dev/null +++ b/.venv/bin/pip3.12 @@ -0,0 +1,8 @@ +#!/home/tiijay/Development/Microcontroller/rapsberry_pico/micropython/weather-info/.venv/bin/python3 +# -*- coding: utf-8 -*- +import re +import sys +from pip._internal.cli.main import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/.venv/bin/pyserial-miniterm b/.venv/bin/pyserial-miniterm new file mode 100755 index 0000000..e2d58fb --- /dev/null +++ b/.venv/bin/pyserial-miniterm @@ -0,0 +1,8 @@ +#!/home/tiijay/Development/Microcontroller/rapsberry_pico/micropython/weather-info/.venv/bin/python3 +# -*- coding: utf-8 -*- +import re +import sys +from serial.tools.miniterm import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/.venv/bin/pyserial-ports b/.venv/bin/pyserial-ports new file mode 100755 index 0000000..f75b918 --- /dev/null +++ b/.venv/bin/pyserial-ports @@ -0,0 +1,8 @@ +#!/home/tiijay/Development/Microcontroller/rapsberry_pico/micropython/weather-info/.venv/bin/python3 +# -*- coding: utf-8 -*- +import re +import sys +from serial.tools.list_ports import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/.venv/bin/python b/.venv/bin/python new file mode 120000 index 0000000..b8a0adb --- /dev/null +++ b/.venv/bin/python @@ -0,0 +1 @@ +python3 \ No newline at end of file diff --git a/.venv/bin/python3 b/.venv/bin/python3 new file mode 120000 index 0000000..ae65fda --- /dev/null +++ b/.venv/bin/python3 @@ -0,0 +1 @@ +/usr/bin/python3 \ No newline at end of file diff --git a/.venv/bin/python3.12 b/.venv/bin/python3.12 new file mode 120000 index 0000000..b8a0adb --- /dev/null +++ b/.venv/bin/python3.12 @@ -0,0 +1 @@ +python3 \ No newline at end of file diff --git a/.venv/lib/python3.12/site-packages/__builtins__.pyi b/.venv/lib/python3.12/site-packages/__builtins__.pyi new file mode 100644 index 0000000..60a8dc3 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/__builtins__.pyi @@ -0,0 +1,28 @@ +"""Allows for type checking of Micropython specific builtins by pyright and pylance. +""" + +from typing import Tuple, TypeVar + +Const_T = TypeVar("Const_T", int, float, str, bytes, Tuple) # constant + +def const(expr: Const_T) -> Const_T: + """ + Used to declare that the expression is a constant so that the compiler can + optimise it. The use of this function should be as follows:: + + from micropython import const + + CONST_X = const(123) + CONST_Y = const(2 * CONST_X + 1) + + Constants declared this way are still accessible as global variables from + outside the module they are declared in. On the other hand, if a constant + begins with an underscore then it is hidden, it is not available as a global + variable, and does not take up any memory during execution. + + This `const` function is recognised directly by the MicroPython parser and is + provided as part of the :mod:`micropython` module mainly so that scripts can be + written which run under both CPython and MicroPython, by following the above + pattern. + """ + ... diff --git a/.venv/lib/python3.12/site-packages/_boot.pyi b/.venv/lib/python3.12/site-packages/_boot.pyi new file mode 100644 index 0000000..75abd7c --- /dev/null +++ b/.venv/lib/python3.12/site-packages/_boot.pyi @@ -0,0 +1,4 @@ +from _typeshed import Incomplete + +bdev: Incomplete +fs: Incomplete diff --git a/.venv/lib/python3.12/site-packages/_boot_fat.pyi b/.venv/lib/python3.12/site-packages/_boot_fat.pyi new file mode 100644 index 0000000..0bd844c --- /dev/null +++ b/.venv/lib/python3.12/site-packages/_boot_fat.pyi @@ -0,0 +1,3 @@ +from _typeshed import Incomplete + +bdev: Incomplete diff --git a/.venv/lib/python3.12/site-packages/_mpy_shed/IRQs.pyi b/.venv/lib/python3.12/site-packages/_mpy_shed/IRQs.pyi new file mode 100644 index 0000000..f312564 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/_mpy_shed/IRQs.pyi @@ -0,0 +1,31 @@ +""" +IRQ object types, used in the machine, bluetooth, _rp2 and rp2 modules + +_IRQ is a union of the types _IRQ_ESP32, _IRQ_RP2 and _IRQ_PYB +to allow the same stubs to support of the different ports of MicroPython. + +""" + +from typing import Type + +from _typeshed import Incomplete +from typing_extensions import TypeAlias + +class _IRQ_ESP32: + def trigger(self) -> int: ... + # def flags(self) -> int: ... + +class _IRQ_RP2: + # rp2040 + # object is of type irq + # flags -- + # trigger -- + def flags(self) -> int: ... + def trigger(self) -> int: ... + +# pybv11 +# TODO: Not sure what the correct implementation is +# NoneType +_IRQ_PYB: TypeAlias = None + +_IRQ: TypeAlias = Type[_IRQ_ESP32] | Type[_IRQ_RP2] | Type[_IRQ_PYB] | Incomplete diff --git a/.venv/lib/python3.12/site-packages/_mpy_shed/__init__.pyi b/.venv/lib/python3.12/site-packages/_mpy_shed/__init__.pyi new file mode 100644 index 0000000..bd135c1 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/_mpy_shed/__init__.pyi @@ -0,0 +1,112 @@ +""" +MicroPython-stubs base types that are not present in typeshed. + +This is a collection of types that are not present in typeshed, but are used in the micropython stubs. + +Common cases are: +- MicroPython implementation is different from CPython, so the types are different. +- MicroPython has some types that are not present in CPython. + +""" + +from __future__ import annotations + +import abc # type: ignore - not collections.abc +import sys + +from typing import Final, final + +from _typeshed import Incomplete, structseq, AnyStr_co +from typing_extensions import TypeAlias, TypeVar + +from .subscriptable import Subscriptable as Subscriptable +from .IRQs import _IRQ +from .neopixelbase import _NeoPixelBase as _NeoPixelBase +from .blockdevice import ( + _BlockDeviceProtocol as _BlockDeviceProtocol, + _OldAbstractBlockDev, + _OldAbstractReadOnlyBlockDev, +) +from .buffer_mp import AnyReadableBuf as AnyReadableBuf, AnyWritableBuf as AnyWritableBuf + +from .io_mp import ( + BytesIO as BytesIO, + FileIO as FileIO, + IncrementalNewlineDecoder as IncrementalNewlineDecoder, + StringIO as StringIO, + TextIOWrapper as TextIOWrapper, + IOBase_mp as IOBase_mp, + _BufferedIOBase, + _IOBase, + _RawIOBase, + _TextIOBase, + open as open, +) + +from .time_mp import _TimeTuple as _TimeTuple +from .pathlike import PathLike as PathLike + +from .mp_implementation import _mp_implementation as _mp_implementation +from .mp_available import mp_available as mp_available +# ------------------ +# copied from _typeshed os.pyi as os.pyi cannot import from a module with the same name +GenericAlias = type(list[int]) + +# ------------------------------------------------------------------------------------ +StrOrBytesPath: TypeAlias = str | bytes | PathLike[str] | PathLike[bytes] +_StrOrBytesT = TypeVar("_StrOrBytesT", str, bytes) + +# ------------------------------------------------------------------------------------ +_AnyPath: TypeAlias = str | bytes | PathLike[str] | PathLike[bytes] +_FdOrAnyPath: TypeAlias = int | _AnyPath + +# ------------------------------------------------------------------------------------ +# HID_Tuple is used in multiple pyb.submodules +HID_Tuple: TypeAlias = tuple[int, int, int, int, bytes] + +# ------------------------------------------------------------------------------------ +# copied from _typeshed os.pyi as os.pyi cannot import from a module with the same nam@final +@final +class uname_result(structseq[str], tuple[str, str, str, str, str]): + if sys.version_info >= (3, 8): + __match_args__: Final = ("sysname", "nodename", "release", "version", "machine") + + @property + def sysname(self) -> str: ... + @property + def nodename(self) -> str: ... + @property + def release(self) -> str: ... + @property + def version(self) -> str: ... + @property + def machine(self) -> str: ... + +# ------------------------------------------------------------------------------------ + +########################### +# HashLib + +# manual addition to hashlib.pyi + +class _Hash(abc.ABC): + """ + Abstract base class for hashing algorithms that defines methods available in all algorithms. + """ + + def update(self, data: AnyReadableBuf, /) -> None: + """ + Feed more binary data into hash. + """ + + def digest(self) -> bytes: + """ + Return hash for all data passed through hash, as a bytes object. After this + method is called, more data cannot be fed into the hash any longer. + """ + + def hexdigest(self) -> str: + """ + This method is NOT implemented. Use ``binascii.hexlify(hash.digest())`` + to achieve a similar effect. + """ diff --git a/.venv/lib/python3.12/site-packages/_mpy_shed/__pycache__/mp_implementation.cpython-312.pyc b/.venv/lib/python3.12/site-packages/_mpy_shed/__pycache__/mp_implementation.cpython-312.pyc new file mode 100644 index 0000000..99d23ec Binary files /dev/null and b/.venv/lib/python3.12/site-packages/_mpy_shed/__pycache__/mp_implementation.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/_mpy_shed/_collections_abc.pyi b/.venv/lib/python3.12/site-packages/_mpy_shed/_collections_abc.pyi new file mode 100644 index 0000000..7a7ef09 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/_mpy_shed/_collections_abc.pyi @@ -0,0 +1,98 @@ +import sys +from abc import abstractmethod +from types import MappingProxyType +from typing import AbstractSet as Set # noqa: Y022,Y038 +from typing import AsyncGenerator as AsyncGenerator +from typing import AsyncIterable as AsyncIterable +from typing import AsyncIterator as AsyncIterator +from typing import Awaitable as Awaitable +from typing import Callable as Callable +from typing import Collection as Collection +from typing import Container as Container +from typing import Coroutine as Coroutine +from typing import Generator as Generator +from typing import Generic +from typing import Hashable as Hashable +from typing import ItemsView as ItemsView +from typing import Iterable as Iterable +from typing import Iterator as Iterator +from typing import KeysView as KeysView +from typing import Mapping as Mapping +from typing import MappingView as MappingView +from typing import MutableMapping as MutableMapping +from typing import MutableSequence as MutableSequence +from typing import MutableSet as MutableSet +from typing import Protocol +from typing import Reversible as Reversible +from typing import Sequence as Sequence +from typing import Sized as Sized +from typing import TypeVar +from typing import ValuesView as ValuesView +from typing import final, runtime_checkable + +__all__ = [ + "Awaitable", + "Coroutine", + "AsyncIterable", + "AsyncIterator", + "AsyncGenerator", + "Hashable", + "Iterable", + "Iterator", + "Generator", + "Reversible", + "Sized", + "Container", + "Callable", + "Collection", + "Set", + "MutableSet", + "Mapping", + "MutableMapping", + "MappingView", + "KeysView", + "ItemsView", + "ValuesView", + "Sequence", + "MutableSequence", +] +if sys.version_info < (3, 14): + from typing import ByteString as ByteString # noqa: Y057 + + __all__ += ["ByteString"] + +if sys.version_info >= (3, 12): + __all__ += ["Buffer"] + +_KT_co = TypeVar("_KT_co", covariant=True) # Key type covariant containers. +_VT_co = TypeVar("_VT_co", covariant=True) # Value type covariant containers. + +@final +class dict_keys(KeysView[_KT_co], Generic[_KT_co, _VT_co]): # undocumented + def __eq__(self, value: object, /) -> bool: ... + if sys.version_info >= (3, 13): + def isdisjoint(self, other: Iterable[_KT_co], /) -> bool: ... + if sys.version_info >= (3, 10): + @property + def mapping(self) -> MappingProxyType[_KT_co, _VT_co]: ... + +@final +class dict_values(ValuesView[_VT_co], Generic[_KT_co, _VT_co]): # undocumented + if sys.version_info >= (3, 10): + @property + def mapping(self) -> MappingProxyType[_KT_co, _VT_co]: ... + +@final +class dict_items(ItemsView[_KT_co, _VT_co]): # undocumented + def __eq__(self, value: object, /) -> bool: ... + if sys.version_info >= (3, 13): + def isdisjoint(self, other: Iterable[tuple[_KT_co, _VT_co]], /) -> bool: ... + if sys.version_info >= (3, 10): + @property + def mapping(self) -> MappingProxyType[_KT_co, _VT_co]: ... + +if sys.version_info >= (3, 12): + @runtime_checkable + class Buffer(Protocol): + @abstractmethod + def __buffer__(self, flags: int, /) -> memoryview: ... diff --git a/.venv/lib/python3.12/site-packages/_mpy_shed/blockdevice.pyi b/.venv/lib/python3.12/site-packages/_mpy_shed/blockdevice.pyi new file mode 100644 index 0000000..8604ddd --- /dev/null +++ b/.venv/lib/python3.12/site-packages/_mpy_shed/blockdevice.pyi @@ -0,0 +1,201 @@ +""" +The AbstractBlockDev class is a template for the design of block device classes, +MicroPython does not actually provide that class. + +In the type stubs this is implemented as a Protocol, which is a Python 3.8 feature that allows for more flexible type checking. + +It has been moved to the _mpy_shed type library for convinience, but may be relocated to the `vfs` stub module in the future. + +- vfs.*(...) +- os.AbstractBlockDev(...) +- pyb.AbstractBlockDev(...) +- pyb.Flash(...) +- (u)os.AbstractBlockDev(...) +- esp32.Partition.ioctl +https://docs.micropython.org/en/v1.24.0/reference/filesystem.html?highlight=abstractblockdev +- https://docs.micropython.org/en/v1.24.0/library/vfs.html#vfs.AbstractBlockDev +- https://docs.micropython.org/en/v1.20.0/library/os.html?highlight=abstractblockdev#block-devices +- https://docs.micropython.org/en/v1.20.0/library/pyb.html?highlight=abstractblockdev#block-devices +- https://docs.micropython.org/en/latest/library/esp32.html#esp32.Partition.ioctl +""" + +from typing import Any, Final, Literal, Protocol, Tuple, Type, final, overload, runtime_checkable + +from _typeshed import AnyStr_co, Incomplete, structseq +from typing_extensions import TypeAlias, TypeVar + +# TODO: improve the typechecking implementation if possible +_OldAbstractReadOnlyBlockDev: TypeAlias = Any +_OldAbstractBlockDev: TypeAlias = Any + +# documented as AbstractBlockDev in the vfs module documentation +@runtime_checkable +class _BlockDeviceProtocol(Protocol): + """ + Block devices + ------------- + + A block device is an object which implements the block protocol. This enables a + device to support MicroPython filesystems. The physical hardware is represented + by a user defined class. The :class:`AbstractBlockDev` class is a template for + the design of such a class: MicroPython does not actually provide that class, + but an actual block device class must implement the methods described below. + + A concrete implementation of this class will usually allow access to the + memory-like functionality of a piece of hardware (like flash memory). A block + device can be formatted to any supported filesystem and mounted using ``os`` + methods. + + See :ref:`filesystem` for example implementations of block devices using the + two variants of the block protocol described below. + + .. _block-device-interface: + + Simple and extended interface + ............................. + + There are two compatible signatures for the ``readblocks`` and ``writeblocks`` + methods (see below), in order to support a variety of use cases. A given block + device may implement one form or the other, or both at the same time. The second + form (with the offset parameter) is referred to as the "extended interface". + + Some filesystems (such as littlefs) that require more control over write + operations, for example writing to sub-block regions without erasing, may require + that the block device supports the extended interface. + """ + + def __init__(self) -> None: + """ + Construct a block device object. The parameters to the constructor are + dependent on the specific block device. + """ + + @overload + def readblocks(self, block_num: int, buf: bytearray, /) -> bool: + """ + The first form reads aligned, multiples of blocks. + Starting at the block given by the index *block_num*, read blocks from + the device into *buf* (an array of bytes). + The number of blocks to read is given by the length of *buf*, + which will be a multiple of the block size. + """ + + @overload + def readblocks(self, block_num: int, buf: bytearray, offset: int, /) -> bool: + """ + The second form allows reading at arbitrary locations within a block, + and arbitrary lengths. + Starting at block index *block_num*, and byte offset within that block + of *offset*, read bytes from the device into *buf* (an array of bytes). + The number of bytes to read is given by the length of *buf*. + """ + + @overload + def writeblocks(self, block_num: int, buf: bytes | bytearray, /) -> None: + """ + The first form writes aligned, multiples of blocks, and requires that the + blocks that are written to be first erased (if necessary) by this method. + Starting at the block given by the index *block_num*, write blocks from + *buf* (an array of bytes) to the device. + The number of blocks to write is given by the length of *buf*, + which will be a multiple of the block size. + + The second form allows writing at arbitrary locations within a block, + and arbitrary lengths. Only the bytes being written should be changed, + and the caller of this method must ensure that the relevant blocks are + erased via a prior ``ioctl`` call. + Starting at block index *block_num*, and byte offset within that block + of *offset*, write bytes from *buf* (an array of bytes) to the device. + The number of bytes to write is given by the length of *buf*. + + Note that implementations must never implicitly erase blocks if the offset + argument is specified, even if it is zero. + """ + + @overload + def writeblocks(self, block_num: int, buf: bytes | bytearray, offset: int, /) -> None: + """ + The first form writes aligned, multiples of blocks, and requires that the + blocks that are written to be first erased (if necessary) by this method. + Starting at the block given by the index *block_num*, write blocks from + *buf* (an array of bytes) to the device. + The number of blocks to write is given by the length of *buf*, + which will be a multiple of the block size. + + The second form allows writing at arbitrary locations within a block, + and arbitrary lengths. Only the bytes being written should be changed, + and the caller of this method must ensure that the relevant blocks are + erased via a prior ``ioctl`` call. + Starting at block index *block_num*, and byte offset within that block + of *offset*, write bytes from *buf* (an array of bytes) to the device. + The number of bytes to write is given by the length of *buf*. + + Note that implementations must never implicitly erase blocks if the offset + argument is specified, even if it is zero. + """ + + @overload + def ioctl(self, op: Literal[4, 5], arg: int) -> int: + """ + Control the block device and query its parameters. The operation to + perform is given by *op* which is one of the following integers: + + - 1 -- initialise the device (*arg* is unused) + - 2 -- shutdown the device (*arg* is unused) + - 3 -- sync the device (*arg* is unused) + - 4 -- get a count of the number of blocks, should return an integer + (*arg* is unused) + - 5 -- get the number of bytes in a block, should return an integer, + or ``None`` in which case the default value of 512 is used + (*arg* is unused) + - 6 -- erase a block, *arg* is the block number to erase + + As a minimum ``ioctl(4, ...)`` must be intercepted; for littlefs + ``ioctl(6, ...)`` must also be intercepted. The need for others is + hardware dependent. + + Prior to any call to ``writeblocks(block, ...)`` littlefs issues + ``ioctl(6, block)``. This enables a device driver to erase the block + prior to a write if the hardware requires it. Alternatively a driver + might intercept ``ioctl(6, block)`` and return 0 (success). In this case + the driver assumes responsibility for detecting the need for erasure. + + Unless otherwise stated ``ioctl(op, arg)`` can return ``None``. + Consequently an implementation can ignore unused values of ``op``. Where + ``op`` is intercepted, the return value for operations 4 and 5 are as + detailed above. Other operations should return 0 on success and non-zero + for failure, with the value returned being an ``OSError`` errno code. + """ + + @overload + def ioctl(self, op: Literal[1, 2, 3, 6], arg: int) -> int | None: + """ + Control the block device and query its parameters. The operation to + perform is given by *op* which is one of the following integers: + + - 1 -- initialise the device (*arg* is unused) + - 2 -- shutdown the device (*arg* is unused) + - 3 -- sync the device (*arg* is unused) + - 4 -- get a count of the number of blocks, should return an integer + (*arg* is unused) + - 5 -- get the number of bytes in a block, should return an integer, + or ``None`` in which case the default value of 512 is used + (*arg* is unused) + - 6 -- erase a block, *arg* is the block number to erase + + As a minimum ``ioctl(4, ...)`` must be intercepted; for littlefs + ``ioctl(6, ...)`` must also be intercepted. The need for others is + hardware dependent. + + Prior to any call to ``writeblocks(block, ...)`` littlefs issues + ``ioctl(6, block)``. This enables a device driver to erase the block + prior to a write if the hardware requires it. Alternatively a driver + might intercept ``ioctl(6, block)`` and return 0 (success). In this case + the driver assumes responsibility for detecting the need for erasure. + + Unless otherwise stated ``ioctl(op, arg)`` can return ``None``. + Consequently an implementation can ignore unused values of ``op``. Where + ``op`` is intercepted, the return value for operations 4 and 5 are as + detailed above. Other operations should return 0 on success and non-zero + for failure, with the value returned being an ``OSError`` errno code. + """ diff --git a/.venv/lib/python3.12/site-packages/_mpy_shed/buffer_mp.pyi b/.venv/lib/python3.12/site-packages/_mpy_shed/buffer_mp.pyi new file mode 100644 index 0000000..3ca190a --- /dev/null +++ b/.venv/lib/python3.12/site-packages/_mpy_shed/buffer_mp.pyi @@ -0,0 +1,8 @@ +from _typeshed import Incomplete, structseq, AnyStr_co +from typing_extensions import TypeAlias, TypeVar +from array import array + +# ------------------------------------------------------------------------------------ +# TODO: need some to allow string to be passed in : uart_1.write("hello") +AnyReadableBuf: TypeAlias = bytearray | array | memoryview | bytes | Incomplete +AnyWritableBuf: TypeAlias = bytearray | array | memoryview | Incomplete diff --git a/.venv/lib/python3.12/site-packages/_mpy_shed/collections/__init__.pyi b/.venv/lib/python3.12/site-packages/_mpy_shed/collections/__init__.pyi new file mode 100644 index 0000000..2d3196f --- /dev/null +++ b/.venv/lib/python3.12/site-packages/_mpy_shed/collections/__init__.pyi @@ -0,0 +1,553 @@ +import sys +from typing import Any, Generic, NoReturn, SupportsIndex, TypeVar, final, overload + +from _collections_abc import dict_items, dict_keys, dict_values +from _typeshed import ( + SupportsItems, + SupportsKeysAndGetItem, + SupportsRichComparison, + SupportsRichComparisonT, +) +from typing_extensions import Self + +if sys.version_info >= (3, 9): + # from types import GenericAlias + from _mpy_shed import GenericAlias + +if sys.version_info >= (3, 10): + from collections.abc import ( + Callable, + ItemsView, + Iterable, + Iterator, + KeysView, + Mapping, + MutableMapping, + MutableSequence, + Sequence, + ValuesView, + ) +else: + from _collections_abc import * + +__all__ = [ + "ChainMap", + "Counter", + "OrderedDict", + "UserDict", + "UserList", + "UserString", + "defaultdict", + "deque", + "namedtuple", +] + +_S = TypeVar("_S") +_T = TypeVar("_T") +_T1 = TypeVar("_T1") +_T2 = TypeVar("_T2") +_KT = TypeVar("_KT") +_VT = TypeVar("_VT") +_KT_co = TypeVar("_KT_co", covariant=True) +_VT_co = TypeVar("_VT_co", covariant=True) + +# namedtuple is special-cased in the type checker; the initializer is ignored. +def namedtuple( + typename: str, + field_names: str | Iterable[str], + *, + rename: bool = False, + module: str | None = None, + defaults: Iterable[Any] | None = None, +) -> type[tuple[Any, ...]]: ... + +class UserDict(MutableMapping[_KT, _VT]): + data: dict[_KT, _VT] + # __init__ should be kept roughly in line with `dict.__init__`, which has the same semantics + @overload + def __init__(self, dict: None = None, /) -> None: ... + @overload + def __init__( + self: UserDict[str, _VT], # pyright: ignore[reportInvalidTypeVarUse] #11780 + dict: None = None, + /, + **kwargs: _VT, # pyright: ignore[reportInvalidTypeVarUse] #11780 + ) -> None: ... + @overload + def __init__(self, dict: SupportsKeysAndGetItem[_KT, _VT], /) -> None: ... + @overload + def __init__( + self: UserDict[str, _VT], # pyright: ignore[reportInvalidTypeVarUse] #11780 + dict: SupportsKeysAndGetItem[str, _VT], + /, + **kwargs: _VT, + ) -> None: ... + @overload + def __init__(self, iterable: Iterable[tuple[_KT, _VT]], /) -> None: ... + @overload + def __init__( + self: UserDict[str, _VT], # pyright: ignore[reportInvalidTypeVarUse] #11780 + iterable: Iterable[tuple[str, _VT]], + /, + **kwargs: _VT, + ) -> None: ... + @overload + def __init__(self: UserDict[str, str], iterable: Iterable[list[str]], /) -> None: ... + @overload + def __init__(self: UserDict[bytes, bytes], iterable: Iterable[list[bytes]], /) -> None: ... + def __len__(self) -> int: ... + def __getitem__(self, key: _KT) -> _VT: ... + def __setitem__(self, key: _KT, item: _VT) -> None: ... + def __delitem__(self, key: _KT) -> None: ... + def __iter__(self) -> Iterator[_KT]: ... + def __contains__(self, key: object) -> bool: ... + def copy(self) -> Self: ... + def __copy__(self) -> Self: ... + + # `UserDict.fromkeys` has the same semantics as `dict.fromkeys`, so should be kept in line with `dict.fromkeys`. + # TODO: Much like `dict.fromkeys`, the true signature of `UserDict.fromkeys` is inexpressible in the current type system. + # See #3800 & https://github.com/python/typing/issues/548#issuecomment-683336963. + @classmethod + @overload + def fromkeys(cls, iterable: Iterable[_T], value: None = None) -> UserDict[_T, Any | None]: ... + @classmethod + @overload + def fromkeys(cls, iterable: Iterable[_T], value: _S) -> UserDict[_T, _S]: ... + if sys.version_info >= (3, 9): + @overload + def __or__(self, other: UserDict[_KT, _VT] | dict[_KT, _VT]) -> Self: ... + @overload + def __or__( + self, other: UserDict[_T1, _T2] | dict[_T1, _T2] + ) -> UserDict[_KT | _T1, _VT | _T2]: ... + @overload + def __ror__(self, other: UserDict[_KT, _VT] | dict[_KT, _VT]) -> Self: ... + @overload + def __ror__( + self, other: UserDict[_T1, _T2] | dict[_T1, _T2] + ) -> UserDict[_KT | _T1, _VT | _T2]: ... + # UserDict.__ior__ should be kept roughly in line with MutableMapping.update() + @overload # type: ignore[misc] + def __ior__(self, other: SupportsKeysAndGetItem[_KT, _VT]) -> Self: ... + @overload + def __ior__(self, other: Iterable[tuple[_KT, _VT]]) -> Self: ... + if sys.version_info >= (3, 12): + @overload + def get(self, key: _KT, default: None = None) -> _VT | None: ... + @overload + def get(self, key: _KT, default: _T) -> _VT | _T: ... + +class UserList(MutableSequence[_T]): + data: list[_T] + @overload + def __init__(self, initlist: None = None) -> None: ... + @overload + def __init__(self, initlist: Iterable[_T]) -> None: ... + def __lt__(self, other: list[_T] | UserList[_T]) -> bool: ... + def __le__(self, other: list[_T] | UserList[_T]) -> bool: ... + def __gt__(self, other: list[_T] | UserList[_T]) -> bool: ... + def __ge__(self, other: list[_T] | UserList[_T]) -> bool: ... + def __eq__(self, other: object) -> bool: ... + def __contains__(self, item: object) -> bool: ... + def __len__(self) -> int: ... + @overload + def __getitem__(self, i: SupportsIndex) -> _T: ... + @overload + def __getitem__(self, i: slice) -> Self: ... + @overload + def __setitem__(self, i: SupportsIndex, item: _T) -> None: ... + @overload + def __setitem__(self, i: slice, item: Iterable[_T]) -> None: ... + def __delitem__(self, i: SupportsIndex | slice) -> None: ... + def __add__(self, other: Iterable[_T]) -> Self: ... + def __radd__(self, other: Iterable[_T]) -> Self: ... + def __iadd__(self, other: Iterable[_T]) -> Self: ... + def __mul__(self, n: int) -> Self: ... + def __rmul__(self, n: int) -> Self: ... + def __imul__(self, n: int) -> Self: ... + def append(self, item: _T) -> None: ... + def insert(self, i: int, item: _T) -> None: ... + def pop(self, i: int = -1) -> _T: ... + def remove(self, item: _T) -> None: ... + def copy(self) -> Self: ... + def __copy__(self) -> Self: ... + def count(self, item: _T) -> int: ... + # The runtime signature is "item, *args", and the arguments are then passed + # to `list.index`. In order to give more precise types, we pretend that the + # `item` argument is positional-only. + def index( + self, item: _T, start: SupportsIndex = 0, stop: SupportsIndex = sys.maxsize, / + ) -> int: ... + # All arguments are passed to `list.sort` at runtime, so the signature should be kept in line with `list.sort`. + @overload + def sort( + self: UserList[SupportsRichComparisonT], *, key: None = None, reverse: bool = False + ) -> None: ... + @overload + def sort( + self, *, key: Callable[[_T], SupportsRichComparison], reverse: bool = False + ) -> None: ... + def extend(self, other: Iterable[_T]) -> None: ... + +class UserString(Sequence[UserString]): + data: str + def __init__(self, seq: object) -> None: ... + def __int__(self) -> int: ... + def __float__(self) -> float: ... + def __complex__(self) -> complex: ... + def __getnewargs__(self) -> tuple[str]: ... + def __lt__(self, string: str | UserString) -> bool: ... + def __le__(self, string: str | UserString) -> bool: ... + def __gt__(self, string: str | UserString) -> bool: ... + def __ge__(self, string: str | UserString) -> bool: ... + def __eq__(self, string: object) -> bool: ... + def __hash__(self) -> int: ... + def __contains__(self, char: object) -> bool: ... + def __len__(self) -> int: ... + def __getitem__(self, index: SupportsIndex | slice) -> Self: ... + def __iter__(self) -> Iterator[Self]: ... + def __reversed__(self) -> Iterator[Self]: ... + def __add__(self, other: object) -> Self: ... + def __radd__(self, other: object) -> Self: ... + def __mul__(self, n: int) -> Self: ... + def __rmul__(self, n: int) -> Self: ... + def __mod__(self, args: Any) -> Self: ... + def __rmod__(self, template: object) -> Self: ... + def capitalize(self) -> Self: ... + def casefold(self) -> Self: ... + def center(self, width: int, *args: Any) -> Self: ... + def count(self, sub: str | UserString, start: int = 0, end: int = sys.maxsize) -> int: ... + def encode( + self: UserString, encoding: str | None = "utf-8", errors: str | None = "strict" + ) -> bytes: ... + def endswith( + self, suffix: str | tuple[str, ...], start: int | None = 0, end: int | None = sys.maxsize + ) -> bool: ... + def expandtabs(self, tabsize: int = 8) -> Self: ... + def find(self, sub: str | UserString, start: int = 0, end: int = sys.maxsize) -> int: ... + def format(self, *args: Any, **kwds: Any) -> str: ... + def format_map(self, mapping: Mapping[str, Any]) -> str: ... + def index(self, sub: str, start: int = 0, end: int = sys.maxsize) -> int: ... + def isalpha(self) -> bool: ... + def isalnum(self) -> bool: ... + def isdecimal(self) -> bool: ... + def isdigit(self) -> bool: ... + def isidentifier(self) -> bool: ... + def islower(self) -> bool: ... + def isnumeric(self) -> bool: ... + def isprintable(self) -> bool: ... + def isspace(self) -> bool: ... + def istitle(self) -> bool: ... + def isupper(self) -> bool: ... + def isascii(self) -> bool: ... + def join(self, seq: Iterable[str]) -> str: ... + def ljust(self, width: int, *args: Any) -> Self: ... + def lower(self) -> Self: ... + def lstrip(self, chars: str | None = None) -> Self: ... + maketrans = str.maketrans + def partition(self, sep: str) -> tuple[str, str, str]: ... + if sys.version_info >= (3, 9): + def removeprefix(self, prefix: str | UserString, /) -> Self: ... + def removesuffix(self, suffix: str | UserString, /) -> Self: ... + + def replace( + self, old: str | UserString, new: str | UserString, maxsplit: int = -1 + ) -> Self: ... + def rfind(self, sub: str | UserString, start: int = 0, end: int = sys.maxsize) -> int: ... + def rindex(self, sub: str | UserString, start: int = 0, end: int = sys.maxsize) -> int: ... + def rjust(self, width: int, *args: Any) -> Self: ... + def rpartition(self, sep: str) -> tuple[str, str, str]: ... + def rstrip(self, chars: str | None = None) -> Self: ... + def split(self, sep: str | None = None, maxsplit: int = -1) -> list[str]: ... + def rsplit(self, sep: str | None = None, maxsplit: int = -1) -> list[str]: ... + def splitlines(self, keepends: bool = False) -> list[str]: ... + def startswith( + self, prefix: str | tuple[str, ...], start: int | None = 0, end: int | None = sys.maxsize + ) -> bool: ... + def strip(self, chars: str | None = None) -> Self: ... + def swapcase(self) -> Self: ... + def title(self) -> Self: ... + def translate(self, *args: Any) -> Self: ... + def upper(self) -> Self: ... + def zfill(self, width: int) -> Self: ... + +class deque(MutableSequence[_T]): + @property + def maxlen(self) -> int | None: ... + @overload + def __init__(self, *, maxlen: int | None = None) -> None: ... + @overload + def __init__(self, iterable: Iterable[_T], maxlen: int | None = None) -> None: ... + def append(self, x: _T, /) -> None: ... + def appendleft(self, x: _T, /) -> None: ... + def copy(self) -> Self: ... + def count(self, x: _T, /) -> int: ... + def extend(self, iterable: Iterable[_T], /) -> None: ... + def extendleft(self, iterable: Iterable[_T], /) -> None: ... + def insert(self, i: int, x: _T, /) -> None: ... + def index(self, x: _T, start: int = 0, stop: int = ..., /) -> int: ... + def pop(self) -> _T: ... # type: ignore[override] + def popleft(self) -> _T: ... + def remove(self, value: _T, /) -> None: ... + def rotate(self, n: int = 1, /) -> None: ... + def __copy__(self) -> Self: ... + def __len__(self) -> int: ... + # These methods of deque don't take slices, unlike MutableSequence, hence the type: ignores + def __getitem__(self, key: SupportsIndex, /) -> _T: ... # type: ignore[override] + def __setitem__(self, key: SupportsIndex, value: _T, /) -> None: ... # type: ignore[override] + def __delitem__(self, key: SupportsIndex, /) -> None: ... # type: ignore[override] + def __contains__(self, key: object, /) -> bool: ... + def __reduce__(self) -> tuple[type[Self], tuple[()], None, Iterator[_T]]: ... + def __iadd__(self, value: Iterable[_T], /) -> Self: ... + def __add__(self, value: Self, /) -> Self: ... + def __mul__(self, value: int, /) -> Self: ... + def __imul__(self, value: int, /) -> Self: ... + def __lt__(self, value: deque[_T], /) -> bool: ... + def __le__(self, value: deque[_T], /) -> bool: ... + def __gt__(self, value: deque[_T], /) -> bool: ... + def __ge__(self, value: deque[_T], /) -> bool: ... + def __eq__(self, value: object, /) -> bool: ... + if sys.version_info >= (3, 9): + def __class_getitem__(cls, item: Any, /) -> GenericAlias: ... + +class Counter(dict[_T, int], Generic[_T]): + @overload + def __init__(self, iterable: None = None, /) -> None: ... + @overload + def __init__(self: Counter[str], iterable: None = None, /, **kwargs: int) -> None: ... + @overload + def __init__(self, mapping: SupportsKeysAndGetItem[_T, int], /) -> None: ... + @overload + def __init__(self, iterable: Iterable[_T], /) -> None: ... + def copy(self) -> Self: ... + def elements(self) -> Iterator[_T]: ... + def most_common(self, n: int | None = None) -> list[tuple[_T, int]]: ... + @classmethod + def fromkeys(cls, iterable: Any, v: int | None = None) -> NoReturn: ... # type: ignore[override] + @overload + def subtract(self, iterable: None = None, /) -> None: ... + @overload + def subtract(self, mapping: Mapping[_T, int], /) -> None: ... + @overload + def subtract(self, iterable: Iterable[_T], /) -> None: ... + # Unlike dict.update(), use Mapping instead of SupportsKeysAndGetItem for the first overload + # (source code does an `isinstance(other, Mapping)` check) + # + # The second overload is also deliberately different to dict.update() + # (if it were `Iterable[_T] | Iterable[tuple[_T, int]]`, + # the tuples would be added as keys, breaking type safety) + @overload # type: ignore[override] + def update(self, m: Mapping[_T, int], /, **kwargs: int) -> None: ... + @overload + def update(self, iterable: Iterable[_T], /, **kwargs: int) -> None: ... + @overload + def update(self, iterable: None = None, /, **kwargs: int) -> None: ... + def __missing__(self, key: _T) -> int: ... + def __delitem__(self, elem: object) -> None: ... + if sys.version_info >= (3, 10): + def __eq__(self, other: object) -> bool: ... + def __ne__(self, other: object) -> bool: ... + + def __add__(self, other: Counter[_S]) -> Counter[_T | _S]: ... + def __sub__(self, other: Counter[_T]) -> Counter[_T]: ... + def __and__(self, other: Counter[_T]) -> Counter[_T]: ... + def __or__(self, other: Counter[_S]) -> Counter[_T | _S]: ... # type: ignore[override] + def __pos__(self) -> Counter[_T]: ... + def __neg__(self) -> Counter[_T]: ... + # several type: ignores because __iadd__ is supposedly incompatible with __add__, etc. + def __iadd__(self, other: SupportsItems[_T, int]) -> Self: ... # type: ignore[misc] + def __isub__(self, other: SupportsItems[_T, int]) -> Self: ... + def __iand__(self, other: SupportsItems[_T, int]) -> Self: ... + def __ior__(self, other: SupportsItems[_T, int]) -> Self: ... # type: ignore[override,misc] + if sys.version_info >= (3, 10): + def total(self) -> int: ... + def __le__(self, other: Counter[Any]) -> bool: ... + def __lt__(self, other: Counter[Any]) -> bool: ... + def __ge__(self, other: Counter[Any]) -> bool: ... + def __gt__(self, other: Counter[Any]) -> bool: ... + +# The pure-Python implementations of the "views" classes +# These are exposed at runtime in `collections/__init__.py` +class _OrderedDictKeysView(KeysView[_KT_co]): + def __reversed__(self) -> Iterator[_KT_co]: ... + +class _OrderedDictItemsView(ItemsView[_KT_co, _VT_co]): + def __reversed__(self) -> Iterator[tuple[_KT_co, _VT_co]]: ... + +class _OrderedDictValuesView(ValuesView[_VT_co]): + def __reversed__(self) -> Iterator[_VT_co]: ... + +# The C implementations of the "views" classes +# (At runtime, these are called `odict_keys`, `odict_items` and `odict_values`, +# but they are not exposed anywhere) +# pyright doesn't have a specific error code for subclassing error! +@final +class _odict_keys(dict_keys[_KT_co, _VT_co]): # type: ignore[misc] # pyright: ignore[reportGeneralTypeIssues] + def __reversed__(self) -> Iterator[_KT_co]: ... + +@final +class _odict_items(dict_items[_KT_co, _VT_co]): # type: ignore[misc] # pyright: ignore[reportGeneralTypeIssues] + def __reversed__(self) -> Iterator[tuple[_KT_co, _VT_co]]: ... + +@final +class _odict_values(dict_values[_KT_co, _VT_co]): # type: ignore[misc] # pyright: ignore[reportGeneralTypeIssues] + def __reversed__(self) -> Iterator[_VT_co]: ... + +class OrderedDict(dict[_KT, _VT]): + def popitem(self, last: bool = True) -> tuple[_KT, _VT]: ... + def move_to_end(self, key: _KT, last: bool = True) -> None: ... + def copy(self) -> Self: ... + def __reversed__(self) -> Iterator[_KT]: ... + def keys(self) -> _odict_keys[_KT, _VT]: ... + def items(self) -> _odict_items[_KT, _VT]: ... + def values(self) -> _odict_values[_KT, _VT]: ... + # The signature of OrderedDict.fromkeys should be kept in line with `dict.fromkeys`, modulo positional-only differences. + # Like dict.fromkeys, its true signature is not expressible in the current type system. + # See #3800 & https://github.com/python/typing/issues/548#issuecomment-683336963. + @classmethod + @overload + def fromkeys( + cls, iterable: Iterable[_T], value: None = None + ) -> OrderedDict[_T, Any | None]: ... + @classmethod + @overload + def fromkeys(cls, iterable: Iterable[_T], value: _S) -> OrderedDict[_T, _S]: ... + # Keep OrderedDict.setdefault in line with MutableMapping.setdefault, modulo positional-only differences. + @overload + def setdefault( + self: OrderedDict[_KT, _T | None], key: _KT, default: None = None + ) -> _T | None: ... + @overload + def setdefault(self, key: _KT, default: _VT) -> _VT: ... + # Same as dict.pop, but accepts keyword arguments + @overload + def pop(self, key: _KT) -> _VT: ... + @overload + def pop(self, key: _KT, default: _VT) -> _VT: ... + @overload + def pop(self, key: _KT, default: _T) -> _VT | _T: ... + def __eq__(self, value: object, /) -> bool: ... + if sys.version_info >= (3, 9): + @overload + def __or__(self, value: dict[_KT, _VT], /) -> Self: ... + @overload + def __or__(self, value: dict[_T1, _T2], /) -> OrderedDict[_KT | _T1, _VT | _T2]: ... + @overload + def __ror__(self, value: dict[_KT, _VT], /) -> Self: ... + @overload + def __ror__(self, value: dict[_T1, _T2], /) -> OrderedDict[_KT | _T1, _VT | _T2]: ... # type: ignore[misc] + +class defaultdict(dict[_KT, _VT]): + default_factory: Callable[[], _VT] | None + @overload + def __init__(self) -> None: ... + @overload + def __init__( + self: defaultdict[str, _VT], # pyright: ignore[reportInvalidTypeVarUse] #11780 + **kwargs: _VT, + ) -> None: ... # pyright: ignore[reportInvalidTypeVarUse] #11780 + @overload + def __init__(self, default_factory: Callable[[], _VT] | None, /) -> None: ... + @overload + def __init__( + self: defaultdict[str, _VT], # pyright: ignore[reportInvalidTypeVarUse] #11780 + default_factory: Callable[[], _VT] | None, + /, + **kwargs: _VT, + ) -> None: ... + @overload + def __init__( + self, default_factory: Callable[[], _VT] | None, map: SupportsKeysAndGetItem[_KT, _VT], / + ) -> None: ... + @overload + def __init__( + self: defaultdict[str, _VT], # pyright: ignore[reportInvalidTypeVarUse] #11780 + default_factory: Callable[[], _VT] | None, + map: SupportsKeysAndGetItem[str, _VT], + /, + **kwargs: _VT, + ) -> None: ... + @overload + def __init__( + self, default_factory: Callable[[], _VT] | None, iterable: Iterable[tuple[_KT, _VT]], / + ) -> None: ... + @overload + def __init__( + self: defaultdict[str, _VT], # pyright: ignore[reportInvalidTypeVarUse] #11780 + default_factory: Callable[[], _VT] | None, + iterable: Iterable[tuple[str, _VT]], + /, + **kwargs: _VT, + ) -> None: ... + def __missing__(self, key: _KT, /) -> _VT: ... + def __copy__(self) -> Self: ... + def copy(self) -> Self: ... + if sys.version_info >= (3, 9): + @overload + def __or__(self, value: dict[_KT, _VT], /) -> Self: ... + @overload + def __or__(self, value: dict[_T1, _T2], /) -> defaultdict[_KT | _T1, _VT | _T2]: ... + @overload + def __ror__(self, value: dict[_KT, _VT], /) -> Self: ... + @overload + def __ror__(self, value: dict[_T1, _T2], /) -> defaultdict[_KT | _T1, _VT | _T2]: ... # type: ignore[misc] + +class ChainMap(MutableMapping[_KT, _VT]): + maps: list[MutableMapping[_KT, _VT]] + def __init__(self, *maps: MutableMapping[_KT, _VT]) -> None: ... + def new_child(self, m: MutableMapping[_KT, _VT] | None = None) -> Self: ... + @property + def parents(self) -> Self: ... + def __setitem__(self, key: _KT, value: _VT) -> None: ... + def __delitem__(self, key: _KT) -> None: ... + def __getitem__(self, key: _KT) -> _VT: ... + def __iter__(self) -> Iterator[_KT]: ... + def __len__(self) -> int: ... + def __contains__(self, key: object) -> bool: ... + @overload + def get(self, key: _KT, default: None = None) -> _VT | None: ... + @overload + def get(self, key: _KT, default: _T) -> _VT | _T: ... + def __missing__(self, key: _KT) -> _VT: ... # undocumented + def __bool__(self) -> bool: ... + # Keep ChainMap.setdefault in line with MutableMapping.setdefault, modulo positional-only differences. + @overload + def setdefault( + self: ChainMap[_KT, _T | None], key: _KT, default: None = None + ) -> _T | None: ... + @overload + def setdefault(self, key: _KT, default: _VT) -> _VT: ... + @overload + def pop(self, key: _KT) -> _VT: ... + @overload + def pop(self, key: _KT, default: _VT) -> _VT: ... + @overload + def pop(self, key: _KT, default: _T) -> _VT | _T: ... + def copy(self) -> Self: ... + __copy__ = copy + # All arguments to `fromkeys` are passed to `dict.fromkeys` at runtime, + # so the signature should be kept in line with `dict.fromkeys`. + @classmethod + @overload + def fromkeys(cls, iterable: Iterable[_T]) -> ChainMap[_T, Any | None]: ... + @classmethod + @overload + # Special-case None: the user probably wants to add non-None values later. + def fromkeys(cls, iterable: Iterable[_T], value: None, /) -> ChainMap[_T, Any | None]: ... + @classmethod + @overload + def fromkeys(cls, iterable: Iterable[_T], value: _S, /) -> ChainMap[_T, _S]: ... + if sys.version_info >= (3, 9): + @overload + def __or__(self, other: Mapping[_KT, _VT]) -> Self: ... + @overload + def __or__(self, other: Mapping[_T1, _T2]) -> ChainMap[_KT | _T1, _VT | _T2]: ... + @overload + def __ror__(self, other: Mapping[_KT, _VT]) -> Self: ... + @overload + def __ror__(self, other: Mapping[_T1, _T2]) -> ChainMap[_KT | _T1, _VT | _T2]: ... + # ChainMap.__ior__ should be kept roughly in line with MutableMapping.update() + @overload # type: ignore[misc] + def __ior__(self, other: SupportsKeysAndGetItem[_KT, _VT]) -> Self: ... + @overload + def __ior__(self, other: Iterable[tuple[_KT, _VT]]) -> Self: ... diff --git a/.venv/lib/python3.12/site-packages/_mpy_shed/collections/abc.pyi b/.venv/lib/python3.12/site-packages/_mpy_shed/collections/abc.pyi new file mode 100644 index 0000000..1ed47cc --- /dev/null +++ b/.venv/lib/python3.12/site-packages/_mpy_shed/collections/abc.pyi @@ -0,0 +1,3 @@ +from _collections_abc import * + +# from _collections_abc import __all__ as __all__ diff --git a/.venv/lib/python3.12/site-packages/_mpy_shed/io_modes.pyi b/.venv/lib/python3.12/site-packages/_mpy_shed/io_modes.pyi new file mode 100644 index 0000000..cdc46c6 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/_mpy_shed/io_modes.pyi @@ -0,0 +1,87 @@ +""" +Type aliases for the Micropython specific modes used in the `open` function. + +References: + - https://docs.micropython.org/en/latest/library/io.html#conceptual-hierarchy + - https://docs.python.org/3/library/io.html +""" + +# MIT License +# Howard C Lovatt, 2020 onwards. +# Jos Verlinde, 2025 onwards. + +from typing import Literal + +from typing_extensions import TypeAlias + +_OpenTextModeUpdating: TypeAlias = Literal[ + "r+", + "+r", + "rt+", + "r+t", + "+rt", + "tr+", + "t+r", + "+tr", + "w+", + "+w", + "wt+", + "w+t", + "+wt", + "tw+", + "t+w", + "+tw", + "a+", + "+a", + "at+", + "a+t", + "+at", + "ta+", + "t+a", + "+ta", + "x+", + "+x", + "xt+", + "x+t", + "+xt", + "tx+", + "t+x", + "+tx", +] +_OpenTextModeWriting: TypeAlias = Literal["w", "wt", "tw", "a", "at", "ta", "x", "xt", "tx"] +_OpenTextModeReading: TypeAlias = Literal[ + "r", "rt", "tr", "U", "rU", "Ur", "rtU", "rUt", "Urt", "trU", "tUr", "Utr" +] +_OpenTextMode: TypeAlias = _OpenTextModeUpdating | _OpenTextModeWriting | _OpenTextModeReading + +_OpenBinaryModeUpdating: TypeAlias = Literal[ + "rb+", + "r+b", + "+rb", + "br+", + "b+r", + "+br", + "wb+", + "w+b", + "+wb", + "bw+", + "b+w", + "+bw", + "ab+", + "a+b", + "+ab", + "ba+", + "b+a", + "+ba", + "xb+", + "x+b", + "+xb", + "bx+", + "b+x", + "+bx", +] +_OpenBinaryModeWriting: TypeAlias = Literal["wb", "bw", "ab", "ba", "xb", "bx"] +_OpenBinaryModeReading: TypeAlias = Literal["rb", "br", "rbU", "rUb", "Urb", "brU", "bUr", "Ubr"] +_OpenBinaryMode: TypeAlias = ( + _OpenBinaryModeUpdating | _OpenBinaryModeReading | _OpenBinaryModeWriting +) diff --git a/.venv/lib/python3.12/site-packages/_mpy_shed/io_mp.pyi b/.venv/lib/python3.12/site-packages/_mpy_shed/io_mp.pyi new file mode 100644 index 0000000..93d7167 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/_mpy_shed/io_mp.pyi @@ -0,0 +1,52 @@ +# ------------------ +# from typeshed/stdlib/io.pyi + +import abc +from types import TracebackType +from typing import TypeVar + +from _io import BytesIO as BytesIO +from _io import FileIO as FileIO +from _io import IncrementalNewlineDecoder as IncrementalNewlineDecoder +from _io import StringIO as StringIO +from _io import TextIOWrapper as TextIOWrapper +from _io import _BufferedIOBase, _IOBase, _RawIOBase, _TextIOBase +from _io import open as open +from typing_extensions import Self + +from .buffer_mp import AnyReadableBuf, AnyWritableBuf +from .pathlike import PathLike + +class IOBase_mp(_IOBase, metaclass=abc.ABCMeta): ... +# class IOBase_mp(Stream, metaclass=abc.ABCMeta): ... + +# Andy +# +# class Stream(metaclass=abc.ABCMeta): +# """ +# MicroPython stream "base class". Due to implementation mechanism +# not all methods are guaranteed to be available on all classes +# based on the stream type / protocol. +# """ +# def __init__(self, *argv, **kwargs) -> None: ... +# def __enter__(self: Self) -> Self: ... +# def __exit__( +# self, +# exc_type: type[BaseException] | None, +# exc_val: BaseException | None, +# exc_tb: TracebackType | None, +# ) -> None: ... +# def close(self) -> None: ... +# def flush(self) -> None: ... +# def read(self, __size: int | None = ...) -> bytes: ... +# def read1(self, __size: int = ...) -> bytes: ... +# def readinto(self, __buffer: AnyWritableBuf) -> int: ... +# def readline(self, __size: int | None = ...) -> bytes: ... +# def readlines(self, __hint: int = ...) -> list[bytes]: ... +# def seek(self, __offset: int, __whence: int = ...) -> int: ... +# def tell(self) -> int: ... +# def write(self, __buffer: AnyReadableBuf) -> int: ... +# def write1(self, __buffer: AnyReadableBuf) -> int: ... + +# Howard +_OpenFile = TypeVar("_OpenFile", str, bytes, PathLike[str], PathLike[bytes], int) diff --git a/.venv/lib/python3.12/site-packages/_mpy_shed/mp_available.pyi b/.venv/lib/python3.12/site-packages/_mpy_shed/mp_available.pyi new file mode 100644 index 0000000..1f1ef95 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/_mpy_shed/mp_available.pyi @@ -0,0 +1,32 @@ +from typing import Callable, Iterable, Tuple, TypeVar, Union + +""" +Decorator to annotate objects with the MicroPython ports they are available on. + +Usage: + @mp_available(port="esp32") + def foo(): ... + + @mp_available(port=["esp32", "rp2"]) + class Bar: ... +""" + + +__all__ = ["mp_available"] + +T = TypeVar("T") # Works for functions, classes, and other callables + +def mp_available( + *, + port: Union[str, Iterable[str]] =["*"], + version: Union[str, Iterable[str]] =["*"], + macro: Union[str, Iterable[str]] =["*"], + ) -> Callable[[T], T]: + """ + Decorator factory that marks an object as available on the given MicroPython ports. + The ports list is stored on the decorated object as __mp_available_ports__. + """ + def decorator(obj: T) -> T: + return obj + return decorator + diff --git a/.venv/lib/python3.12/site-packages/_mpy_shed/mp_implementation.py b/.venv/lib/python3.12/site-packages/_mpy_shed/mp_implementation.py new file mode 100644 index 0000000..8f8bf36 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/_mpy_shed/mp_implementation.py @@ -0,0 +1,24 @@ +""" +MicroPython version of the sys.implementation object +""" + +from typing import Any, Tuple + + +class _mp_implementation(): + """ + This object is the recommended way to distinguish MicroPython from other Python implementations (note that it still may not exist in the very minimal ports). + Starting with version 1.22.0-preview, the fourth node releaselevel in implementation.version is either an empty string or "preview". + """ + name: str + version: Tuple[int,int,int, str] + _machine: str + "string describing the underlying machine" + _mpy: int + "supported mpy file-format version (optional attribute)" + _build: str + "string that can help identify the configuration that MicroPython was built with" + # Define __getattr__, as the documentation states: + # > sys.implementation may contain additional attributes specific to the Python implementation. + # > These non-standard attributes must start with an underscore, and are not described here. + def __getattr__(self, name: str) -> Any: ... \ No newline at end of file diff --git a/.venv/lib/python3.12/site-packages/_mpy_shed/neopixelbase.pyi b/.venv/lib/python3.12/site-packages/_mpy_shed/neopixelbase.pyi new file mode 100644 index 0000000..089a124 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/_mpy_shed/neopixelbase.pyi @@ -0,0 +1,26 @@ +########################### +# neopixel +from typing import Tuple + +class _NeoPixelBase: + """ + a class to add a few missing methods to the NeoPixel class + """ + + def __len__(self) -> int: + """ + Returns the number of LEDs in the strip. + """ + ... + + def __setitem__(self, index: int, val, /) -> None: + """ + Set the pixel at *index* to the value, which is an RGB/RGBW tuple. + """ + ... + + def __getitem__(self, index: int, /) -> Tuple: + """ + Returns the pixel at *index* as an RGB/RGBW tuple. + """ + ... diff --git a/.venv/lib/python3.12/site-packages/_mpy_shed/pathlike.pyi b/.venv/lib/python3.12/site-packages/_mpy_shed/pathlike.pyi new file mode 100644 index 0000000..c601cd6 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/_mpy_shed/pathlike.pyi @@ -0,0 +1,17 @@ +""" +pathlike is used in multiple stdlib stubs - but does not exists in MicroPython +copied from typeshed/stdlib/os.pyi as os.pyi cannot import from a module with the same name +""" + +import abc +from typing import Protocol, Tuple, runtime_checkable + +from _typeshed import AnyStr_co + +# mypy and pyright object to this being both ABC and Protocol. +# At runtime it inherits from ABC and is not a Protocol, but it will be +# on the allowlist for use as a Protocol starting in 3.14. +@runtime_checkable +class PathLike(ABC, Protocol[AnyStr_co]): # type: ignore[misc] # pyright: ignore[reportGeneralTypeIssues] + @abc.abstractmethod + def __fspath__(self) -> AnyStr_co: ... diff --git a/.venv/lib/python3.12/site-packages/_mpy_shed/subscriptable.pyi b/.venv/lib/python3.12/site-packages/_mpy_shed/subscriptable.pyi new file mode 100644 index 0000000..0794446 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/_mpy_shed/subscriptable.pyi @@ -0,0 +1,17 @@ +from typing import Protocol, TypeVar, runtime_checkable + +_T_Co = TypeVar("_T_Co", covariant=True) + +@runtime_checkable +class Subscriptable(Protocol[_T_Co]): + """A `Protocol` (structurally typed) for an object that is subscriptable and of finite length.""" + + __slots__ = () + def __len__(self) -> int: + """Number of elements, normally called via `len(x)` where `x` is an object that implements this protocol.""" + + def __getitem__(self, index: int) -> _T_Co: + """ + Element at the given index, + normally called via `x[index]` where `x` is an object that implements this protocol. + """ diff --git a/.venv/lib/python3.12/site-packages/_mpy_shed/time_mp.pyi b/.venv/lib/python3.12/site-packages/_mpy_shed/time_mp.pyi new file mode 100644 index 0000000..32caf34 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/_mpy_shed/time_mp.pyi @@ -0,0 +1,15 @@ +""" +The tuple to pass or receive from the time methods is unfortunately +defined differently on different ports, boards and versions of MicroPython. + +The _Time8Tuple and _Time9Tuple are the most common ones, and are unified in the _TimeTuple. + +As this still does not cover all cases, the _TimeTuple is a union of the two common cases and the generic Tuple. +""" + +from typing import Tuple +from typing_extensions import TypeAlias + +_Time8Tuple: TypeAlias = Tuple[int, int, int, int, int, int, int, int] +_Time9Tuple: TypeAlias = Tuple[int, int, int, int, int, int, int, int, int] +_TimeTuple: TypeAlias = _Time8Tuple | _Time9Tuple | Tuple[int, ...] diff --git a/.venv/lib/python3.12/site-packages/_onewire.pyi b/.venv/lib/python3.12/site-packages/_onewire.pyi new file mode 100644 index 0000000..52e94e7 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/_onewire.pyi @@ -0,0 +1,15 @@ +""" +Module: '_onewire' on micropython-v1.26.0-rp2-RPI_PICO +""" + +# MCU: {'mpy': 'v6.3', 'build': '', 'ver': '1.26.0', 'arch': 'armv6m', 'version': '1.26.0', 'port': 'rp2', 'board': 'RPI_PICO', 'family': 'micropython', 'board_id': 'RPI_PICO', 'variant': '', 'cpu': 'RP2040'} +# Stubber: v1.26.0 +from __future__ import annotations +from _typeshed import Incomplete + +def reset(*args, **kwargs) -> Incomplete: ... +def writebyte(*args, **kwargs) -> Incomplete: ... +def writebit(*args, **kwargs) -> Incomplete: ... +def crc8(*args, **kwargs) -> Incomplete: ... +def readbyte(*args, **kwargs) -> Incomplete: ... +def readbit(*args, **kwargs) -> Incomplete: ... diff --git a/.venv/lib/python3.12/site-packages/_thread.pyi b/.venv/lib/python3.12/site-packages/_thread.pyi new file mode 100644 index 0000000..2048aea --- /dev/null +++ b/.venv/lib/python3.12/site-packages/_thread.pyi @@ -0,0 +1,33 @@ +""" +Multithreading support. + +MicroPython module: https://docs.micropython.org/en/v1.26.0/library/_thread.html + +CPython module: :mod:`python:_thread` https://docs.python.org/3/library/_thread.html . + +This module implements multithreading support. + +This module is highly experimental and its API is not yet fully settled +and not yet described in this documentation. + +--- +Module: '_thread' on micropython-v1.26.0-rp2-RPI_PICO +""" + +# MCU: {'mpy': 'v6.3', 'build': '', 'ver': '1.26.0', 'arch': 'armv6m', 'version': '1.26.0', 'port': 'rp2', 'board': 'RPI_PICO', 'family': 'micropython', 'board_id': 'RPI_PICO', 'variant': '', 'cpu': 'RP2040'} +# Stubber: v1.26.0 +from __future__ import annotations +from _typeshed import Incomplete +from typing_extensions import Awaitable, TypeAlias, TypeVar + +def get_ident(*args, **kwargs) -> Incomplete: ... +def start_new_thread(*args, **kwargs) -> Incomplete: ... +def stack_size(*args, **kwargs) -> Incomplete: ... +def exit(*args, **kwargs) -> Incomplete: ... +def allocate_lock(*args, **kwargs) -> Incomplete: ... + +class LockType: + def locked(self, *args, **kwargs) -> Incomplete: ... + def release(self, *args, **kwargs) -> Incomplete: ... + def acquire(self, *args, **kwargs) -> Incomplete: ... + def __init__(self, *argv, **kwargs) -> None: ... diff --git a/.venv/lib/python3.12/site-packages/binascii.pyi b/.venv/lib/python3.12/site-packages/binascii.pyi new file mode 100644 index 0000000..4fad282 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/binascii.pyi @@ -0,0 +1,61 @@ +""" +Binary/ASCII conversions. + +MicroPython module: https://docs.micropython.org/en/v1.26.0/library/binascii.html + +CPython module: :mod:`python:binascii` https://docs.python.org/3/library/binascii.html . + +This module implements conversions between binary data and various +encodings of it in ASCII form (in both directions). + +--- +Module: 'binascii' on micropython-v1.26.0-rp2-RPI_PICO +""" + +# MCU: {'mpy': 'v6.3', 'build': '', 'ver': '1.26.0', 'arch': 'armv6m', 'version': '1.26.0', 'port': 'rp2', 'board': 'RPI_PICO', 'family': 'micropython', 'board_id': 'RPI_PICO', 'variant': '', 'cpu': 'RP2040'} +# Stubber: v1.26.0 +from __future__ import annotations +from _typeshed import Incomplete +from typing import Any, Optional +from typing_extensions import Awaitable, TypeAlias, TypeVar + +def crc32(data, value: Optional[Any] = None) -> Incomplete: + """ + Compute CRC-32, the 32-bit checksum of *data*, starting with an initial CRC + of *value*. The default initial CRC is zero. The algorithm is consistent + with the ZIP file checksum. + """ + ... + +def hexlify(data: bytes, sep: str | bytes = ..., /) -> bytes: + """ + Convert the bytes in the *data* object to a hexadecimal representation. + Returns a bytes object. + + If the additional argument *sep* is supplied it is used as a separator + between hexadecimal values. + """ + ... + +def unhexlify(data: str | bytes, /) -> bytes: + """ + Convert hexadecimal data to binary representation. Returns bytes string. + (i.e. inverse of hexlify) + """ + ... + +def b2a_base64(data: bytes, /) -> bytes: + """ + Encode binary data in base64 format, as in `RFC 3548 + `_. Returns the encoded data + followed by a newline character if newline is true, as a bytes object. + """ + ... + +def a2b_base64(data: str | bytes, /) -> bytes: + """ + Decode base64-encoded data, ignoring invalid characters in the input. + Conforms to `RFC 2045 s.6.8 `_. + Returns a bytes object. + """ + ... diff --git a/.venv/lib/python3.12/site-packages/cmath.pyi b/.venv/lib/python3.12/site-packages/cmath.pyi new file mode 100644 index 0000000..b362a72 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/cmath.pyi @@ -0,0 +1,82 @@ +""" +Mathematical functions for complex numbers. + +MicroPython module: https://docs.micropython.org/en/v1.26.0/library/cmath.html + +CPython module: :mod:`python:cmath` https://docs.python.org/3/library/cmath.html . + +The ``cmath`` module provides some basic mathematical functions for +working with complex numbers. + +Availability: not available on WiPy and ESP8266. Floating point support +required for this module. + +--- +Module: 'cmath' on micropython-v1.26.0-rp2-RPI_PICO +""" + +# MCU: {'mpy': 'v6.3', 'build': '', 'ver': '1.26.0', 'arch': 'armv6m', 'version': '1.26.0', 'port': 'rp2', 'board': 'RPI_PICO', 'family': 'micropython', 'board_id': 'RPI_PICO', 'variant': '', 'cpu': 'RP2040'} +# Stubber: v1.26.0 +from __future__ import annotations +from _typeshed import Incomplete +from typing import SupportsComplex, SupportsFloat, SupportsIndex, Tuple +from typing_extensions import Awaitable, TypeAlias, TypeVar + +_C: TypeAlias = SupportsFloat | SupportsComplex | SupportsIndex | complex + +e: float = 2.7182818 +pi: float = 3.1415928 + +def polar(z: _C, /) -> Tuple: + """ + Returns, as a tuple, the polar form of ``z``. + """ + ... + +def sqrt(z: _C, /) -> complex: + """ + Return the square-root of ``z``. + """ + ... + +def rect(r: float, phi: float, /) -> float: + """ + Returns the complex number with modulus ``r`` and phase ``phi``. + """ + ... + +def sin(z: _C, /) -> float: + """ + Return the sine of ``z``. + """ + ... + +def exp(z: _C, /) -> float: + """ + Return the exponential of ``z``. + """ + ... + +def cos(z: _C, /) -> float: + """ + Return the cosine of ``z``. + """ + ... + +def phase(z: _C, /) -> float: + """ + Returns the phase of the number ``z``, in the range (-pi, +pi]. + """ + ... + +def log(z: _C, /) -> float: + """ + Return the natural logarithm of ``z``. The branch cut is along the negative real axis. + """ + ... + +def log10(z: _C, /) -> float: + """ + Return the base-10 logarithm of ``z``. The branch cut is along the negative real axis. + """ + ... diff --git a/.venv/lib/python3.12/site-packages/cryptolib.pyi b/.venv/lib/python3.12/site-packages/cryptolib.pyi new file mode 100644 index 0000000..358a054 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/cryptolib.pyi @@ -0,0 +1,165 @@ +""" +Cryptographic ciphers. + +MicroPython module: https://docs.micropython.org/en/v1.26.0/library/cryptolib.html + +--- +Module: 'cryptolib' on micropython-v1.26.0-rp2-RPI_PICO +""" + +# MCU: {'mpy': 'v6.3', 'build': '', 'ver': '1.26.0', 'arch': 'armv6m', 'version': '1.26.0', 'port': 'rp2', 'board': 'RPI_PICO', 'family': 'micropython', 'board_id': 'RPI_PICO', 'variant': '', 'cpu': 'RP2040'} +# Stubber: v1.26.0 +from __future__ import annotations +from _typeshed import Incomplete +from _mpy_shed import AnyReadableBuf, AnyWritableBuf +from typing import overload +from typing_extensions import Awaitable, TypeAlias, TypeVar + +class aes: + """ + .. class:: aes + """ + + @overload + def encrypt(self, in_buf: AnyReadableBuf, /) -> bytes: + """ + Encrypt *in_buf*. If no *out_buf* is given result is returned as a + newly allocated `bytes` object. Otherwise, result is written into + mutable buffer *out_buf*. *in_buf* and *out_buf* can also refer + to the same mutable buffer, in which case data is encrypted in-place. + """ + + @overload + def encrypt(self, in_buf: AnyReadableBuf, out_buf: AnyWritableBuf, /) -> None: + """ + Encrypt *in_buf*. If no *out_buf* is given result is returned as a + newly allocated `bytes` object. Otherwise, result is written into + mutable buffer *out_buf*. *in_buf* and *out_buf* can also refer + to the same mutable buffer, in which case data is encrypted in-place. + """ + + @overload + def encrypt(self, in_buf: AnyReadableBuf, /) -> bytes: + """ + Encrypt *in_buf*. If no *out_buf* is given result is returned as a + newly allocated `bytes` object. Otherwise, result is written into + mutable buffer *out_buf*. *in_buf* and *out_buf* can also refer + to the same mutable buffer, in which case data is encrypted in-place. + """ + + @overload + def encrypt(self, in_buf: AnyReadableBuf, out_buf: AnyWritableBuf, /) -> None: + """ + Encrypt *in_buf*. If no *out_buf* is given result is returned as a + newly allocated `bytes` object. Otherwise, result is written into + mutable buffer *out_buf*. *in_buf* and *out_buf* can also refer + to the same mutable buffer, in which case data is encrypted in-place. + """ + + @overload + def decrypt(self, in_buf: AnyReadableBuf, /) -> bytes: + """ + Like `encrypt()`, but for decryption. + """ + + @overload + def decrypt(self, in_buf: AnyReadableBuf, out_buf: AnyWritableBuf, /) -> None: + """ + Like `encrypt()`, but for decryption. + """ + + @overload + def decrypt(self, in_buf: AnyReadableBuf, /) -> bytes: + """ + Like `encrypt()`, but for decryption. + """ + + @overload + def decrypt(self, in_buf: AnyReadableBuf, out_buf: AnyWritableBuf, /) -> None: + """ + Like `encrypt()`, but for decryption. + """ + + @overload + def __init__(self, key: AnyReadableBuf, mode: int, /): + """ + Initialize cipher object, suitable for encryption/decryption. Note: + after initialization, cipher object can be use only either for + encryption or decryption. Running decrypt() operation after encrypt() + or vice versa is not supported. + + Parameters are: + + * *key* is an encryption/decryption key (bytes-like). + * *mode* is: + + * ``1`` (or ``cryptolib.MODE_ECB`` if it exists) for Electronic Code Book (ECB). + * ``2`` (or ``cryptolib.MODE_CBC`` if it exists) for Cipher Block Chaining (CBC). + * ``6`` (or ``cryptolib.MODE_CTR`` if it exists) for Counter mode (CTR). + + * *IV* is an initialization vector for CBC mode. + * For Counter mode, *IV* is the initial value for the counter. + """ + + @overload + def __init__(self, key: AnyReadableBuf, mode: int, IV: AnyReadableBuf, /): + """ + Initialize cipher object, suitable for encryption/decryption. Note: + after initialization, cipher object can be use only either for + encryption or decryption. Running decrypt() operation after encrypt() + or vice versa is not supported. + + Parameters are: + + * *key* is an encryption/decryption key (bytes-like). + * *mode* is: + + * ``1`` (or ``cryptolib.MODE_ECB`` if it exists) for Electronic Code Book (ECB). + * ``2`` (or ``cryptolib.MODE_CBC`` if it exists) for Cipher Block Chaining (CBC). + * ``6`` (or ``cryptolib.MODE_CTR`` if it exists) for Counter mode (CTR). + + * *IV* is an initialization vector for CBC mode. + * For Counter mode, *IV* is the initial value for the counter. + """ + + @overload + def __init__(self, key: AnyReadableBuf, mode: int, /): + """ + Initialize cipher object, suitable for encryption/decryption. Note: + after initialization, cipher object can be use only either for + encryption or decryption. Running decrypt() operation after encrypt() + or vice versa is not supported. + + Parameters are: + + * *key* is an encryption/decryption key (bytes-like). + * *mode* is: + + * ``1`` (or ``cryptolib.MODE_ECB`` if it exists) for Electronic Code Book (ECB). + * ``2`` (or ``cryptolib.MODE_CBC`` if it exists) for Cipher Block Chaining (CBC). + * ``6`` (or ``cryptolib.MODE_CTR`` if it exists) for Counter mode (CTR). + + * *IV* is an initialization vector for CBC mode. + * For Counter mode, *IV* is the initial value for the counter. + """ + + @overload + def __init__(self, key: AnyReadableBuf, mode: int, IV: AnyReadableBuf, /): + """ + Initialize cipher object, suitable for encryption/decryption. Note: + after initialization, cipher object can be use only either for + encryption or decryption. Running decrypt() operation after encrypt() + or vice versa is not supported. + + Parameters are: + + * *key* is an encryption/decryption key (bytes-like). + * *mode* is: + + * ``1`` (or ``cryptolib.MODE_ECB`` if it exists) for Electronic Code Book (ECB). + * ``2`` (or ``cryptolib.MODE_CBC`` if it exists) for Cipher Block Chaining (CBC). + * ``6`` (or ``cryptolib.MODE_CTR`` if it exists) for Counter mode (CTR). + + * *IV* is an initialization vector for CBC mode. + * For Counter mode, *IV* is the initial value for the counter. + """ diff --git a/.venv/lib/python3.12/site-packages/deflate.pyi b/.venv/lib/python3.12/site-packages/deflate.pyi new file mode 100644 index 0000000..77b9b36 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/deflate.pyi @@ -0,0 +1,85 @@ +""" +Deflate compression & decompression. + +MicroPython module: https://docs.micropython.org/en/v1.26.0/library/deflate.html + +This module allows compression and decompression of binary data with the +`DEFLATE algorithm `_ +(commonly used in the zlib library and gzip archiver). + +**Availability:** + +* Added in MicroPython v1.21. + +* Decompression: Enabled via the ``MICROPY_PY_DEFLATE`` build option, on by default + on ports with the "extra features" level or higher (which is most boards). + +* Compression: Enabled via the ``MICROPY_PY_DEFLATE_COMPRESS`` build option, on + by default on ports with the "full features" level or higher (generally this means + you need to build your own firmware to enable this). + +--- +Module: 'deflate' on micropython-v1.26.0-rp2-RPI_PICO +""" + +# MCU: {'mpy': 'v6.3', 'build': '', 'ver': '1.26.0', 'arch': 'armv6m', 'version': '1.26.0', 'port': 'rp2', 'board': 'RPI_PICO', 'family': 'micropython', 'board_id': 'RPI_PICO', 'variant': '', 'cpu': 'RP2040'} +# Stubber: v1.26.0 +from __future__ import annotations +from typing import Final +from _typeshed import Incomplete +from typing_extensions import Awaitable, TypeAlias, TypeVar + +GZIP: Final[int] = 3 +RAW: Final[int] = 1 +ZLIB: Final[int] = 2 +AUTO: Final[int] = 0 + +class DeflateIO: + """ + This class can be used to wrap a *stream* which is any + :term:`stream-like ` object such as a file, socket, or stream + (including :class:`io.BytesIO`). It is itself a stream and implements the + standard read/readinto/write/close methods. + + The *stream* must be a blocking stream. Non-blocking streams are currently + not supported. + + The *format* can be set to any of the constants defined below, and defaults + to ``AUTO`` which for decompressing will auto-detect gzip or zlib streams, + and for compressing it will generate a raw stream. + + The *wbits* parameter sets the base-2 logarithm of the DEFLATE dictionary + window size. So for example, setting *wbits* to ``10`` sets the window size + to 1024 bytes. Valid values are ``5`` to ``15`` inclusive (corresponding to + window sizes of 32 to 32k bytes). + + If *wbits* is set to ``0`` (the default), then for compression a window size + of 256 bytes will be used (as if *wbits* was set to 8). For decompression, it + depends on the format: + + * ``RAW`` will use 256 bytes (corresponding to *wbits* set to 8). + * ``ZLIB`` (or ``AUTO`` with zlib detected) will use the value from the zlib + header. + * ``GZIP`` (or ``AUTO`` with gzip detected) will use 32 kilobytes + (corresponding to *wbits* set to 15). + + See the :ref:`window size ` notes below for more information + about the window size, zlib, and gzip streams. + + If *close* is set to ``True`` then the underlying stream will be closed + automatically when the :class:`deflate.DeflateIO` stream is closed. This is + useful if you want to return a :class:`deflate.DeflateIO` stream that wraps + another stream and not have the caller need to know about managing the + underlying stream. + + If compression is enabled, a given :class:`deflate.DeflateIO` instance + supports both reading and writing. For example, a bidirectional stream like + a socket can be wrapped, which allows for compression/decompression in both + directions. + """ + + def readline(self, *args, **kwargs) -> Incomplete: ... + def readinto(self, *args, **kwargs) -> Incomplete: ... + def read(self, *args, **kwargs) -> Incomplete: ... + def close(self, *args, **kwargs) -> Incomplete: ... + def __init__(self, stream, format=AUTO, wbits=0, close=False, /) -> None: ... diff --git a/.venv/lib/python3.12/site-packages/dht.pyi b/.venv/lib/python3.12/site-packages/dht.pyi new file mode 100644 index 0000000..f374267 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/dht.pyi @@ -0,0 +1,15 @@ +from _typeshed import Incomplete + +class DHTBase: + pin: Incomplete + buf: Incomplete + def __init__(self, pin) -> None: ... + def measure(self) -> None: ... + +class DHT11(DHTBase): + def humidity(self): ... + def temperature(self): ... + +class DHT22(DHTBase): + def humidity(self): ... + def temperature(self): ... diff --git a/.venv/lib/python3.12/site-packages/ds18x20.pyi b/.venv/lib/python3.12/site-packages/ds18x20.pyi new file mode 100644 index 0000000..a1f9a03 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/ds18x20.pyi @@ -0,0 +1,16 @@ +from _typeshed import Incomplete +from micropython import const as const + +_CONVERT: int +_RD_SCRATCH: int +_WR_SCRATCH: int + +class DS18X20: + ow: Incomplete + buf: Incomplete + def __init__(self, onewire) -> None: ... + def scan(self): ... + def convert_temp(self) -> None: ... + def read_scratch(self, rom): ... + def write_scratch(self, rom, buf) -> None: ... + def read_temp(self, rom): ... diff --git a/.venv/lib/python3.12/site-packages/errno.pyi b/.venv/lib/python3.12/site-packages/errno.pyi new file mode 100644 index 0000000..3c6fbc6 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/errno.pyi @@ -0,0 +1,45 @@ +""" +System error codes. + +MicroPython module: https://docs.micropython.org/en/v1.26.0/library/errno.html + +CPython module: :mod:`python:errno` https://docs.python.org/3/library/errno.html . + +This module provides access to symbolic error codes for `OSError` exception. +A particular inventory of codes depends on :term:`MicroPython port`. + +--- +Module: 'errno' on micropython-v1.26.0-rp2-RPI_PICO +""" + +# MCU: {'mpy': 'v6.3', 'build': '', 'ver': '1.26.0', 'arch': 'armv6m', 'version': '1.26.0', 'port': 'rp2', 'board': 'RPI_PICO', 'family': 'micropython', 'board_id': 'RPI_PICO', 'variant': '', 'cpu': 'RP2040'} +# Stubber: v1.26.0 +from __future__ import annotations +from typing import Dict, Final +from _typeshed import Incomplete +from typing_extensions import Awaitable, TypeAlias, TypeVar + +ENOBUFS: Final[int] = 105 +ENODEV: Final[int] = 19 +ENOENT: Final[int] = 2 +EISDIR: Final[int] = 21 +EIO: Final[int] = 5 +EINVAL: Final[int] = 22 +EPERM: Final[int] = 1 +ETIMEDOUT: Final[int] = 110 +ENOMEM: Final[int] = 12 +EOPNOTSUPP: Final[int] = 95 +ENOTCONN: Final[int] = 107 +errorcode: dict = {} +EAGAIN: Final[int] = 11 +EALREADY: Final[int] = 114 +EBADF: Final[int] = 9 +EADDRINUSE: Final[int] = 98 +EACCES: Final[int] = 13 +EINPROGRESS: Final[int] = 115 +EEXIST: Final[int] = 17 +EHOSTUNREACH: Final[int] = 113 +ECONNABORTED: Final[int] = 103 +ECONNRESET: Final[int] = 104 +ECONNREFUSED: Final[int] = 111 +ENOTSUP: Final[int] = ... diff --git a/.venv/lib/python3.12/site-packages/framebuf.pyi b/.venv/lib/python3.12/site-packages/framebuf.pyi new file mode 100644 index 0000000..7b502b5 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/framebuf.pyi @@ -0,0 +1,227 @@ +""" +Frame buffer manipulation. + +MicroPython module: https://docs.micropython.org/en/v1.26.0/library/framebuf.html + +This module provides a general frame buffer which can be used to create +bitmap images, which can then be sent to a display. + +--- +Module: 'framebuf' on micropython-v1.26.0-rp2-RPI_PICO +""" + +# MCU: {'mpy': 'v6.3', 'build': '', 'ver': '1.26.0', 'arch': 'armv6m', 'version': '1.26.0', 'port': 'rp2', 'board': 'RPI_PICO', 'family': 'micropython', 'board_id': 'RPI_PICO', 'variant': '', 'cpu': 'RP2040'} +# Stubber: v1.26.0 +from __future__ import annotations +from typing import Any, Optional, overload, Final +from _typeshed import Incomplete +from _mpy_shed import AnyReadableBuf, AnyWritableBuf +from typing_extensions import Awaitable, TypeAlias, TypeVar + +MONO_HMSB: Final[int] = 4 +MONO_HLSB: Final[int] = 3 +RGB565: Final[int] = 1 +MONO_VLSB: Final[int] = 0 +MVLSB: Final[int] = 0 +GS2_HMSB: Final[int] = 5 +GS8: Final[int] = 6 +GS4_HMSB: Final[int] = 2 + +def FrameBuffer1(*args, **kwargs) -> Incomplete: ... + +class FrameBuffer: + """ + The FrameBuffer class provides a pixel buffer which can be drawn upon with + pixels, lines, rectangles, text and even other FrameBuffer's. It is useful + when generating output for displays. + + For example:: + + import framebuf + + # FrameBuffer needs 2 bytes for every RGB565 pixel + fbuf = framebuf.FrameBuffer(bytearray(100 * 10 * 2), 100, 10, framebuf.RGB565) + + fbuf.fill(0) + fbuf.text('MicroPython!', 0, 0, 0xffff) + fbuf.hline(0, 9, 96, 0xffff) + """ + + def poly(self, x, y, coords, c, f: Optional[Any] = None) -> Incomplete: + """ + Given a list of coordinates, draw an arbitrary (convex or concave) closed + polygon at the given x, y location using the given color. + + The *coords* must be specified as a :mod:`array` of integers, e.g. + ``array('h', [x0, y0, x1, y1, ... xn, yn])``. + + The optional *f* parameter can be set to ``True`` to fill the polygon. + Otherwise just a one pixel outline is drawn. + """ + ... + + def vline(self, x: int, y: int, h: int, c: int, /) -> None: + """ + Draw a line from a set of coordinates using the given color and + a thickness of 1 pixel. The `line` method draws the line up to + a second set of coordinates whereas the `hline` and `vline` + methods draw horizontal and vertical lines respectively up to + a given length. + """ + + @overload + def pixel(self, x: int, y: int, /) -> int: + """ + If *c* is not given, get the color value of the specified pixel. + If *c* is given, set the specified pixel to the given color. + """ + + @overload + def pixel(self, x: int, y: int, c: int, /) -> None: + """ + If *c* is not given, get the color value of the specified pixel. + If *c* is given, set the specified pixel to the given color. + """ + + def text(self, s: str, x: int, y: int, c: int = 1, /) -> None: + """ + Write text to the FrameBuffer using the coordinates as the upper-left + corner of the text. The color of the text can be defined by the optional + argument but is otherwise a default value of 1. All characters have + dimensions of 8x8 pixels and there is currently no way to change the font. + """ + ... + + def rect(self, x: int, y: int, w: int, h: int, c: int, /) -> None: + """ + Draw a rectangle at the given location, size and color. + + The optional *f* parameter can be set to ``True`` to fill the rectangle. + Otherwise just a one pixel outline is drawn. + """ + ... + + def scroll(self, xstep: int, ystep: int, /) -> None: + """ + Shift the contents of the FrameBuffer by the given vector. This may + leave a footprint of the previous colors in the FrameBuffer. + """ + ... + + def ellipse(self, x, y, xr, yr, c, f, m: Optional[Any] = None) -> None: + """ + Draw an ellipse at the given location. Radii *xr* and *yr* define the + geometry; equal values cause a circle to be drawn. The *c* parameter + defines the color. + + The optional *f* parameter can be set to ``True`` to fill the ellipse. + Otherwise just a one pixel outline is drawn. + + The optional *m* parameter enables drawing to be restricted to certain + quadrants of the ellipse. The LS four bits determine which quadrants are + to be drawn, with bit 0 specifying Q1, b1 Q2, b2 Q3 and b3 Q4. Quadrants + are numbered counterclockwise with Q1 being top right. + """ + ... + + def line(self, x1: int, y1: int, x2: int, y2: int, c: int, /) -> None: + """ + Draw a line from a set of coordinates using the given color and + a thickness of 1 pixel. The `line` method draws the line up to + a second set of coordinates whereas the `hline` and `vline` + methods draw horizontal and vertical lines respectively up to + a given length. + """ + ... + + def blit( + self, + fbuf: FrameBuffer, + x: int, + y: int, + key: int = -1, + palette: Optional[bytes] = None, + /, + ) -> None: + """ + Draw another FrameBuffer on top of the current one at the given coordinates. + If *key* is specified then it should be a color integer and the + corresponding color will be considered transparent: all pixels with that + color value will not be drawn. (If the *palette* is specified then the *key* + is compared to the value from *palette*, not to the value directly from + *fbuf*.) + + *fbuf* can be another FrameBuffer instance, or a tuple or list of the form:: + + (buffer, width, height, format) + + or:: + + (buffer, width, height, format, stride) + + This matches the signature of the FrameBuffer constructor, and the elements + of the tuple/list are the same as the arguments to the constructor except that + the *buffer* here can be read-only. + + The *palette* argument enables blitting between FrameBuffers with differing + formats. Typical usage is to render a monochrome or grayscale glyph/icon to + a color display. The *palette* is a FrameBuffer instance whose format is + that of the current FrameBuffer. The *palette* height is one pixel and its + pixel width is the number of colors in the source FrameBuffer. The *palette* + for an N-bit source needs 2**N pixels; the *palette* for a monochrome source + would have 2 pixels representing background and foreground colors. The + application assigns a color to each pixel in the *palette*. The color of the + current pixel will be that of that *palette* pixel whose x position is the + color of the corresponding source pixel. + """ + ... + + def hline(self, x: int, y: int, w: int, c: int, /) -> None: + """ + Draw a line from a set of coordinates using the given color and + a thickness of 1 pixel. The `line` method draws the line up to + a second set of coordinates whereas the `hline` and `vline` + methods draw horizontal and vertical lines respectively up to + a given length. + """ + + def fill(self, c: int, /) -> None: + """ + Fill the entire FrameBuffer with the specified color. + """ + ... + + def fill_rect(self, *args, **kwargs) -> Incomplete: ... + def __init__( + self, + buffer: AnyWritableBuf, + width: int, + height: int, + format: int, + stride: int = ..., + /, + ) -> None: + """ + Construct a FrameBuffer object. The parameters are: + + - *buffer* is an object with a buffer protocol which must be large + enough to contain every pixel defined by the width, height and + format of the FrameBuffer. + - *width* is the width of the FrameBuffer in pixels + - *height* is the height of the FrameBuffer in pixels + - *format* specifies the type of pixel used in the FrameBuffer; + permissible values are listed under Constants below. These set the + number of bits used to encode a color value and the layout of these + bits in *buffer*. + Where a color value c is passed to a method, c is a small integer + with an encoding that is dependent on the format of the FrameBuffer. + - *stride* is the number of pixels between each horizontal line + of pixels in the FrameBuffer. This defaults to *width* but may + need adjustments when implementing a FrameBuffer within another + larger FrameBuffer or screen. The *buffer* size must accommodate + an increased step size. + + One must specify valid *buffer*, *width*, *height*, *format* and + optionally *stride*. Invalid *buffer* size or dimensions may lead to + unexpected errors. + """ diff --git a/.venv/lib/python3.12/site-packages/gc.pyi b/.venv/lib/python3.12/site-packages/gc.pyi new file mode 100644 index 0000000..3d7a77b --- /dev/null +++ b/.venv/lib/python3.12/site-packages/gc.pyi @@ -0,0 +1,112 @@ +""" +Control the garbage collector. + +MicroPython module: https://docs.micropython.org/en/v1.26.0/library/gc.html + +CPython module: :mod:`python:gc` https://docs.python.org/3/library/gc.html . + +--- +Module: 'gc' on micropython-v1.26.0-rp2-RPI_PICO +""" + +# MCU: {'mpy': 'v6.3', 'build': '', 'ver': '1.26.0', 'arch': 'armv6m', 'version': '1.26.0', 'port': 'rp2', 'board': 'RPI_PICO', 'family': 'micropython', 'board_id': 'RPI_PICO', 'variant': '', 'cpu': 'RP2040'} +# Stubber: v1.26.0 +from __future__ import annotations +from _typeshed import Incomplete +from typing import overload +from typing_extensions import Awaitable, TypeAlias, TypeVar + +def mem_alloc() -> int: + """ + Return the number of bytes of heap RAM that are allocated by Python code. + + Admonition:Difference to CPython + :class: attention + + This function is MicroPython extension. + """ + ... + +def isenabled(*args, **kwargs) -> Incomplete: ... +def mem_free() -> int: + """ + Return the number of bytes of heap RAM that is available for Python + code to allocate, or -1 if this amount is not known. + + Admonition:Difference to CPython + :class: attention + + This function is MicroPython extension. + """ + ... + +@overload +def threshold() -> int: + """ + Set or query the additional GC allocation threshold. Normally, a collection + is triggered only when a new allocation cannot be satisfied, i.e. on an + out-of-memory (OOM) condition. If this function is called, in addition to + OOM, a collection will be triggered each time after *amount* bytes have been + allocated (in total, since the previous time such an amount of bytes + have been allocated). *amount* is usually specified as less than the + full heap size, with the intention to trigger a collection earlier than when the + heap becomes exhausted, and in the hope that an early collection will prevent + excessive memory fragmentation. This is a heuristic measure, the effect + of which will vary from application to application, as well as + the optimal value of the *amount* parameter. + + Calling the function without argument will return the current value of + the threshold. A value of -1 means a disabled allocation threshold. + + Admonition:Difference to CPython + :class: attention + + This function is a MicroPython extension. CPython has a similar + function - ``set_threshold()``, but due to different GC + implementations, its signature and semantics are different. + """ + +@overload +def threshold(amount: int) -> None: + """ + Set or query the additional GC allocation threshold. Normally, a collection + is triggered only when a new allocation cannot be satisfied, i.e. on an + out-of-memory (OOM) condition. If this function is called, in addition to + OOM, a collection will be triggered each time after *amount* bytes have been + allocated (in total, since the previous time such an amount of bytes + have been allocated). *amount* is usually specified as less than the + full heap size, with the intention to trigger a collection earlier than when the + heap becomes exhausted, and in the hope that an early collection will prevent + excessive memory fragmentation. This is a heuristic measure, the effect + of which will vary from application to application, as well as + the optimal value of the *amount* parameter. + + Calling the function without argument will return the current value of + the threshold. A value of -1 means a disabled allocation threshold. + + Admonition:Difference to CPython + :class: attention + + This function is a MicroPython extension. CPython has a similar + function - ``set_threshold()``, but due to different GC + implementations, its signature and semantics are different. + """ + +def collect() -> None: + """ + Run a garbage collection. + """ + ... + +def enable() -> None: + """ + Enable automatic garbage collection. + """ + ... + +def disable() -> None: + """ + Disable automatic garbage collection. Heap memory can still be allocated, + and garbage collection can still be initiated manually using :meth:`gc.collect`. + """ + ... diff --git a/.venv/lib/python3.12/site-packages/hashlib.pyi b/.venv/lib/python3.12/site-packages/hashlib.pyi new file mode 100644 index 0000000..4ff97f3 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/hashlib.pyi @@ -0,0 +1,104 @@ +""" +Hashing algorithms. + +MicroPython module: https://docs.micropython.org/en/v1.26.0/library/hashlib.html + +CPython module: :mod:`python:hashlib` https://docs.python.org/3/library/hashlib.html . + +This module implements binary data hashing algorithms. The exact inventory +of available algorithms depends on a board. Among the algorithms which may +be implemented: + +* SHA256 - The current generation, modern hashing algorithm (of SHA2 series). + It is suitable for cryptographically-secure purposes. Included in the + MicroPython core and any board is recommended to provide this, unless + it has particular code size constraints. + +* SHA1 - A previous generation algorithm. Not recommended for new usages, + but SHA1 is a part of number of Internet standards and existing + applications, so boards targeting network connectivity and + interoperability will try to provide this. + +* MD5 - A legacy algorithm, not considered cryptographically secure. Only + selected boards, targeting interoperability with legacy applications, + will offer this. + +--- +Module: 'hashlib' on micropython-v1.26.0-rp2-RPI_PICO +""" + +# MCU: {'mpy': 'v6.3', 'build': '', 'ver': '1.26.0', 'arch': 'armv6m', 'version': '1.26.0', 'port': 'rp2', 'board': 'RPI_PICO', 'family': 'micropython', 'board_id': 'RPI_PICO', 'variant': '', 'cpu': 'RP2040'} +# Stubber: v1.26.0 +from __future__ import annotations +from _typeshed import Incomplete +from _mpy_shed import AnyReadableBuf, AnyWritableBuf, _Hash +from typing import overload +from typing_extensions import Awaitable, TypeAlias, TypeVar + +class sha256(_Hash): + """ + The current generation, modern hashing algorithm (of SHA2 series). + It is suitable for cryptographically-secure purposes. Included in the + MicroPython core and any board is recommended to provide this, unless + it has particular code size constraints. + """ + + def digest(self, *args, **kwargs) -> Incomplete: ... + def update(self, *args, **kwargs) -> Incomplete: ... + @overload + def __init__(self): + """ + Create an SHA256 hasher object and optionally feed ``data`` into it. + """ + + @overload + def __init__(self, data: AnyReadableBuf): + """ + Create an SHA256 hasher object and optionally feed ``data`` into it. + """ + + @overload + def __init__(self): + """ + Create an SHA256 hasher object and optionally feed ``data`` into it. + """ + + @overload + def __init__(self, data: AnyReadableBuf): + """ + Create an SHA256 hasher object and optionally feed ``data`` into it. + """ + +class sha1(_Hash): + """ + A previous generation algorithm. Not recommended for new usages, + but SHA1 is a part of number of Internet standards and existing + applications, so boards targeting network connectivity and + interoperability will try to provide this. + """ + + def digest(self, *args, **kwargs) -> Incomplete: ... + def update(self, *args, **kwargs) -> Incomplete: ... + @overload + def __init__(self): + """ + Create an SHA1 hasher object and optionally feed ``data`` into it. + """ + + @overload + def __init__(self, data: AnyReadableBuf): + """ + Create an SHA1 hasher object and optionally feed ``data`` into it. + """ + + @overload + def __init__(self): + """ + Create an SHA1 hasher object and optionally feed ``data`` into it. + """ + + @overload + def __init__(self, data: AnyReadableBuf): + """ + Create an SHA1 hasher object and optionally feed ``data`` into it. + """ diff --git a/.venv/lib/python3.12/site-packages/heapq.pyi b/.venv/lib/python3.12/site-packages/heapq.pyi new file mode 100644 index 0000000..dd452a4 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/heapq.pyi @@ -0,0 +1,46 @@ +""" +Heap queue algorithm. + +MicroPython module: https://docs.micropython.org/en/v1.26.0/library/heapq.html + +CPython module: :mod:`python:heapq` https://docs.python.org/3/library/heapq.html . + +This module implements the +`min heap queue algorithm `_. + +A heap queue is essentially a list that has its elements stored in such a way +that the first item of the list is always the smallest. + +--- +Module: 'heapq' on micropython-v1.26.0-rp2-RPI_PICO +""" + +# MCU: {'mpy': 'v6.3', 'build': '', 'ver': '1.26.0', 'arch': 'armv6m', 'version': '1.26.0', 'port': 'rp2', 'board': 'RPI_PICO', 'family': 'micropython', 'board_id': 'RPI_PICO', 'variant': '', 'cpu': 'RP2040'} +# Stubber: v1.26.0 +from __future__ import annotations +from _typeshed import Incomplete +from typing import Any +from typing_extensions import Awaitable, TypeAlias, TypeVar + +_T = TypeVar("_T") + +def heappop(heap: list[_T], /) -> _T: + """ + Pop the first item from the ``heap``, and return it. Raise ``IndexError`` if + ``heap`` is empty. + + The returned item will be the smallest item in the ``heap``. + """ + ... + +def heappush(heap: list[_T], item: _T, /) -> None: + """ + Push the ``item`` onto the ``heap``. + """ + ... + +def heapify(x: list[Any], /) -> None: + """ + Convert the list ``x`` into a heap. This is an in-place operation. + """ + ... diff --git a/.venv/lib/python3.12/site-packages/machine.pyi b/.venv/lib/python3.12/site-packages/machine.pyi new file mode 100644 index 0000000..6f62fb7 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/machine.pyi @@ -0,0 +1,3165 @@ +""" +Functions related to the hardware. + +MicroPython module: https://docs.micropython.org/en/v1.26.0/library/machine.html + +The ``machine`` module contains specific functions related to the hardware +on a particular board. Most functions in this module allow to achieve direct +and unrestricted access to and control of hardware blocks on a system +(like CPU, timers, buses, etc.). Used incorrectly, this can lead to +malfunction, lockups, crashes of your board, and in extreme cases, hardware +damage. + +--- +Module: 'machine' on micropython-v1.26.0-rp2-RPI_PICO +""" + +# MCU: {'mpy': 'v6.3', 'build': '', 'ver': '1.26.0', 'arch': 'armv6m', 'version': '1.26.0', 'port': 'rp2', 'board': 'RPI_PICO', 'family': 'micropython', 'board_id': 'RPI_PICO', 'variant': '', 'cpu': 'RP2040'} +# Stubber: v1.26.0 +from __future__ import annotations +from typing import NoReturn, Union, Tuple, Callable, List, Sequence, Any, Optional, overload, Final +from _typeshed import Incomplete +from _mpy_shed import _IRQ, AnyReadableBuf, AnyWritableBuf, mp_available +from typing_extensions import Awaitable, TypeAlias, TypeVar, deprecated +from vfs import AbstractBlockDev + +PWRON_RESET: Final[int] = 1 +WDT_RESET: Final[int] = 3 +ATTN_0DB: int = ... +ID_T: TypeAlias = int | str +PinLike: TypeAlias = Pin | int | str +IDLE: Incomplete +SLEEP: Incomplete +DEEPSLEEP: Incomplete +HARD_RESET: Incomplete +DEEPSLEEP_RESET: Incomplete +SOFT_RESET: Incomplete +WLAN_WAKE: Incomplete +PIN_WAKE: Incomplete +RTC_WAKE: Incomplete +_IRQ_STATE: TypeAlias = int + +def dht_readinto(*args, **kwargs) -> Incomplete: ... +def disable_irq() -> _IRQ_STATE: + """ + Disable interrupt requests. + Returns the previous IRQ state which should be considered an opaque value. + This return value should be passed to the `enable_irq()` function to restore + interrupts to their original state, before `disable_irq()` was called. + """ + ... + +def enable_irq(state: _IRQ_STATE, /) -> None: + """ + Re-enable interrupt requests. + The *state* parameter should be the value that was returned from the most + recent call to the `disable_irq()` function. + """ + ... + +def bitstream(pin, encoding, timing, data, /) -> Incomplete: + """ + Transmits *data* by bit-banging the specified *pin*. The *encoding* argument + specifies how the bits are encoded, and *timing* is an encoding-specific timing + specification. + + The supported encodings are: + + - ``0`` for "high low" pulse duration modulation. This will transmit 0 and + 1 bits as timed pulses, starting with the most significant bit. + The *timing* must be a four-tuple of nanoseconds in the format + ``(high_time_0, low_time_0, high_time_1, low_time_1)``. For example, + ``(400, 850, 800, 450)`` is the timing specification for WS2812 RGB LEDs + at 800kHz. + + The accuracy of the timing varies between ports. On Cortex M0 at 48MHz, it is + at best +/- 120ns, however on faster MCUs (ESP8266, ESP32, STM32, Pyboard), it + will be closer to +/-30ns. + + ``Note:`` For controlling WS2812 / NeoPixel strips, see the :mod:`neopixel` + module for a higher-level API. + """ + ... + +@overload +def deepsleep() -> NoReturn: + """ + Stops execution in an attempt to enter a low power state. + + If *time_ms* is specified then this will be the maximum time in milliseconds that + the sleep will last for. Otherwise the sleep can last indefinitely. + + With or without a timeout, execution may resume at any time if there are events + that require processing. Such events, or wake sources, should be configured before + sleeping, like `Pin` change or `RTC` timeout. + + The precise behaviour and power-saving capabilities of lightsleep and deepsleep is + highly dependent on the underlying hardware, but the general properties are: + + * A lightsleep has full RAM and state retention. Upon wake execution is resumed + from the point where the sleep was requested, with all subsystems operational. + + * A deepsleep may not retain RAM or any other state of the system (for example + peripherals or network interfaces). Upon wake execution is resumed from the main + script, similar to a hard or power-on reset. The `reset_cause()` function will + return `machine.DEEPSLEEP` and this can be used to distinguish a deepsleep wake + from other resets. + """ + +@overload +def deepsleep(time_ms: int, /) -> NoReturn: + """ + Stops execution in an attempt to enter a low power state. + + If *time_ms* is specified then this will be the maximum time in milliseconds that + the sleep will last for. Otherwise the sleep can last indefinitely. + + With or without a timeout, execution may resume at any time if there are events + that require processing. Such events, or wake sources, should be configured before + sleeping, like `Pin` change or `RTC` timeout. + + The precise behaviour and power-saving capabilities of lightsleep and deepsleep is + highly dependent on the underlying hardware, but the general properties are: + + * A lightsleep has full RAM and state retention. Upon wake execution is resumed + from the point where the sleep was requested, with all subsystems operational. + + * A deepsleep may not retain RAM or any other state of the system (for example + peripherals or network interfaces). Upon wake execution is resumed from the main + script, similar to a hard or power-on reset. The `reset_cause()` function will + return `machine.DEEPSLEEP` and this can be used to distinguish a deepsleep wake + from other resets. + """ + +def bootloader(value: Optional[Any] = None) -> None: + """ + Reset the device and enter its bootloader. This is typically used to put the + device into a state where it can be programmed with new firmware. + + Some ports support passing in an optional *value* argument which can control + which bootloader to enter, what to pass to it, or other things. + """ + ... + +def unique_id() -> bytes: + """ + Returns a byte string with a unique identifier of a board/SoC. It will vary + from a board/SoC instance to another, if underlying hardware allows. Length + varies by hardware (so use substring of a full value if you expect a short + ID). In some MicroPython ports, ID corresponds to the network MAC address. + """ + ... + +def soft_reset() -> NoReturn: + """ + Performs a :ref:`soft reset ` of the interpreter, deleting all + Python objects and resetting the Python heap. + """ + ... + +def reset_cause() -> int: + """ + Get the reset cause. See :ref:`constants ` for the possible return values. + """ + ... + +def time_pulse_us(pin: Pin, pulse_level: int, timeout_us: int = 1_000_000, /) -> int: + """ + Time a pulse on the given *pin*, and return the duration of the pulse in + microseconds. The *pulse_level* argument should be 0 to time a low pulse + or 1 to time a high pulse. + + If the current input value of the pin is different to *pulse_level*, + the function first (*) waits until the pin input becomes equal to *pulse_level*, + then (**) times the duration that the pin is equal to *pulse_level*. + If the pin is already equal to *pulse_level* then timing starts straight away. + + The function will return -2 if there was timeout waiting for condition marked + (*) above, and -1 if there was timeout during the main measurement, marked (**) + above. The timeout is the same for both cases and given by *timeout_us* (which + is in microseconds). + """ + ... + +@overload +def freq() -> int: + """ + Returns the CPU frequency in hertz. + + On some ports this can also be used to set the CPU frequency by passing in *hz*. + """ + +@overload +def freq(hz: int, /) -> None: + """ + Returns the CPU frequency in hertz. + + On some ports this can also be used to set the CPU frequency by passing in *hz*. + """ + +@overload +def freq(self) -> int: + """ + Returns the CPU frequency in hertz. + + On some ports this can also be used to set the CPU frequency by passing in *hz*. + """ + +@overload +def freq( + self, + value: int, + /, +) -> None: + """ + Returns the CPU frequency in hertz. + + On some ports this can also be used to set the CPU frequency by passing in *hz*. + """ + +def idle() -> None: + """ + Gates the clock to the CPU, useful to reduce power consumption at any time + during short or long periods. Peripherals continue working and execution + resumes as soon as any interrupt is triggered, or at most one millisecond + after the CPU was paused. + + It is recommended to call this function inside any tight loop that is + continuously checking for an external change (i.e. polling). This will reduce + power consumption without significantly impacting performance. To reduce + power consumption further then see the :func:`lightsleep`, + :func:`time.sleep()` and :func:`time.sleep_ms()` functions. + """ + ... + +def reset() -> NoReturn: + """ + :ref:`Hard resets ` the device in a manner similar to pushing the + external RESET button. + """ + ... + +@overload +def lightsleep() -> None: + """ + Stops execution in an attempt to enter a low power state. + + If *time_ms* is specified then this will be the maximum time in milliseconds that + the sleep will last for. Otherwise the sleep can last indefinitely. + + With or without a timeout, execution may resume at any time if there are events + that require processing. Such events, or wake sources, should be configured before + sleeping, like `Pin` change or `RTC` timeout. + + The precise behaviour and power-saving capabilities of lightsleep and deepsleep is + highly dependent on the underlying hardware, but the general properties are: + + * A lightsleep has full RAM and state retention. Upon wake execution is resumed + from the point where the sleep was requested, with all subsystems operational. + + * A deepsleep may not retain RAM or any other state of the system (for example + peripherals or network interfaces). Upon wake execution is resumed from the main + script, similar to a hard or power-on reset. The `reset_cause()` function will + return `machine.DEEPSLEEP` and this can be used to distinguish a deepsleep wake + from other resets. + """ + +@overload +def lightsleep(time_ms: int, /) -> None: + """ + Stops execution in an attempt to enter a low power state. + + If *time_ms* is specified then this will be the maximum time in milliseconds that + the sleep will last for. Otherwise the sleep can last indefinitely. + + With or without a timeout, execution may resume at any time if there are events + that require processing. Such events, or wake sources, should be configured before + sleeping, like `Pin` change or `RTC` timeout. + + The precise behaviour and power-saving capabilities of lightsleep and deepsleep is + highly dependent on the underlying hardware, but the general properties are: + + * A lightsleep has full RAM and state retention. Upon wake execution is resumed + from the point where the sleep was requested, with all subsystems operational. + + * A deepsleep may not retain RAM or any other state of the system (for example + peripherals or network interfaces). Upon wake execution is resumed from the main + script, similar to a hard or power-on reset. The `reset_cause()` function will + return `machine.DEEPSLEEP` and this can be used to distinguish a deepsleep wake + from other resets. + """ + +mem8: Incomplete ## = <8-bit memory> +mem32: Incomplete ## = <32-bit memory> +mem16: Incomplete ## = <16-bit memory> + +class PWM: + """ + This class provides pulse width modulation output. + + Example usage:: + + from machine import PWM + + pwm = PWM(pin) # create a PWM object on a pin + pwm.duty_u16(32768) # set duty to 50% + + # reinitialise with a period of 200us, duty of 5us + pwm.init(freq=5000, duty_ns=5000) + + pwm.duty_ns(3000) # set pulse width to 3us + + pwm.deinit() + + + Limitations of PWM + ------------------ + + * Not all frequencies can be generated with absolute accuracy due to + the discrete nature of the computing hardware. Typically the PWM frequency + is obtained by dividing some integer base frequency by an integer divider. + For example, if the base frequency is 80MHz and the required PWM frequency is + 300kHz the divider must be a non-integer number 80000000 / 300000 = 266.67. + After rounding the divider is set to 267 and the PWM frequency will be + 80000000 / 267 = 299625.5 Hz, not 300kHz. If the divider is set to 266 then + the PWM frequency will be 80000000 / 266 = 300751.9 Hz, but again not 300kHz. + + * The duty cycle has the same discrete nature and its absolute accuracy is not + achievable. On most hardware platforms the duty will be applied at the next + frequency period. Therefore, you should wait more than "1/frequency" before + measuring the duty. + + * The frequency and the duty cycle resolution are usually interdependent. + The higher the PWM frequency the lower the duty resolution which is available, + and vice versa. For example, a 300kHz PWM frequency can have a duty cycle + resolution of 8 bit, not 16-bit as may be expected. In this case, the lowest + 8 bits of *duty_u16* are insignificant. So:: + + pwm=PWM(Pin(13), freq=300_000, duty_u16=2**16//2) + + and:: + + pwm=PWM(Pin(13), freq=300_000, duty_u16=2**16//2 + 255) + + will generate PWM with the same 50% duty cycle. + """ + + @overload + def duty_u16(self) -> int: + """ + Get or set the current duty cycle of the PWM output, as an unsigned 16-bit + value in the range 0 to 65535 inclusive. + + With no arguments the duty cycle is returned. + + With a single *value* argument the duty cycle is set to that value, measured + as the ratio ``value / 65535``. + """ + + @overload + def duty_u16( + self, + value: int, + /, + ) -> None: + """ + Get or set the current duty cycle of the PWM output, as an unsigned 16-bit + value in the range 0 to 65535 inclusive. + + With no arguments the duty cycle is returned. + + With a single *value* argument the duty cycle is set to that value, measured + as the ratio ``value / 65535``. + """ + + @overload + def freq(self) -> int: + """ + Get or set the current frequency of the PWM output. + + With no arguments the frequency in Hz is returned. + + With a single *value* argument the frequency is set to that value in Hz. The + method may raise a ``ValueError`` if the frequency is outside the valid range. + """ + + @overload + def freq( + self, + value: int, + /, + ) -> None: + """ + Get or set the current frequency of the PWM output. + + With no arguments the frequency in Hz is returned. + + With a single *value* argument the frequency is set to that value in Hz. The + method may raise a ``ValueError`` if the frequency is outside the valid range. + """ + + def init(self, *, freq: int = ..., duty_u16: int = ..., duty_ns: int = ...) -> None: + """ + Modify settings for the PWM object. See the above constructor for details + about the parameters. + """ + ... + + @overload + def duty_ns(self) -> int: + """ + Get or set the current pulse width of the PWM output, as a value in nanoseconds. + + With no arguments the pulse width in nanoseconds is returned. + + With a single *value* argument the pulse width is set to that value. + """ + + @overload + def duty_ns( + self, + value: int, + /, + ) -> None: + """ + Get or set the current pulse width of the PWM output, as a value in nanoseconds. + + With no arguments the pulse width in nanoseconds is returned. + + With a single *value* argument the pulse width is set to that value. + """ + + def deinit(self) -> None: + """ + Disable the PWM output. + """ + ... + + def __init__( + self, + dest: PinLike, + /, + *, + freq: int = ..., + duty_u16: int = ..., + duty_ns: int = ..., + ) -> None: + """ + Construct and return a new PWM object using the following parameters: + + - *dest* is the entity on which the PWM is output, which is usually a + :ref:`machine.Pin ` object, but a port may allow other values, + like integers. + - *freq* should be an integer which sets the frequency in Hz for the + PWM cycle. + - *duty_u16* sets the duty cycle as a ratio ``duty_u16 / 65535``. + - *duty_ns* sets the pulse width in nanoseconds. + + Setting *freq* may affect other PWM objects if the objects share the same + underlying PWM generator (this is hardware specific). + Only one of *duty_u16* and *duty_ns* should be specified at a time. + """ + +class WDT: + """ + The WDT is used to restart the system when the application crashes and ends + up into a non recoverable state. Once started it cannot be stopped or + reconfigured in any way. After enabling, the application must "feed" the + watchdog periodically to prevent it from expiring and resetting the system. + + Example usage:: + + from machine import WDT + wdt = WDT(timeout=2000) # enable it with a timeout of 2s + wdt.feed() + + Availability of this class: pyboard, WiPy, esp8266, esp32. + """ + + def feed(self) -> None: + """ + Feed the WDT to prevent it from resetting the system. The application + should place this call in a sensible place ensuring that the WDT is + only fed after verifying that everything is functioning correctly. + """ + ... + + def __init__(self, *, id: int = 0, timeout: int = 5000) -> None: + """ + Create a WDT object and start it. The timeout must be given in milliseconds. + Once it is running the timeout cannot be changed and the WDT cannot be stopped either. + + Notes: On the esp32 the minimum timeout is 1 second. On the esp8266 a timeout + cannot be specified, it is determined by the underlying system. + """ + +class I2S: + """ + I2S is a synchronous serial protocol used to connect digital audio devices. + At the physical level, a bus consists of 3 lines: SCK, WS, SD. + The I2S class supports controller operation. Peripheral operation is not supported. + + The I2S class is currently available as a Technical Preview. During the preview period, feedback from + users is encouraged. Based on this feedback, the I2S class API and implementation may be changed. + + I2S objects can be created and initialized using:: + + from machine import I2S + from machine import Pin + + # ESP32 + sck_pin = Pin(14) # Serial clock output + ws_pin = Pin(13) # Word clock output + sd_pin = Pin(12) # Serial data output + + or + + # PyBoards + sck_pin = Pin("Y6") # Serial clock output + ws_pin = Pin("Y5") # Word clock output + sd_pin = Pin("Y8") # Serial data output + + audio_out = I2S(2, + sck=sck_pin, ws=ws_pin, sd=sd_pin, + mode=I2S.TX, + bits=16, + format=I2S.MONO, + rate=44100, + ibuf=20000) + + audio_in = I2S(2, + sck=sck_pin, ws=ws_pin, sd=sd_pin, + mode=I2S.RX, + bits=32, + format=I2S.STEREO, + rate=22050, + ibuf=20000) + + 3 modes of operation are supported: + - blocking + - non-blocking + - uasyncio + + blocking:: + + num_written = audio_out.write(buf) # blocks until buf emptied + + num_read = audio_in.readinto(buf) # blocks until buf filled + + non-blocking:: + + audio_out.irq(i2s_callback) # i2s_callback is called when buf is emptied + num_written = audio_out.write(buf) # returns immediately + + audio_in.irq(i2s_callback) # i2s_callback is called when buf is filled + num_read = audio_in.readinto(buf) # returns immediately + + uasyncio:: + + swriter = uasyncio.StreamWriter(audio_out) + swriter.write(buf) + await swriter.drain() + + sreader = uasyncio.StreamReader(audio_in) + num_read = await sreader.readinto(buf) + """ + + RX: Final[int] = 0 + MONO: Final[int] = 0 + STEREO: Final[int] = 1 + TX: Final[int] = 1 + @staticmethod + def shift( + buf: AnyWritableBuf, + bits: int, + shift: int, + /, + ) -> None: + """ + bitwise shift of all samples contained in ``buf``. ``bits`` specifies sample size in bits. ``shift`` specifies the number of bits to shift each sample. + Positive for left shift, negative for right shift. + Typically used for volume control. Each bit shift changes sample volume by 6dB. + """ + ... + + def init( + self, + *, + sck: PinLike, + ws: PinLike, + sd: PinLike, + mode: int, + bits: int, + format: int, + rate: int, + ibuf: int, + ) -> None: + """ + see Constructor for argument descriptions + """ + ... + + def irq( + self, + handler: Callable[[], None], + /, + ) -> None: + """ + Set a callback. ``handler`` is called when ``buf`` is emptied (``write`` method) or becomes full (``readinto`` method). + Setting a callback changes the ``write`` and ``readinto`` methods to non-blocking operation. + ``handler`` is called in the context of the MicroPython scheduler. + """ + ... + + def readinto( + self, + buf: AnyWritableBuf, + /, + ) -> int: + """ + Read audio samples into the buffer specified by ``buf``. ``buf`` must support the buffer protocol, such as bytearray or array. + "buf" byte ordering is little-endian. For Stereo format, left channel sample precedes right channel sample. For Mono format, + the left channel sample data is used. + Returns number of bytes read + """ + ... + + def deinit(self) -> None: + """ + Deinitialize the I2S bus + """ + ... + + def write( + self, + buf: AnyReadableBuf, + /, + ) -> int: + """ + Write audio samples contained in ``buf``. ``buf`` must support the buffer protocol, such as bytearray or array. + "buf" byte ordering is little-endian. For Stereo format, left channel sample precedes right channel sample. For Mono format, + the sample data is written to both the right and left channels. + Returns number of bytes written + """ + ... + + def __init__( + self, + id: ID_T, + /, + *, + sck: PinLike, + ws: PinLike, + sd: PinLike, + mode: int, + bits: int, + format: int, + rate: int, + ibuf: int, + ) -> None: + """ + Construct an I2S object of the given id: + + - ``id`` identifies a particular I2S bus. + + ``id`` is board and port specific: + + - PYBv1.0/v1.1: has one I2S bus with id=2. + - PYBD-SFxW: has two I2S buses with id=1 and id=2. + - ESP32: has two I2S buses with id=0 and id=1. + + Keyword-only parameters that are supported on all ports: + + - ``sck`` is a pin object for the serial clock line + - ``ws`` is a pin object for the word select line + - ``sd`` is a pin object for the serial data line + - ``mode`` specifies receive or transmit + - ``bits`` specifies sample size (bits), 16 or 32 + - ``format`` specifies channel format, STEREO or MONO + - ``rate`` specifies audio sampling rate (samples/s) + - ``ibuf`` specifies internal buffer length (bytes) + + For all ports, DMA runs continuously in the background and allows user applications to perform other operations while + sample data is transfered between the internal buffer and the I2S peripheral unit. + Increasing the size of the internal buffer has the potential to increase the time that user applications can perform non-I2S operations + before underflow (e.g. ``write`` method) or overflow (e.g. ``readinto`` method). + """ + +class ADC: + """ + The ADC class provides an interface to analog-to-digital convertors, and + represents a single endpoint that can sample a continuous voltage and + convert it to a discretised value. + + Example usage:: + + import machine + + adc = machine.ADC(pin) # create an ADC object acting on a pin + val = adc.read_u16() # read a raw analog value in the range 0-65535 + """ + + CORE_TEMP: Final[int] = 4 + VREF: int = ... + CORE_VREF: int = ... + CORE_VBAT: int = ... + ATTN_0DB: int = 0 + ATTN_2_5DB: int = 1 + ATTN_6DB: int = 2 + ATTN_11DB: int = 3 + WIDTH_9BIT: int = 9 + WIDTH_10BIT: int = 10 + WIDTH_11BIT: int = 11 + WIDTH_12BIT: int = 12 + def read_u16(self) -> int: + """ + Take an analog reading and return an integer in the range 0-65535. + The return value represents the raw reading taken by the ADC, scaled + such that the minimum value is 0 and the maximum value is 65535. + """ + ... + + def __init__(self, pin: PinLike, *, atten=ATTN_0DB) -> None: + """ + Access the ADC associated with a source identified by *id*. This + *id* may be an integer (usually specifying a channel number), a + :ref:`Pin ` object, or other value supported by the + underlying machine. + .. note:: + + WiPy has a custom implementation of ADC, see ADCWiPy for details. + + on ESP32 : `atten` specifies the attenuation level for the ADC input. + """ + # ESP32 specific + @mp_available(port="esp32") + @deprecated("Use ADC.block().init(bits=bits) instead.") + def width(self, bits: int) -> None: + """ + Equivalent to ADC.block().init(bits=bits). + The only chip that can switch resolution to a lower one is the normal esp32. The C2 & S3 are stuck at 12 bits, while the S2 is at 13 bits. + + For compatibility, the ADC object also provides constants matching the supported ADC resolutions, per chip: + + ESP32: + ADC.WIDTH_9BIT = 9 + ADC.WIDTH_10BIT = 10 + ADC.WIDTH_11BIT = 11 + ADC.WIDTH_12BIT = 12 + + ESP32 C3 & S3: + ADC.WIDTH_12BIT = 12 + + ESP32 S2: + ADC.WIDTH_13BIT = 13 + + Available : ESP32 + """ + ... + + @mp_available(port="esp32") + @deprecated("Use read_u16() instead.") + def read(self) -> int: + """ + Take an analog reading and return an integer in the range 0-4095. + The return value represents the raw reading taken by the ADC, scaled + such that the minimum value is 0 and the maximum value is 4095. + + This method is deprecated, use `read_u16()` instead. + + Available : ESP32 + """ + ... + + @mp_available(port="esp32") + @deprecated("Use ADC.init(atten=atten) instead.") + def atten(self, atten: int) -> None: + """ + Set the attenuation level for the ADC input. + + Available : ESP32 + """ + ... + +class I2C: + """ + I2C is a two-wire protocol for communicating between devices. At the physical + level it consists of 2 wires: SCL and SDA, the clock and data lines respectively. + + I2C objects are created attached to a specific bus. They can be initialised + when created, or initialised later on. + + Printing the I2C object gives you information about its configuration. + + Both hardware and software I2C implementations exist via the + :ref:`machine.I2C ` and `machine.SoftI2C` classes. Hardware I2C uses + underlying hardware support of the system to perform the reads/writes and is + usually efficient and fast but may have restrictions on which pins can be used. + Software I2C is implemented by bit-banging and can be used on any pin but is not + as efficient. These classes have the same methods available and differ primarily + in the way they are constructed. + + Example usage:: + + from machine import I2C + + i2c = I2C(freq=400000) # create I2C peripheral at frequency of 400kHz + # depending on the port, extra parameters may be required + # to select the peripheral and/or pins to use + + i2c.scan() # scan for peripherals, returning a list of 7-bit addresses + + i2c.writeto(42, b'123') # write 3 bytes to peripheral with 7-bit address 42 + i2c.readfrom(42, 4) # read 4 bytes from peripheral with 7-bit address 42 + + i2c.readfrom_mem(42, 8, 3) # read 3 bytes from memory of peripheral 42, + # starting at memory-address 8 in the peripheral + i2c.writeto_mem(42, 2, b'\x10') # write 1 byte to memory of peripheral 42 + # starting at address 2 in the peripheral + """ + + def readfrom_mem_into(self, addr: int, memaddr: int, buf: AnyWritableBuf, /, *, addrsize: int = 8) -> None: + """ + Read into *buf* from the peripheral specified by *addr* starting from the + memory address specified by *memaddr*. The number of bytes read is the + length of *buf*. + The argument *addrsize* specifies the address size in bits (on ESP8266 + this argument is not recognised and the address size is always 8 bits). + + The method returns ``None``. + """ + ... + + def readfrom_into(self, addr: int, buf: AnyWritableBuf, stop: bool = True, /) -> None: + """ + Read into *buf* from the peripheral specified by *addr*. + The number of bytes read will be the length of *buf*. + If *stop* is true then a STOP condition is generated at the end of the transfer. + + The method returns ``None``. + """ + ... + + def readfrom_mem(self, addr: int, memaddr: int, nbytes: int, /, *, addrsize: int = 8) -> bytes: + """ + Read *nbytes* from the peripheral specified by *addr* starting from the memory + address specified by *memaddr*. + The argument *addrsize* specifies the address size in bits. + Returns a `bytes` object with the data read. + """ + ... + + def writeto_mem(self, addr: int, memaddr: int, buf: AnyReadableBuf, /, *, addrsize: int = 8) -> None: + """ + Write *buf* to the peripheral specified by *addr* starting from the + memory address specified by *memaddr*. + The argument *addrsize* specifies the address size in bits (on ESP8266 + this argument is not recognised and the address size is always 8 bits). + + The method returns ``None``. + """ + ... + + def scan(self) -> List: + """ + Scan all I2C addresses between 0x08 and 0x77 inclusive and return a list of + those that respond. A device responds if it pulls the SDA line low after + its address (including a write bit) is sent on the bus. + """ + ... + + def writeto(self, addr: int, buf: AnyReadableBuf, stop: bool = True, /) -> int: + """ + Write the bytes from *buf* to the peripheral specified by *addr*. If a + NACK is received following the write of a byte from *buf* then the + remaining bytes are not sent. If *stop* is true then a STOP condition is + generated at the end of the transfer, even if a NACK is received. + The function returns the number of ACKs that were received. + """ + ... + + def writevto(self, addr: int, vector: Sequence[AnyReadableBuf], stop: bool = True, /) -> int: + """ + Write the bytes contained in *vector* to the peripheral specified by *addr*. + *vector* should be a tuple or list of objects with the buffer protocol. + The *addr* is sent once and then the bytes from each object in *vector* + are written out sequentially. The objects in *vector* may be zero bytes + in length in which case they don't contribute to the output. + + If a NACK is received following the write of a byte from one of the + objects in *vector* then the remaining bytes, and any remaining objects, + are not sent. If *stop* is true then a STOP condition is generated at + the end of the transfer, even if a NACK is received. The function + returns the number of ACKs that were received. + """ + ... + + def start(self) -> None: + """ + Generate a START condition on the bus (SDA transitions to low while SCL is high). + """ + ... + + def readfrom(self, addr: int, nbytes: int, stop: bool = True, /) -> bytes: + """ + Read *nbytes* from the peripheral specified by *addr*. + If *stop* is true then a STOP condition is generated at the end of the transfer. + Returns a `bytes` object with the data read. + """ + ... + + def readinto(self, buf: AnyWritableBuf, nack: bool = True, /) -> None: + """ + Reads bytes from the bus and stores them into *buf*. The number of bytes + read is the length of *buf*. An ACK will be sent on the bus after + receiving all but the last byte. After the last byte is received, if *nack* + is true then a NACK will be sent, otherwise an ACK will be sent (and in this + case the peripheral assumes more bytes are going to be read in a later call). + """ + ... + + @overload + def init(self, *, freq: int = 400_000) -> None: + """ + Initialise the I2C bus with the given arguments: + + - *scl* is a pin object for the SCL line + - *sda* is a pin object for the SDA line + - *freq* is the SCL clock rate + + In the case of hardware I2C the actual clock frequency may be lower than the + requested frequency. This is dependent on the platform hardware. The actual + rate may be determined by printing the I2C object. + """ + + @overload + def init(self, *, scl: PinLike, sda: PinLike, freq: int = 400_000) -> None: + """ + Initialise the I2C bus with the given arguments: + + - *scl* is a pin object for the SCL line + - *sda* is a pin object for the SDA line + - *freq* is the SCL clock rate + + In the case of hardware I2C the actual clock frequency may be lower than the + requested frequency. This is dependent on the platform hardware. The actual + rate may be determined by printing the I2C object. + """ + + def stop(self) -> None: + """ + Generate a STOP condition on the bus (SDA transitions to high while SCL is high). + """ + ... + + def write(self, buf: AnyReadableBuf, /) -> int: + """ + Write the bytes from *buf* to the bus. Checks that an ACK is received + after each byte and stops transmitting the remaining bytes if a NACK is + received. The function returns the number of ACKs that were received. + """ + ... + + @overload + def __init__(self, id: ID_T, /, *, freq: int = 400_000): + """ + Construct and return a new I2C object using the following parameters: + + - *id* identifies a particular I2C peripheral. Allowed values for + depend on the particular port/board + - *scl* should be a pin object specifying the pin to use for SCL. + - *sda* should be a pin object specifying the pin to use for SDA. + - *freq* should be an integer which sets the maximum frequency + for SCL. + + Note that some ports/boards will have default values of *scl* and *sda* + that can be changed in this constructor. Others will have fixed values + of *scl* and *sda* that cannot be changed. + """ + + @overload + def __init__(self, id: ID_T, /, *, scl: PinLike, sda: PinLike, freq: int = 400_000): + """ + Construct and return a new I2C object using the following parameters: + + - *id* identifies a particular I2C peripheral. Allowed values for + depend on the particular port/board + - *scl* should be a pin object specifying the pin to use for SCL. + - *sda* should be a pin object specifying the pin to use for SDA. + - *freq* should be an integer which sets the maximum frequency + for SCL. + + Note that some ports/boards will have default values of *scl* and *sda* + that can be changed in this constructor. Others will have fixed values + of *scl* and *sda* that cannot be changed. + """ + + @overload + def __init__(self, *, scl: PinLike, sda: PinLike, freq: int = 400_000) -> None: + """ + Initialise the I2C bus with the given arguments: + + - *scl* is a pin object for the SCL line + - *sda* is a pin object for the SDA line + - *freq* is the SCL clock rate + + In the case of hardware I2C the actual clock frequency may be lower than the + requested frequency. This is dependent on the platform hardware. The actual + rate may be determined by printing the I2C object. + """ + +class I2CTarget: + """ + Construct and return a new I2CTarget object using the following parameters: + + - *id* identifies a particular I2C peripheral. Allowed values depend on the + particular port/board. Some ports have a default in which case this parameter + can be omitted. + - *addr* is the I2C address of the target. + - *addrsize* is the number of bits in the I2C target address. Valid values + are 7 and 10. + - *mem* is an object with the buffer protocol that is writable. If not + specified then there is no backing memory and data must be read/written + using the :meth:`I2CTarget.readinto` and :meth:`I2CTarget.write` methods. + - *mem_addrsize* is the number of bits in the memory address. Valid values + are 0, 8, 16, 24 and 32. + - *scl* is a pin object specifying the pin to use for SCL. + - *sda* is a pin object specifying the pin to use for SDA. + + Note that some ports/boards will have default values of *scl* and *sda* + that can be changed in this constructor. Others will have fixed values + of *scl* and *sda* that cannot be changed. + """ + + IRQ_END_READ: Final[int] = 16 + IRQ_ADDR_MATCH_WRITE: Final[int] = 2 + IRQ_END_WRITE: Final[int] = 32 + IRQ_READ_REQ: Final[int] = 4 + IRQ_ADDR_MATCH_READ: Final[int] = 1 + IRQ_WRITE_REQ: Final[int] = 8 + def deinit(self) -> Incomplete: + """ + Deinitialise the I2C target. After this method is called the hardware will no + longer respond to requests on the I2C bus, and no other methods can be called. + """ + ... + + def irq(self, handler=None, trigger=IRQ_END_READ | IRQ_END_WRITE, hard=False) -> Incomplete: + """ + Configure an IRQ *handler* to be called when an event occurs. The possible events are + given by the following constants, which can be or'd together and passed to the *trigger* + argument: + + - ``IRQ_ADDR_MATCH_READ`` indicates that the target was addressed by a + controller for a read transaction. + - ``IRQ_ADDR_MATCH_READ`` indicates that the target was addressed by a + controller for a write transaction. + - ``IRQ_READ_REQ`` indicates that the controller is requesting data, and this + request must be satisfied by calling `I2CTarget.write` with the data to be + passed back to the controller. + - ``IRQ_WRITE_REQ`` indicates that the controller has written data, and the + data must be read by calling `I2CTarget.readinto`. + - ``IRQ_END_READ`` indicates that the controller has finished a read transaction. + - ``IRQ_END_WRITE`` indicates that the controller has finished a write transaction. + + Not all triggers are available on all ports. If a port has the constant then that + event is available. + + Note the following restrictions: + + - ``IRQ_ADDR_MATCH_READ``, ``IRQ_ADDR_MATCH_READ``, ``IRQ_READ_REQ`` and + ``IRQ_WRITE_REQ`` must be handled by a hard IRQ callback (with the *hard* argument + set to ``True``). This is because these events have very strict timing requirements + and must usually be satisfied synchronously with the hardware event. + + - ``IRQ_END_READ`` and ``IRQ_END_WRITE`` may be handled by either a soft or hard + IRQ callback (although note that all events must be registered with the same handler, + so if any events need a hard callback then all events must be hard). + + - If a memory buffer has been supplied in the constructor then ``IRQ_END_WRITE`` + is not emitted for the transaction that writes the memory address. This is to + allow ``IRQ_END_READ`` and ``IRQ_END_WRITE`` to function correctly as soft IRQ + callbacks, where the IRQ handler may be called quite some time after the actual + hardware event. + """ + ... + + def write(self, buf) -> int: + """ + Write out the bytes from the given buffer, to be passed to the I2C controller + after it sends a read request. Returns the number of bytes written. Most ports + only accept one byte at a time to this method. + """ + ... + + def readinto(self, buf) -> int: + """ + Read into the given buffer any pending bytes written by the I2C controller. + Returns the number of bytes read. + """ + ... + + def __init__(self, id, addr, *, addrsize=7, mem=None, mem_addrsize=8, scl=None, sda=None) -> None: ... + +class SoftSPI(SPI): + """ + Construct a new software SPI object. Additional parameters must be + given, usually at least *sck*, *mosi* and *miso*, and these are used + to initialise the bus. See `SPI.init` for a description of the parameters. + """ + + LSB: Final[int] = 0 + MSB: Final[int] = 1 + def deinit(self, *args, **kwargs) -> Incomplete: ... + def init(self, *args, **kwargs) -> Incomplete: ... + def write_readinto(self, *args, **kwargs) -> Incomplete: ... + def read(self, *args, **kwargs) -> Incomplete: ... + def write(self, *args, **kwargs) -> Incomplete: ... + def readinto(self, *args, **kwargs) -> Incomplete: ... + def __init__( + self, + baudrate=500000, + *, + polarity=0, + phase=0, + bits=8, + firstbit=MSB, + sck: PinLike | None = None, + mosi: PinLike | None = None, + miso: PinLike | None = None, + ) -> None: ... + +class Timer: + """ + Hardware timers deal with timing of periods and events. Timers are perhaps + the most flexible and heterogeneous kind of hardware in MCUs and SoCs, + differently greatly from a model to a model. MicroPython's Timer class + defines a baseline operation of executing a callback with a given period + (or once after some delay), and allow specific boards to define more + non-standard behaviour (which thus won't be portable to other boards). + + See discussion of :ref:`important constraints ` on + Timer callbacks. + + .. note:: + + Memory can't be allocated inside irq handlers (an interrupt) and so + exceptions raised within a handler don't give much information. See + :func:`micropython.alloc_emergency_exception_buf` for how to get around this + limitation. + + If you are using a WiPy board please refer to :ref:`machine.TimerWiPy ` + instead of this class. + """ + + PERIODIC: Final[int] = 1 + ONE_SHOT: Final[int] = 0 + + @overload + def init( + self, + *, + mode: int = PERIODIC, + period: int | None = None, + callback: Callable[[Timer], None] | None = None, + ) -> None: ... + @overload + def init( + self, + *, + mode: int = PERIODIC, + freq: int | None = None, + callback: Callable[[Timer], None] | None = None, + ) -> None: ... + @overload + def init( + self, + *, + mode: int = PERIODIC, + tick_hz: int | None = None, + callback: Callable[[Timer], None] | None = None, + ) -> None: + """ + Initialise the timer. Example:: + + def mycallback(t): + pass + + # periodic at 1kHz + tim.init(mode=Timer.PERIODIC, freq=1000, callback=mycallback) + + # periodic with 100ms period + tim.init(period=100, callback=mycallback) + + # one shot firing after 1000ms + tim.init(mode=Timer.ONE_SHOT, period=1000, callback=mycallback) + + Keyword arguments: + + - ``mode`` can be one of: + + - ``Timer.ONE_SHOT`` - The timer runs once until the configured + period of the channel expires. + - ``Timer.PERIODIC`` - The timer runs periodically at the configured + frequency of the channel. + + - ``freq`` - The timer frequency, in units of Hz. The upper bound of + the frequency is dependent on the port. When both the ``freq`` and + ``period`` arguments are given, ``freq`` has a higher priority and + ``period`` is ignored. + + - ``period`` - The timer period, in milliseconds. + + - ``callback`` - The callable to call upon expiration of the timer period. + The callback must take one argument, which is passed the Timer object. + The ``callback`` argument shall be specified. Otherwise an exception + will occur upon timer expiration: + ``TypeError: 'NoneType' object isn't callable`` + """ + ... + + def deinit(self) -> None: + """ + Deinitialises the timer. Stops the timer, and disables the timer peripheral. + """ + ... + + @overload + def __init__(self, id: int, /): + """ + Construct a new timer object of the given ``id``. ``id`` of -1 constructs a + virtual timer (if supported by a board). + ``id`` shall not be passed as a keyword argument. + + See ``init`` for parameters of initialisation. + """ + + @overload + def __init__( + self, + id: int, + /, + *, + mode: int = PERIODIC, + period: int | None = None, + callback: Callable[[Timer], None] | None = None, + ): + """ + Construct a new timer object of the given ``id``. ``id`` of -1 constructs a + virtual timer (if supported by a board). + ``id`` shall not be passed as a keyword argument. + + See ``init`` for parameters of initialisation. + """ + + @overload + def __init__( + self, + id: int, + /, + *, + mode: int = PERIODIC, + freq: int | None = None, + callback: Callable[[Timer], None] | None = None, + ): + """ + Construct a new timer object of the given ``id``. ``id`` of -1 constructs a + virtual timer (if supported by a board). + ``id`` shall not be passed as a keyword argument. + + See ``init`` for parameters of initialisation. + """ + + @overload + def __init__( + self, + id: int, + /, + *, + mode: int = PERIODIC, + tick_hz: int | None = None, + callback: Callable[[Timer], None] | None = None, + ): + """ + Construct a new timer object of the given ``id``. ``id`` of -1 constructs a + virtual timer (if supported by a board). + ``id`` shall not be passed as a keyword argument. + + See ``init`` for parameters of initialisation. + """ + +class UART: + """ + UART implements the standard UART/USART duplex serial communications protocol. At + the physical level it consists of 2 lines: RX and TX. The unit of communication + is a character (not to be confused with a string character) which can be 8 or 9 + bits wide. + + UART objects can be created and initialised using:: + + from machine import UART + + uart = UART(1, 9600) # init with given baudrate + uart.init(9600, bits=8, parity=None, stop=1) # init with given parameters + + Supported parameters differ on a board: + + Pyboard: Bits can be 7, 8 or 9. Stop can be 1 or 2. With *parity=None*, + only 8 and 9 bits are supported. With parity enabled, only 7 and 8 bits + are supported. + + WiPy/CC3200: Bits can be 5, 6, 7, 8. Stop can be 1 or 2. + + A UART object acts like a `stream` object and reading and writing is done + using the standard stream methods:: + + uart.read(10) # read 10 characters, returns a bytes object + uart.read() # read all available characters + uart.readline() # read a line + uart.readinto(buf) # read and store into the given buffer + uart.write('abc') # write the 3 characters + """ + + INV_TX: Final[int] = 1 + RTS: Final[int] = 2 + INV_RX: Final[int] = 2 + IRQ_TXIDLE: Final[int] = 32 + IRQ_BREAK: Final[int] = 512 + IRQ_RXIDLE: Final[int] = 64 + CTS: Final[int] = 1 + IRQ_RX: Incomplete + IDLE: int = ... + def irq( + self, + handler: Callable[[UART], None] | None = None, + trigger: int = 0, + hard: bool = False, + /, + ) -> _IRQ: + """ + Configure an interrupt handler to be called when a UART event occurs. + + The arguments are: + + - *handler* is an optional function to be called when the interrupt event + triggers. The handler must take exactly one argument which is the + ``UART`` instance. + + - *trigger* configures the event(s) which can generate an interrupt. + Possible values are a mask of one or more of the following: + + - ``UART.IRQ_RXIDLE`` interrupt after receiving at least one character + and then the RX line goes idle. + - ``UART.IRQ_RX`` interrupt after each received character. + - ``UART.IRQ_TXIDLE`` interrupt after or while the last character(s) of + a message are or have been sent. + - ``UART.IRQ_BREAK`` interrupt when a break state is detected at RX + + - *hard* if true a hardware interrupt is used. This reduces the delay + between the pin change and the handler being called. Hard interrupt + handlers may not allocate memory; see :ref:`isr_rules`. + + Returns an irq object. + + Due to limitations of the hardware not all trigger events are available on all ports. + """ + ... + + def sendbreak(self) -> None: + """ + Send a break condition on the bus. This drives the bus low for a duration + longer than required for a normal transmission of a character. + """ + ... + + def deinit(self) -> None: + """ + Turn off the UART bus. + + .. note:: + You will not be able to call ``init()`` on the object after ``deinit()``. + A new instance needs to be created in that case. + """ + ... + + @overload + def init( + self, + /, + baudrate: int = 9600, + bits: int = 8, + parity: int | None = None, + stop: int = 1, + *, + tx: PinLike | None = None, + rx: PinLike | None = None, + txbuf: int | None = None, + rxbuf: int | None = None, + timeout: int | None = None, + timeout_char: int | None = None, + invert: int | None = None, + ) -> None: + """ + Initialise the UART bus with the given parameters: + + - *baudrate* is the clock rate. + - *bits* is the number of bits per character, 7, 8 or 9. + - *parity* is the parity, ``None``, 0 (even) or 1 (odd). + - *stop* is the number of stop bits, 1 or 2. + + Additional keyword-only parameters that may be supported by a port are: + + - *tx* specifies the TX pin to use. + - *rx* specifies the RX pin to use. + - *rts* specifies the RTS (output) pin to use for hardware receive flow control. + - *cts* specifies the CTS (input) pin to use for hardware transmit flow control. + - *txbuf* specifies the length in characters of the TX buffer. + - *rxbuf* specifies the length in characters of the RX buffer. + - *timeout* specifies the time to wait for the first character (in ms). + - *timeout_char* specifies the time to wait between characters (in ms). + - *invert* specifies which lines to invert. + + - ``0`` will not invert lines (idle state of both lines is logic high). + - ``UART.INV_TX`` will invert TX line (idle state of TX line now logic low). + - ``UART.INV_RX`` will invert RX line (idle state of RX line now logic low). + - ``UART.INV_TX | UART.INV_RX`` will invert both lines (idle state at logic low). + + - *flow* specifies which hardware flow control signals to use. The value + is a bitmask. + + - ``0`` will ignore hardware flow control signals. + - ``UART.RTS`` will enable receive flow control by using the RTS output pin to + signal if the receive FIFO has sufficient space to accept more data. + - ``UART.CTS`` will enable transmit flow control by pausing transmission when the + CTS input pin signals that the receiver is running low on buffer space. + - ``UART.RTS | UART.CTS`` will enable both, for full hardware flow control. + + On the WiPy only the following keyword-only parameter is supported: + + - *pins* is a 4 or 2 item list indicating the TX, RX, RTS and CTS pins (in that order). + Any of the pins can be None if one wants the UART to operate with limited functionality. + If the RTS pin is given the RX pin must be given as well. The same applies to CTS. + When no pins are given, then the default set of TX and RX pins is taken, and hardware + flow control will be disabled. If *pins* is ``None``, no pin assignment will be made. + + .. note:: + It is possible to call ``init()`` multiple times on the same object in + order to reconfigure UART on the fly. That allows using single UART + peripheral to serve different devices attached to different GPIO pins. + Only one device can be served at a time in that case. + Also do not call ``deinit()`` as it will prevent calling ``init()`` + again. + """ + + @overload + def init( + self, + /, + baudrate: int = 9600, + bits: int = 8, + parity: int | None = None, + stop: int = 1, + *, + pins: tuple[PinLike, PinLike] | None = None, + ) -> None: + """ + Initialise the UART bus with the given parameters: + + - *baudrate* is the clock rate. + - *bits* is the number of bits per character, 7, 8 or 9. + - *parity* is the parity, ``None``, 0 (even) or 1 (odd). + - *stop* is the number of stop bits, 1 or 2. + + Additional keyword-only parameters that may be supported by a port are: + + - *tx* specifies the TX pin to use. + - *rx* specifies the RX pin to use. + - *rts* specifies the RTS (output) pin to use for hardware receive flow control. + - *cts* specifies the CTS (input) pin to use for hardware transmit flow control. + - *txbuf* specifies the length in characters of the TX buffer. + - *rxbuf* specifies the length in characters of the RX buffer. + - *timeout* specifies the time to wait for the first character (in ms). + - *timeout_char* specifies the time to wait between characters (in ms). + - *invert* specifies which lines to invert. + + - ``0`` will not invert lines (idle state of both lines is logic high). + - ``UART.INV_TX`` will invert TX line (idle state of TX line now logic low). + - ``UART.INV_RX`` will invert RX line (idle state of RX line now logic low). + - ``UART.INV_TX | UART.INV_RX`` will invert both lines (idle state at logic low). + + - *flow* specifies which hardware flow control signals to use. The value + is a bitmask. + + - ``0`` will ignore hardware flow control signals. + - ``UART.RTS`` will enable receive flow control by using the RTS output pin to + signal if the receive FIFO has sufficient space to accept more data. + - ``UART.CTS`` will enable transmit flow control by pausing transmission when the + CTS input pin signals that the receiver is running low on buffer space. + - ``UART.RTS | UART.CTS`` will enable both, for full hardware flow control. + + On the WiPy only the following keyword-only parameter is supported: + + - *pins* is a 4 or 2 item list indicating the TX, RX, RTS and CTS pins (in that order). + Any of the pins can be None if one wants the UART to operate with limited functionality. + If the RTS pin is given the RX pin must be given as well. The same applies to CTS. + When no pins are given, then the default set of TX and RX pins is taken, and hardware + flow control will be disabled. If *pins* is ``None``, no pin assignment will be made. + + .. note:: + It is possible to call ``init()`` multiple times on the same object in + order to reconfigure UART on the fly. That allows using single UART + peripheral to serve different devices attached to different GPIO pins. + Only one device can be served at a time in that case. + Also do not call ``deinit()`` as it will prevent calling ``init()`` + again. + """ + + @overload + def init( + self, + /, + baudrate: int = 9600, + bits: int = 8, + parity: int | None = None, + stop: int = 1, + *, + pins: tuple[PinLike, PinLike, PinLike, PinLike] | None = None, + ) -> None: + """ + Initialise the UART bus with the given parameters: + + - *baudrate* is the clock rate. + - *bits* is the number of bits per character, 7, 8 or 9. + - *parity* is the parity, ``None``, 0 (even) or 1 (odd). + - *stop* is the number of stop bits, 1 or 2. + + Additional keyword-only parameters that may be supported by a port are: + + - *tx* specifies the TX pin to use. + - *rx* specifies the RX pin to use. + - *rts* specifies the RTS (output) pin to use for hardware receive flow control. + - *cts* specifies the CTS (input) pin to use for hardware transmit flow control. + - *txbuf* specifies the length in characters of the TX buffer. + - *rxbuf* specifies the length in characters of the RX buffer. + - *timeout* specifies the time to wait for the first character (in ms). + - *timeout_char* specifies the time to wait between characters (in ms). + - *invert* specifies which lines to invert. + + - ``0`` will not invert lines (idle state of both lines is logic high). + - ``UART.INV_TX`` will invert TX line (idle state of TX line now logic low). + - ``UART.INV_RX`` will invert RX line (idle state of RX line now logic low). + - ``UART.INV_TX | UART.INV_RX`` will invert both lines (idle state at logic low). + + - *flow* specifies which hardware flow control signals to use. The value + is a bitmask. + + - ``0`` will ignore hardware flow control signals. + - ``UART.RTS`` will enable receive flow control by using the RTS output pin to + signal if the receive FIFO has sufficient space to accept more data. + - ``UART.CTS`` will enable transmit flow control by pausing transmission when the + CTS input pin signals that the receiver is running low on buffer space. + - ``UART.RTS | UART.CTS`` will enable both, for full hardware flow control. + + On the WiPy only the following keyword-only parameter is supported: + + - *pins* is a 4 or 2 item list indicating the TX, RX, RTS and CTS pins (in that order). + Any of the pins can be None if one wants the UART to operate with limited functionality. + If the RTS pin is given the RX pin must be given as well. The same applies to CTS. + When no pins are given, then the default set of TX and RX pins is taken, and hardware + flow control will be disabled. If *pins* is ``None``, no pin assignment will be made. + + .. note:: + It is possible to call ``init()`` multiple times on the same object in + order to reconfigure UART on the fly. That allows using single UART + peripheral to serve different devices attached to different GPIO pins. + Only one device can be served at a time in that case. + Also do not call ``deinit()`` as it will prevent calling ``init()`` + again. + """ + + def flush(self) -> Incomplete: + """ + Waits until all data has been sent. In case of a timeout, an exception is raised. The timeout + duration depends on the tx buffer size and the baud rate. Unless flow control is enabled, a timeout + should not occur. + + .. note:: + + For the esp8266 and nrf ports the call returns while the last byte is sent. + If required, a one character wait time has to be added in the calling script. + + Availability: rp2, esp32, esp8266, mimxrt, cc3200, stm32, nrf ports, renesas-ra + """ + ... + + def txdone(self) -> bool: + """ + Tells whether all data has been sent or no data transfer is happening. In this case, + it returns ``True``. If a data transmission is ongoing it returns ``False``. + + .. note:: + + For the esp8266 and nrf ports the call may return ``True`` even if the last byte + of a transfer is still being sent. If required, a one character wait time has to be + added in the calling script. + + Availability: rp2, esp32, esp8266, mimxrt, cc3200, stm32, nrf ports, renesas-ra + """ + ... + + @overload + def read(self) -> bytes | None: + """ + Read characters. If ``nbytes`` is specified then read at most that many bytes, + otherwise read as much data as possible. It may return sooner if a timeout + is reached. The timeout is configurable in the constructor. + + Return value: a bytes object containing the bytes read in. Returns ``None`` + on timeout. + """ + + @overload + def read(self, nbytes: int, /) -> bytes | None: + """ + Read characters. If ``nbytes`` is specified then read at most that many bytes, + otherwise read as much data as possible. It may return sooner if a timeout + is reached. The timeout is configurable in the constructor. + + Return value: a bytes object containing the bytes read in. Returns ``None`` + on timeout. + """ + + def any(self) -> int: + """ + Returns an integer counting the number of characters that can be read without + blocking. It will return 0 if there are no characters available and a positive + number if there are characters. The method may return 1 even if there is more + than one character available for reading. + + For more sophisticated querying of available characters use select.poll:: + + poll = select.poll() + poll.register(uart, select.POLLIN) + poll.poll(timeout) + """ + ... + + def write(self, buf: AnyReadableBuf, /) -> Union[int, None]: + """ + Write the buffer of bytes to the bus. + + Return value: number of bytes written or ``None`` on timeout. + """ + ... + + @overload + def readinto(self, buf: AnyWritableBuf, /) -> int | None: + """ + Read bytes into the ``buf``. If ``nbytes`` is specified then read at most + that many bytes. Otherwise, read at most ``len(buf)`` bytes. It may return sooner if a timeout + is reached. The timeout is configurable in the constructor. + + Return value: number of bytes read and stored into ``buf`` or ``None`` on + timeout. + """ + + @overload + def readinto(self, buf: AnyWritableBuf, nbytes: int, /) -> int | None: + """ + Read bytes into the ``buf``. If ``nbytes`` is specified then read at most + that many bytes. Otherwise, read at most ``len(buf)`` bytes. It may return sooner if a timeout + is reached. The timeout is configurable in the constructor. + + Return value: number of bytes read and stored into ``buf`` or ``None`` on + timeout. + """ + + def readline(self) -> Union[str, None]: + """ + Read a line, ending in a newline character. It may return sooner if a timeout + is reached. The timeout is configurable in the constructor. + + Return value: the line read or ``None`` on timeout. + """ + ... + + @overload + def __init__( + self, + id: ID_T, + /, + baudrate: int = 9600, + bits: int = 8, + parity: int | None = None, + stop: int = 1, + *, + tx: PinLike | None = None, + rx: PinLike | None = None, + txbuf: int | None = None, + rxbuf: int | None = None, + timeout: int | None = None, + timeout_char: int | None = None, + invert: int | None = None, + ): + """ + Construct a UART object of the given id. + """ + + @overload + def __init__( + self, + id: ID_T, + /, + baudrate: int = 9600, + bits: int = 8, + parity: int | None = None, + stop: int = 1, + *, + pins: tuple[PinLike, PinLike] | None = None, + ): + """ + Construct a UART object of the given id from a tuple of two pins. + """ + + @overload + def __init__( + self, + id: ID_T, + /, + baudrate: int = 9600, + bits: int = 8, + parity: int | None = None, + stop: int = 1, + *, + pins: tuple[PinLike, PinLike, PinLike, PinLike] | None = None, + ): + """ + Construct a UART object of the given id from a tuple of four pins. + """ + +class USBDevice: + """ + Construct a USBDevice object. + + ``Note:`` This object is a singleton, each call to this constructor + returns the same object reference. + """ + + BUILTIN_NONE: Incomplete + BUILTIN_DEFAULT: Incomplete + BUILTIN_CDC: Incomplete + BUILTIN_MSC: Incomplete + BUILTIN_CDC_MSC: int + def submit_xfer(self, ep, buffer, /) -> bool: + """ + Submit a USB transfer on endpoint number ``ep``. ``buffer`` must be + an object implementing the buffer interface, with read access for + ``IN`` endpoints and write access for ``OUT`` endpoints. + + ``Note:`` ``ep`` cannot be the control Endpoint number 0. Control + transfers are built up through successive executions of + ``control_xfer_cb``, see above. + + Returns ``True`` if successful, ``False`` if the transfer could not + be queued (as USB device is not configured by host, or because + another transfer is queued on this endpoint.) + + When the USB host completes the transfer, the ``xfer_cb`` callback + is called (see above). + + Raises ``OSError`` with reason ``MP_EINVAL`` If the USB device is not + active. + """ + ... + + def config( + self, + desc_dev, + desc_cfg, + desc_strs=None, + open_itf_cb=None, + reset_cb=None, + control_xfer_cb=None, + xfer_cb=None, + ) -> None: + """ + Configures the ``USBDevice`` singleton object with the USB runtime device + state and callback functions: + + - ``desc_dev`` - A bytes-like object containing + the new USB device descriptor. + + - ``desc_cfg`` - A bytes-like object containing the + new USB configuration descriptor. + + - ``desc_strs`` - Optional object holding strings or bytes objects + containing USB string descriptor values. Can be a list, a dict, or any + object which supports subscript indexing with integer keys (USB string + descriptor index). + + Strings are an optional USB feature, and this parameter can be unset + (default) if no strings are referenced in the device and configuration + descriptors, or if only built-in strings should be used. + + Apart from index 0, all the string values should be plain ASCII. Index 0 + is the special "languages" USB descriptor, represented as a bytes object + with a custom format defined in the USB standard. ``None`` can be + returned at index 0 in order to use a default "English" language + descriptor. + + To fall back to providing a built-in string value for a given index, a + subscript lookup can return ``None``, raise ``KeyError``, or raise + ``IndexError``. + + - ``open_itf_cb`` - This callback is called once for each interface + or Interface Association Descriptor in response to a Set + Configuration request from the USB Host (the final stage before + the USB device is available to the host). + + The callback takes a single argument, which is a memoryview of the + interface or IAD descriptor that the host is accepting (including + all associated descriptors). It is a view into the same + ``desc_cfg`` object that was provided as a separate + argument to this function. The memoryview is only valid until the + callback function returns. + + - ``reset_cb`` - This callback is called when the USB host performs + a bus reset. The callback takes no arguments. Any in-progress + transfers will never complete. The USB host will most likely + proceed to re-enumerate the USB device by calling the descriptor + callbacks and then ``open_itf_cb()``. + + - ``control_xfer_cb`` - This callback is called one or more times + for each USB control transfer (device Endpoint 0). It takes two + arguments. + + The first argument is the control transfer stage. It is one of: + + - ``1`` for SETUP stage. + - ``2`` for DATA stage. + - ``3`` for ACK stage. + + Second argument is a memoryview to read the USB control request + data for this stage. The memoryview is only valid until the + callback function returns. Data in this memoryview will be the same + across each of the three stages of a single transfer. + + A successful transfer consists of this callback being called in sequence + for the three stages. Generally speaking, if a device wants to do + something in response to a control request then it's best to wait until + the ACK stage to confirm the host controller completed the transfer as + expected. + + The callback should return one of the following values: + + - ``False`` to stall the endpoint and reject the transfer. It won't + proceed to any remaining stages. + - ``True`` to continue the transfer to the next stage. + - A buffer object can be returned at the SETUP stage when the transfer + will send or receive additional data. Typically this is the case when + the ``wLength`` field in the request has a non-zero value. This should + be a writable buffer for an ``OUT`` direction transfer, or a readable + buffer with data for an ``IN`` direction transfer. + + - ``xfer_cb`` - This callback is called whenever a non-control + transfer submitted by calling :func:`USBDevice.submit_xfer` completes. + + The callback has three arguments: + + 1. The Endpoint number for the completed transfer. + 2. Result value: ``True`` if the transfer succeeded, ``False`` + otherwise. + 3. Number of bytes successfully transferred. In the case of a + "short" transfer, The result is ``True`` and ``xferred_bytes`` + will be smaller than the length of the buffer submitted for the + transfer. + + ``Note:`` If a bus reset occurs (see :func:`USBDevice.reset`), + ``xfer_cb`` is not called for any transfers that have not + already completed. + """ + ... + + def remote_wakeup(self) -> bool: + """ + Wake up host if we are in suspend mode and the REMOTE_WAKEUP feature + is enabled by the host. This has to be enabled in the USB attributes, + and on the host. Returns ``True`` if remote wakeup was enabled and + active and the host was woken up. + """ + ... + + def stall(self, ep, stall: bool | None = None, /) -> bool: + """ + Calling this function gets or sets the STALL state of a device endpoint. + + ``ep`` is the number of the endpoint. + + If the optional ``stall`` parameter is set, this is a boolean flag + for the STALL state. + + The return value is the current stall state of the endpoint (before + any change made by this function). + + An endpoint that is set to STALL may remain stalled until this + function is called again, or STALL may be cleared automatically by + the USB host. + + Raises ``OSError`` with reason ``MP_EINVAL`` If the USB device is not + active. + """ + ... + + def active(self, value: Any | None = None, /) -> bool: + """ + Returns the current active state of this runtime USB device as a + boolean. The runtime USB device is "active" when it is available to + interact with the host, it doesn't mean that a USB Host is actually + present. + + If the optional ``value`` argument is set to a truthy value, then + the USB device will be activated. + + If the optional ``value`` argument is set to a falsey value, then + the USB device is deactivated. While the USB device is deactivated, + it will not be detected by the USB Host. + + To simulate a disconnect and a reconnect of the USB device, call + ``active(False)`` followed by ``active(True)``. This may be + necessary if the runtime device configuration has changed, so that + the host sees the new device. + """ + ... + + class BUILTIN_CDC: + ep_max: int = 3 + itf_max: int = 2 + str_max: int = 5 + desc_dev: bytes = b"\x12\x01\x00\x02\xef\x02\x01@\x8a.\x05\x00\x00\x01\x01\x02\x03\x01" + desc_cfg: bytes = ( + b"\t\x02K\x00\x02\x01\x00\x80}\x08\x0b\x00\x02\x02\x02\x00\x00\t\x04\x00\x00\x01\x02\x02\x00\x04\x05$\x00 \x01\x05$\x01\x00\x01\x04$\x02\x06\x05$\x06\x00\x01\x07\x05\x81\x03\x08\x00\x10\t\x04\x01\x00\x02\n\x00\x00\x00\x07\x05\x02\x02@\x00\x00\x07\x05\x82\x02@\x00\x00" + ) + def __init__(self, *argv, **kwargs) -> None: ... + + class BUILTIN_NONE: + ep_max: int = 0 + itf_max: int = 0 + str_max: int = 1 + desc_dev: bytes = b"\x12\x01\x00\x02\xef\x02\x01@\x8a.\x05\x00\x00\x01\x01\x02\x03\x01" + desc_cfg: bytes = b"" + def __init__(self, *argv, **kwargs) -> None: ... + + class BUILTIN_DEFAULT: + ep_max: int = 3 + itf_max: int = 2 + str_max: int = 5 + desc_dev: bytes = b"\x12\x01\x00\x02\xef\x02\x01@\x8a.\x05\x00\x00\x01\x01\x02\x03\x01" + desc_cfg: bytes = ( + b"\t\x02K\x00\x02\x01\x00\x80}\x08\x0b\x00\x02\x02\x02\x00\x00\t\x04\x00\x00\x01\x02\x02\x00\x04\x05$\x00 \x01\x05$\x01\x00\x01\x04$\x02\x06\x05$\x06\x00\x01\x07\x05\x81\x03\x08\x00\x10\t\x04\x01\x00\x02\n\x00\x00\x00\x07\x05\x02\x02@\x00\x00\x07\x05\x82\x02@\x00\x00" + ) + def __init__(self, *argv, **kwargs) -> None: ... + + def __init__(self) -> None: ... + +class Pin: + """ + A pin object is used to control I/O pins (also known as GPIO - general-purpose + input/output). Pin objects are commonly associated with a physical pin that can + drive an output voltage and read input voltages. The pin class has methods to set the mode of + the pin (IN, OUT, etc) and methods to get and set the digital logic level. + For analog control of a pin, see the :class:`ADC` class. + + A pin object is constructed by using an identifier which unambiguously + specifies a certain I/O pin. The allowed forms of the identifier and the + physical pin that the identifier maps to are port-specific. Possibilities + for the identifier are an integer, a string or a tuple with port and pin + number. + + Usage Model:: + + from machine import Pin + + # create an output pin on pin #0 + p0 = Pin(0, Pin.OUT) + + # set the value low then high + p0.value(0) + p0.value(1) + + # create an input pin on pin #2, with a pull up resistor + p2 = Pin(2, Pin.IN, Pin.PULL_UP) + + # read and print the pin value + print(p2.value()) + + # reconfigure pin #0 in input mode with a pull down resistor + p0.init(p0.IN, p0.PULL_DOWN) + + # configure an irq callback + p0.irq(lambda p:print(p)) + """ + + ALT_SPI: Final[int] = 1 + IN: Final[int] = 0 + ALT_USB: Final[int] = 9 + ALT_UART: Final[int] = 2 + IRQ_FALLING: Final[int] = 4 + OUT: Final[int] = 1 + OPEN_DRAIN: Final[int] = 2 + IRQ_RISING: Final[int] = 8 + PULL_DOWN: Final[int] = 2 + ALT_SIO: Final[int] = 5 + ALT_GPCK: Final[int] = 8 + ALT: Final[int] = 3 + PULL_UP: Final[int] = 1 + ALT_I2C: Final[int] = 3 + ALT_PWM: Final[int] = 4 + ALT_PIO1: Final[int] = 7 + ALT_PIO0: Final[int] = 6 + ALT_OPEN_DRAIN: Incomplete + ANALOG: Incomplete + PULL_HOLD: Incomplete + DRIVE_0: int + DRIVE_1: int + DRIVE_2: int + IRQ_LOW_LEVEL: Incomplete + IRQ_HIGH_LEVEL: Incomplete + def low(self) -> None: + """ + Set pin to "0" output level. + + Availability: mimxrt, nrf, renesas-ra, rp2, samd, stm32 ports. + """ + ... + + def irq( + self, + /, + handler: Callable[[Pin], None] | None = None, + trigger: int = (IRQ_FALLING | IRQ_RISING), + *, + priority: int = 1, + wake: int | None = None, + hard: bool = False, + ) -> Callable[..., Incomplete]: + """ + Configure an interrupt handler to be called when the trigger source of the + pin is active. If the pin mode is ``Pin.IN`` then the trigger source is + the external value on the pin. If the pin mode is ``Pin.OUT`` then the + trigger source is the output buffer of the pin. Otherwise, if the pin mode + is ``Pin.OPEN_DRAIN`` then the trigger source is the output buffer for + state '0' and the external pin value for state '1'. + + The arguments are: + + - ``handler`` is an optional function to be called when the interrupt + triggers. The handler must take exactly one argument which is the + ``Pin`` instance. + + - ``trigger`` configures the event which can generate an interrupt. + Possible values are: + + - ``Pin.IRQ_FALLING`` interrupt on falling edge. + - ``Pin.IRQ_RISING`` interrupt on rising edge. + - ``Pin.IRQ_LOW_LEVEL`` interrupt on low level. + - ``Pin.IRQ_HIGH_LEVEL`` interrupt on high level. + + These values can be OR'ed together to trigger on multiple events. + + - ``priority`` sets the priority level of the interrupt. The values it + can take are port-specific, but higher values always represent higher + priorities. + + - ``wake`` selects the power mode in which this interrupt can wake up the + system. It can be ``machine.IDLE``, ``machine.SLEEP`` or ``machine.DEEPSLEEP``. + These values can also be OR'ed together to make a pin generate interrupts in + more than one power mode. + + - ``hard`` if true a hardware interrupt is used. This reduces the delay + between the pin change and the handler being called. Hard interrupt + handlers may not allocate memory; see :ref:`isr_rules`. + Not all ports support this argument. + + This method returns a callback object. + + The following methods are not part of the core Pin API and only implemented on certain ports. + """ + ... + + def toggle(self) -> Incomplete: + """ + Toggle output pin from "0" to "1" or vice-versa. + + Availability: cc3200, esp32, esp8266, mimxrt, rp2, samd ports. + """ + ... + + def off(self) -> None: + """ + Set pin to "0" output level. + """ + ... + + def on(self) -> None: + """ + Set pin to "1" output level. + """ + ... + + def init( + self, + mode: int = -1, + pull: int = -1, + *, + value: Any = None, + drive: int | None = None, + alt: int | None = None, + ) -> None: + """ + Re-initialise the pin using the given parameters. Only those arguments that + are specified will be set. The rest of the pin peripheral state will remain + unchanged. See the constructor documentation for details of the arguments. + + Returns ``None``. + """ + ... + + @overload + def value(self) -> int: + """ + This method allows to set and get the value of the pin, depending on whether + the argument ``x`` is supplied or not. + + If the argument is omitted then this method gets the digital logic level of + the pin, returning 0 or 1 corresponding to low and high voltage signals + respectively. The behaviour of this method depends on the mode of the pin: + + - ``Pin.IN`` - The method returns the actual input value currently present + on the pin. + - ``Pin.OUT`` - The behaviour and return value of the method is undefined. + - ``Pin.OPEN_DRAIN`` - If the pin is in state '0' then the behaviour and + return value of the method is undefined. Otherwise, if the pin is in + state '1', the method returns the actual input value currently present + on the pin. + + If the argument is supplied then this method sets the digital logic level of + the pin. The argument ``x`` can be anything that converts to a boolean. + If it converts to ``True``, the pin is set to state '1', otherwise it is set + to state '0'. The behaviour of this method depends on the mode of the pin: + + - ``Pin.IN`` - The value is stored in the output buffer for the pin. The + pin state does not change, it remains in the high-impedance state. The + stored value will become active on the pin as soon as it is changed to + ``Pin.OUT`` or ``Pin.OPEN_DRAIN`` mode. + - ``Pin.OUT`` - The output buffer is set to the given value immediately. + - ``Pin.OPEN_DRAIN`` - If the value is '0' the pin is set to a low voltage + state. Otherwise the pin is set to high-impedance state. + + When setting the value this method returns ``None``. + """ + + @overload + def value(self, x: Any, /) -> None: + """ + This method allows to set and get the value of the pin, depending on whether + the argument ``x`` is supplied or not. + + If the argument is omitted then this method gets the digital logic level of + the pin, returning 0 or 1 corresponding to low and high voltage signals + respectively. The behaviour of this method depends on the mode of the pin: + + - ``Pin.IN`` - The method returns the actual input value currently present + on the pin. + - ``Pin.OUT`` - The behaviour and return value of the method is undefined. + - ``Pin.OPEN_DRAIN`` - If the pin is in state '0' then the behaviour and + return value of the method is undefined. Otherwise, if the pin is in + state '1', the method returns the actual input value currently present + on the pin. + + If the argument is supplied then this method sets the digital logic level of + the pin. The argument ``x`` can be anything that converts to a boolean. + If it converts to ``True``, the pin is set to state '1', otherwise it is set + to state '0'. The behaviour of this method depends on the mode of the pin: + + - ``Pin.IN`` - The value is stored in the output buffer for the pin. The + pin state does not change, it remains in the high-impedance state. The + stored value will become active on the pin as soon as it is changed to + ``Pin.OUT`` or ``Pin.OPEN_DRAIN`` mode. + - ``Pin.OUT`` - The output buffer is set to the given value immediately. + - ``Pin.OPEN_DRAIN`` - If the value is '0' the pin is set to a low voltage + state. Otherwise the pin is set to high-impedance state. + + When setting the value this method returns ``None``. + """ + + def high(self) -> None: + """ + Set pin to "1" output level. + + Availability: mimxrt, nrf, renesas-ra, rp2, samd, stm32 ports. + """ + ... + + class cpu: + GPIO26: Pin ## = Pin(GPIO26, mode=ALT, pull=PULL_DOWN, alt=31) + GPIO25: Pin ## = Pin(GPIO25, mode=ALT, pull=PULL_DOWN, alt=31) + GPIO27: Pin ## = Pin(GPIO27, mode=ALT, pull=PULL_DOWN, alt=31) + GPIO28: Pin ## = Pin(GPIO28, mode=ALT, pull=PULL_DOWN, alt=31) + GPIO22: Pin ## = Pin(GPIO22, mode=ALT, pull=PULL_DOWN, alt=31) + GPIO24: Pin ## = Pin(GPIO24, mode=ALT, pull=PULL_DOWN, alt=31) + GPIO23: Pin ## = Pin(GPIO23, mode=ALT, pull=PULL_DOWN, alt=31) + GPIO9: Pin ## = Pin(GPIO9, mode=ALT, pull=PULL_DOWN, alt=31) + GPIO7: Pin ## = Pin(GPIO7, mode=ALT, pull=PULL_DOWN, alt=31) + GPIO6: Pin ## = Pin(GPIO6, mode=ALT, pull=PULL_DOWN, alt=31) + GPIO8: Pin ## = Pin(GPIO8, mode=ALT, pull=PULL_DOWN, alt=31) + GPIO29: Pin ## = Pin(GPIO29, mode=ALT, pull=PULL_DOWN, alt=31) + GPIO3: Pin ## = Pin(GPIO3, mode=ALT, pull=PULL_DOWN, alt=31) + GPIO5: Pin ## = Pin(GPIO5, mode=ALT, pull=PULL_DOWN, alt=31) + GPIO4: Pin ## = Pin(GPIO4, mode=ALT, pull=PULL_DOWN, alt=31) + GPIO12: Pin ## = Pin(GPIO12, mode=ALT, pull=PULL_DOWN, alt=31) + GPIO11: Pin ## = Pin(GPIO11, mode=ALT, pull=PULL_DOWN, alt=31) + GPIO13: Pin ## = Pin(GPIO13, mode=ALT, pull=PULL_DOWN, alt=31) + GPIO14: Pin ## = Pin(GPIO14, mode=ALT, pull=PULL_DOWN, alt=31) + GPIO0: Pin ## = Pin(GPIO0, mode=ALT, pull=PULL_DOWN, alt=31) + GPIO10: Pin ## = Pin(GPIO10, mode=ALT, pull=PULL_DOWN, alt=31) + GPIO1: Pin ## = Pin(GPIO1, mode=ALT, pull=PULL_DOWN, alt=31) + GPIO21: Pin ## = Pin(GPIO21, mode=ALT, pull=PULL_DOWN, alt=31) + GPIO2: Pin ## = Pin(GPIO2, mode=ALT, pull=PULL_DOWN, alt=31) + GPIO19: Pin ## = Pin(GPIO19, mode=ALT, pull=PULL_DOWN, alt=31) + GPIO20: Pin ## = Pin(GPIO20, mode=ALT, pull=PULL_DOWN, alt=31) + GPIO15: Pin ## = Pin(GPIO15, mode=ALT, pull=PULL_DOWN, alt=31) + GPIO16: Pin ## = Pin(GPIO16, mode=ALT, pull=PULL_DOWN, alt=31) + GPIO18: Pin ## = Pin(GPIO18, mode=ALT, pull=PULL_DOWN, alt=31) + GPIO17: Pin ## = Pin(GPIO17, mode=ALT, pull=PULL_DOWN, alt=31) + def __init__(self, *argv, **kwargs) -> None: ... + + class board: + GP27: Pin ## = Pin(GPIO27, mode=ALT, pull=PULL_DOWN, alt=31) + GP26: Pin ## = Pin(GPIO26, mode=ALT, pull=PULL_DOWN, alt=31) + GP28: Pin ## = Pin(GPIO28, mode=ALT, pull=PULL_DOWN, alt=31) + LED: Pin ## = Pin(GPIO25, mode=ALT, pull=PULL_DOWN, alt=31) + GP21: Pin ## = Pin(GPIO21, mode=ALT, pull=PULL_DOWN, alt=31) + GP25: Pin ## = Pin(GPIO25, mode=ALT, pull=PULL_DOWN, alt=31) + GP22: Pin ## = Pin(GPIO22, mode=ALT, pull=PULL_DOWN, alt=31) + GP8: Pin ## = Pin(GPIO8, mode=ALT, pull=PULL_DOWN, alt=31) + GP7: Pin ## = Pin(GPIO7, mode=ALT, pull=PULL_DOWN, alt=31) + GP9: Pin ## = Pin(GPIO9, mode=ALT, pull=PULL_DOWN, alt=31) + GP3: Pin ## = Pin(GPIO3, mode=ALT, pull=PULL_DOWN, alt=31) + GP4: Pin ## = Pin(GPIO4, mode=ALT, pull=PULL_DOWN, alt=31) + GP6: Pin ## = Pin(GPIO6, mode=ALT, pull=PULL_DOWN, alt=31) + GP5: Pin ## = Pin(GPIO5, mode=ALT, pull=PULL_DOWN, alt=31) + GP12: Pin ## = Pin(GPIO12, mode=ALT, pull=PULL_DOWN, alt=31) + GP11: Pin ## = Pin(GPIO11, mode=ALT, pull=PULL_DOWN, alt=31) + GP13: Pin ## = Pin(GPIO13, mode=ALT, pull=PULL_DOWN, alt=31) + GP20: Pin ## = Pin(GPIO20, mode=ALT, pull=PULL_DOWN, alt=31) + GP0: Pin ## = Pin(GPIO0, mode=ALT, pull=PULL_DOWN, alt=31) + GP10: Pin ## = Pin(GPIO10, mode=ALT, pull=PULL_DOWN, alt=31) + GP1: Pin ## = Pin(GPIO1, mode=ALT, pull=PULL_DOWN, alt=31) + GP19: Pin ## = Pin(GPIO19, mode=ALT, pull=PULL_DOWN, alt=31) + GP18: Pin ## = Pin(GPIO18, mode=ALT, pull=PULL_DOWN, alt=31) + GP2: Pin ## = Pin(GPIO2, mode=ALT, pull=PULL_DOWN, alt=31) + GP14: Pin ## = Pin(GPIO14, mode=ALT, pull=PULL_DOWN, alt=31) + GP15: Pin ## = Pin(GPIO15, mode=ALT, pull=PULL_DOWN, alt=31) + GP17: Pin ## = Pin(GPIO17, mode=ALT, pull=PULL_DOWN, alt=31) + GP16: Pin ## = Pin(GPIO16, mode=ALT, pull=PULL_DOWN, alt=31) + def __init__(self, *argv, **kwargs) -> None: ... + + def __init__( + self, + id: Any, + /, + mode: int = -1, + pull: int = -1, + *, + value: Any = None, + drive: int | None = None, + alt: int | None = None, + ) -> None: + """ + Access the pin peripheral (GPIO pin) associated with the given ``id``. If + additional arguments are given in the constructor then they are used to initialise + the pin. Any settings that are not specified will remain in their previous state. + + The arguments are: + + - ``id`` is mandatory and can be an arbitrary object. Among possible value + types are: int (an internal Pin identifier), str (a Pin name), and tuple + (pair of [port, pin]). + + - ``mode`` specifies the pin mode, which can be one of: + + - ``Pin.IN`` - Pin is configured for input. If viewed as an output the pin + is in high-impedance state. + + - ``Pin.OUT`` - Pin is configured for (normal) output. + + - ``Pin.OPEN_DRAIN`` - Pin is configured for open-drain output. Open-drain + output works in the following way: if the output value is set to 0 the pin + is active at a low level; if the output value is 1 the pin is in a high-impedance + state. Not all ports implement this mode, or some might only on certain pins. + + - ``Pin.ALT`` - Pin is configured to perform an alternative function, which is + port specific. For a pin configured in such a way any other Pin methods + (except :meth:`Pin.init`) are not applicable (calling them will lead to undefined, + or a hardware-specific, result). Not all ports implement this mode. + + - ``Pin.ALT_OPEN_DRAIN`` - The Same as ``Pin.ALT``, but the pin is configured as + open-drain. Not all ports implement this mode. + + - ``Pin.ANALOG`` - Pin is configured for analog input, see the :class:`ADC` class. + + - ``pull`` specifies if the pin has a (weak) pull resistor attached, and can be + one of: + + - ``None`` - No pull up or down resistor. + - ``Pin.PULL_UP`` - Pull up resistor enabled. + - ``Pin.PULL_DOWN`` - Pull down resistor enabled. + + - ``value`` is valid only for Pin.OUT and Pin.OPEN_DRAIN modes and specifies initial + output pin value if given, otherwise the state of the pin peripheral remains + unchanged. + + - ``drive`` specifies the output power of the pin and can be one of: ``Pin.LOW_POWER``, + ``Pin.MED_POWER`` or ``Pin.HIGH_POWER``. The actual current driving capabilities + are port dependent. Not all ports implement this argument. + + - ``alt`` specifies an alternate function for the pin and the values it can take are + port dependent. This argument is valid only for ``Pin.ALT`` and ``Pin.ALT_OPEN_DRAIN`` + modes. It may be used when a pin supports more than one alternate function. If only + one pin alternate function is supported the this argument is not required. Not all + ports implement this argument. + + As specified above, the Pin class allows to set an alternate function for a particular + pin, but it does not specify any further operations on such a pin. Pins configured in + alternate-function mode are usually not used as GPIO but are instead driven by other + hardware peripherals. The only operation supported on such a pin is re-initialising, + by calling the constructor or :meth:`Pin.init` method. If a pin that is configured in + alternate-function mode is re-initialised with ``Pin.IN``, ``Pin.OUT``, or + ``Pin.OPEN_DRAIN``, the alternate function will be removed from the pin. + """ + + @overload + def __call__(self) -> int: + """ + Pin objects are callable. The call method provides a (fast) shortcut to set + and get the value of the pin. It is equivalent to Pin.value([x]). + See :meth:`Pin.value` for more details. + """ + + @overload + def __call__(self, x: Any, /) -> None: + """ + Pin objects are callable. The call method provides a (fast) shortcut to set + and get the value of the pin. It is equivalent to Pin.value([x]). + See :meth:`Pin.value` for more details. + """ + + @overload + def mode(self) -> int: + """ + Get or set the pin mode. + See the constructor documentation for details of the ``mode`` argument. + + Availability: cc3200, stm32 ports. + """ + + @overload + def mode(self, mode: int, /) -> None: + """ + Get or set the pin mode. + See the constructor documentation for details of the ``mode`` argument. + + Availability: cc3200, stm32 ports. + """ + + @overload + def pull(self) -> int: + """ + Get or set the pin pull state. + See the constructor documentation for details of the ``pull`` argument. + + Availability: cc3200, stm32 ports. + """ + + @overload + def pull(self, pull: int, /) -> None: + """ + Get or set the pin pull state. + See the constructor documentation for details of the ``pull`` argument. + + Availability: cc3200, stm32 ports. + """ + + @overload + def drive(self, drive: int, /) -> None: + """ + Get or set the pin drive strength. + See the constructor documentation for details of the ``drive`` argument. + + Availability: cc3200 port. + """ + ... + + @overload + def drive(self, /) -> int: + """ + Get or set the pin drive strength. + See the constructor documentation for details of the ``drive`` argument. + + Availability: cc3200 port. + """ + +class SoftI2C(I2C): + """ + Construct a new software I2C object. The parameters are: + + - *scl* should be a pin object specifying the pin to use for SCL. + - *sda* should be a pin object specifying the pin to use for SDA. + - *freq* should be an integer which sets the maximum frequency + for SCL. + - *timeout* is the maximum time in microseconds to wait for clock + stretching (SCL held low by another device on the bus), after + which an ``OSError(ETIMEDOUT)`` exception is raised. + """ + + def readfrom_mem_into(self, *args, **kwargs) -> Incomplete: ... + def readfrom_into(self, *args, **kwargs) -> Incomplete: ... + def readfrom_mem(self, *args, **kwargs) -> Incomplete: ... + def writeto_mem(self, *args, **kwargs) -> Incomplete: ... + def scan(self, *args, **kwargs) -> Incomplete: ... + def writeto(self, *args, **kwargs) -> Incomplete: ... + def writevto(self, *args, **kwargs) -> Incomplete: ... + def start(self, *args, **kwargs) -> Incomplete: ... + def readfrom(self, *args, **kwargs) -> Incomplete: ... + def readinto(self, *args, **kwargs) -> Incomplete: ... + def init(self, *args, **kwargs) -> Incomplete: ... + def stop(self, *args, **kwargs) -> Incomplete: ... + def write(self, *args, **kwargs) -> Incomplete: ... + def __init__(self, scl, sda, *, freq=400000, timeout=50000) -> None: ... + +class RTC: + """ + The RTC is an independent clock that keeps track of the date + and time. + + Example usage:: + + rtc = machine.RTC() + rtc.datetime((2020, 1, 21, 2, 10, 32, 36, 0)) + print(rtc.datetime()) + + + + The documentation for RTC is in a poor state;1 + """ + + ALARM0: Incomplete + def datetime(self, datetimetuple: Any | None = None) -> Tuple: + """ + Get or set the date and time of the RTC. + + With no arguments, this method returns an 8-tuple with the current + date and time. With 1 argument (being an 8-tuple) it sets the date + and time. + + The 8-tuple has the following format: + + (year, month, day, weekday, hours, minutes, seconds, subseconds) + + The meaning of the ``subseconds`` field is hardware dependent. + """ + ... + + @overload + def __init__(self, id: int = 0): + """ + Create an RTC object. See init for parameters of initialization. + """ + + @overload + def __init__(self, id: int = 0, /, *, datetime: tuple[int, int, int]): + """ + Create an RTC object. See init for parameters of initialization. + + The documentation for RTC is in a poor state; better to experiment and use `dir`! + """ + + @overload + def __init__(self, id: int = 0, /, *, datetime: tuple[int, int, int, int]): + """ + Create an RTC object. See init for parameters of initialization. + + The documentation for RTC is in a poor state; better to experiment and use `dir`! + """ + + @overload + def __init__(self, id: int = 0, /, *, datetime: tuple[int, int, int, int, int]): + """ + Create an RTC object. See init for parameters of initialization. + + The documentation for RTC is in a poor state; better to experiment and use `dir`! + """ + + @overload + def __init__(self, id: int = 0, /, *, datetime: tuple[int, int, int, int, int, int]): + """ + Create an RTC object. See init for parameters of initialization. + + The documentation for RTC is in a poor state; better to experiment and use `dir`! + """ + + @overload + def __init__(self, id: int = 0, /, *, datetime: tuple[int, int, int, int, int, int, int]): + """ + Create an RTC object. See init for parameters of initialization. + + The documentation for RTC is in a poor state; better to experiment and use `dir`! + """ + + @overload + def __init__(self, id: int = 0, /, *, datetime: tuple[int, int, int, int, int, int, int, int]): + """ + Create an RTC object. See init for parameters of initialization. + + The documentation for RTC is in a poor state; better to experiment and use `dir`! + """ + + @overload + def init(self) -> None: + """ + Initialise the RTC. Datetime is a tuple of the form: + + ``(year, month, day, hour, minute, second, microsecond, tzinfo)`` + + All eight arguments must be present. The ``microsecond`` and ``tzinfo`` + values are currently ignored but might be used in the future. + + Availability: CC3200, ESP32, MIMXRT, SAMD. The rtc.init() method on + the stm32 and renesas-ra ports just (re-)starts the RTC and does not + accept arguments. + """ + + @overload + def init(self, datetime: tuple[int, int, int], /) -> None: + """ + Initialise the RTC. Datetime is a tuple of the form: + + ``(year, month, day, hour, minute, second, microsecond, tzinfo)`` + + All eight arguments must be present. The ``microsecond`` and ``tzinfo`` + values are currently ignored but might be used in the future. + + Availability: CC3200, ESP32, MIMXRT, SAMD. The rtc.init() method on + the stm32 and renesas-ra ports just (re-)starts the RTC and does not + accept arguments. + """ + + @overload + def init(self, datetime: tuple[int, int, int, int], /) -> None: + """ + Initialise the RTC. Datetime is a tuple of the form: + + ``(year, month, day, hour, minute, second, microsecond, tzinfo)`` + + All eight arguments must be present. The ``microsecond`` and ``tzinfo`` + values are currently ignored but might be used in the future. + + Availability: CC3200, ESP32, MIMXRT, SAMD. The rtc.init() method on + the stm32 and renesas-ra ports just (re-)starts the RTC and does not + accept arguments. + """ + + @overload + def init(self, datetime: tuple[int, int, int, int, int], /) -> None: + """ + Initialise the RTC. Datetime is a tuple of the form: + + ``(year, month, day, hour, minute, second, microsecond, tzinfo)`` + + All eight arguments must be present. The ``microsecond`` and ``tzinfo`` + values are currently ignored but might be used in the future. + + Availability: CC3200, ESP32, MIMXRT, SAMD. The rtc.init() method on + the stm32 and renesas-ra ports just (re-)starts the RTC and does not + accept arguments. + """ + + @overload + def init(self, datetime: tuple[int, int, int, int, int, int], /) -> None: + """ + Initialise the RTC. Datetime is a tuple of the form: + + ``(year, month, day, hour, minute, second, microsecond, tzinfo)`` + + All eight arguments must be present. The ``microsecond`` and ``tzinfo`` + values are currently ignored but might be used in the future. + + Availability: CC3200, ESP32, MIMXRT, SAMD. The rtc.init() method on + the stm32 and renesas-ra ports just (re-)starts the RTC and does not + accept arguments. + """ + + @overload + def init(self, datetime: tuple[int, int, int, int, int, int, int], /) -> None: + """ + Initialise the RTC. Datetime is a tuple of the form: + + ``(year, month, day, hour, minute, second, microsecond, tzinfo)`` + + All eight arguments must be present. The ``microsecond`` and ``tzinfo`` + values are currently ignored but might be used in the future. + + Availability: CC3200, ESP32, MIMXRT, SAMD. The rtc.init() method on + the stm32 and renesas-ra ports just (re-)starts the RTC and does not + accept arguments. + """ + + @overload + def init(self, datetime: tuple[int, int, int, int, int, int, int, int], /) -> None: + """ + Initialise the RTC. Datetime is a tuple of the form: + + ``(year, month, day, hour, minute, second, microsecond, tzinfo)`` + + All eight arguments must be present. The ``microsecond`` and ``tzinfo`` + values are currently ignored but might be used in the future. + + Availability: CC3200, ESP32, MIMXRT, SAMD. The rtc.init() method on + the stm32 and renesas-ra ports just (re-)starts the RTC and does not + accept arguments. + """ + + @overload + def alarm(self, id: int, time: int, /, *, repeat: bool = False) -> None: + """ + Set the RTC alarm. Time might be either a millisecond value to program the alarm to + current time + time_in_ms in the future, or a datetimetuple. If the time passed is in + milliseconds, repeat can be set to ``True`` to make the alarm periodic. + """ + + @overload + def alarm(self, id: int, time: tuple[int, int, int], /) -> None: + """ + Set the RTC alarm. Time might be either a millisecond value to program the alarm to + current time + time_in_ms in the future, or a datetimetuple. If the time passed is in + milliseconds, repeat can be set to ``True`` to make the alarm periodic. + """ + + @overload + def alarm(self, id: int, time: tuple[int, int, int, int], /) -> None: + """ + Set the RTC alarm. Time might be either a millisecond value to program the alarm to + current time + time_in_ms in the future, or a datetimetuple. If the time passed is in + milliseconds, repeat can be set to ``True`` to make the alarm periodic. + """ + + @overload + def alarm(self, id: int, time: tuple[int, int, int, int, int], /) -> None: + """ + Set the RTC alarm. Time might be either a millisecond value to program the alarm to + current time + time_in_ms in the future, or a datetimetuple. If the time passed is in + milliseconds, repeat can be set to ``True`` to make the alarm periodic. + """ + + @overload + def alarm(self, id: int, time: tuple[int, int, int, int, int, int], /) -> None: + """ + Set the RTC alarm. Time might be either a millisecond value to program the alarm to + current time + time_in_ms in the future, or a datetimetuple. If the time passed is in + milliseconds, repeat can be set to ``True`` to make the alarm periodic. + """ + + @overload + def alarm(self, id: int, time: tuple[int, int, int, int, int, int, int], /) -> None: + """ + Set the RTC alarm. Time might be either a millisecond value to program the alarm to + current time + time_in_ms in the future, or a datetimetuple. If the time passed is in + milliseconds, repeat can be set to ``True`` to make the alarm periodic. + """ + + @overload + def alarm(self, id: int, time: tuple[int, int, int, int, int, int, int, int], /) -> None: + """ + Set the RTC alarm. Time might be either a millisecond value to program the alarm to + current time + time_in_ms in the future, or a datetimetuple. If the time passed is in + milliseconds, repeat can be set to ``True`` to make the alarm periodic. + """ + +class SPI: + """ + SPI is a synchronous serial protocol that is driven by a controller. At the + physical level, a bus consists of 3 lines: SCK, MOSI, MISO. Multiple devices + can share the same bus. Each device should have a separate, 4th signal, + CS (Chip Select), to select a particular device on a bus with which + communication takes place. Management of a CS signal should happen in + user code (via machine.Pin class). + + Both hardware and software SPI implementations exist via the + :ref:`machine.SPI ` and `machine.SoftSPI` classes. Hardware SPI uses underlying + hardware support of the system to perform the reads/writes and is usually + efficient and fast but may have restrictions on which pins can be used. + Software SPI is implemented by bit-banging and can be used on any pin but + is not as efficient. These classes have the same methods available and + differ primarily in the way they are constructed. + + Example usage:: + + from machine import SPI, Pin + + spi = SPI(0, baudrate=400000) # Create SPI peripheral 0 at frequency of 400kHz. + # Depending on the use case, extra parameters may be required + # to select the bus characteristics and/or pins to use. + cs = Pin(4, mode=Pin.OUT, value=1) # Create chip-select on pin 4. + + try: + cs(0) # Select peripheral. + spi.write(b"12345678") # Write 8 bytes, and don't care about received data. + finally: + cs(1) # Deselect peripheral. + + try: + cs(0) # Select peripheral. + rxdata = spi.read(8, 0x42) # Read 8 bytes while writing 0x42 for each byte. + finally: + cs(1) # Deselect peripheral. + + rxdata = bytearray(8) + try: + cs(0) # Select peripheral. + spi.readinto(rxdata, 0x42) # Read 8 bytes inplace while writing 0x42 for each byte. + finally: + cs(1) # Deselect peripheral. + + txdata = b"12345678" + rxdata = bytearray(len(txdata)) + try: + cs(0) # Select peripheral. + spi.write_readinto(txdata, rxdata) # Simultaneously write and read bytes. + finally: + cs(1) # Deselect peripheral. + """ + + LSB: Final[int] = 0 + MSB: Final[int] = 1 + CONTROLLER: Incomplete + def deinit(self) -> None: + """ + Turn off the SPI bus. + """ + ... + + @overload + def init( + self, + baudrate: int = 1_000_000, + *, + polarity: int = 0, + phase: int = 0, + bits: int = 8, + firstbit: int = MSB, + sck: PinLike | None = None, + mosi: PinLike | None = None, + miso: PinLike | None = None, + ) -> None: + """ + Initialise the SPI bus with the given parameters: + + - ``baudrate`` is the SCK clock rate. + - ``polarity`` can be 0 or 1, and is the level the idle clock line sits at. + - ``phase`` can be 0 or 1 to sample data on the first or second clock edge + respectively. + - ``bits`` is the width in bits of each transfer. Only 8 is guaranteed to be supported by all hardware. + - ``firstbit`` can be ``SPI.MSB`` or ``SPI.LSB``. + - ``sck``, ``mosi``, ``miso`` are pins (machine.Pin) objects to use for bus signals. For most + hardware SPI blocks (as selected by ``id`` parameter to the constructor), pins are fixed + and cannot be changed. In some cases, hardware blocks allow 2-3 alternative pin sets for + a hardware SPI block. Arbitrary pin assignments are possible only for a bitbanging SPI driver + (``id`` = -1). + - ``pins`` - WiPy port doesn't ``sck``, ``mosi``, ``miso`` arguments, and instead allows to + specify them as a tuple of ``pins`` parameter. + + In the case of hardware SPI the actual clock frequency may be lower than the + requested baudrate. This is dependent on the platform hardware. The actual + rate may be determined by printing the SPI object. + """ + + @overload + def init( + self, + baudrate: int = 1_000_000, + *, + polarity: int = 0, + phase: int = 0, + bits: int = 8, + firstbit: int = MSB, + pins: tuple[PinLike, PinLike, PinLike] | None = None, + ) -> None: + """ + Initialise the SPI bus with the given parameters: + + - ``baudrate`` is the SCK clock rate. + - ``polarity`` can be 0 or 1, and is the level the idle clock line sits at. + - ``phase`` can be 0 or 1 to sample data on the first or second clock edge + respectively. + - ``bits`` is the width in bits of each transfer. Only 8 is guaranteed to be supported by all hardware. + - ``firstbit`` can be ``SPI.MSB`` or ``SPI.LSB``. + - ``sck``, ``mosi``, ``miso`` are pins (machine.Pin) objects to use for bus signals. For most + hardware SPI blocks (as selected by ``id`` parameter to the constructor), pins are fixed + and cannot be changed. In some cases, hardware blocks allow 2-3 alternative pin sets for + a hardware SPI block. Arbitrary pin assignments are possible only for a bitbanging SPI driver + (``id`` = -1). + - ``pins`` - WiPy port doesn't ``sck``, ``mosi``, ``miso`` arguments, and instead allows to + specify them as a tuple of ``pins`` parameter. + + In the case of hardware SPI the actual clock frequency may be lower than the + requested baudrate. This is dependent on the platform hardware. The actual + rate may be determined by printing the SPI object. + """ + + def write_readinto(self, write_buf: AnyReadableBuf, read_buf: AnyWritableBuf, /) -> int: + """ + Write the bytes from ``write_buf`` while reading into ``read_buf``. The + buffers can be the same or different, but both buffers must have the + same length. + Returns ``None``. + + Note: on WiPy this function returns the number of bytes written. + """ + ... + + def read(self, nbytes: int, write: int = 0x00, /) -> bytes: + """ + Read a number of bytes specified by ``nbytes`` while continuously writing + the single byte given by ``write``. + Returns a ``bytes`` object with the data that was read. + """ + ... + + def write(self, buf: AnyReadableBuf, /) -> int: + """ + Write the bytes contained in ``buf``. + Returns ``None``. + + Note: on WiPy this function returns the number of bytes written. + """ + ... + + def readinto(self, buf: AnyWritableBuf, write: int = 0x00, /) -> int: + """ + Read into the buffer specified by ``buf`` while continuously writing the + single byte given by ``write``. + Returns ``None``. + + Note: on WiPy this function returns the number of bytes read. + """ + ... + + @overload + def __init__(self, id: int, /): + """ + Construct an SPI object on the given bus, *id*. Values of *id* depend + on a particular port and its hardware. Values 0, 1, etc. are commonly used + to select hardware SPI block #0, #1, etc. + + With no additional parameters, the SPI object is created but not + initialised (it has the settings from the last initialisation of + the bus, if any). If extra arguments are given, the bus is initialised. + See ``init`` for parameters of initialisation. + """ + + @overload + def __init__( + self, + id: int, + /, + baudrate: int = 1_000_000, + *, + polarity: int = 0, + phase: int = 0, + bits: int = 8, + firstbit: int = MSB, + sck: PinLike | None = None, + mosi: PinLike | None = None, + miso: PinLike | None = None, + ): + """ + Construct an SPI object on the given bus, *id*. Values of *id* depend + on a particular port and its hardware. Values 0, 1, etc. are commonly used + to select hardware SPI block #0, #1, etc. + + With no additional parameters, the SPI object is created but not + initialised (it has the settings from the last initialisation of + the bus, if any). If extra arguments are given, the bus is initialised. + See ``init`` for parameters of initialisation. + """ + + @overload + def __init__( + self, + id: int, + /, + baudrate: int = 1_000_000, + *, + polarity: int = 0, + phase: int = 0, + bits: int = 8, + firstbit: int = MSB, + pins: tuple[PinLike, PinLike, PinLike] | None = None, + ): + """ + Construct an SPI object on the given bus, *id*. Values of *id* depend + on a particular port and its hardware. Values 0, 1, etc. are commonly used + to select hardware SPI block #0, #1, etc. + + With no additional parameters, the SPI object is created but not + initialised (it has the settings from the last initialisation of + the bus, if any). If extra arguments are given, the bus is initialised. + See ``init`` for parameters of initialisation. + """ + +class Signal(Pin): + """ + The Signal class is a simple extension of the `Pin` class. Unlike Pin, which + can be only in "absolute" 0 and 1 states, a Signal can be in "asserted" + (on) or "deasserted" (off) states, while being inverted (active-low) or + not. In other words, it adds logical inversion support to Pin functionality. + While this may seem a simple addition, it is exactly what is needed to + support wide array of simple digital devices in a way portable across + different boards, which is one of the major MicroPython goals. Regardless + of whether different users have an active-high or active-low LED, a normally + open or normally closed relay - you can develop a single, nicely looking + application which works with each of them, and capture hardware + configuration differences in few lines in the config file of your app. + + Example:: + + from machine import Pin, Signal + + # Suppose you have an active-high LED on pin 0 + led1_pin = Pin(0, Pin.OUT) + # ... and active-low LED on pin 1 + led2_pin = Pin(1, Pin.OUT) + + # Now to light up both of them using Pin class, you'll need to set + # them to different values + led1_pin.value(1) + led2_pin.value(0) + + # Signal class allows to abstract away active-high/active-low + # difference + led1 = Signal(led1_pin, invert=False) + led2 = Signal(led2_pin, invert=True) + + # Now lighting up them looks the same + led1.value(1) + led2.value(1) + + # Even better: + led1.on() + led2.on() + + Following is the guide when Signal vs Pin should be used: + + * Use Signal: If you want to control a simple on/off (including software + PWM!) devices like LEDs, multi-segment indicators, relays, buzzers, or + read simple binary sensors, like normally open or normally closed buttons, + pulled high or low, Reed switches, moisture/flame detectors, etc. etc. + Summing up, if you have a real physical device/sensor requiring GPIO + access, you likely should use a Signal. + + * Use Pin: If you implement a higher-level protocol or bus to communicate + with more complex devices. + + The split between Pin and Signal come from the use cases above and the + architecture of MicroPython: Pin offers the lowest overhead, which may + be important when bit-banging protocols. But Signal adds additional + flexibility on top of Pin, at the cost of minor overhead (much smaller + than if you implemented active-high vs active-low device differences in + Python manually!). Also, Pin is a low-level object which needs to be + implemented for each support board, while Signal is a high-level object + which comes for free once Pin is implemented. + + If in doubt, give the Signal a try! Once again, it is offered to save + developers from the need to handle unexciting differences like active-low + vs active-high signals, and allow other users to share and enjoy your + application, instead of being frustrated by the fact that it doesn't + work for them simply because their LEDs or relays are wired in a slightly + different way. + """ + + def off(self) -> None: + """ + Deactivate signal. + """ + ... + + def on(self) -> None: + """ + Activate signal. + """ + ... + + @overload + def value(self) -> int: + """ + This method allows to set and get the value of the signal, depending on whether + the argument ``x`` is supplied or not. + + If the argument is omitted then this method gets the signal level, 1 meaning + signal is asserted (active) and 0 - signal inactive. + + If the argument is supplied then this method sets the signal level. The + argument ``x`` can be anything that converts to a boolean. If it converts + to ``True``, the signal is active, otherwise it is inactive. + + Correspondence between signal being active and actual logic level on the + underlying pin depends on whether signal is inverted (active-low) or not. + For non-inverted signal, active status corresponds to logical 1, inactive - + to logical 0. For inverted/active-low signal, active status corresponds + to logical 0, while inactive - to logical 1. + """ + + @overload + def value(self, x: Any, /) -> None: + """ + This method allows to set and get the value of the signal, depending on whether + the argument ``x`` is supplied or not. + + If the argument is omitted then this method gets the signal level, 1 meaning + signal is asserted (active) and 0 - signal inactive. + + If the argument is supplied then this method sets the signal level. The + argument ``x`` can be anything that converts to a boolean. If it converts + to ``True``, the signal is active, otherwise it is inactive. + + Correspondence between signal being active and actual logic level on the + underlying pin depends on whether signal is inverted (active-low) or not. + For non-inverted signal, active status corresponds to logical 1, inactive - + to logical 0. For inverted/active-low signal, active status corresponds + to logical 0, while inactive - to logical 1. + """ + + @overload + def __init__(self, pin_obj: PinLike, invert: bool = False, /): + """ + Create a Signal object. There're two ways to create it: + + * By wrapping existing Pin object - universal method which works for + any board. + * By passing required Pin parameters directly to Signal constructor, + skipping the need to create intermediate Pin object. Available on + many, but not all boards. + + The arguments are: + + - ``pin_obj`` is existing Pin object. + + - ``pin_arguments`` are the same arguments as can be passed to Pin constructor. + + - ``invert`` - if True, the signal will be inverted (active low). + """ + + @overload + def __init__( + self, + id: PinLike, + /, + mode: int = -1, + pull: int = -1, + *, + value: Any = None, + drive: int | None = None, + alt: int | None = None, + invert: bool = False, + ): + """ + Create a Signal object. There're two ways to create it: + + * By wrapping existing Pin object - universal method which works for + any board. + * By passing required Pin parameters directly to Signal constructor, + skipping the need to create intermediate Pin object. Available on + many, but not all boards. + + The arguments are: + + - ``pin_obj`` is existing Pin object. + + - ``pin_arguments`` are the same arguments as can be passed to Pin constructor. + + - ``invert`` - if True, the signal will be inverted (active low). + """ + +class ADCBlock: + @overload + def connect(self, channel: int, **kwargs) -> ADC: ... + @overload + def connect(self, source: PinLike, **kwargs) -> ADC: ... + @overload + def connect(self, channel: int, source: PinLike, **kwargs) -> ADC: + """ + Connect up a channel on the ADC peripheral so it is ready for sampling, + and return an :ref:`ADC ` object that represents that connection. + + The *channel* argument must be an integer, and *source* must be an object + (for example a :ref:`Pin `) which can be connected up for sampling. + + If only *channel* is given then it is configured for sampling. + + If only *source* is given then that object is connected to a default + channel ready for sampling. + + If both *channel* and *source* are given then they are connected together + and made ready for sampling. + + Any additional keyword arguments are used to configure the returned ADC object, + via its :meth:`init ` method. + """ + ... + +class SDCard: + @overload + def readblocks(self, block_num: int, buf: bytearray) -> bool: + """ + The first form reads aligned, multiples of blocks. + Starting at the block given by the index *block_num*, read blocks from + the device into *buf* (an array of bytes). + The number of blocks to read is given by the length of *buf*, + which will be a multiple of the block size. + """ + + @overload + def readblocks(self, block_num: int, buf: bytearray, offset: int) -> bool: + """ + The second form allows reading at arbitrary locations within a block, + and arbitrary lengths. + Starting at block index *block_num*, and byte offset within that block + of *offset*, read bytes from the device into *buf* (an array of bytes). + The number of bytes to read is given by the length of *buf*. + """ + + @overload + def writeblocks(self, block_num: int, buf: bytes | bytearray, /) -> None: + """ + The first form writes aligned, multiples of blocks, and requires that the + blocks that are written to be first erased (if necessary) by this method. + Starting at the block given by the index *block_num*, write blocks from + *buf* (an array of bytes) to the device. + The number of blocks to write is given by the length of *buf*, + which will be a multiple of the block size. + """ + + @overload + def writeblocks(self, block_num: int, buf: bytes | bytearray, offset: int, /) -> None: + """ + The second form allows writing at arbitrary locations within a block, + and arbitrary lengths. Only the bytes being written should be changed, + and the caller of this method must ensure that the relevant blocks are + erased via a prior ``ioctl`` call. + Starting at block index *block_num*, and byte offset within that block + of *offset*, write bytes from *buf* (an array of bytes) to the device. + The number of bytes to write is given by the length of *buf*. + + Note that implementations must never implicitly erase blocks if the offset + argument is specified, even if it is zero. + """ diff --git a/.venv/lib/python3.12/site-packages/math.pyi b/.venv/lib/python3.12/site-packages/math.pyi new file mode 100644 index 0000000..61208d5 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/math.pyi @@ -0,0 +1,267 @@ +""" +Mathematical functions. + +MicroPython module: https://docs.micropython.org/en/v1.26.0/library/math.html + +CPython module: :mod:`python:math` https://docs.python.org/3/library/math.html . + +The ``math`` module provides some basic mathematical functions for +working with floating-point numbers. + +*Note:* On the pyboard, floating-point numbers have 32-bit precision. + +Availability: not available on WiPy. Floating point support required +for this module. + +--- +Module: 'math' on micropython-v1.26.0-rp2-RPI_PICO +""" + +# MCU: {'mpy': 'v6.3', 'build': '', 'ver': '1.26.0', 'arch': 'armv6m', 'version': '1.26.0', 'port': 'rp2', 'board': 'RPI_PICO', 'family': 'micropython', 'board_id': 'RPI_PICO', 'variant': '', 'cpu': 'RP2040'} +# Stubber: v1.26.0 +from __future__ import annotations +from _typeshed import Incomplete +from typing import SupportsFloat, Tuple +from typing_extensions import Awaitable, TypeAlias, TypeVar + +inf: float = inf +nan: float = nan +pi: float = 3.1415928 +e: float = 2.7182818 +tau: float = 6.2831856 + +def ldexp(x: SupportsFloat, exp: int, /) -> float: + """ + Return ``x * (2**exp)``. + """ + ... + +def lgamma(x: SupportsFloat, /) -> float: + """ + Return the natural logarithm of the gamma function of ``x``. + """ + ... + +def trunc(x: SupportsFloat, /) -> int: + """ + Return an integer, being ``x`` rounded towards 0. + """ + ... + +def isclose(*args, **kwargs) -> Incomplete: ... +def gamma(x: SupportsFloat, /) -> float: + """ + Return the gamma function of ``x``. + """ + ... + +def isnan(x: SupportsFloat, /) -> bool: + """ + Return ``True`` if ``x`` is not-a-number + """ + ... + +def isfinite(x: SupportsFloat, /) -> bool: + """ + Return ``True`` if ``x`` is finite. + """ + ... + +def isinf(x: SupportsFloat, /) -> bool: + """ + Return ``True`` if ``x`` is infinite. + """ + ... + +def sqrt(x: SupportsFloat, /) -> float: + """ + Return the square root of ``x``. + """ + ... + +def sinh(x: SupportsFloat, /) -> float: + """ + Return the hyperbolic sine of ``x``. + """ + ... + +def log(x: SupportsFloat, /) -> float: + """ + With one argument, return the natural logarithm of *x*. + + With two arguments, return the logarithm of *x* to the given *base*. + """ + ... + +def tan(x: SupportsFloat, /) -> float: + """ + Return the tangent of ``x``. + """ + ... + +def tanh(x: SupportsFloat, /) -> float: + """ + Return the hyperbolic tangent of ``x``. + """ + ... + +def log2(x: SupportsFloat, /) -> float: + """ + Return the base-2 logarithm of ``x``. + """ + ... + +def log10(x: SupportsFloat, /) -> float: + """ + Return the base-10 logarithm of ``x``. + """ + ... + +def sin(x: SupportsFloat, /) -> float: + """ + Return the sine of ``x``. + """ + ... + +def modf(x: SupportsFloat, /) -> Tuple: + """ + Return a tuple of two floats, being the fractional and integral parts of + ``x``. Both return values have the same sign as ``x``. + """ + ... + +def radians(x: SupportsFloat, /) -> float: + """ + Return degrees ``x`` converted to radians. + """ + ... + +def atanh(x: SupportsFloat, /) -> float: + """ + Return the inverse hyperbolic tangent of ``x``. + """ + ... + +def atan2(y: SupportsFloat, x: SupportsFloat, /) -> float: + """ + Return the principal value of the inverse tangent of ``y/x``. + """ + ... + +def atan(x: SupportsFloat, /) -> float: + """ + Return the inverse tangent of ``x``. + """ + ... + +def ceil(x: SupportsFloat, /) -> int: + """ + Return an integer, being ``x`` rounded towards positive infinity. + """ + ... + +def copysign(x: SupportsFloat, y: SupportsFloat, /) -> float: + """ + Return ``x`` with the sign of ``y``. + """ + ... + +def frexp(x: SupportsFloat, /) -> tuple[float, int]: + """ + Decomposes a floating-point number into its mantissa and exponent. + The returned value is the tuple ``(m, e)`` such that ``x == m * 2**e`` + exactly. If ``x == 0`` then the function returns ``(0.0, 0)``, otherwise + the relation ``0.5 <= abs(m) < 1`` holds. + """ + ... + +def acos(x: SupportsFloat, /) -> float: + """ + Return the inverse cosine of ``x``. + """ + ... + +def pow(x: SupportsFloat, y: SupportsFloat, /) -> float: + """ + Returns ``x`` to the power of ``y``. + """ + ... + +def asinh(x: SupportsFloat, /) -> float: + """ + Return the inverse hyperbolic sine of ``x``. + """ + ... + +def acosh(x: SupportsFloat, /) -> float: + """ + Return the inverse hyperbolic cosine of ``x``. + """ + ... + +def asin(x: SupportsFloat, /) -> float: + """ + Return the inverse sine of ``x``. + """ + ... + +def factorial(*args, **kwargs) -> Incomplete: ... +def fabs(x: SupportsFloat, /) -> float: + """ + Return the absolute value of ``x``. + """ + ... + +def expm1(x: SupportsFloat, /) -> float: + """ + Return ``exp(x) - 1``. + """ + ... + +def floor(x: SupportsFloat, /) -> int: + """ + Return an integer, being ``x`` rounded towards negative infinity. + """ + ... + +def fmod(x: SupportsFloat, y: SupportsFloat, /) -> float: + """ + Return the remainder of ``x/y``. + """ + ... + +def cos(x: SupportsFloat, /) -> float: + """ + Return the cosine of ``x``. + """ + ... + +def degrees(x: SupportsFloat, /) -> float: + """ + Return radians ``x`` converted to degrees. + """ + ... + +def cosh(x: SupportsFloat, /) -> float: + """ + Return the hyperbolic cosine of ``x``. + """ + ... + +def exp(x: SupportsFloat, /) -> float: + """ + Return the exponential of ``x``. + """ + ... + +def erf(x: SupportsFloat, /) -> float: + """ + Return the error function of ``x``. + """ + ... + +def erfc(x: SupportsFloat, /) -> float: + """ + Return the complementary error function of ``x``. + """ + ... diff --git a/.venv/lib/python3.12/site-packages/micropython.pyi b/.venv/lib/python3.12/site-packages/micropython.pyi new file mode 100644 index 0000000..9c00696 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/micropython.pyi @@ -0,0 +1,350 @@ +""" +Access and control MicroPython internals. + +MicroPython module: https://docs.micropython.org/en/v1.26.0/library/micropython.html + +--- +Module: 'micropython' on micropython-v1.26.0-rp2-RPI_PICO +""" + +# MCU: {'mpy': 'v6.3', 'build': '', 'ver': '1.26.0', 'arch': 'armv6m', 'version': '1.26.0', 'port': 'rp2', 'board': 'RPI_PICO', 'family': 'micropython', 'board_id': 'RPI_PICO', 'variant': '', 'cpu': 'RP2040'} +# Stubber: v1.26.0 +from __future__ import annotations +from _typeshed import Incomplete +from _mpy_shed import mp_available +from typing import Any, Callable, Optional, Tuple, overload +from typing_extensions import Awaitable, ParamSpec, TypeAlias, TypeVar + +_T = TypeVar("_T") +_F = TypeVar("_F", bound=Callable[..., Any]) +Const_T = TypeVar("Const_T", int, float, str, bytes, Tuple) +_Param = ParamSpec("_Param") +_Ret = TypeVar("_Ret") + +@overload +def opt_level() -> int: + """ + If *level* is given then this function sets the optimisation level for subsequent + compilation of scripts, and returns ``None``. Otherwise it returns the current + optimisation level. + + The optimisation level controls the following compilation features: + + - Assertions: at level 0 assertion statements are enabled and compiled into the + bytecode; at levels 1 and higher assertions are not compiled. + - Built-in ``__debug__`` variable: at level 0 this variable expands to ``True``; + at levels 1 and higher it expands to ``False``. + - Source-code line numbers: at levels 0, 1 and 2 source-code line number are + stored along with the bytecode so that exceptions can report the line number + they occurred at; at levels 3 and higher line numbers are not stored. + + The default optimisation level is usually level 0. + """ + +@overload +def opt_level(level: int, /) -> None: + """ + If *level* is given then this function sets the optimisation level for subsequent + compilation of scripts, and returns ``None``. Otherwise it returns the current + optimisation level. + + The optimisation level controls the following compilation features: + + - Assertions: at level 0 assertion statements are enabled and compiled into the + bytecode; at levels 1 and higher assertions are not compiled. + - Built-in ``__debug__`` variable: at level 0 this variable expands to ``True``; + at levels 1 and higher it expands to ``False``. + - Source-code line numbers: at levels 0, 1 and 2 source-code line number are + stored along with the bytecode so that exceptions can report the line number + they occurred at; at levels 3 and higher line numbers are not stored. + + The default optimisation level is usually level 0. + """ + +@overload +def mem_info() -> None: + """ + Print information about currently used memory. If the *verbose* argument + is given then extra information is printed. + + The information that is printed is implementation dependent, but currently + includes the amount of stack and heap used. In verbose mode it prints out + the entire heap indicating which blocks are used and which are free. + """ + +@overload +def mem_info(verbose: Any, /) -> None: + """ + Print information about currently used memory. If the *verbose* argument + is given then extra information is printed. + + The information that is printed is implementation dependent, but currently + includes the amount of stack and heap used. In verbose mode it prints out + the entire heap indicating which blocks are used and which are free. + """ + +def kbd_intr(chr: int) -> None: + """ + Set the character that will raise a `KeyboardInterrupt` exception. By + default this is set to 3 during script execution, corresponding to Ctrl-C. + Passing -1 to this function will disable capture of Ctrl-C, and passing 3 + will restore it. + + This function can be used to prevent the capturing of Ctrl-C on the + incoming stream of characters that is usually used for the REPL, in case + that stream is used for other purposes. + """ + ... + +@overload +def qstr_info() -> None: + """ + Print information about currently interned strings. If the *verbose* + argument is given then extra information is printed. + + The information that is printed is implementation dependent, but currently + includes the number of interned strings and the amount of RAM they use. In + verbose mode it prints out the names of all RAM-interned strings. + """ + +@overload +def qstr_info(verbose: bool, /) -> None: + """ + Print information about currently interned strings. If the *verbose* + argument is given then extra information is printed. + + The information that is printed is implementation dependent, but currently + includes the number of interned strings and the amount of RAM they use. In + verbose mode it prints out the names of all RAM-interned strings. + """ + +def schedule(func: Callable[[_T], None], arg: _T, /) -> None: + """ + Schedule the function *func* to be executed "very soon". The function + is passed the value *arg* as its single argument. "Very soon" means that + the MicroPython runtime will do its best to execute the function at the + earliest possible time, given that it is also trying to be efficient, and + that the following conditions hold: + + - A scheduled function will never preempt another scheduled function. + - Scheduled functions are always executed "between opcodes" which means + that all fundamental Python operations (such as appending to a list) + are guaranteed to be atomic. + - A given port may define "critical regions" within which scheduled + functions will never be executed. Functions may be scheduled within + a critical region but they will not be executed until that region + is exited. An example of a critical region is a preempting interrupt + handler (an IRQ). + + A use for this function is to schedule a callback from a preempting IRQ. + Such an IRQ puts restrictions on the code that runs in the IRQ (for example + the heap may be locked) and scheduling a function to call later will lift + those restrictions. + + On multi-threaded ports, the scheduled function's behaviour depends on + whether the Global Interpreter Lock (GIL) is enabled for the specific port: + + - If GIL is enabled, the function can preempt any thread and run in its + context. + - If GIL is disabled, the function will only preempt the main thread and run + in its context. + + Note: If `schedule()` is called from a preempting IRQ, when memory + allocation is not allowed and the callback to be passed to `schedule()` is + a bound method, passing this directly will fail. This is because creating a + reference to a bound method causes memory allocation. A solution is to + create a reference to the method in the class constructor and to pass that + reference to `schedule()`. This is discussed in detail here + :ref:`reference documentation ` under "Creation of Python + objects". + + There is a finite queue to hold the scheduled functions and `schedule()` + will raise a `RuntimeError` if the queue is full. + """ + ... + +def stack_use() -> int: + """ + Return an integer representing the current amount of stack that is being + used. The absolute value of this is not particularly useful, rather it + should be used to compute differences in stack usage at different points. + """ + ... + +def heap_unlock() -> int: + """ + Lock or unlock the heap. When locked no memory allocation can occur and a + `MemoryError` will be raised if any heap allocation is attempted. + `heap_locked()` returns a true value if the heap is currently locked. + + These functions can be nested, ie `heap_lock()` can be called multiple times + in a row and the lock-depth will increase, and then `heap_unlock()` must be + called the same number of times to make the heap available again. + + Both `heap_unlock()` and `heap_locked()` return the current lock depth + (after unlocking for the former) as a non-negative integer, with 0 meaning + the heap is not locked. + + If the REPL becomes active with the heap locked then it will be forcefully + unlocked. + + Note: `heap_locked()` is not enabled on most ports by default, + requires ``MICROPY_PY_MICROPYTHON_HEAP_LOCKED``. + """ + +def const(expr: Const_T, /) -> Const_T: + """ + Used to declare that the expression is a constant so that the compiler can + optimise it. The use of this function should be as follows:: + + from micropython import const + + CONST_X = const(123) + CONST_Y = const(2 * CONST_X + 1) + + Constants declared this way are still accessible as global variables from + outside the module they are declared in. On the other hand, if a constant + begins with an underscore then it is hidden, it is not available as a global + variable, and does not take up any memory during execution. + + This `const` function is recognised directly by the MicroPython parser and is + provided as part of the :mod:`micropython` module mainly so that scripts can be + written which run under both CPython and MicroPython, by following the above + pattern. + """ + ... + +def heap_lock() -> int: + """ + Lock or unlock the heap. When locked no memory allocation can occur and a + `MemoryError` will be raised if any heap allocation is attempted. + `heap_locked()` returns a true value if the heap is currently locked. + + These functions can be nested, ie `heap_lock()` can be called multiple times + in a row and the lock-depth will increase, and then `heap_unlock()` must be + called the same number of times to make the heap available again. + + Both `heap_unlock()` and `heap_locked()` return the current lock depth + (after unlocking for the former) as a non-negative integer, with 0 meaning + the heap is not locked. + + If the REPL becomes active with the heap locked then it will be forcefully + unlocked. + + Note: `heap_locked()` is not enabled on most ports by default, + requires ``MICROPY_PY_MICROPYTHON_HEAP_LOCKED``. + """ + +def alloc_emergency_exception_buf(size: int, /) -> None: + """ + Allocate *size* bytes of RAM for the emergency exception buffer (a good + size is around 100 bytes). The buffer is used to create exceptions in cases + when normal RAM allocation would fail (eg within an interrupt handler) and + therefore give useful traceback information in these situations. + + A good way to use this function is to put it at the start of your main script + (eg ``boot.py`` or ``main.py``) and then the emergency exception buffer will be active + for all the code following it. + """ + ... + +class RingIO: + def readinto(self, buf, nbytes: Optional[Any] = None) -> int: + """ + Read available bytes into the provided ``buf``. If ``nbytes`` is + specified then read at most that many bytes. Otherwise, read at + most ``len(buf)`` bytes. + + Return value: Integer count of the number of bytes read into ``buf``. + """ + ... + + def write(self, buf) -> int: + """ + Non-blocking write of bytes from ``buf`` into the ringbuffer, limited + by the available space in the ringbuffer. + + Return value: Integer count of bytes written. + """ + ... + + def readline(self, nbytes: Optional[Any] = None) -> bytes: + """ + Read a line, ending in a newline character or return if one exists in + the buffer, else return available bytes in buffer. If ``nbytes`` is + specified then read at most that many bytes. + + Return value: a bytes object containing the line read. + """ + ... + + def any(self) -> int: + """ + Returns an integer counting the number of characters that can be read. + """ + ... + + def read(self, nbytes: Optional[Any] = None) -> bytes: + """ + Read available characters. This is a non-blocking function. If ``nbytes`` + is specified then read at most that many bytes, otherwise read as much + data as possible. + + Return value: a bytes object containing the bytes read. Will be + zero-length bytes object if no data is available. + """ + ... + + def close(self) -> Incomplete: + """ + No-op provided as part of standard `stream` interface. Has no effect + on data in the ringbuffer. + """ + ... + + def __init__(self, size) -> None: ... + +# decorators +@mp_available() # force merge +def viper(_func: Callable[_Param, _Ret], /) -> Callable[_Param, _Ret]: + """ + The Viper code emitter is not fully compliant. It supports special Viper native data types in pursuit of performance. + Integer processing is non-compliant because it uses machine words: arithmetic on 32 bit hardware is performed modulo 2**32. + Like the Native emitter Viper produces machine instructions but further optimisations are performed, substantially increasing + performance especially for integer arithmetic and bit manipulations. + See: https://docs.micropython.org/en/latest/reference/speed_python.html?highlight=viper#the-native-code-emitter + """ + ... + +@mp_available() # force merge +def native(_func: Callable[_Param, _Ret], /) -> Callable[_Param, _Ret]: + """ + This causes the MicroPython compiler to emit native CPU opcodes rather than bytecode. + It covers the bulk of the MicroPython functionality, so most functions will require no adaptation. + See: https://docs.micropython.org/en/latest/reference/speed_python.html#the-native-code-emitter + """ + ... + +@mp_available(macro="MICROPY_EMIT_INLINE_THUMB") # force merge +def asm_thumb(_func: Callable[_Param, _Ret], /) -> Callable[_Param, _Ret]: + """ + This decorator is used to mark a function as containing inline assembler code. + The assembler code is written is a subset of the ARM Thumb-2 instruction set, and is executed on the target CPU. + + Availability: Only on specific boards where MICROPY_EMIT_INLINE_THUMB is defined. + See: https://docs.micropython.org/en/latest/reference/asm_thumb2_index.html + """ + ... + +@mp_available(port="esp8266") # force merge +def asm_xtensa(_func: Callable[_Param, _Ret], /) -> Callable[_Param, _Ret]: + """ + This decorator is used to mark a function as containing inline assembler code for the esp8266. + The assembler code is written in the Xtensa instruction set, and is executed on the target CPU. + + Availability: Only on eps8266 boards. + """ + ... + # See : + # - https://github.com/orgs/micropython/discussions/12965 + # - https://github.com/micropython/micropython/pull/16731 diff --git a/.venv/lib/python3.12/site-packages/micropython_rp2_stubs-1.26.0.post1.dist-info/INSTALLER b/.venv/lib/python3.12/site-packages/micropython_rp2_stubs-1.26.0.post1.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/.venv/lib/python3.12/site-packages/micropython_rp2_stubs-1.26.0.post1.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/.venv/lib/python3.12/site-packages/micropython_rp2_stubs-1.26.0.post1.dist-info/LICENSE.md b/.venv/lib/python3.12/site-packages/micropython_rp2_stubs-1.26.0.post1.dist-info/LICENSE.md new file mode 100644 index 0000000..72b7b16 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/micropython_rp2_stubs-1.26.0.post1.dist-info/LICENSE.md @@ -0,0 +1,22 @@ +MIT License + +Copyright (c) 2022 Jos Verlinde + +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. + diff --git a/.venv/lib/python3.12/site-packages/micropython_rp2_stubs-1.26.0.post1.dist-info/METADATA b/.venv/lib/python3.12/site-packages/micropython_rp2_stubs-1.26.0.post1.dist-info/METADATA new file mode 100644 index 0000000..17a7d41 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/micropython_rp2_stubs-1.26.0.post1.dist-info/METADATA @@ -0,0 +1,64 @@ +Metadata-Version: 2.3 +Name: micropython-rp2-stubs +Version: 1.26.0.post1 +Summary: MicroPython stubs +License: MIT +Author: Jos Verlinde +Author-email: josverl@users.noreply.github.com +Classifier: Typing :: Stubs Only +Classifier: Development Status :: 5 - Production/Stable +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3 :: Only +Classifier: Programming Language :: Python :: Implementation :: MicroPython +Classifier: Operating System :: OS Independent +Classifier: Topic :: Text Editors :: Integrated Development Environments (IDE) +Classifier: Topic :: Software Development :: Documentation +Classifier: Topic :: Software Development :: Embedded Systems +Classifier: Topic :: Software Development :: Testing +Classifier: Natural Language :: English +Requires-Dist: micropython-stdlib-stubs (>=1.26.0,<1.27.0) +Project-URL: Documentation, https://micropython-stubs.readthedocs.io/ +Project-URL: Homepage, https://github.com/josverl/micropython-stubs#micropython-stubs +Project-URL: Repository, https://github.com/josverl/micropython-stubs +Description-Content-Type: text/markdown + +# micropython-rp2-stubs + + +This is a stub-only package for MicroPython. +It is intended to be installed in a projects virtual environment to allow static type checkers and intellisense features to be used while writing Micropython code. + +The version of this package is alligned the the version of the MicroPython firmware. + - Major, Minor and Patch levels are alligned to the same version as the firmware. + - The post release level is used to publish new releases of the stubs. + +For `Micropython 1.17` the stubs are published as `1.17.post1` ... `1.17.post2` +for `Micropython 1.18` the stubs are published as `1.18.post1` ... `1.18.post2` + +To install the latest stubs: +`pip install -I micropython--stubs` where port is the port of the MicroPython firmware. + +To install the stubs for an older version, such as MicroPython 1.17: +`pip install micropython-stm32-stubs==1.17.*` which will install the last post release of the stubs for MicroPython 1.17. + + +As the creation of the stubs, and merging of the different types is still going though improvements, the stub packages are marked as Beta. +To upgrade stubs to the latest stubs for a specific version use `pip install micropython-stm32-stubs==1.17.* --upgrade` + +If you have suggestions or find any issues with the stubs, please report them in the [MicroPython-stubs Discussions](https://github.com/Josverl/micropython-stubs/discussions) + +For an overview of Micropython Stubs please see: https://micropython-stubs.readthedocs.io/en/main/ + * List of all stubs : https://micropython-stubs.readthedocs.io/en/main/firmware_grp.html + + + +Included stubs: +* Merged stubs from `stubs/micropython-v1_26_0-rp2-RPI_PICO-merged` +* Frozen stubs from `stubs/micropython-v1_26_0-frozen/rp2/GENERIC` +* Core stubs from `stubs/micropython-core` + + +origin | Family | Port | Board | Version +-------|--------|------|-------|-------- + diff --git a/.venv/lib/python3.12/site-packages/micropython_rp2_stubs-1.26.0.post1.dist-info/RECORD b/.venv/lib/python3.12/site-packages/micropython_rp2_stubs-1.26.0.post1.dist-info/RECORD new file mode 100644 index 0000000..19fafcd --- /dev/null +++ b/.venv/lib/python3.12/site-packages/micropython_rp2_stubs-1.26.0.post1.dist-info/RECORD @@ -0,0 +1,58 @@ +__builtins__.pyi,sha256=P0dwpsSqizQRPmaI6J275kc7G35m38YjafDPz4SEdKI,1097 +_boot.pyi,sha256=0e1lrk87JxZMowULLiOAz7leOmzBkvFCabOD4i-djzY,70 +_boot_fat.pyi,sha256=5SN-IunMd7ESRkWUm4XH1DLoX8F2_R0gm-p_dvC4i-4,54 +_onewire.pyi,sha256=Aoqj9t5Zo48w2nwqKFF3bKUjvDFKGM0TBcRhcMDoMQE,663 +_thread.pyi,sha256=qruh97SKzvBuIMEP6g-pEOwEw_X18yhcNpnvmQMznCw,1318 +binascii.pyi,sha256=Js4mvTBtShAqzpkr53R_OS94gZnxyr5EvSavOiLZScg,2121 +cmath.pyi,sha256=W7LjCb4tdmlZVxtU3_E49ae_CLumfotRT36AItkySMA,2110 +cryptolib.pyi,sha256=fyYS0lSiMjhSQCN6FEHB10llwxyrghxvk8LucmF1tto,6734 +deflate.pyi,sha256=4GYBP3Ce-Trro2pMGFwNTeBM_sCux681xE3J1fGVYKA,3746 +dht.pyi,sha256=zamvhZo46pXwloiPKKlldLlMYmb7waNyZE1aeUnz-vA,344 +ds18x20.pyi,sha256=aHK7R9hREAFdOgPBd5dx8-MPBORBUvwHWNDDSVULl-Q,423 +errno.pyi,sha256=8036ME2KKlPQhWRvp-GYue4P7vYrMHKIM4UTemfgSkA,1448 +framebuf.pyi,sha256=DWoxiTKnEjO0_0nrK0SuLOvFSrnNdLSsAoQiqOoaBDw,9265 +gc.pyi,sha256=Dg_YTQxCHCGzNWFyBD0LtVvz4q1EpDpD3Khvuxxz70g,4279 +hashlib.pyi,sha256=JASAsPp2aT0JvqOz9eE44AulQ63PKKVgPsx4WPPJDKM,3665 +heapq.pyi,sha256=zVdjTbcM-IpP6FXBhDPhlbxb3Q0yfbu6-lkGvOxoBmk,1433 +machine.pyi,sha256=3ZcwR0rvop3NAjhBxDMfsDb1w95J6oIGXfozOoDGN2g,129722 +math.pyi,sha256=u6AllM7vjnJdLS45X5xGJHfeH0FJXS6ypCJznS5defQ,6041 +micropython.pyi,sha256=oyWt_RtD_SfZfSgwUmrxJobn_VTGjHU3ZqmvedPh7FM,14996 +micropython_rp2_stubs-1.26.0.post1.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +micropython_rp2_stubs-1.26.0.post1.dist-info/LICENSE.md,sha256=EerY3Evf4ZqwZBZMGIokOHR70txtsAlS_GGHuxmxUJY,1092 +micropython_rp2_stubs-1.26.0.post1.dist-info/METADATA,sha256=TgVmz4GDRvkH6jpyzXhgRQ98fOCpJc9S6uHnpdTNbhs,3033 +micropython_rp2_stubs-1.26.0.post1.dist-info/RECORD,, +micropython_rp2_stubs-1.26.0.post1.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +micropython_rp2_stubs-1.26.0.post1.dist-info/WHEEL,sha256=5druYqcII7zHXzX7qmN0TH895Jg3yuTtfjMgJIVBrKE,92 +neopixel.pyi,sha256=FdRUbjJVKfF98ojrMeBrFsw6Sm9AY6ES9HM6NmYvxa0,2607 +onewire.pyi,sha256=UboaaLJILaciyu73yPK4sF7B-humChu0LOWtEUM6ktk,619 +platform.pyi,sha256=2BjgGrD2-65FgM-_ypN2pPqXkTM8EGnmBgP9WATwUls,1829 +random.pyi,sha256=X040iEdWm4DM1bGhRYrNz4Pxmkn3pjPmYCF1OfCEIvs,4030 +rp2/__init__.pyi,sha256=gHedoolqLnlAUpaAjYFGb-dz5eZ0foeSwPwMs2PlA7U,42977 +rp2/asm_pio.pyi,sha256=-JsGzHyzi8dsRP3QNHyvm-6at6VUJzwEDj-Yaq-Z0mc,23085 +select.pyi,sha256=XT6lIWsV6LjvCWAx2sSUQcNyTokFlWlzj-385eZIV00,4695 +time.pyi,sha256=MgdDX9YL8fosE8AKbRd8mMrgsWvBt1sk6h9wtZeCQz0,14007 +uarray.pyi,sha256=_vDoA-BKjQMQIwjaCAV1nll5vAEL2T-xgrQiDm5xVdE,73 +uasyncio.pyi,sha256=jeB0u_5xMQ2V5xyJ6YzCNrCdjy4_O_28uRd3qCRbuhI,77 +ubinascii.pyi,sha256=TJgiLXvErAY6Md4T6yyuBNMJZ57o0IqBbmwrKi42DVA,79 +ubluetooth.pyi,sha256=qx8fxO2JRh4LcUimgzbDAG-O2g1N-U_WOPz36sE1ZRs,81 +ucollections.pyi,sha256=JlFgl88kORBqQ_XreUQVVUmI2jwKnOgOCIl-GhuBv6Q,460 +ucryptolib.pyi,sha256=ZFBml3gtn0iraWDms2FPcrZPjGWXJCLgxPR6zR1ey80,598 +uctypes.pyi,sha256=7MQ1ku0y4yWQ316kBiExgJl8gHoaw7L-zTTPWMBqsbI,3803 +uerrno.pyi,sha256=O8b_ZlyhYouSdtOm7p53FTymfarjAKAupHOx1brBq3s,73 +uhashlib.pyi,sha256=4l0OybeRxckunXbeFW748giv6giTcOkeZg5ZLFX4s7Q,782 +uheapq.pyi,sha256=vzpZiyC3LfaTphjTfKWTATjRoD7XVGUy3kr2C242v6M,558 +uio.pyi,sha256=dWmUZ-iYMZu4KKOqspZ5ZXj3jv9K6dCOojK7_nlihUk,67 +ujson.pyi,sha256=pggiInEKs9lBzun6IvWh8m9iQr6cadxBUYgyp8dugQk,71 +umachine.pyi,sha256=NpuoOYQYmWHwFuUCk3jAvPRyRg4S6WqoR1ddVKsLre0,77 +uos.pyi,sha256=00KOdXyvwpFYd_DhOpOkDC6qI0-F9tCOxvyIo00dsL8,67 +uplatform.pyi,sha256=mKYGUtsWRzkXT-nhG5XPR32jJ1IbJNSMmYodaAvZaJc,79 +urandom.pyi,sha256=BAm-lBWsPMYYFukHYb1-CQElDGconl4n51MWoQmGbO4,755 +ure.pyi,sha256=MIvrONKD5LKa9fwXMllrbDm_lzkqGWLwpreoCHMJBSc,596 +uselect.pyi,sha256=i3wd5YYMhhhN0oROk4fMPYkwFPjunp8C09_3dPLQdVM,75 +usocket.pyi,sha256=ih8oT6AEAf9mslyw7AksnAmkUWbT4uyhV4Y_HFLPE6Q,75 +ussl.pyi,sha256=4gPHz7LcHDQS4oA3uFgH0yfeoTUslSk72qgqDqSN9BA,69 +ustruct.pyi,sha256=szRH88vBKutJsEKsfkzRYn8nYQP4j8POjBMHPbIedws,75 +usys.pyi,sha256=HRfWC305rZ4OKTBu_1UmPpDNNS1uKMy8DuFrfHV-4G4,69 +utime.pyi,sha256=bf-Oee8krzlA5AkXG_hrNgkijrmD9eNXEpUWLjt8o6s,71 +uzlib.pyi,sha256=TaBEcTT07wPvtMX6Vtkz2KLnfGSqmnq6lVPtp9Wh3yc,71 +vfs.pyi,sha256=vrMyC_Y_gt3mvxOwQuH2o0sI4Ccu5Kme3ydPTsWzi7s,10897 diff --git a/.venv/lib/python3.12/site-packages/micropython_rp2_stubs-1.26.0.post1.dist-info/REQUESTED b/.venv/lib/python3.12/site-packages/micropython_rp2_stubs-1.26.0.post1.dist-info/REQUESTED new file mode 100644 index 0000000..e69de29 diff --git a/.venv/lib/python3.12/site-packages/micropython_rp2_stubs-1.26.0.post1.dist-info/WHEEL b/.venv/lib/python3.12/site-packages/micropython_rp2_stubs-1.26.0.post1.dist-info/WHEEL new file mode 100644 index 0000000..a1641b7 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/micropython_rp2_stubs-1.26.0.post1.dist-info/WHEEL @@ -0,0 +1,4 @@ +Wheel-Version: 1.0 +Generator: poetry-core 2.1.3 +Root-Is-Purelib: true +Tag: py2.py3-none-any diff --git a/.venv/lib/python3.12/site-packages/micropython_stdlib_stubs-1.26.0.post3.dist-info/INSTALLER b/.venv/lib/python3.12/site-packages/micropython_stdlib_stubs-1.26.0.post3.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/.venv/lib/python3.12/site-packages/micropython_stdlib_stubs-1.26.0.post3.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/.venv/lib/python3.12/site-packages/micropython_stdlib_stubs-1.26.0.post3.dist-info/METADATA b/.venv/lib/python3.12/site-packages/micropython_stdlib_stubs-1.26.0.post3.dist-info/METADATA new file mode 100644 index 0000000..225aced --- /dev/null +++ b/.venv/lib/python3.12/site-packages/micropython_stdlib_stubs-1.26.0.post3.dist-info/METADATA @@ -0,0 +1,86 @@ +Metadata-Version: 2.4 +Name: micropython-stdlib-stubs +Version: 1.26.0.post3 +Summary: Micropython stdlib is a reduced and augmented copy of typeshed's stdlib for use by MicroPython stub packages +Project-URL: homepage, https://github.com/josverl/micropython-stubs#micropython-stubs +Project-URL: documentation, https://micropython-stubs.readthedocs.io/ +Project-URL: repository, https://github.com/josverl/micropython-stubs +Author-email: Jos Verlinde +License-Expression: MIT +License-File: LICENSE.md +License-File: LICENSE_typeshed +Classifier: Development Status :: 5 - Production/Stable +Classifier: Operating System :: OS Independent +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3 :: Only +Classifier: Programming Language :: Python :: Implementation :: MicroPython +Classifier: Topic :: Software Development :: Build Tools +Classifier: Topic :: Text Editors :: Integrated Development Environments (IDE) +Classifier: Typing :: Stubs Only +Requires-Python: >=3.7 +Description-Content-Type: text/markdown + +# micropython-stdlib-stubs +A limited size copy of typesheds stdlib directory. +https://github.com/python/typeshed/tree/main/stdlib + +This is used as a dependency in the micropython-*-stub packages to allow overriding of some of the stdlib modules with MicroPython specific implementations. + +MicroPython specific updates to: +- collections + +If you have suggestions or find any issues with the stubs, please report them in the [MicroPython-stubs Discussions](https://github.com/Josverl/micropython-stubs/discussions) + +For an overview of Micropython Stubs please see: https://micropython-stubs.readthedocs.io/en/main/ + * List of all stubs : https://micropython-stubs.readthedocs.io/en/main/firmware_grp.html + +## Building + +This is a short description of the steps taken to create or update the stubs for the micropython-stdlib-stubs distribution. +this package is built using `uv build` and published using `uv publish`. + +## There are two possible reasons to rebuild + 1. Rebuild in order to update from the reference-stubs or ducument-stubs. This will use the same typeshed stubs, and infuse or enrich them with new information from MicroPython. + 2. Rebuild in order to update to a newer version of theof the typeshedrepo.for this you will need to manually advance the typeset repo to a newer version. Perhaps the newest versionand then rerun the update script it might be that due to the changes in the base 5 stubs that you'll need to make updates to the updatescript in order to accommodate for that. + +*Steps* + - clone the typeshed repository + ```bash + cd repos + git clone https://github.com/python/typeshed.git + cd typeshed + git checkout + ``` +- update the version in pyproject toml to the new version ( .postnn) + +- from the publish/micropython-stdlib-stubs directory + - run `python build.py` + +- update and publish the micropython-stdlib-stubs package + ```bash + uv publish + ``` + +- commit the changes to the micropython-stdlib-stubs repository + +## asyncio notes +## asyncio +- no _asyncio.pyi stubs to avoid conflict with stdlib re-use + +- Generators + are not values - but are always callables, or coroutines + so rewrite + `open_connection: Generator ## = ` + to + `async def open_connection () -> Callable[..., Awaitable[Tuple[StreamReader, StreamWriter]]]` + or similar + + +## Publish to PyPi + +Publish using `uv publish`. + + + + diff --git a/.venv/lib/python3.12/site-packages/micropython_stdlib_stubs-1.26.0.post3.dist-info/RECORD b/.venv/lib/python3.12/site-packages/micropython_stdlib_stubs-1.26.0.post3.dist-info/RECORD new file mode 100644 index 0000000..21a1b37 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/micropython_stdlib_stubs-1.26.0.post3.dist-info/RECORD @@ -0,0 +1,83 @@ +_mpy_shed/IRQs.pyi,sha256=hCqQDClcgx77uDiho57KFrS9HYVvD0zh0Smcs09KIgk,808 +_mpy_shed/__init__.pyi,sha256=821KoaqheWqvdKcrZjT9wX9USu8usFvptCJkZbmZsW4,3753 +_mpy_shed/__pycache__/mp_implementation.cpython-312.pyc,, +_mpy_shed/_collections_abc.pyi,sha256=qthswhc_-15h8F74Fb9Bu-aKXcgwdiKNaikkPnNeMvs,3241 +_mpy_shed/blockdevice.pyi,sha256=oT5r8wKFBQcds6uGt4V6voRZnYUg2HaDXEbpt8UwWXc,10065 +_mpy_shed/buffer_mp.pyi,sha256=P7SGDfT8i0St5mhj9HwH_6J6WoP2Hq9Zhsh4k6Pf2Bs,450 +_mpy_shed/collections/__init__.pyi,sha256=DKGew2BelWHgR31vYu4UCMpGOPF1DJpoZIXcvJN6th4,24476 +_mpy_shed/collections/abc.pyi,sha256=zgovA8n11pYi3KyJJJeHveG0G3KpnvsljqQ5QirtDpk,85 +_mpy_shed/io_modes.pyi,sha256=JiP86MvsJpGFCIIxhkYvcI8xvgdKKPoA_nMKo8dDkIc,1762 +_mpy_shed/io_mp.pyi,sha256=paBaW8dgurf4SF6ZAT4O8yzc_XxI9u6WIwYL5SHIrUk,1954 +_mpy_shed/mp_available.pyi,sha256=JDAwXLHVWG4eaCzhaL-MuG1QUJWud2O68WhRlAwYOiM,868 +_mpy_shed/mp_implementation.py,sha256=Lvx6d7p16eVdIhUCEPISyBQo1MmoRsdyPXKa351TZJs,1057 +_mpy_shed/neopixelbase.pyi,sha256=fHfGkJCrn1JoWu2_sgSIHu7igdqfLxHjOc15lUaBFeQ,621 +_mpy_shed/pathlike.pyi,sha256=kW6M9m1ekNlohS2GxrWUHfu1WOJcr4yAACueFKXgUhg,684 +_mpy_shed/subscriptable.pyi,sha256=nKVNhNjinrzFYaR0DqE7cEyN3jqJsvhxTnswzRGmdAY,644 +_mpy_shed/time_mp.pyi,sha256=aHVWS8uJJIHEWqawx2IwT5zUNauv9b4LRdi1Sph5s9I,658 +micropython_stdlib_stubs-1.26.0.post3.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +micropython_stdlib_stubs-1.26.0.post3.dist-info/METADATA,sha256=FxCF4g1NHo5lnX-LG2Z3W8tsOI-1G8FDPAm9JUVly5U,3518 +micropython_stdlib_stubs-1.26.0.post3.dist-info/RECORD,, +micropython_stdlib_stubs-1.26.0.post3.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +micropython_stdlib_stubs-1.26.0.post3.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87 +micropython_stdlib_stubs-1.26.0.post3.dist-info/licenses/LICENSE.md,sha256=XnIlPftszZeoPSWf1jwR9a1w2zp3zOL_-oC0qRi-gbE,13067 +micropython_stdlib_stubs-1.26.0.post3.dist-info/licenses/LICENSE_typeshed,sha256=E8ceCWKDbYhQdivaD2I0_yEwNIcfpmtsQpYlSdc1F6Q,12894 +stdlib/VERSIONS,sha256=mM3ASvFIjLqG4GJyqeZt6hRAEr8B5reRT7dCmtbYYDw,5995 +stdlib/__future__.pyi,sha256=qIwWDmjaw3XCiulKYoKBQB_eJjLxweesUKwBdpkgQkU,915 +stdlib/_ast.pyi,sha256=Hp9iS4qcJfo4KlueBTaYkR9IfdelifXU3bBhnAe_tmw,3466 +stdlib/_codecs.pyi,sha256=dWiEtxcI9QnZYo0tGkMS14ksIK8Nn1jQvoHznsDRf20,6919 +stdlib/_collections_abc.pyi,sha256=tAxXudfHJqSZco-VYEA3KdeHisUgq5iGleLPkylU0-8,2778 +stdlib/_decimal.pyi,sha256=CGJcsPJpGBn_uIAse-6mJCtssMMcHsWiJGTnZdTVOI8,2105 +stdlib/_typeshed/README.md,sha256=upGLmqNVRlXIE70i0vGA969dc26GVqU9Gs5cHEzb8Ys,1043 +stdlib/_typeshed/__init__.pyi,sha256=W67NAhSV3NF1R4na73c966olOqM3NHheEu3Z-8PlRO0,12563 +stdlib/_typeshed/dbapi.pyi,sha256=DbFvZC7aeSFuw_hopshe-nz6OL_btPB06zIoJ8O-9tA,1636 +stdlib/_typeshed/importlib.pyi,sha256=iSR1SQrIgH39dZwu1o0M0qk8ZsxRUkn4DtG2_K5tO4o,727 +stdlib/_typeshed/wsgi.pyi,sha256=6sb45JIA9DuSd1hYwxt2418TU6E4tVFiIfflHKMnpnE,1614 +stdlib/_typeshed/xml.pyi,sha256=W4c9PcHw737FUoezcPAkfRuoMB--7Up7uKlZ0ShNIG0,499 +stdlib/abc.pyi,sha256=oli4JypsePdvKt1xAB0sqDFbX1aUYddNRzj2BP65M-w,1987 +stdlib/array.pyi,sha256=CqeQucdU-czxtV4634Q-sUeQ_relrCnXQxJ86lAMGZg,24658 +stdlib/asyncio/__init__.pyi,sha256=aJXL2LflxMaFW91K3mH1L4RakIV4bR_ZuHMnDn51eRg,1337 +stdlib/asyncio/base_events.pyi,sha256=av8dDqKw4UttfGfla1x780I2Q6kVrNcQ59DlHea5a0k,19986 +stdlib/asyncio/base_futures.pyi,sha256=64lMK_8YEQQoxRnN-2OAQzKnEx9F9VVQ4GKIQKeqFxE,749 +stdlib/asyncio/base_tasks.pyi,sha256=PYv3qwMz2WIqDs3GGdLTaJfiJBTuUwIK0PUEKHIl9Uc,413 +stdlib/asyncio/constants.pyi,sha256=aQWt89UfXp0rZM29OQDAGGlGzieOr6dAQ6nlSS5gjAU,576 +stdlib/asyncio/coroutines.pyi,sha256=ndCXCDSwGk4ZLKmlNCW59cbfxwc2cExSYyrkpV63TDM,1062 +stdlib/asyncio/events.pyi,sha256=BPITbGyq8A1SbwxsdTkLYzANtPOQ95R5qVK5ExptrAc,25189 +stdlib/asyncio/exceptions.pyi,sha256=sSiIocmo4Zgxt7_n-7ms-FthtJTCmEC4dbNuN0R11Pc,1142 +stdlib/asyncio/format_helpers.pyi,sha256=ur-vKOrzAmO4JvC4YmbVuQhTDi8giSx0ym7_Uu91nxw,1334 +stdlib/asyncio/futures.pyi,sha256=kSqape-NQOeANur5Z9e6lJMNj4rTgDtsRv5C8C4skLU,653 +stdlib/asyncio/locks.pyi,sha256=2a1PhjkhMpTRmCS49kkF0r7YGwocFL6Gio3s8oGGMBo,4391 +stdlib/asyncio/log.pyi,sha256=--UJmDmbuqm1EdrcBW5c94k3pzoNwlZKjsqn-ckSpPA,42 +stdlib/asyncio/micropython.pyi,sha256=yKAHRdTaLJXYCPPJTWf6r9k7YiW11heX01YIDzW4nhg,1153 +stdlib/asyncio/mixins.pyi,sha256=M8E77-G6AYPE2HyZEua5Rht1DP5-URJ2rBDPSmkiclA,224 +stdlib/asyncio/proactor_events.pyi,sha256=zQnjKl-JdZqz6p4L-VySG6rDjb0_DF0r87twIdaWsvM,2596 +stdlib/asyncio/protocols.pyi,sha256=3ooDCGHhxxYPcM5o20stbqOPNd-RBbiIDNk4ungvJqU,1665 +stdlib/asyncio/queues.pyi,sha256=M71sCrWslDdIlWEZQ4Uk9p2TbZmv-GHWAJtGLFTYA_o,1918 +stdlib/asyncio/readme.md,sha256=CmUrpswtK8eLayHzofxLEDDwPYryiyVlK3G2t2y9C6o,357 +stdlib/asyncio/runners.pyi,sha256=DO4xjsc9DNqIqnNg_HdrBbweDWfZrHguZH8DDZKB9Mo,1205 +stdlib/asyncio/selector_events.pyi,sha256=-40IJS-J9MsqcwKb9SkSsO-5-679O_7ocPwOZQZ44yA,231 +stdlib/asyncio/sslproto.pyi,sha256=rqtzXumHJODjJt0YsYzA9BVk_16lEKFydp4Lo_EOFtE,6615 +stdlib/asyncio/staggered.pyi,sha256=Qwgygm1Wd5ydD1Q9Iwu1lCq5uHRl0q_p5wca_HD7ask,351 +stdlib/asyncio/streams.pyi,sha256=x-l1vbdqy8bPq6i0B8X4mzF4jfkkdIl-UHopz_hrCVM,6785 +stdlib/asyncio/tasks.pyi,sha256=tEtbuaBujf8PZN4GYCIl2ZyOBr-QeQ22I5KEQJa1Fdo,17702 +stdlib/asyncio/threads.pyi,sha256=MEYiLgK_Q1coLUEaPtNQdmOWOMnGaofaSV_vshKvyQE,275 +stdlib/asyncio/timeouts.pyi,sha256=5LCrJFI5pNOFfQWPPTbljcMrAIbvYG8AzuTf5-QAt1g,672 +stdlib/asyncio/transports.pyi,sha256=eFNxnqiwNWvstKzb5aMGbIvWxaIAdNX5msIOWqZfxvo,2087 +stdlib/asyncio/trsock.pyi,sha256=hbdvHTSOHTInMcYxuj32WkQ2nbvcDdmcXooQxjvddYg,4714 +stdlib/builtins.pyi,sha256=TR7v_4KLL5OhAzD8dmYI0y7gY-IJDhPVEIvDAXqsvkA,91758 +stdlib/collections/__init__.pyi,sha256=a6HGdIW4RrokNu1TGz9U52B20u6jxcMpu_bxC0OeaxA,27912 +stdlib/collections/abc.pyi,sha256=kBiZAN0VPf8qpkInbjqKZRRe0PXrZ7jxNmCGs4o5UOc,79 +stdlib/enum.pyi,sha256=x5vIwgtEe_VLYdCC30GwurkMHOBzrNF31QXaUrEIi5w,12074 +stdlib/io.pyi,sha256=cprNnue_TSUsS9-SSKYTjX_1y2rhTp_3Bp1LwxMWQj8,46125 +stdlib/json/__init__.pyi,sha256=RSCtGbMWkNbZdsQ2DoXRW1p8SesGlpfz3e1FwlOtfHc,10005 +stdlib/os/__init__.pyi,sha256=YWq8bkIvatKsakZi8NgbqpkRgUrwk873pPPhYFKZDIU,58598 +stdlib/re.pyi,sha256=M25Rpd8KC_5Aw5heVggCVmbxuxAb28c3fu0Pjt8cssM,11784 +stdlib/sre_compile.pyi,sha256=xhzSJueTiaUdn2OeQbQ7xPqDEWEitDfRA9n76sIUm94,304 +stdlib/sre_constants.pyi,sha256=Z7OUqL_OUe75kpGXw0tHCG4CN62AoY-5FyrSlXFuQOs,3794 +stdlib/sre_parse.pyi,sha256=9PT58-Q2oMDqtejzbWG2D5-UiBo8mQnptiAevjW7ZyQ,3790 +stdlib/ssl.pyi,sha256=lfADY9On5yncg5VvRo604wAmJM8mA9LMSndAlDcMayw,25657 +stdlib/struct.pyi,sha256=Pvce2bp43lUS1vG9xCV4EypjJqH6_WokPudxrTSJrIA,5579 +stdlib/sys/__init__.pyi,sha256=4ntB01895ZnSYU4pQymzSrEpizm5mp9-rrDpACQ-U50,28576 +stdlib/types.pyi,sha256=H_o9m3Le36mQWUCTtW061R5TMFP3EnqLSvupvWJ6jmg,21898 +stdlib/typing.pyi,sha256=DE2DSoBLttgjFWp-27b8krO5RNkxZ3xUwMTwRRtHWtY,39273 +stdlib/typing_extensions.pyi,sha256=AQILGFIJ8YG-c7QnIDncfFLHA3wVC72Ng-c80HSJ16Q,16296 +stubs/mypy-extensions/mypy_extensions.pyi,sha256=LIU5CWrCyJ6G8xqMM_P3fztnO2y177WwSk0HXk_l-4M,9102 diff --git a/.venv/lib/python3.12/site-packages/micropython_stdlib_stubs-1.26.0.post3.dist-info/REQUESTED b/.venv/lib/python3.12/site-packages/micropython_stdlib_stubs-1.26.0.post3.dist-info/REQUESTED new file mode 100644 index 0000000..e69de29 diff --git a/.venv/lib/python3.12/site-packages/micropython_stdlib_stubs-1.26.0.post3.dist-info/WHEEL b/.venv/lib/python3.12/site-packages/micropython_stdlib_stubs-1.26.0.post3.dist-info/WHEEL new file mode 100644 index 0000000..12228d4 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/micropython_stdlib_stubs-1.26.0.post3.dist-info/WHEEL @@ -0,0 +1,4 @@ +Wheel-Version: 1.0 +Generator: hatchling 1.27.0 +Root-Is-Purelib: true +Tag: py3-none-any diff --git a/.venv/lib/python3.12/site-packages/micropython_stdlib_stubs-1.26.0.post3.dist-info/licenses/LICENSE.md b/.venv/lib/python3.12/site-packages/micropython_stdlib_stubs-1.26.0.post3.dist-info/licenses/LICENSE.md new file mode 100644 index 0000000..cd4ef68 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/micropython_stdlib_stubs-1.26.0.post3.dist-info/licenses/LICENSE.md @@ -0,0 +1,239 @@ +MIT License + +Copyright (c) 2023 Jos Verlinde + +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. + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +Parts of this package are licenced are licensed under different licenses , reproduced below. +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- + +The "typeshed" project is licensed under the terms of the Apache license, as +reproduced below. + += = = = = + +Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + += = = = = + +Parts of typeshed are licensed under different licenses (like the MIT +license), reproduced below. + += = = = = + +The MIT License + +Copyright (c) 2015 Jukka Lehtosalo and contributors + +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. + += = = = = diff --git a/.venv/lib/python3.12/site-packages/micropython_stdlib_stubs-1.26.0.post3.dist-info/licenses/LICENSE_typeshed b/.venv/lib/python3.12/site-packages/micropython_stdlib_stubs-1.26.0.post3.dist-info/licenses/LICENSE_typeshed new file mode 100644 index 0000000..2ed01b9 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/micropython_stdlib_stubs-1.26.0.post3.dist-info/licenses/LICENSE_typeshed @@ -0,0 +1,237 @@ +The "typeshed" project is licensed under the terms of the Apache license, as +reproduced below. + += = = = = + +Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright {yyyy} {name of copyright owner} + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + += = = = = + +Parts of typeshed are licensed under different licenses (like the MIT +license), reproduced below. + += = = = = + +The MIT License + +Copyright (c) 2015 Jukka Lehtosalo and contributors + +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. + += = = = = diff --git a/.venv/lib/python3.12/site-packages/mpremote-1.26.1.dist-info/INSTALLER b/.venv/lib/python3.12/site-packages/mpremote-1.26.1.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/.venv/lib/python3.12/site-packages/mpremote-1.26.1.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/.venv/lib/python3.12/site-packages/mpremote-1.26.1.dist-info/METADATA b/.venv/lib/python3.12/site-packages/mpremote-1.26.1.dist-info/METADATA new file mode 100644 index 0000000..3d7145a --- /dev/null +++ b/.venv/lib/python3.12/site-packages/mpremote-1.26.1.dist-info/METADATA @@ -0,0 +1,105 @@ +Metadata-Version: 2.4 +Name: mpremote +Version: 1.26.1 +Summary: Tool for interacting remotely with MicroPython devices +Project-URL: Homepage, https://github.com/micropython/micropython +Author-email: Damien George +License: MIT +License-File: LICENSE +Keywords: hardware,micropython +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: MIT License +Classifier: Operating System :: OS Independent +Classifier: Programming Language :: Python :: 3 +Classifier: Topic :: Software Development :: Embedded Systems +Classifier: Topic :: System :: Hardware +Requires-Python: >=3.4 +Requires-Dist: importlib-metadata>=1.4; python_version < '3.8' +Requires-Dist: platformdirs>=4.3.7 +Requires-Dist: pyserial>=3.3 +Description-Content-Type: text/markdown + +# mpremote -- MicroPython remote control + +This CLI tool provides an integrated set of utilities to remotely interact with +and automate a MicroPython device over a serial connection. + +The simplest way to use this tool is: + + mpremote + +This will automatically connect to a USB serial port and provide an interactive REPL. + +The full list of supported commands are: + + mpremote connect -- connect to given device + device may be: list, auto, id:x, port:x + or any valid device name/path + mpremote disconnect -- disconnect current device + mpremote mount -- mount local directory on device + mpremote eval -- evaluate and print the string + mpremote exec -- execute the string + mpremote run -- run the given local script + mpremote fs -- execute filesystem commands on the device + command may be: cat, ls, cp, rm, mkdir, rmdir, sha256sum + use ":" as a prefix to specify a file on the device + mpremote repl -- enter REPL + options: + --capture + --inject-code + --inject-file + mpremote mip install -- Install packages (from micropython-lib or third-party sources) + options: + --target + --index + --no-mpy + mpremote help -- print list of commands and exit + +Multiple commands can be specified and they will be run sequentially. Connection +and disconnection will be done automatically at the start and end of the execution +of the tool, if such commands are not explicitly given. Automatic connection will +search for the first available serial device. If no action is specified then the +REPL will be entered. + +Shortcuts can be defined using the macro system. Built-in shortcuts are: + +- a0, a1, a2, a3: connect to `/dev/ttyACM?` +- u0, u1, u2, u3: connect to `/dev/ttyUSB?` +- c0, c1, c2, c3: connect to `COM?` +- cat, ls, cp, rm, mkdir, rmdir, df: filesystem commands +- reset: reset the device +- bootloader: make the device enter its bootloader + +Any user configuration, including user-defined shortcuts, can be placed in +.config/mpremote/config.py. For example: + + # Custom macro commands + commands = { + "c33": "connect id:334D335C3138", + "bl": "bootloader", + "double x=4": { + "command": "eval x*2", + "help": "multiply by two" + } + } + +Examples: + + mpremote + mpremote a1 + mpremote connect /dev/ttyUSB0 repl + mpremote ls + mpremote a1 ls + mpremote exec "import micropython; micropython.mem_info()" + mpremote eval 1/2 eval 3/4 + mpremote mount . + mpremote mount . exec "import local_script" + mpremote ls + mpremote cat boot.py + mpremote cp :main.py . + mpremote cp main.py : + mpremote cp -r dir/ : + mpremote sha256sum :main.py + mpremote mip install aioble + mpremote mip install github:org/repo@branch + mpremote mip install gitlab:org/repo@branch diff --git a/.venv/lib/python3.12/site-packages/mpremote-1.26.1.dist-info/RECORD b/.venv/lib/python3.12/site-packages/mpremote-1.26.1.dist-info/RECORD new file mode 100644 index 0000000..653d1f0 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/mpremote-1.26.1.dist-info/RECORD @@ -0,0 +1,30 @@ +../../../bin/mpremote,sha256=bxRhc--5JOlFN19yFeyBH9VXJIkmYE0TRc6U9CnmTA4,294 +mpremote-1.26.1.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +mpremote-1.26.1.dist-info/METADATA,sha256=XiPdewkwrkIupLuKevz-YxqgbKpoZgy1aj7CzhavNa8,4271 +mpremote-1.26.1.dist-info/RECORD,, +mpremote-1.26.1.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +mpremote-1.26.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87 +mpremote-1.26.1.dist-info/entry_points.txt,sha256=sgvfZwY5hhV3pe7WBKbJX-A3K4rPSalISc2Et9J5488,48 +mpremote-1.26.1.dist-info/licenses/LICENSE,sha256=t5Ak-wggyYkaKWW9RhUOoCxzdThAgY9_-bVQ0fauFuU,1088 +mpremote/__init__.py,sha256=uCMjbbM9nO3VqYqqvGIZIzXy3juW1hHD8b4LrW0mWiQ,438 +mpremote/__main__.py,sha256=4uulmJ59a37e2DlZJwGhd0wmwvK1KHTbeDnhBWqpFtQ,84 +mpremote/__pycache__/__init__.cpython-312.pyc,, +mpremote/__pycache__/__main__.cpython-312.pyc,, +mpremote/__pycache__/commands.cpython-312.pyc,, +mpremote/__pycache__/console.cpython-312.pyc,, +mpremote/__pycache__/main.cpython-312.pyc,, +mpremote/__pycache__/mip.cpython-312.pyc,, +mpremote/__pycache__/mp_errno.cpython-312.pyc,, +mpremote/__pycache__/repl.cpython-312.pyc,, +mpremote/__pycache__/romfs.cpython-312.pyc,, +mpremote/__pycache__/transport.cpython-312.pyc,, +mpremote/__pycache__/transport_serial.cpython-312.pyc,, +mpremote/commands.py,sha256=qMNSaRwLm_HQJhPcIOzZubtqGgAU1Zq2M0z_CdXlRhs,26587 +mpremote/console.py,sha256=doc59IfVkosiqlexQlZrLRsQmtzFb5hrm7q2HabKnMU,5280 +mpremote/main.py,sha256=7JS0_t8fKCwISGX9k4vxojWEGFYqVla9U5A4PPzVF8I,19305 +mpremote/mip.py,sha256=IRQeQ0jkYxvo0EPVCaEHVoP5xSZ8JPT8qDdVBoE-Pko,7380 +mpremote/mp_errno.py,sha256=xlupFzO1KKSe_nN9ogUIUZzJsCJKcsf0TyUyCDG5bvw,1280 +mpremote/repl.py,sha256=-qEslvMdWDfGgbglvIqdT6zgwbtXeK_m_x2pGvODflo,4679 +mpremote/romfs.py,sha256=j-aCEzxWg4kryrRDgO_mETEyg2xpZyxOnpS1mcVDmbU,4966 +mpremote/transport.py,sha256=rTtyBJDYfzTPpLkcAJ30avaql6Ak055ekR513SURza0,7608 +mpremote/transport_serial.py,sha256=Q3jFpmZIUBi1RLDBbU83EjnMD3lcAN2O8696Q-6fNTg,33927 diff --git a/.venv/lib/python3.12/site-packages/mpremote-1.26.1.dist-info/REQUESTED b/.venv/lib/python3.12/site-packages/mpremote-1.26.1.dist-info/REQUESTED new file mode 100644 index 0000000..e69de29 diff --git a/.venv/lib/python3.12/site-packages/mpremote-1.26.1.dist-info/WHEEL b/.venv/lib/python3.12/site-packages/mpremote-1.26.1.dist-info/WHEEL new file mode 100644 index 0000000..12228d4 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/mpremote-1.26.1.dist-info/WHEEL @@ -0,0 +1,4 @@ +Wheel-Version: 1.0 +Generator: hatchling 1.27.0 +Root-Is-Purelib: true +Tag: py3-none-any diff --git a/.venv/lib/python3.12/site-packages/mpremote-1.26.1.dist-info/entry_points.txt b/.venv/lib/python3.12/site-packages/mpremote-1.26.1.dist-info/entry_points.txt new file mode 100644 index 0000000..4e023f9 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/mpremote-1.26.1.dist-info/entry_points.txt @@ -0,0 +1,2 @@ +[console_scripts] +mpremote = mpremote.main:main diff --git a/.venv/lib/python3.12/site-packages/mpremote-1.26.1.dist-info/licenses/LICENSE b/.venv/lib/python3.12/site-packages/mpremote-1.26.1.dist-info/licenses/LICENSE new file mode 100644 index 0000000..a9ea6c2 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/mpremote-1.26.1.dist-info/licenses/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2021-2022 Damien P. George + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/.venv/lib/python3.12/site-packages/mpremote/__init__.py b/.venv/lib/python3.12/site-packages/mpremote/__init__.py new file mode 100644 index 0000000..d141623 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/mpremote/__init__.py @@ -0,0 +1,12 @@ +try: + from importlib.metadata import version, PackageNotFoundError + + try: + __version__ = version("mpremote") + except PackageNotFoundError: + # Error loading package version (e.g. running from source). + __version__ = "0.0.0-local" +except ImportError: + # importlib.metadata not available (e.g. CPython <3.8 without + # importlib_metadata compatibility package installed). + __version__ = "0.0.0-unknown" diff --git a/.venv/lib/python3.12/site-packages/mpremote/__main__.py b/.venv/lib/python3.12/site-packages/mpremote/__main__.py new file mode 100644 index 0000000..a91ff67 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/mpremote/__main__.py @@ -0,0 +1,6 @@ +#!/usr/bin/env python3 + +import sys +from mpremote import main + +sys.exit(main.main()) diff --git a/.venv/lib/python3.12/site-packages/mpremote/__pycache__/__init__.cpython-312.pyc b/.venv/lib/python3.12/site-packages/mpremote/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000..098059b Binary files /dev/null and b/.venv/lib/python3.12/site-packages/mpremote/__pycache__/__init__.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/mpremote/__pycache__/__main__.cpython-312.pyc b/.venv/lib/python3.12/site-packages/mpremote/__pycache__/__main__.cpython-312.pyc new file mode 100644 index 0000000..9581bf4 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/mpremote/__pycache__/__main__.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/mpremote/__pycache__/commands.cpython-312.pyc b/.venv/lib/python3.12/site-packages/mpremote/__pycache__/commands.cpython-312.pyc new file mode 100644 index 0000000..f0e1fae Binary files /dev/null and b/.venv/lib/python3.12/site-packages/mpremote/__pycache__/commands.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/mpremote/__pycache__/console.cpython-312.pyc b/.venv/lib/python3.12/site-packages/mpremote/__pycache__/console.cpython-312.pyc new file mode 100644 index 0000000..c035f53 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/mpremote/__pycache__/console.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/mpremote/__pycache__/main.cpython-312.pyc b/.venv/lib/python3.12/site-packages/mpremote/__pycache__/main.cpython-312.pyc new file mode 100644 index 0000000..cb85b97 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/mpremote/__pycache__/main.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/mpremote/__pycache__/mip.cpython-312.pyc b/.venv/lib/python3.12/site-packages/mpremote/__pycache__/mip.cpython-312.pyc new file mode 100644 index 0000000..759d455 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/mpremote/__pycache__/mip.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/mpremote/__pycache__/mp_errno.cpython-312.pyc b/.venv/lib/python3.12/site-packages/mpremote/__pycache__/mp_errno.cpython-312.pyc new file mode 100644 index 0000000..4864c9b Binary files /dev/null and b/.venv/lib/python3.12/site-packages/mpremote/__pycache__/mp_errno.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/mpremote/__pycache__/repl.cpython-312.pyc b/.venv/lib/python3.12/site-packages/mpremote/__pycache__/repl.cpython-312.pyc new file mode 100644 index 0000000..797f933 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/mpremote/__pycache__/repl.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/mpremote/__pycache__/romfs.cpython-312.pyc b/.venv/lib/python3.12/site-packages/mpremote/__pycache__/romfs.cpython-312.pyc new file mode 100644 index 0000000..6c14d4b Binary files /dev/null and b/.venv/lib/python3.12/site-packages/mpremote/__pycache__/romfs.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/mpremote/__pycache__/transport.cpython-312.pyc b/.venv/lib/python3.12/site-packages/mpremote/__pycache__/transport.cpython-312.pyc new file mode 100644 index 0000000..2e2483a Binary files /dev/null and b/.venv/lib/python3.12/site-packages/mpremote/__pycache__/transport.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/mpremote/__pycache__/transport_serial.cpython-312.pyc b/.venv/lib/python3.12/site-packages/mpremote/__pycache__/transport_serial.cpython-312.pyc new file mode 100644 index 0000000..065f9d4 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/mpremote/__pycache__/transport_serial.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/mpremote/commands.py b/.venv/lib/python3.12/site-packages/mpremote/commands.py new file mode 100644 index 0000000..4974c71 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/mpremote/commands.py @@ -0,0 +1,746 @@ +import binascii +import errno +import hashlib +import os +import sys +import tempfile +import zlib + +import serial.tools.list_ports + +from .transport import TransportError, TransportExecError, stdout_write_bytes +from .transport_serial import SerialTransport +from .romfs import make_romfs, VfsRomWriter + + +class CommandError(Exception): + pass + + +def do_connect(state, args=None): + dev = args.device[0] if args else "auto" + do_disconnect(state) + + try: + if dev == "list": + # List attached devices. + for p in sorted(serial.tools.list_ports.comports()): + print( + "{} {} {:04x}:{:04x} {} {}".format( + p.device, + p.serial_number, + p.vid if isinstance(p.vid, int) else 0, + p.pid if isinstance(p.pid, int) else 0, + p.manufacturer, + p.product, + ) + ) + # Don't do implicit REPL command. + state.did_action() + elif dev == "auto": + # Auto-detect and auto-connect to the first available USB serial port. + for p in sorted(serial.tools.list_ports.comports()): + if p.vid is not None and p.pid is not None: + try: + state.transport = SerialTransport(p.device, baudrate=115200) + return + except TransportError as er: + if not er.args[0].startswith("failed to access"): + raise er + raise TransportError("no device found") + elif dev.startswith("id:"): + # Search for a device with the given serial number. + serial_number = dev[len("id:") :] + dev = None + for p in serial.tools.list_ports.comports(): + if p.serial_number == serial_number: + state.transport = SerialTransport(p.device, baudrate=115200) + return + raise TransportError("no device with serial number {}".format(serial_number)) + else: + # Connect to the given device. + if dev.startswith("port:"): + dev = dev[len("port:") :] + state.transport = SerialTransport(dev, baudrate=115200) + return + except TransportError as er: + msg = er.args[0] + if msg.startswith("failed to access"): + msg += " (it may be in use by another program)" + raise CommandError(msg) + + +def do_disconnect(state, _args=None): + if not state.transport: + return + + try: + if state.transport.mounted: + if not state.transport.in_raw_repl: + state.transport.enter_raw_repl(soft_reset=False) + state.transport.umount_local() + if state.transport.in_raw_repl: + state.transport.exit_raw_repl() + except OSError: + # Ignore any OSError exceptions when shutting down, eg: + # - filesystem_command will close the connection if it had an error + # - umounting will fail if serial port disappeared + pass + state.transport.close() + state.transport = None + state._auto_soft_reset = True + + +def show_progress_bar(size, total_size, op="copying"): + if not sys.stdout.isatty(): + return + verbose_size = 2048 + bar_length = 20 + if total_size < verbose_size: + return + elif size >= total_size: + # Clear progress bar when copy completes + print("\r" + " " * (13 + len(op) + bar_length) + "\r", end="") + else: + bar = size * bar_length // total_size + progress = size * 100 // total_size + print( + "\r ... {} {:3d}% [{}{}]".format(op, progress, "#" * bar, "-" * (bar_length - bar)), + end="", + ) + + +def _remote_path_join(a, *b): + if not a: + a = "./" + result = a.rstrip("/") + for x in b: + result += "/" + x.strip("/") + return result + + +def _remote_path_dirname(a): + a = a.rsplit("/", 1) + if len(a) == 1: + return "" + else: + return a[0] + + +def _remote_path_basename(a): + return a.rsplit("/", 1)[-1] + + +def do_filesystem_cp(state, src, dest, multiple, check_hash=False): + if dest.startswith(":"): + dest_no_slash = dest.rstrip("/" + os.path.sep + (os.path.altsep or "")) + dest_exists = state.transport.fs_exists(dest_no_slash[1:]) + dest_isdir = dest_exists and state.transport.fs_isdir(dest_no_slash[1:]) + + # A trailing / on dest forces it to be a directory. + if dest != dest_no_slash: + if not dest_isdir: + raise CommandError("cp: destination is not a directory") + dest = dest_no_slash + else: + dest_exists = os.path.exists(dest) + dest_isdir = dest_exists and os.path.isdir(dest) + + if multiple: + if not dest_exists: + raise CommandError("cp: destination does not exist") + if not dest_isdir: + raise CommandError("cp: destination is not a directory") + + # Download the contents of source. + try: + if src.startswith(":"): + data = state.transport.fs_readfile(src[1:], progress_callback=show_progress_bar) + filename = _remote_path_basename(src[1:]) + else: + with open(src, "rb") as f: + data = f.read() + filename = os.path.basename(src) + except IsADirectoryError: + raise CommandError("cp: -r not specified; omitting directory") + + # Write back to dest. + if dest.startswith(":"): + # If the destination path is just the directory, then add the source filename. + if dest_isdir: + dest = ":" + _remote_path_join(dest[1:], filename) + + # Skip copy if the destination file is identical. + if check_hash: + try: + remote_hash = state.transport.fs_hashfile(dest[1:], "sha256") + source_hash = hashlib.sha256(data).digest() + # remote_hash will be None if the device doesn't support + # hashlib.sha256 (and therefore won't match). + if remote_hash == source_hash: + print("Up to date:", dest[1:]) + return + except OSError: + pass + + # Write to remote. + state.transport.fs_writefile(dest[1:], data, progress_callback=show_progress_bar) + else: + # If the destination path is just the directory, then add the source filename. + if dest_isdir: + dest = os.path.join(dest, filename) + + # Write to local file. + with open(dest, "wb") as f: + f.write(data) + + +def do_filesystem_recursive_cp(state, src, dest, multiple, check_hash): + # Ignore trailing / on both src and dest. (Unix cp ignores them too) + src = src.rstrip("/" + os.path.sep + (os.path.altsep if os.path.altsep else "")) + dest = dest.rstrip("/" + os.path.sep + (os.path.altsep if os.path.altsep else "")) + + # If the destination directory exists, then we copy into it. Otherwise we + # use the destination as the target. + if dest.startswith(":"): + dest_exists = state.transport.fs_exists(dest[1:]) + else: + dest_exists = os.path.exists(dest) + + # Recursively find all files to copy from a directory. + # `dirs` will be a list of dest split paths. + # `files` will be a list of `(dest split path, src joined path)`. + dirs = [] + files = [] + + # For example, if src=/tmp/foo, with /tmp/foo/x.py and /tmp/foo/a/b/c.py, + # and if the destination directory exists, then we will have: + # dirs = [['foo'], ['foo', 'a'], ['foo', 'a', 'b']] + # files = [(['foo', 'x.py'], '/tmp/foo/x.py'), (['foo', 'a', 'b', 'c.py'], '/tmp/foo/a/b/c.py')] + # If the destination doesn't exist, then we will have: + # dirs = [['a'], ['a', 'b']] + # files = [(['x.py'], '/tmp/foo/x.py'), (['a', 'b', 'c.py'], '/tmp/foo/a/b/c.py')] + + def _list_recursive(base, src_path, dest_path, src_join_fun, src_isdir_fun, src_listdir_fun): + src_path_joined = src_join_fun(base, *src_path) + if src_isdir_fun(src_path_joined): + if dest_path: + dirs.append(dest_path) + for entry in src_listdir_fun(src_path_joined): + _list_recursive( + base, + src_path + [entry], + dest_path + [entry], + src_join_fun, + src_isdir_fun, + src_listdir_fun, + ) + else: + files.append( + ( + dest_path, + src_path_joined, + ) + ) + + if src.startswith(":"): + src_dirname = [_remote_path_basename(src[1:])] + dest_dirname = src_dirname if dest_exists else [] + _list_recursive( + _remote_path_dirname(src[1:]), + src_dirname, + dest_dirname, + src_join_fun=_remote_path_join, + src_isdir_fun=state.transport.fs_isdir, + src_listdir_fun=lambda p: [x.name for x in state.transport.fs_listdir(p)], + ) + else: + src_dirname = [os.path.basename(src)] + dest_dirname = src_dirname if dest_exists else [] + _list_recursive( + os.path.dirname(src), + src_dirname, + dest_dirname, + src_join_fun=os.path.join, + src_isdir_fun=os.path.isdir, + src_listdir_fun=os.listdir, + ) + + # If no directories were encountered then we must have just had a file. + if not dirs: + return do_filesystem_cp(state, src, dest, multiple, check_hash) + + def _mkdir(a, *b): + try: + if a.startswith(":"): + state.transport.fs_mkdir(_remote_path_join(a[1:], *b)) + else: + os.mkdir(os.path.join(a, *b)) + except FileExistsError: + pass + + # Create the destination if necessary. + if not dest_exists: + _mkdir(dest) + + # Create all sub-directories relative to the destination. + for d in dirs: + _mkdir(dest, *d) + + # Copy all files, in sorted order to help it be deterministic. + files.sort() + for dest_path_split, src_path_joined in files: + if src.startswith(":"): + src_path_joined = ":" + src_path_joined + + if dest.startswith(":"): + dest_path_joined = ":" + _remote_path_join(dest[1:], *dest_path_split) + else: + dest_path_joined = os.path.join(dest, *dest_path_split) + + do_filesystem_cp(state, src_path_joined, dest_path_joined, False, check_hash) + + +def do_filesystem_recursive_rm(state, path, args): + if state.transport.fs_isdir(path): + if state.transport.mounted: + r_cwd = state.transport.eval("os.getcwd()") + abs_path = os.path.normpath( + os.path.join(r_cwd, path) if not os.path.isabs(path) else path + ) + if isinstance(state.transport, SerialTransport) and abs_path.startswith( + f"{SerialTransport.fs_hook_mount}/" + ): + raise CommandError( + f"rm -r not permitted on {SerialTransport.fs_hook_mount} directory" + ) + for entry in state.transport.fs_listdir(path): + do_filesystem_recursive_rm(state, _remote_path_join(path, entry.name), args) + if path: + try: + state.transport.fs_rmdir(path) + if args.verbose: + print(f"removed directory: '{path}'") + except OSError as e: + if e.errno != errno.EINVAL: # not vfs mountpoint + raise CommandError( + f"rm -r: cannot remove :{path} {os.strerror(e.errno) if e.errno else ''}" + ) from e + if args.verbose: + print(f"skipped: '{path}' (vfs mountpoint)") + else: + state.transport.fs_rmfile(path) + if args.verbose: + print(f"removed: '{path}'") + + +def human_size(size, decimals=1): + for unit in ["B", "K", "M", "G", "T"]: + if size < 1024.0 or unit == "T": + break + size /= 1024.0 + return f"{size:.{decimals}f}{unit}" if unit != "B" else f"{int(size)}" + + +def do_filesystem_tree(state, path, args): + """Print a tree of the device's filesystem starting at path.""" + connectors = ("├── ", "└── ") + + def _tree_recursive(path, prefix=""): + entries = state.transport.fs_listdir(path) + entries.sort(key=lambda e: e.name) + for i, entry in enumerate(entries): + connector = connectors[1] if i == len(entries) - 1 else connectors[0] + is_dir = entry.st_mode & 0x4000 # Directory + size_str = "" + # most MicroPython filesystems don't support st_size on directories, reduce clutter + if entry.st_size > 0 or not is_dir: + if args.size: + size_str = f"[{entry.st_size:>9}] " + elif args.human: + size_str = f"[{human_size(entry.st_size):>6}] " + print(f"{prefix}{connector}{size_str}{entry.name}") + if is_dir: + _tree_recursive( + _remote_path_join(path, entry.name), + prefix + (" " if i == len(entries) - 1 else "│ "), + ) + + if not path or path == ".": + path = state.transport.exec("import os;print(os.getcwd())").strip().decode("utf-8") + if not (path == "." or state.transport.fs_isdir(path)): + raise CommandError(f"tree: '{path}' is not a directory") + if args.verbose: + print(f":{path} on {state.transport.device_name}") + else: + print(f":{path}") + _tree_recursive(path) + + +def do_filesystem(state, args): + state.ensure_raw_repl() + state.did_action() + + command = args.command[0] + paths = args.path + + if command == "cat": + # Don't do verbose output for `cat` unless explicitly requested. + verbose = args.verbose is True + else: + verbose = args.verbose is not False + + if command == "cp": + # Note: cp requires the user to specify local/remote explicitly via + # leading ':'. + + # The last argument must be the destination. + if len(paths) <= 1: + raise CommandError("cp: missing destination path") + cp_dest = paths[-1] + paths = paths[:-1] + else: + # All other commands implicitly use remote paths. Strip the + # leading ':' if the user included them. + paths = [path[1:] if path.startswith(":") else path for path in paths] + + # ls and tree implicitly lists the cwd. + if command in ("ls", "tree") and not paths: + paths = [""] + + try: + # Handle each path sequentially. + for path in paths: + if verbose: + if command == "cp": + print("{} {} {}".format(command, path, cp_dest)) + else: + print("{} :{}".format(command, path)) + + if command == "cat": + state.transport.fs_printfile(path) + elif command == "ls": + for result in state.transport.fs_listdir(path): + print( + "{:12} {}{}".format( + result.st_size, result.name, "/" if result.st_mode & 0x4000 else "" + ) + ) + elif command == "mkdir": + state.transport.fs_mkdir(path) + elif command == "rm": + if args.recursive: + do_filesystem_recursive_rm(state, path, args) + else: + state.transport.fs_rmfile(path) + elif command == "rmdir": + state.transport.fs_rmdir(path) + elif command == "touch": + state.transport.fs_touchfile(path) + elif command.endswith("sum") and command[-4].isdigit(): + digest = state.transport.fs_hashfile(path, command[:-3]) + print(digest.hex()) + elif command == "cp": + if args.recursive: + do_filesystem_recursive_cp( + state, path, cp_dest, len(paths) > 1, not args.force + ) + else: + do_filesystem_cp(state, path, cp_dest, len(paths) > 1, not args.force) + elif command == "tree": + do_filesystem_tree(state, path, args) + except OSError as er: + raise CommandError("{}: {}: {}.".format(command, er.strerror, os.strerror(er.errno))) + except TransportError as er: + raise CommandError("Error with transport:\n{}".format(er.args[0])) + + +def do_edit(state, args): + state.ensure_raw_repl() + state.did_action() + + if not os.getenv("EDITOR"): + raise CommandError("edit: $EDITOR not set") + for src in args.files: + src = src.lstrip(":") + dest_fd, dest = tempfile.mkstemp(suffix=os.path.basename(src)) + try: + print("edit :%s" % (src,)) + state.transport.fs_touchfile(src) + data = state.transport.fs_readfile(src, progress_callback=show_progress_bar) + with open(dest_fd, "wb") as f: + f.write(data) + if os.system('%s "%s"' % (os.getenv("EDITOR"), dest)) == 0: + with open(dest, "rb") as f: + state.transport.fs_writefile( + src, f.read(), progress_callback=show_progress_bar + ) + finally: + os.unlink(dest) + + +def _do_execbuffer(state, buf, follow): + state.ensure_raw_repl() + state.did_action() + + try: + state.transport.exec_raw_no_follow(buf) + if follow: + ret, ret_err = state.transport.follow(timeout=None, data_consumer=stdout_write_bytes) + if ret_err: + stdout_write_bytes(ret_err) + sys.exit(1) + except TransportError as er: + raise CommandError(er.args[0]) + except KeyboardInterrupt: + sys.exit(1) + + +def do_exec(state, args): + _do_execbuffer(state, args.expr[0], args.follow) + + +def do_eval(state, args): + buf = "print(" + args.expr[0] + ")" + _do_execbuffer(state, buf, True) + + +def do_run(state, args): + filename = args.path[0] + try: + with open(filename, "rb") as f: + buf = f.read() + except OSError: + raise CommandError(f"could not read file '{filename}'") + _do_execbuffer(state, buf, args.follow) + + +def do_mount(state, args): + state.ensure_raw_repl() + path = args.path[0] + state.transport.mount_local(path, unsafe_links=args.unsafe_links) + print(f"Local directory {path} is mounted at /remote") + + +def do_umount(state, path): + state.ensure_raw_repl() + state.transport.umount_local() + + +def do_resume(state, _args=None): + state._auto_soft_reset = False + + +def do_soft_reset(state, _args=None): + state.ensure_raw_repl(soft_reset=True) + state.did_action() + + +def do_rtc(state, args): + state.ensure_raw_repl() + state.did_action() + + state.transport.exec("import machine") + + if args.set: + import datetime + + now = datetime.datetime.now() + timetuple = "({}, {}, {}, {}, {}, {}, {}, {})".format( + now.year, + now.month, + now.day, + now.weekday(), + now.hour, + now.minute, + now.second, + now.microsecond, + ) + state.transport.exec("machine.RTC().datetime({})".format(timetuple)) + else: + print(state.transport.eval("machine.RTC().datetime()")) + + +def _do_romfs_query(state, args): + state.ensure_raw_repl() + state.did_action() + + # Detect the romfs and get its associated device. + state.transport.exec("import vfs") + if not state.transport.eval("hasattr(vfs,'rom_ioctl')"): + print("ROMFS is not enabled on this device") + return + num_rom_partitions = state.transport.eval("vfs.rom_ioctl(1)") + if num_rom_partitions <= 0: + print("No ROMFS partitions available") + return + + for rom_id in range(num_rom_partitions): + state.transport.exec(f"dev=vfs.rom_ioctl(2,{rom_id})") + has_object = state.transport.eval("hasattr(dev,'ioctl')") + if has_object: + rom_block_count = state.transport.eval("dev.ioctl(4,0)") + rom_block_size = state.transport.eval("dev.ioctl(5,0)") + rom_size = rom_block_count * rom_block_size + print( + f"ROMFS{rom_id} partition has size {rom_size} bytes ({rom_block_count} blocks of {rom_block_size} bytes each)" + ) + else: + rom_size = state.transport.eval("len(dev)") + print(f"ROMFS{rom_id} partition has size {rom_size} bytes") + romfs = state.transport.eval("bytes(memoryview(dev)[:12])") + print(f" Raw contents: {romfs.hex(':')} ...") + if not romfs.startswith(b"\xd2\xcd\x31"): + print(" Not a valid ROMFS") + else: + size = 0 + for value in romfs[3:]: + size = (size << 7) | (value & 0x7F) + if not value & 0x80: + break + print(f" ROMFS image size: {size}") + + +def _do_romfs_build(state, args): + state.did_action() + + if args.path is None: + raise CommandError("romfs build: source path not given") + + input_directory = args.path + + if args.output is None: + output_file = input_directory + ".romfs" + else: + output_file = args.output + + romfs = make_romfs(input_directory, mpy_cross=args.mpy) + + print(f"Writing {len(romfs)} bytes to output file {output_file}") + with open(output_file, "wb") as f: + f.write(romfs) + + +def _do_romfs_deploy(state, args): + state.ensure_raw_repl() + state.did_action() + transport = state.transport + + if args.path is None: + raise CommandError("romfs deploy: source path not given") + + rom_id = args.partition + romfs_filename = args.path + + # Read in or create the ROMFS filesystem image. + if os.path.isfile(romfs_filename) and romfs_filename.endswith((".img", ".romfs")): + with open(romfs_filename, "rb") as f: + romfs = f.read() + else: + romfs = make_romfs(romfs_filename, mpy_cross=args.mpy) + print(f"Image size is {len(romfs)} bytes") + + # Detect the ROMFS partition and get its associated device. + state.transport.exec("import vfs") + if not state.transport.eval("hasattr(vfs,'rom_ioctl')"): + raise CommandError("ROMFS is not enabled on this device") + transport.exec(f"dev=vfs.rom_ioctl(2,{rom_id})") + if transport.eval("isinstance(dev,int) and dev<0"): + raise CommandError(f"ROMFS{rom_id} partition not found on device") + has_object = transport.eval("hasattr(dev,'ioctl')") + if has_object: + rom_block_count = transport.eval("dev.ioctl(4,0)") + rom_block_size = transport.eval("dev.ioctl(5,0)") + rom_size = rom_block_count * rom_block_size + print( + f"ROMFS{rom_id} partition has size {rom_size} bytes ({rom_block_count} blocks of {rom_block_size} bytes each)" + ) + else: + rom_size = transport.eval("len(dev)") + print(f"ROMFS{rom_id} partition has size {rom_size} bytes") + + # Check if ROMFS image is valid + if not romfs.startswith(VfsRomWriter.ROMFS_HEADER): + print("Invalid ROMFS image") + sys.exit(1) + + # Check if ROMFS filesystem image will fit in the target partition. + if len(romfs) > rom_size: + print("ROMFS image is too big for the target partition") + sys.exit(1) + + # Prepare ROMFS partition for writing. + print(f"Preparing ROMFS{rom_id} partition for writing") + transport.exec("import vfs\ntry:\n vfs.umount('/rom')\nexcept:\n pass") + chunk_size = 4096 + if has_object: + for offset in range(0, len(romfs), rom_block_size): + transport.exec(f"dev.ioctl(6,{offset // rom_block_size})") + chunk_size = min(chunk_size, rom_block_size) + else: + rom_min_write = transport.eval(f"vfs.rom_ioctl(3,{rom_id},{len(romfs)})") + chunk_size = max(chunk_size, rom_min_write) + + # Detect capabilities of the device to use the fastest method of transfer. + has_bytes_fromhex = transport.eval("hasattr(bytes,'fromhex')") + try: + transport.exec("from binascii import a2b_base64") + has_a2b_base64 = True + except TransportExecError: + has_a2b_base64 = False + try: + transport.exec("from io import BytesIO") + transport.exec("from deflate import DeflateIO,RAW") + has_deflate_io = True + except TransportExecError: + has_deflate_io = False + + # Deploy the ROMFS filesystem image to the device. + for offset in range(0, len(romfs), chunk_size): + romfs_chunk = romfs[offset : offset + chunk_size] + romfs_chunk += bytes(chunk_size - len(romfs_chunk)) + if has_deflate_io: + # Needs: binascii.a2b_base64, io.BytesIO, deflate.DeflateIO. + compressor = zlib.compressobj(wbits=-9) + romfs_chunk_compressed = compressor.compress(romfs_chunk) + romfs_chunk_compressed += compressor.flush() + buf = binascii.b2a_base64(romfs_chunk_compressed).strip() + transport.exec(f"buf=DeflateIO(BytesIO(a2b_base64({buf})),RAW,9).read()") + elif has_a2b_base64: + # Needs: binascii.a2b_base64. + buf = binascii.b2a_base64(romfs_chunk) + transport.exec(f"buf=a2b_base64({buf})") + elif has_bytes_fromhex: + # Needs: bytes.fromhex. + buf = romfs_chunk.hex() + transport.exec(f"buf=bytes.fromhex('{buf}')") + else: + # Needs nothing special. + transport.exec("buf=" + repr(romfs_chunk)) + print(f"\rWriting at offset {offset}", end="") + if has_object: + transport.exec( + f"dev.writeblocks({offset // rom_block_size},buf,{offset % rom_block_size})" + ) + else: + transport.exec(f"vfs.rom_ioctl(4,{rom_id},{offset},buf)") + + # Complete writing. + if not has_object: + transport.eval(f"vfs.rom_ioctl(5,{rom_id})") + + print() + print("ROMFS image deployed") + + +def do_romfs(state, args): + if args.command[0] == "query": + _do_romfs_query(state, args) + elif args.command[0] == "build": + _do_romfs_build(state, args) + elif args.command[0] == "deploy": + _do_romfs_deploy(state, args) + else: + raise CommandError( + f"romfs: '{args.command[0]}' is not a command; pass romfs --help for a list" + ) diff --git a/.venv/lib/python3.12/site-packages/mpremote/console.py b/.venv/lib/python3.12/site-packages/mpremote/console.py new file mode 100644 index 0000000..e34fd9e --- /dev/null +++ b/.venv/lib/python3.12/site-packages/mpremote/console.py @@ -0,0 +1,176 @@ +import sys, time + +try: + import select, termios +except ImportError: + termios = None + select = None + import msvcrt, signal + + +class ConsolePosix: + def __init__(self): + self.infd = sys.stdin.fileno() + self.infile = sys.stdin.buffer + self.outfile = sys.stdout.buffer + if hasattr(self.infile, "raw"): + self.infile = self.infile.raw + if hasattr(self.outfile, "raw"): + self.outfile = self.outfile.raw + + self.orig_attr = termios.tcgetattr(self.infd) + + def enter(self): + # attr is: [iflag, oflag, cflag, lflag, ispeed, ospeed, cc] + attr = termios.tcgetattr(self.infd) + attr[0] &= ~( + termios.BRKINT | termios.ICRNL | termios.INPCK | termios.ISTRIP | termios.IXON + ) + attr[1] = 0 + attr[2] = attr[2] & ~(termios.CSIZE | termios.PARENB) | termios.CS8 + attr[3] = 0 + attr[6][termios.VMIN] = 1 + attr[6][termios.VTIME] = 0 + termios.tcsetattr(self.infd, termios.TCSANOW, attr) + + def exit(self): + termios.tcsetattr(self.infd, termios.TCSANOW, self.orig_attr) + + def waitchar(self, pyb_serial): + # TODO pyb_serial might not have fd + select.select([self.infd, pyb_serial.fd], [], []) + + def readchar(self): + res = select.select([self.infd], [], [], 0) + if res[0]: + return self.infile.read(1) + else: + return None + + def write(self, buf): + self.outfile.write(buf) + + +class ConsoleWindows: + KEY_MAP = { + b"H": b"A", # UP + b"P": b"B", # DOWN + b"M": b"C", # RIGHT + b"K": b"D", # LEFT + b"G": b"H", # POS1 + b"O": b"F", # END + b"Q": b"6~", # PGDN + b"I": b"5~", # PGUP + b"s": b"1;5D", # CTRL-LEFT, + b"t": b"1;5C", # CTRL-RIGHT, + b"\x8d": b"1;5A", # CTRL-UP, + b"\x91": b"1;5B", # CTRL-DOWN, + b"w": b"1;5H", # CTRL-POS1 + b"u": b"1;5F", # CTRL-END + b"\x98": b"1;3A", # ALT-UP, + b"\xa0": b"1;3B", # ALT-DOWN, + b"\x9d": b"1;3C", # ALT-RIGHT, + b"\x9b": b"1;3D", # ALT-LEFT, + b"\x97": b"1;3H", # ALT-POS1, + b"\x9f": b"1;3F", # ALT-END, + b"S": b"3~", # DEL, + b"\x93": b"3;5~", # CTRL-DEL + b"R": b"2~", # INS + b"\x92": b"2;5~", # CTRL-INS + b"\x94": b"Z", # Ctrl-Tab = BACKTAB, + } + + def __init__(self): + self.ctrl_c = 0 + + def _sigint_handler(self, signo, frame): + self.ctrl_c += 1 + + def enter(self): + signal.signal(signal.SIGINT, self._sigint_handler) + + def exit(self): + signal.signal(signal.SIGINT, signal.SIG_DFL) + + def inWaiting(self): + return 1 if self.ctrl_c or msvcrt.kbhit() else 0 + + def waitchar(self, pyb_serial): + while not (self.inWaiting() or pyb_serial.inWaiting()): + time.sleep(0.01) + + def readchar(self): + if self.ctrl_c: + self.ctrl_c -= 1 + return b"\x03" + if msvcrt.kbhit(): + ch = msvcrt.getch() + while ch in b"\x00\xe0": # arrow or function key prefix? + if not msvcrt.kbhit(): + return None + ch = msvcrt.getch() # second call returns the actual key code + try: + ch = b"\x1b[" + self.KEY_MAP[ch] + except KeyError: + return None + return ch + + def write(self, buf): + buf = buf.decode() if isinstance(buf, bytes) else buf + sys.stdout.write(buf) + sys.stdout.flush() + # for b in buf: + # if isinstance(b, bytes): + # msvcrt.putch(b) + # else: + # msvcrt.putwch(b) + + +if termios: + Console = ConsolePosix + VT_ENABLED = True +else: + Console = ConsoleWindows + + # Windows VT mode ( >= win10 only) + # https://bugs.python.org/msg291732 + import ctypes, os + from ctypes import wintypes + + kernel32 = ctypes.WinDLL("kernel32", use_last_error=True) + + ERROR_INVALID_PARAMETER = 0x0057 + ENABLE_VIRTUAL_TERMINAL_PROCESSING = 0x0004 + + def _check_bool(result, func, args): + if not result: + raise ctypes.WinError(ctypes.get_last_error()) + return args + + LPDWORD = ctypes.POINTER(wintypes.DWORD) + kernel32.GetConsoleMode.errcheck = _check_bool + kernel32.GetConsoleMode.argtypes = (wintypes.HANDLE, LPDWORD) + kernel32.SetConsoleMode.errcheck = _check_bool + kernel32.SetConsoleMode.argtypes = (wintypes.HANDLE, wintypes.DWORD) + + def set_conout_mode(new_mode, mask=0xFFFFFFFF): + # don't assume StandardOutput is a console. + # open CONOUT$ instead + fdout = os.open("CONOUT$", os.O_RDWR) + try: + hout = msvcrt.get_osfhandle(fdout) + old_mode = wintypes.DWORD() + kernel32.GetConsoleMode(hout, ctypes.byref(old_mode)) + mode = (new_mode & mask) | (old_mode.value & ~mask) + kernel32.SetConsoleMode(hout, mode) + return old_mode.value + finally: + os.close(fdout) + + # def enable_vt_mode(): + mode = mask = ENABLE_VIRTUAL_TERMINAL_PROCESSING + try: + set_conout_mode(mode, mask) + VT_ENABLED = True + except WindowsError: + VT_ENABLED = False diff --git a/.venv/lib/python3.12/site-packages/mpremote/main.py b/.venv/lib/python3.12/site-packages/mpremote/main.py new file mode 100644 index 0000000..b31186b --- /dev/null +++ b/.venv/lib/python3.12/site-packages/mpremote/main.py @@ -0,0 +1,636 @@ +""" +MicroPython Remote - Interaction and automation tool for MicroPython +MIT license; Copyright (c) 2019-2022 Damien P. George + +This program provides a set of utilities to interact with and automate a +MicroPython device over a serial connection. Commands supported are: + + mpremote -- auto-detect, connect and enter REPL + mpremote -- connect to given device + mpremote connect -- connect to given device + mpremote disconnect -- disconnect current device + mpremote mount -- mount local directory on device + mpremote eval -- evaluate and print the string + mpremote exec -- execute the string + mpremote run