diff --git a/micropython/bundles/bundle-typing/manifest.py b/micropython/bundles/bundle-typing/manifest.py new file mode 100644 index 000000000..5b1c854ca --- /dev/null +++ b/micropython/bundles/bundle-typing/manifest.py @@ -0,0 +1,18 @@ +# type: ignore[all] + +metadata( + version="1.26.1", + description="Limited runtime typing support for MicroPython.", +) + +options.defaults(opt_level=3, extensions=False) + +# Primary typing related modules +require("__future__", opt_level=options.opt_level) +require("typing", opt_level=options.opt_level) +require("abc", opt_level=options.opt_level) + +# # Optional typing modules +if options.extensions: + require("typing_extensions", opt_level=options.opt_level) + require("collections-abc", opt_level=options.opt_level) diff --git a/python-stdlib/__future__/manifest.py b/python-stdlib/__future__/manifest.py index e06f3268d..017d10e9e 100644 --- a/python-stdlib/__future__/manifest.py +++ b/python-stdlib/__future__/manifest.py @@ -1,3 +1,5 @@ -metadata(version="0.1.0") +metadata(version="1.26.1") -module("__future__.py") +options.defaults(opt_level=3) + +module("__future__.py", opt=options.opt_level) diff --git a/python-stdlib/abc/abc.py b/python-stdlib/abc/abc.py index c2c707f62..670e4e5ac 100644 --- a/python-stdlib/abc/abc.py +++ b/python-stdlib/abc/abc.py @@ -1,6 +1,14 @@ +# type: ignore class ABC: pass -def abstractmethod(f): - return f +def abstractmethod(arg): + return arg + +try: + # add functionality if typing module is available + from typing import __getattr__ as __getattr__ + +except: # naked except saves 4 bytes + pass diff --git a/python-stdlib/abc/manifest.py b/python-stdlib/abc/manifest.py index c76312960..277dc3ef9 100644 --- a/python-stdlib/abc/manifest.py +++ b/python-stdlib/abc/manifest.py @@ -1,3 +1,5 @@ -metadata(version="0.1.0") +metadata(version="0.2.0") -module("abc.py") +options.defaults(opt_level=3) + +module("abc.py", opt=options.opt_level) diff --git a/python-stdlib/collections-abc/collections/abc.py b/python-stdlib/collections-abc/collections/abc.py new file mode 100644 index 000000000..ef626141a --- /dev/null +++ b/python-stdlib/collections-abc/collections/abc.py @@ -0,0 +1,7 @@ +# collections.abc +# minimal support for runtime typing +# type: ignore +try: + from typing import __Ignore as ABC, __getattr__ as __getattr__ +except: + pass \ No newline at end of file diff --git a/python-stdlib/collections-abc/manifest.py b/python-stdlib/collections-abc/manifest.py new file mode 100644 index 000000000..24376bb5e --- /dev/null +++ b/python-stdlib/collections-abc/manifest.py @@ -0,0 +1,5 @@ +metadata(version="1.26.1") + +# require("collections") +require("typing") +package("collections") diff --git a/python-stdlib/collections/collections/__init__.py b/python-stdlib/collections/collections/__init__.py index 36dfc1c41..da0df43bc 100644 --- a/python-stdlib/collections/collections/__init__.py +++ b/python-stdlib/collections/collections/__init__.py @@ -6,6 +6,14 @@ from .defaultdict import defaultdict except ImportError: pass +# optional collections.abc typing dummy module +try: + # cannot use relative import here + import collections.abc as abc + import sys + sys.modules['collections.abc'] = abc +except ImportError: + pass class MutableMapping: diff --git a/python-stdlib/typing/manifest.py b/python-stdlib/typing/manifest.py new file mode 100644 index 000000000..e7866b38b --- /dev/null +++ b/python-stdlib/typing/manifest.py @@ -0,0 +1,8 @@ +# type: ignore + +metadata(version="1.26.1", description="Typing module for MicroPython.") + +# default to opt_level 3 for minimal firmware size +options.defaults(opt_level=3) + +module("typing.py", opt=options.opt_level) diff --git a/python-stdlib/typing/typing.py b/python-stdlib/typing/typing.py new file mode 100644 index 000000000..23cfc04fc --- /dev/null +++ b/python-stdlib/typing/typing.py @@ -0,0 +1,97 @@ +""" +This module provides runtime support for type hints. +based on : +- https://github.com/micropython/micropython-lib/pull/584 +- https://github.com/Josverl/micropython-stubs/tree/main/mip +- https://github.com/Josverl/rt_typing + +""" + +# ------------------------------------- +# code reduction by Ignoring type hints +# ------------------------------------- +class __Ignore: + """A class to ignore type hints in code.""" + + def __call__(*args, **kwargs): + # May need some guardrails here + pass + + def __getitem__(self, arg): + # May need some guardrails here + return __ignore + + def __getattr__(self, attr): + if attr in self.__dict__: + return self.__dict__[attr] + return __ignore + + +__ignore = __Ignore() +# ----------------- +# typing essentials +# ----------------- +TYPE_CHECKING = False + +def final(arg): # ( 6 + bytes) + # decorator to indicate that a method should not be overridden + # https://docs.python.org/3/library/typing.html#typing.final + return arg + + +# def overload(arg): # ( 27 bytes) +# # ignore functions signatures with @overload decorator +# return None +overload = __ignore # saves bytes, and is semantically similar + +def NewType(_, arg): # (21 bytes) + # https://docs.python.org/3/library/typing.html#newtype + # MicroPython: just use the original type. + return arg + +# --------------- +# useful methods +# --------------- + +# https://docs.python.org/3/library/typing.html#typing.cast +# def cast(type, arg): # ( 23 bytes) +# return arg +cast = NewType # saves bytes, and is semantically similar + +# https://docs.python.org/3/library/typing.html#typing.no_type_check +# def no_type_check(arg): # ( 26 bytes) +# # decorator to disable type checking on a function or method +# return arg +no_type_check = final # saves bytes, and is semantically similar + +# ------------------- +# less useful methods +# ------------------- + +# def reveal_type(x): # ( 38 bytes) +# # # https://docs.python.org/3/library/typing.html#typing.reveal_type +# return x +# or for smaller size: +reveal_type = final # saves bytes, and is semantically similar + + +# def get_origin(type): # ( 23 bytes) +# # https://docs.python.org/3/library/typing.html#typing.get_origin +# # Return None for all unsupported objects. +# return None + + +# def get_args(arg): # ( 22 bytes) +# # https://docs.python.org/3/library/typing.html#typing.get_args +# # Python 3.8+ only +# return () + + +# ref: https://github.com/micropython/micropython-lib/pull/584#issuecomment-2317690854 + +def __getattr__(x): + return __ignore + +# snarky way to alias typing_extensions to typing ( saving 59 bytes) +import sys +sys.modules["typing_extensions"] = sys.modules["typing"] diff --git a/python-stdlib/typing_extensions/manifest.py b/python-stdlib/typing_extensions/manifest.py new file mode 100644 index 000000000..addbec166 --- /dev/null +++ b/python-stdlib/typing_extensions/manifest.py @@ -0,0 +1,10 @@ +metadata(version="1.26.1") + + +# default to opt_level 3 for minimal firmware size +options.defaults(opt_level=3) + +module("typing_extensions.py", opt=options.opt_level) + +require("typing") +package("typing_extensions") diff --git a/python-stdlib/typing_extensions/typing_extensions.py b/python-stdlib/typing_extensions/typing_extensions.py new file mode 100644 index 000000000..3f800bfaf --- /dev/null +++ b/python-stdlib/typing_extensions/typing_extensions.py @@ -0,0 +1,5 @@ +# typing_extensions.py +# type: ignore + +from typing import * +from typing import __getattr__ \ No newline at end of file