Skip to content

Commit b771de3

Browse files
CopilotJosverl
authored andcommitted
Update mip packages
1 parent 901786c commit b771de3

23 files changed

+2349
-1882
lines changed

mip/v5/createstubs.py

Lines changed: 72 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@
2525
from ucollections import OrderedDict # type: ignore
2626

2727
__version__ = "v1.26.1"
28-
ENOENT = 2 # on most ports
29-
ENOMESSAGE = 44 # on pyscript
28+
ENOENT = 2 # on most ports
29+
ENOMESSAGE = 44 # on pyscript
3030
_MAX_CLASS_LEVEL = 2 # Max class nesting
3131
LIBS = ["lib", "/lib", "/sd/lib", "/flash/lib", "."]
3232

@@ -154,11 +154,7 @@ def get_obj_attributes(self, item_instance: object):
154154
order = 4
155155
_result.append((name, repr(val), repr(type(val)), val, order))
156156
except AttributeError as e:
157-
_errors.append(
158-
"Couldn't get attribute '{}' from object '{}', Err: {}".format(
159-
name, item_instance, e
160-
)
161-
)
157+
_errors.append("Couldn't get attribute '{}' from object '{}', Err: {}".format(name, item_instance, e))
162158
except MemoryError as e:
163159
print("MemoryError: {}".format(e))
164160
sleep(1)
@@ -224,9 +220,7 @@ def create_module_stub(self, module_name: str, file_name: str = None) -> bool:
224220
try:
225221
new_module = __import__(module_name, None, None, ("*"))
226222
m1 = gc.mem_free() # type: ignore
227-
log.info(
228-
"Stub module: {:<25} to file: {:<70} mem:{:>5}".format(module_name, fname, m1)
229-
)
223+
log.info("Stub module: {:<25} to file: {:<70} mem:{:>5}".format(module_name, fname, m1))
230224

231225
except ImportError:
232226
# log.debug("Skip module: {:<25} {:<79}".format(module_name, "Module not found."))
@@ -237,13 +231,9 @@ def create_module_stub(self, module_name: str, file_name: str = None) -> bool:
237231
ensure_folder(file_name)
238232
with open(file_name, "w") as fp:
239233
info_ = str(self.info).replace("OrderedDict(", "").replace("})", "}")
240-
s = '"""\nModule: \'{0}\' on {1}\n"""\n# MCU: {2}\n# Stubber: {3}\n'.format(
241-
module_name, self._fwid, info_, __version__
242-
)
234+
s = '"""\nModule: \'{0}\' on {1}\n"""\n# MCU: {2}\n# Stubber: {3}\n'.format(module_name, self._fwid, info_, __version__)
243235
fp.write(s)
244-
fp.write(
245-
"from __future__ import annotations\nfrom typing import Any, Final, Generator\nfrom _typeshed import Incomplete\n\n"
246-
)
236+
fp.write("from __future__ import annotations\nfrom typing import Any, Final, Generator\nfrom _typeshed import Incomplete\n\n")
247237
self.write_object_stub(fp, new_module, module_name, "")
248238

249239
self.report_add(module_name, file_name)
@@ -258,9 +248,7 @@ def create_module_stub(self, module_name: str, file_name: str = None) -> bool:
258248
gc.collect()
259249
return True
260250

