first save

This commit is contained in:
tiijay
2025-10-19 18:29:10 +02:00
commit b5a30adb27
1303 changed files with 234711 additions and 0 deletions

View File

@@ -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 <irq> is of type irq
# flags -- <function>
# trigger -- <function>
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

View File

@@ -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.
"""

View File

@@ -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: ...

View File

@@ -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.
"""

View File

@@ -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

View File

@@ -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: ...

View File

@@ -0,0 +1,3 @@
from _collections_abc import *
# from _collections_abc import __all__ as __all__

View File

@@ -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
)

View File

@@ -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)

View File

@@ -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

View File

@@ -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: ...

View File

@@ -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.
"""
...

View File

@@ -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: ...

View File

@@ -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.
"""

View File

@@ -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, ...]