micropython-stubber 1.16.3__py3-none-any.whl → 1.17.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {micropython_stubber-1.16.3.dist-info → micropython_stubber-1.17.0.dist-info}/METADATA +1 -1
- {micropython_stubber-1.16.3.dist-info → micropython_stubber-1.17.0.dist-info}/RECORD +48 -49
- stubber/__init__.py +1 -1
- stubber/basicgit.py +11 -13
- stubber/board/createstubs.py +138 -97
- stubber/board/createstubs_db.py +211 -239
- stubber/board/createstubs_db_min.py +322 -844
- stubber/board/createstubs_db_mpy.mpy +0 -0
- stubber/board/createstubs_lvgl.py +91 -137
- stubber/board/createstubs_lvgl_min.py +87 -129
- stubber/board/createstubs_lvgl_mpy.mpy +0 -0
- stubber/board/createstubs_mem.py +164 -199
- stubber/board/createstubs_mem_min.py +297 -791
- stubber/board/createstubs_mem_mpy.mpy +0 -0
- stubber/board/createstubs_min.py +286 -1009
- stubber/board/createstubs_mpy.mpy +0 -0
- stubber/board/modulelist.txt +1 -2
- stubber/codemod/_partials/__init__.py +1 -1
- stubber/codemod/_partials/db_main.py +90 -72
- stubber/codemod/_partials/modules_reader.py +29 -17
- stubber/codemod/board.py +2 -4
- stubber/codemod/enrich.py +1 -1
- stubber/commands/build_cmd.py +6 -4
- stubber/commands/get_docstubs_cmd.py +6 -11
- stubber/commands/get_frozen_cmd.py +6 -11
- stubber/commands/switch_cmd.py +6 -4
- stubber/freeze/freeze_manifest_2.py +2 -1
- stubber/freeze/get_frozen.py +28 -13
- stubber/minify.py +51 -38
- stubber/publish/candidates.py +15 -23
- stubber/publish/defaults.py +2 -2
- stubber/publish/merge_docstubs.py +5 -7
- stubber/publish/missing_class_methods.py +2 -2
- stubber/publish/pathnames.py +2 -2
- stubber/publish/publish.py +2 -1
- stubber/publish/stubpackage.py +20 -41
- stubber/rst/lookup.py +9 -7
- stubber/rst/reader.py +2 -1
- stubber/stubber.py +5 -6
- stubber/update_fallback.py +3 -1
- stubber/utils/__init__.py +1 -1
- stubber/utils/config.py +7 -9
- stubber/utils/repos.py +6 -5
- stubber/utils/versions.py +48 -7
- stubber/variants.py +3 -3
- stubber/board/logging.py +0 -99
- {micropython_stubber-1.16.3.dist-info → micropython_stubber-1.17.0.dist-info}/LICENSE +0 -0
- {micropython_stubber-1.16.3.dist-info → micropython_stubber-1.17.0.dist-info}/WHEEL +0 -0
- {micropython_stubber-1.16.3.dist-info → micropython_stubber-1.17.0.dist-info}/entry_points.txt +0 -0
@@ -3,12 +3,11 @@ Create stubs for the lvgl modules on a MicroPython board.
|
|
3
3
|
|
4
4
|
Note that the stubs can be very large, and it may be best to directly store them on an SD card if your device supports this.
|
5
5
|
|
6
|
-
This variant was generated from createstubs.py by micropython-stubber v1.16.
|
6
|
+
This variant was generated from createstubs.py by micropython-stubber v1.16.3
|
7
7
|
"""
|
8
8
|
# Copyright (c) 2019-2023 Jos Verlinde
|
9
9
|
|
10
10
|
import gc
|
11
|
-
# import logging
|
12
11
|
import os
|
13
12
|
import sys
|
14
13
|
from time import sleep
|
@@ -28,26 +27,61 @@ try:
|
|
28
27
|
except ImportError:
|
29
28
|
from ucollections import OrderedDict # type: ignore
|
30
29
|
|
31
|
-
|
32
|
-
|
30
|
+
__version__ = "v1.16.3"
|
31
|
+
ENOENT = 2
|
32
|
+
_MAX_CLASS_LEVEL = 2 # Max class nesting
|
33
|
+
LIBS = ["lib", "/lib", "/sd/lib", "/flash/lib", "."]
|
34
|
+
|
35
|
+
|
36
|
+
# our own logging module to avoid dependency on and interfering with logging module
|
37
|
+
class logging:
|
38
|
+
DEBUG = 10
|
39
|
+
TRACE = 15
|
40
|
+
INFO = 20
|
41
|
+
WARNING = 30
|
42
|
+
ERROR = 40
|
43
|
+
CRITICAL = 50
|
44
|
+
level = INFO
|
45
|
+
prnt = print
|
46
|
+
|
47
|
+
@staticmethod
|
48
|
+
def getLogger(name):
|
49
|
+
return logging()
|
50
|
+
|
51
|
+
@classmethod
|
52
|
+
def basicConfig(cls, level):
|
53
|
+
cls.level = level
|
54
|
+
pass
|
33
55
|
|
34
|
-
|
56
|
+
def trace(self, msg):
|
57
|
+
if self.level <= logging.TRACE:
|
58
|
+
self.prnt("TRACE :", msg)
|
35
59
|
|
36
|
-
|
60
|
+
def debug(self, msg):
|
61
|
+
if self.level <= logging.DEBUG:
|
62
|
+
self.prnt("DEBUG :", msg)
|
37
63
|
|
38
|
-
|
39
|
-
|
40
|
-
|
64
|
+
def info(self, msg):
|
65
|
+
if self.level <= logging.INFO:
|
66
|
+
self.prnt("INFO :", msg)
|
41
67
|
|
42
|
-
|
68
|
+
def warning(self, msg):
|
69
|
+
if self.level <= logging.WARNING:
|
70
|
+
self.prnt("WARN :", msg)
|
43
71
|
|
72
|
+
def error(self, msg):
|
73
|
+
if self.level <= logging.ERROR:
|
74
|
+
self.prnt("ERROR :", msg)
|
44
75
|
|
45
|
-
|
76
|
+
def critical(self, msg):
|
77
|
+
if self.level <= logging.CRITICAL:
|
78
|
+
self.prnt("CRIT :", msg)
|
46
79
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
80
|
+
|
81
|
+
log = logging.getLogger("stubber")
|
82
|
+
logging.basicConfig(level=logging.INFO)
|
83
|
+
# logging.basicConfig(level=logging.TRACE)
|
84
|
+
# logging.basicConfig(level=logging.DEBUG)
|
51
85
|
|
52
86
|
|
53
87
|
class Stubber:
|
@@ -59,13 +93,11 @@ class Stubber:
|
|
59
93
|
raise NotImplementedError("MicroPython 1.13.0 cannot be stubbed")
|
60
94
|
except AttributeError:
|
61
95
|
pass
|
62
|
-
# self.log = logging.getLogger("stubber")
|
63
96
|
self._report = [] # type: list[str]
|
64
97
|
self.info = _info()
|
65
|
-
|
66
|
-
|
98
|
+
log.info("Port: {}".format(self.info["port"]))
|
99
|
+
log.info("Board: {}".format(self.info["board"]))
|
67
100
|
gc.collect()
|
68
|
-
wdt.feed()
|
69
101
|
if firmware_id:
|
70
102
|
self._fwid = firmware_id.lower()
|
71
103
|
else:
|
@@ -82,7 +114,7 @@ class Stubber:
|
|
82
114
|
path = get_root()
|
83
115
|
|
84
116
|
self.path = "{}/stubs/{}".format(path, self.flat_fwid).replace("//", "/")
|
85
|
-
|
117
|
+
log.debug(self.path)
|
86
118
|
try:
|
87
119
|
ensure_folder(path + "/")
|
88
120
|
except OSError:
|
@@ -111,15 +143,15 @@ class Stubber:
|
|
111
143
|
# name_, repr_(value), type as text, item_instance
|
112
144
|
_result = []
|
113
145
|
_errors = []
|
114
|
-
|
146
|
+
log.debug("get attributes {} {}".format(repr(item_instance), item_instance))
|
115
147
|
for name in dir(item_instance):
|
116
148
|
if name.startswith("_") and not name in self.modules:
|
117
149
|
continue
|
118
|
-
|
150
|
+
log.debug("get attribute {}".format(name))
|
119
151
|
try:
|
120
152
|
val = getattr(item_instance, name)
|
121
153
|
# name , item_repr(value) , type as text, item_instance, order
|
122
|
-
|
154
|
+
log.debug("attribute {}:{}".format(name, val))
|
123
155
|
try:
|
124
156
|
type_text = repr(type(val)).split("'")[1]
|
125
157
|
except IndexError:
|
@@ -152,19 +184,18 @@ class Stubber:
|
|
152
184
|
|
153
185
|
def create_all_stubs(self):
|
154
186
|
"Create stubs for all configured modules"
|
155
|
-
|
187
|
+
log.info("Start micropython-stubber v{} on {}".format(__version__, self._fwid))
|
156
188
|
gc.collect()
|
157
189
|
for module_name in self.modules:
|
158
190
|
self.create_one_stub(module_name)
|
159
|
-
|
191
|
+
log.info("Finally done")
|
160
192
|
|
161
193
|
def create_one_stub(self, module_name: str):
|
162
|
-
wdt.feed()
|
163
194
|
if module_name in self.problematic:
|
164
|
-
|
195
|
+
log.warning("Skip module: {:<25} : Known problematic".format(module_name))
|
165
196
|
return False
|
166
197
|
if module_name in self.excluded:
|
167
|
-
|
198
|
+
log.warning("Skip module: {:<25} : Excluded".format(module_name))
|
168
199
|
return False
|
169
200
|
|
170
201
|
file_name = "{}/{}.py".format(self.path, module_name.replace(".", "/"))
|
@@ -199,10 +230,10 @@ class Stubber:
|
|
199
230
|
try:
|
200
231
|
new_module = __import__(module_name, None, None, ("*"))
|
201
232
|
m1 = gc.mem_free() # type: ignore
|
202
|
-
|
233
|
+
log.info("Stub module: {:<25} to file: {:<70} mem:{:>5}".format(module_name, fname, m1))
|
203
234
|
|
204
235
|
except ImportError:
|
205
|
-
|
236
|
+
log.trace("Skip module: {:<25} {:<79}".format(module_name, "Module not found."))
|
206
237
|
return False
|
207
238
|
|
208
239
|
# Start a new file
|
@@ -222,12 +253,12 @@ class Stubber:
|
|
222
253
|
try:
|
223
254
|
del new_module
|
224
255
|
except (OSError, KeyError): # lgtm [py/unreachable-statement]
|
225
|
-
|
256
|
+
log.warning("could not del new_module")
|
226
257
|
# lets not try - most times it does not work anyway
|
227
258
|
# try:
|
228
259
|
# del sys.modules[module_name]
|
229
260
|
# except KeyError:
|
230
|
-
|
261
|
+
# log.warning("could not del sys.modules[{}]".format(module_name))
|
231
262
|
gc.collect()
|
232
263
|
return True
|
233
264
|
|
@@ -235,10 +266,10 @@ class Stubber:
|
|
235
266
|
"Write a module/object stub to an open file. Can be called recursive."
|
236
267
|
gc.collect()
|
237
268
|
if object_expr in self.problematic:
|
238
|
-
|
269
|
+
log.warning("SKIPPING problematic module:{}".format(object_expr))
|
239
270
|
return
|
240
271
|
|
241
|
-
#
|
272
|
+
# log.debug("DUMP : {}".format(object_expr))
|
242
273
|
items, errors = self.get_obj_attributes(object_expr)
|
243
274
|
|
244
275
|
if errors:
|
@@ -250,7 +281,7 @@ class Stubber:
|
|
250
281
|
# do not create stubs for these primitives
|
251
282
|
continue
|
252
283
|
if item_name[0].isdigit():
|
253
|
-
|
284
|
+
log.warning("NameError: invalid name {}".format(item_name))
|
254
285
|
continue
|
255
286
|
# Class expansion only on first 3 levels (bit of a hack)
|
256
287
|
if (
|
@@ -259,7 +290,7 @@ class Stubber:
|
|
259
290
|
# and not obj_name.endswith(".Pin")
|
260
291
|
# avoid expansion of Pin.cpu / Pin.board to avoid crashes on most platforms
|
261
292
|
):
|
262
|
-
|
293
|
+
log.trace("{0}class {1}:".format(indent, item_name))
|
263
294
|
superclass = ""
|
264
295
|
is_exception = (
|
265
296
|
item_name.endswith("Exception")
|
@@ -282,7 +313,7 @@ class Stubber:
|
|
282
313
|
# write classdef
|
283
314
|
fp.write(s)
|
284
315
|
# first write the class literals and methods
|
285
|
-
|
316
|
+
log.debug("# recursion over class {0}".format(item_name))
|
286
317
|
self.write_object_stub(
|
287
318
|
fp,
|
288
319
|
item_instance,
|
@@ -296,7 +327,7 @@ class Stubber:
|
|
296
327
|
s += indent + " ...\n\n"
|
297
328
|
fp.write(s)
|
298
329
|
elif any(word in item_type_txt for word in ["method", "function", "closure"]):
|
299
|
-
|
330
|
+
log.debug("# def {1} function/method/closure, type = '{0}'".format(item_type_txt, item_name))
|
300
331
|
# module Function or class method
|
301
332
|
# will accept any number of params
|
302
333
|
# return type Any/Incomplete
|
@@ -312,7 +343,7 @@ class Stubber:
|
|
312
343
|
s = "{}def {}({}*args, **kwargs) -> {}:\n".format(indent, item_name, first, ret)
|
313
344
|
s += indent + " ...\n\n"
|
314
345
|
fp.write(s)
|
315
|
-
|
346
|
+
log.debug("\n" + s)
|
316
347
|
elif item_type_txt == "<class 'module'>":
|
317
348
|
# Skip imported modules
|
318
349
|
# fp.write("# import {}\n".format(item_name))
|
@@ -340,10 +371,10 @@ class Stubber:
|
|
340
371
|
t = "Incomplete"
|
341
372
|
s = "{0}{1} : {2} ## {3} = {4}\n".format(indent, item_name, t, item_type_txt, item_repr)
|
342
373
|
fp.write(s)
|
343
|
-
|
374
|
+
log.debug("\n" + s)
|
344
375
|
else:
|
345
376
|
# keep only the name
|
346
|
-
|
377
|
+
log.debug("# all other, type = '{0}'".format(item_type_txt))
|
347
378
|
fp.write("# all other, type = '{0}'\n".format(item_type_txt))
|
348
379
|
|
349
380
|
fp.write(indent + item_name + " # type: Incomplete\n")
|
@@ -367,10 +398,9 @@ class Stubber:
|
|
367
398
|
|
368
399
|
def clean(self, path: str = None): # type: ignore
|
369
400
|
"Remove all files from the stub folder"
|
370
|
-
wdt.feed()
|
371
401
|
if path is None:
|
372
402
|
path = self.path
|
373
|
-
|
403
|
+
log.info("Clean/remove files in folder: {}".format(path))
|
374
404
|
try:
|
375
405
|
os.stat(path) # TEMP workaround mpremote listdir bug -
|
376
406
|
items = os.listdir(path)
|
@@ -390,10 +420,9 @@ class Stubber:
|
|
390
420
|
|
391
421
|
def report(self, filename: str = "modules.json"):
|
392
422
|
"create json with list of exported modules"
|
393
|
-
|
394
|
-
# self.log.info("Created stubs for {} modules on board {}\nPath: {}".format(len(self._report), self._fwid, self.path))
|
423
|
+
log.info("Created stubs for {} modules on board {}\nPath: {}".format(len(self._report), self._fwid, self.path))
|
395
424
|
f_name = "{}/{}".format(self.path, filename)
|
396
|
-
|
425
|
+
log.info("Report file: {}".format(f_name))
|
397
426
|
gc.collect()
|
398
427
|
try:
|
399
428
|
# write json by node to reduce memory requirements
|
@@ -405,7 +434,7 @@ class Stubber:
|
|
405
434
|
first = False
|
406
435
|
self.write_json_end(f)
|
407
436
|
used = self._start_free - gc.mem_free() # type: ignore
|
408
|
-
|
437
|
+
log.trace("Memory used: {0} Kb".format(used // 1024))
|
409
438
|
except OSError:
|
410
439
|
print("Failed to create the report.")
|
411
440
|
|
@@ -505,9 +534,7 @@ def _info(): # type:() -> dict[str, str]
|
|
505
534
|
)
|
506
535
|
except (AttributeError, IndexError):
|
507
536
|
pass
|
508
|
-
|
509
|
-
read_boardname(info)
|
510
|
-
gc.collect()
|
537
|
+
info["board"] = get_boardname()
|
511
538
|
|
512
539
|
try:
|
513
540
|
if "uname" in dir(os): # old
|
@@ -595,79 +622,16 @@ def version_str(version: tuple): # -> str:
|
|
595
622
|
return v_str
|
596
623
|
|
597
624
|
|
598
|
-
def
|
599
|
-
|
600
|
-
|
601
|
-
|
602
|
-
|
603
|
-
|
604
|
-
|
605
|
-
|
606
|
-
|
607
|
-
|
608
|
-
info["board"] = data.strip()
|
609
|
-
found = True
|
610
|
-
break
|
611
|
-
if not found:
|
612
|
-
# print("Board not found, guessing board name")
|
613
|
-
descr = ""
|
614
|
-
# descr = desc or info["board"].strip()
|
615
|
-
# if "with " + info["cpu"].upper() in descr:
|
616
|
-
# # remove the with cpu part
|
617
|
-
# descr = descr.split("with " + info["cpu"].upper())[0].strip()
|
618
|
-
info["board"] = descr
|
619
|
-
|
620
|
-
|
621
|
-
# def read_boardname(info, desc: str = ""):
|
622
|
-
# wdt.feed()
|
623
|
-
# # # print("look up the board name in the file", filename)
|
624
|
-
# if file_exists(filename):
|
625
|
-
# descr = desc or info["board"].strip()
|
626
|
-
# pos = descr.rfind(" with")
|
627
|
-
# if pos != -1:
|
628
|
-
# short_descr = descr[:pos].strip()
|
629
|
-
# else:
|
630
|
-
# short_descr = ""
|
631
|
-
# # print("searching info file: {} for: '{}' or '{}'".format(filename, descr, short_descr))
|
632
|
-
# if find_board(info, descr, filename, short_descr):
|
633
|
-
# found = True
|
634
|
-
# break
|
635
|
-
# if not found:
|
636
|
-
# # print("Board not found, guessing board name")
|
637
|
-
# descr = desc or info["board"].strip()
|
638
|
-
# if "with " + info["cpu"].upper() in descr:
|
639
|
-
# # remove the with cpu part
|
640
|
-
# descr = descr.split("with " + info["cpu"].upper())[0].strip()
|
641
|
-
# info["board"] = descr
|
642
|
-
# info["board"] = info["board"].replace(" ", "_")
|
643
|
-
# gc.collect()
|
644
|
-
|
645
|
-
|
646
|
-
# def find_board(info: dict, descr: str, filename: str, short_descr: str):
|
647
|
-
# "Find the board in the provided board_info.csv file"
|
648
|
-
# short_hit = ""
|
649
|
-
# with open(filename, "r") as file:
|
650
|
-
# # ugly code to make testable in python and micropython
|
651
|
-
# # TODO: This is VERY slow on micropython whith MPREMOTE mount on esp32 (2-3 minutes to read file)
|
652
|
-
# while 1:
|
653
|
-
# line = file.readline()
|
654
|
-
# if not line:
|
655
|
-
# break
|
656
|
-
# descr_, board_ = line.split(",")[0].strip(), line.split(",")[1].strip()
|
657
|
-
# if descr_ == descr:
|
658
|
-
# info["board"] = board_
|
659
|
-
# return True
|
660
|
-
# elif short_descr and descr_ == short_descr:
|
661
|
-
# if "with" in short_descr:
|
662
|
-
# # Good enough - no need to trawl the entire file
|
663
|
-
# info["board"] = board_
|
664
|
-
# return True
|
665
|
-
# # good enough if not found in the rest of the file (but slow)
|
666
|
-
# short_hit = board_
|
667
|
-
# if short_hit:
|
668
|
-
# info["board"] = short_hit
|
669
|
-
# return True
|
670
|
-
# return False
|
625
|
+
def get_boardname() -> str:
|
626
|
+
"Read the board name from the boardname.py file that may have been created upfront"
|
627
|
+
try:
|
628
|
+
from boardname import BOARDNAME # type: ignore
|
629
|
+
|
630
|
+
log.info("Found BOARDNAME: {}".format(BOARDNAME))
|
631
|
+
except ImportError:
|
632
|
+
log.warning("BOARDNAME not found")
|
633
|
+
BOARDNAME = ""
|
634
|
+
return BOARDNAME
|
671
635
|
|
672
636
|
|
673
637
|
def get_root() -> str: # sourcery skip: use-assigned-variable
|
@@ -768,12 +732,6 @@ def main():
|
|
768
732
|
|
769
733
|
|
770
734
|
if __name__ == "__main__" or is_micropython():
|
771
|
-
try:
|
772
|
-
log = logging.getLogger("stubber")
|
773
|
-
logging.basicConfig(level=logging.INFO)
|
774
|
-
# logging.basicConfig(level=logging.DEBUG)
|
775
|
-
except NameError:
|
776
|
-
pass
|
777
735
|
if not file_exists("no_auto_stubber.txt"):
|
778
736
|
try:
|
779
737
|
gc.threshold(4 * 1024) # type: ignore
|
Binary file
|