261-
def write_object_stub(
262-
self, fp, object_expr: object, obj_name: str, indent: str, in_class: int = 0
263-
):
251+
def write_object_stub(self, fp, object_expr: object, obj_name: str, indent: str, in_class: int = 0):
264252
"Write a module/object stub to an open file. Can be called recursive."
265253
gc.collect()
266254
if object_expr in self.problematic:
@@ -336,13 +324,9 @@ def write_object_stub(
336324
first = "self, "
337325
# class method - add function decoration
338326
if "bound_method" in item_type_txt or "bound_method" in item_repr:
339-
s = "{}@classmethod\n".format(
340-
indent
341-
) + "{}def {}(cls, *args, **kwargs) -> {}:\n".format(indent, item_name, ret)
327+
s = "{}@classmethod\n".format(indent) + "{}def {}(cls, *args, **kwargs) -> {}:\n".format(indent, item_name, ret)
342328
else:
343-
s = "{}def {}({}*args, **kwargs) -> {}:\n".format(
344-
indent, item_name, first, ret
345-
)
329+
s = "{}def {}({}*args, **kwargs) -> {}:\n".format(indent, item_name, first, ret)
346330
s += indent + " ...\n\n"
347331
fp.write(s)
348332
# log.debug("\n" + s)
@@ -371,9 +355,7 @@ def write_object_stub(
371355
if t in ("object", "set", "frozenset", "Pin"): # "FileIO"
372356
# https://docs.python.org/3/tutorial/classes.html#item_instance-objects
373357
# use these types for the attribute
374-
s = "{0}{1}: {2} ## = {4}\n".format(
375-
indent, item_name, t, item_type_txt, item_repr
376-
)
358+
s = "{0}{1}: {2} ## = {4}\n".format(indent, item_name, t, item_type_txt, item_repr)
377359
elif t == "generator":
378360
# either a normal or async Generator function
379361
t = "Generator"
@@ -387,9 +369,7 @@ def write_object_stub(
387369
item_repr = item_repr.split(" at ")[0] + " at ...>"
388370
if " at " in item_repr:
389371
item_repr = item_repr.split(" at ")[0] + " at ...>"
390-
s = "{0}{1}: {2} ## {3} = {4}\n".format(
391-
indent, item_name, t, item_type_txt, item_repr
392-
)
372+
s = "{0}{1}: {2} ## {3} = {4}\n".format(indent, item_name, t, item_type_txt, item_repr)
393373
fp.write(s)
394374
# log.debug("\n" + s)
395375
else:
@@ -472,9 +452,7 @@ def report_add(self, module_name: str, stub_file: str):
472452
f.write(",\n")
473453
else:
474454
self._json_first = False
475-
line = '{{"module": "{}", "file": "{}"}}'.format(
476-
module_name, stub_file.replace("\\", "/")
477-
)
455+
line = '{{"module": "{}", "file": "{}"}}'.format(module_name, stub_file.replace("\\", "/"))
478456
f.write(line)
479457

480458
except OSError:
@@ -501,7 +479,7 @@ def ensure_folder(path: str):
501479
_ = os.stat(p)
502480
except OSError as e:
503481
# folder does not exist
504-
if e.args[0] in [ENOENT, ENOMESSAGE] :
482+
if e.args[0] in [ENOENT, ENOMESSAGE]:
505483
try:
506484
log.debug("Create folder {}".format(p))
507485
os.mkdir(p)
@@ -512,7 +490,6 @@ def ensure_folder(path: str):
512490
start = i + 1
513491

514492

515-
516493
def _build(s):
517494
# extract build from sys.version or os.uname().version if available
518495
# sys.version: 'MicroPython v1.24.0-preview.6.g3d0b6276f'
@@ -531,7 +508,8 @@ def _build(s):
531508
return b
532509

533510

534-
def _info(): # type:() -> dict[str, str]
511+
def _get_base_system_info() -> OrderedDict[str, str]:
512+
"""Get basic system implementation details."""
535513
try:
536514
fam = sys.implementation[0] # type: ignore
537515
except TypeError:
@@ -553,21 +531,31 @@ def _info(): # type:() -> dict[str, str]
553531
"arch": "",
554532
}
555533
)
556-
# change port names to be consistent with the repo
534+
return info
535+
536+
537+
def _normalize_port_info(info: OrderedDict[str, str]) -> None:
538+
"""Normalize port names to be consistent with the repo."""
557539
if info["port"].startswith("pyb"):
558540
info["port"] = "stm32"
559541
elif info["port"] == "win32":
560542
info["port"] = "windows"
561543
elif info["port"] == "linux":
562544
info["port"] = "unix"
545+
546+
547+
def _extract_version_info(info: OrderedDict[str, str]) -> None:
548+
"""Extract version information from sys.implementation."""
563549
try:
564550
info["version"] = version_str(sys.implementation.version) # type: ignore
565551
except AttributeError:
566552
pass
553+
554+
555+
def _extract_hardware_info(info: OrderedDict[str, str]) -> None:
556+
"""Extract board, CPU, and machine details."""
567557
try:
568-
_machine = (
569-
sys.implementation._machine if "_machine" in dir(sys.implementation) else os.uname().machine # type: ignore
570-
)
558+
_machine = sys.implementation._machine if "_machine" in dir(sys.implementation) else os.uname().machine # type: ignore
571559
info["board"] = _machine.strip()
572560
si_build = sys.implementation._build if "_build" in dir(sys.implementation) else ""
573561
if si_build:
@@ -582,9 +570,13 @@ def _info(): # type:() -> dict[str, str]
582570
)
583571
except (AttributeError, IndexError):
584572
pass
573+
585574
if not info["board_id"]:
586575
get_boardname(info)
587576

577+
578+
def _extract_build_info(info: OrderedDict[str, str]) -> None:
579+
"""Extract build information from various system sources."""
588580
try:
589581
if "uname" in dir(os): # old
590582
# extract build from uname().version if available
@@ -597,17 +589,18 @@ def _info(): # type:() -> dict[str, str]
597589
info["build"] = _build(sys.version)
598590
except (AttributeError, IndexError, TypeError):
599591
pass
600-
# avoid build hashes
601-
# if info["build"] and len(info["build"]) > 5:
602-
# info["build"] = ""
603592

593+
# Fallback version detection for specific platforms
604594
if info["version"] == "" and sys.platform not in ("unix", "win32"):
605595
try:
606596
u = os.uname() # type: ignore
607597
info["version"] = u.release
608598
except (IndexError, AttributeError, TypeError):
609599
pass
610-
# detect families
600+
601+
602+
def _detect_firmware_family(info: OrderedDict[str, str]) -> None:
603+
"""Detect special firmware families (pycopy, pycom, ev3-pybricks)."""
611604
for fam_name, mod_name, mod_thing in [
612605
("pycopy", "pycopy", "const"),
613606
("pycom", "pycom", "FAT"),
@@ -624,18 +617,22 @@ def _info(): # type:() -> dict[str, str]
624617
if info["family"] == "ev3-pybricks":
625618
info["release"] = "2.0.0"
626619

620+
621+
def _process_micropython_version(info: OrderedDict[str, str]) -> None:
622+
"""Process MicroPython-specific version formatting."""
627623
if info["family"] == "micropython":
628-
info["version"]
629624
if (
630625
info["version"]
631626
and info["version"].endswith(".0")
632-
and info["version"]
633-
>= "1.10.0" # versions from 1.10.0 to 1.24.0 do not have a micro .0
627+
and info["version"] >= "1.10.0" # versions from 1.10.0 to 1.24.0 do not have a micro .0
634628
and info["version"] <= "1.19.9"
635629
):
636630
# versions from 1.10.0 to 1.24.0 do not have a micro .0
637631
info["version"] = info["version"][:-2]
638632

633+
634+
def _process_mpy_info(info: OrderedDict[str, str]) -> None:
635+
"""Process MPY architecture and version information."""
639636
# spell-checker: disable
640637
if "mpy" in info and info["mpy"]: # mpy on some v1.11+ builds
641638
sys_mpy = int(info["mpy"])
@@ -661,11 +658,36 @@ def _info(): # type:() -> dict[str, str]
661658
info["arch"] = "unknown"
662659
# .mpy version.minor
663660
info["mpy"] = "v{}.{}".format(sys_mpy & 0xFF, sys_mpy >> 8 & 3)
661+
662+
663+
def _format_version_strings(info: OrderedDict[str, str]) -> None:
664+
"""Handle final version string formatting."""
664665
if info["build"] and not info["version"].endswith("-preview"):
665666
info["version"] = info["version"] + "-preview"
666667
# simple to use version[-build] string
667668
info["ver"] = f"{info['version']}-{info['build']}" if info["build"] else f"{info['version']}"
668669

670+
671+
def _info(): # type:() -> dict[str, str]
672+
"""
673+
Gather comprehensive system information for MicroPython stubbing.
674+
675+
Returns a dictionary containing family, version, port, board, and other
676+
system details needed for stub generation.
677+
"""
678+
# Get base system information
679+
info = _get_base_system_info()
680+
681+
# Apply transformations and gather additional info
682+
_normalize_port_info(info)
683+
_extract_version_info(info)
684+
_extract_hardware_info(info)
685+
_extract_build_info(info)
686+
_detect_firmware_family(info)
687+
_process_micropython_version(info)
688+
_process_mpy_info(info)
689+
_format_version_strings(info)
690+
669691
return info
670692

671693

@@ -743,11 +765,11 @@ def is_micropython() -> bool:
743765

744766
# b) https://docs.micropython.org/en/latest/genrst/builtin_types.html#bytes-with-keywords-not-implemented
745767
# Micropython: NotImplementedError
746-
b = bytes("abc", encoding="utf8") # type: ignore
768+
b = bytes("abc", encoding="utf8") # type: ignore
747769

748770
# c) https://docs.micropython.org/en/latest/genrst/core_language.html#function-objects-do-not-have-the-module-attribute
749771
# Micropython: AttributeError
750-
c = is_micropython.__module__ # type: ignore
772+
c = is_micropython.__module__ # type: ignore
751773
return False
752774
except (NotImplementedError, AttributeError):
753775
return True

0 commit comments

Comments
 (0)