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.
Files changed (49) hide show
  1. {micropython_stubber-1.16.3.dist-info → micropython_stubber-1.17.0.dist-info}/METADATA +1 -1
  2. {micropython_stubber-1.16.3.dist-info → micropython_stubber-1.17.0.dist-info}/RECORD +48 -49
  3. stubber/__init__.py +1 -1
  4. stubber/basicgit.py +11 -13
  5. stubber/board/createstubs.py +138 -97
  6. stubber/board/createstubs_db.py +211 -239
  7. stubber/board/createstubs_db_min.py +322 -844
  8. stubber/board/createstubs_db_mpy.mpy +0 -0
  9. stubber/board/createstubs_lvgl.py +91 -137
  10. stubber/board/createstubs_lvgl_min.py +87 -129
  11. stubber/board/createstubs_lvgl_mpy.mpy +0 -0
  12. stubber/board/createstubs_mem.py +164 -199
  13. stubber/board/createstubs_mem_min.py +297 -791
  14. stubber/board/createstubs_mem_mpy.mpy +0 -0
  15. stubber/board/createstubs_min.py +286 -1009
  16. stubber/board/createstubs_mpy.mpy +0 -0
  17. stubber/board/modulelist.txt +1 -2
  18. stubber/codemod/_partials/__init__.py +1 -1
  19. stubber/codemod/_partials/db_main.py +90 -72
  20. stubber/codemod/_partials/modules_reader.py +29 -17
  21. stubber/codemod/board.py +2 -4
  22. stubber/codemod/enrich.py +1 -1
  23. stubber/commands/build_cmd.py +6 -4
  24. stubber/commands/get_docstubs_cmd.py +6 -11
  25. stubber/commands/get_frozen_cmd.py +6 -11
  26. stubber/commands/switch_cmd.py +6 -4
  27. stubber/freeze/freeze_manifest_2.py +2 -1
  28. stubber/freeze/get_frozen.py +28 -13
  29. stubber/minify.py +51 -38
  30. stubber/publish/candidates.py +15 -23
  31. stubber/publish/defaults.py +2 -2
  32. stubber/publish/merge_docstubs.py +5 -7
  33. stubber/publish/missing_class_methods.py +2 -2
  34. stubber/publish/pathnames.py +2 -2
  35. stubber/publish/publish.py +2 -1
  36. stubber/publish/stubpackage.py +20 -41
  37. stubber/rst/lookup.py +9 -7
  38. stubber/rst/reader.py +2 -1
  39. stubber/stubber.py +5 -6
  40. stubber/update_fallback.py +3 -1
  41. stubber/utils/__init__.py +1 -1
  42. stubber/utils/config.py +7 -9
  43. stubber/utils/repos.py +6 -5
  44. stubber/utils/versions.py +48 -7
  45. stubber/variants.py +3 -3
  46. stubber/board/logging.py +0 -99
  47. {micropython_stubber-1.16.3.dist-info → micropython_stubber-1.17.0.dist-info}/LICENSE +0 -0
  48. {micropython_stubber-1.16.3.dist-info → micropython_stubber-1.17.0.dist-info}/WHEEL +0 -0
  49. {micropython_stubber-1.16.3.dist-info → micropython_stubber-1.17.0.dist-info}/entry_points.txt +0 -0
Binary file
@@ -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.2
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
- try:
32
- from nope_machine import WDT
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
- wdt = WDT()
56
+ def trace(self, msg):
57
+ if self.level <= logging.TRACE:
58
+ self.prnt("TRACE :", msg)
35
59
 
36
- except ImportError:
60
+ def debug(self, msg):
61
+ if self.level <= logging.DEBUG:
62
+ self.prnt("DEBUG :", msg)
37
63
 
38
- class _WDT:
39
- def feed(self):
40
- pass
64
+ def info(self, msg):
65
+ if self.level <= logging.INFO:
66
+ self.prnt("INFO :", msg)
41
67
 
42
- wdt = _WDT()
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
- wdt.feed()
76
+ def critical(self, msg):
77
+ if self.level <= logging.CRITICAL:
78
+ self.prnt("CRIT :", msg)
46
79
 
47
- __version__ = "v1.16.2"
48
- ENOENT = 2
49
- _MAX_CLASS_LEVEL = 2 # Max class nesting
50
- LIBS = [".", "/lib", "/sd/lib", "/flash/lib", "lib"]
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
- self.log.info("Port: {}".format(self.info["port"]))
66
- self.log.info("Board: {}".format(self.info["board"]))
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,11 +114,11 @@ class Stubber:
82
114
  path = get_root()
83
115
 
84
116
  self.path = "{}/stubs/{}".format(path, self.flat_fwid).replace("//", "/")
85
- self.log.debug(self.path)
117
+ log.debug(self.path)
86
118
  try:
87
119
  ensure_folder(path + "/")
88
120
  except OSError:
89
- self.log.error("error creating stub folder {}".format(path))
121
+ log.error("error creating stub folder {}".format(path))
90
122
  self.problematic = [
91
123
  "upip",
92
124
  "upysh",
@@ -111,15 +143,15 @@ class Stubber:
111
143
  # name_, repr_(value), type as text, item_instance
112
144
  _result = []
113
145
  _errors = []
114
- self.log.debug("get attributes {} {}".format(repr(item_instance), item_instance))
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
- self.log.debug("get attribute {}".format(name))
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
- self.log.debug("attribute {}:{}".format(name, val))
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
- self.log.info("Start micropython-stubber v{} on {}".format(__version__, self._fwid))
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
- self.log.info("Finally done")
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
- self.log.warning("Skip module: {:<25} : Known problematic".format(module_name))
195
+ log.warning("Skip module: {:<25} : Known problematic".format(module_name))
165
196
  return False
166
197
  if module_name in self.excluded:
167
- self.log.warning("Skip module: {:<25} : Excluded".format(module_name))
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
- self.log.info("Stub module: {:<25} to file: {:<70} mem:{:>5}".format(module_name, fname, m1))
233
+ log.info("Stub module: {:<25} to file: {:<70} mem:{:>5}".format(module_name, fname, m1))
203
234
 
204
235
  except ImportError:
205
- self.log.warning("Skip module: {:<25} {:<79}".format(module_name, "Module not found."))
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
@@ -210,9 +241,7 @@ class Stubber:
210
241
  with open(file_name, "w") as fp:
211
242
  # todo: improve header
212
243
  info_ = str(self.info).replace("OrderedDict(", "").replace("})", "}")
213
- s = '"""\nModule: \'{0}\' on {1}\n"""\n# MCU: {2}\n# Stubber: {3}\n'.format(
214
- module_name, self._fwid, info_, __version__
215
- )
244
+ s = '"""\nModule: \'{0}\' on {1}\n"""\n# MCU: {2}\n# Stubber: {3}\n'.format(module_name, self._fwid, info_, __version__)
216
245
  fp.write(s)
217
246
  fp.write("from __future__ import annotations\nfrom typing import Any\nfrom _typeshed import Incomplete\n\n")
218
247
  self.write_object_stub(fp, new_module, module_name, "")
@@ -224,12 +253,12 @@ class Stubber:
224
253
  try:
225
254
  del new_module
226
255
  except (OSError, KeyError): # lgtm [py/unreachable-statement]
227
- self.log.warning("could not del new_module")
256
+ log.warning("could not del new_module")
228
257
  # lets not try - most times it does not work anyway
229
258
  # try:
230
259
  # del sys.modules[module_name]
231
260
  # except KeyError:
232
- # self.log.warning("could not del sys.modules[{}]".format(module_name))
261
+ # log.warning("could not del sys.modules[{}]".format(module_name))
233
262
  gc.collect()
234
263
  return True
235
264
 
@@ -237,14 +266,14 @@ class Stubber:
237
266
  "Write a module/object stub to an open file. Can be called recursive."
238
267
  gc.collect()
239
268
  if object_expr in self.problematic:
240
- self.log.warning("SKIPPING problematic module:{}".format(object_expr))
269
+ log.warning("SKIPPING problematic module:{}".format(object_expr))
241
270
  return
242
271
 
243
- # self.log.debug("DUMP : {}".format(object_expr))
272
+ # log.debug("DUMP : {}".format(object_expr))
244
273
  items, errors = self.get_obj_attributes(object_expr)
245
274
 
246
275
  if errors:
247
- self.log.error(errors)
276
+ log.error(errors)
248
277
 
249
278
  for item_name, item_repr, item_type_txt, item_instance, _ in items:
250
279
  # name_, repr_(value), type as text, item_instance, order
@@ -252,7 +281,7 @@ class Stubber:
252
281
  # do not create stubs for these primitives
253
282
  continue
254
283
  if item_name[0].isdigit():
255
- self.log.warning("NameError: invalid name {}".format(item_name))
284
+ log.warning("NameError: invalid name {}".format(item_name))
256
285
  continue
257
286
  # Class expansion only on first 3 levels (bit of a hack)
258
287
  if (
@@ -261,7 +290,7 @@ class Stubber:
261
290
  # and not obj_name.endswith(".Pin")
262
291
  # avoid expansion of Pin.cpu / Pin.board to avoid crashes on most platforms
263
292
  ):
264
- self.log.info("{0}class {1}:".format(indent, item_name))
293
+ log.trace("{0}class {1}:".format(indent, item_name))
265
294
  superclass = ""
266
295
  is_exception = (
267
296
  item_name.endswith("Exception")
@@ -284,7 +313,7 @@ class Stubber:
284
313
  # write classdef
285
314
  fp.write(s)
286
315
  # first write the class literals and methods
287
- self.log.debug("# recursion over class {0}".format(item_name))
316
+ log.debug("# recursion over class {0}".format(item_name))
288
317
  self.write_object_stub(
289
318
  fp,
290
319
  item_instance,
@@ -298,7 +327,7 @@ class Stubber:
298
327
  s += indent + " ...\n\n"
299
328
  fp.write(s)
300
329
  elif any(word in item_type_txt for word in ["method", "function", "closure"]):
301
- self.log.debug("# def {1} function/method/closure, type = '{0}'".format(item_type_txt, item_name))
330
+ log.debug("# def {1} function/method/closure, type = '{0}'".format(item_type_txt, item_name))
302
331
  # module Function or class method
303
332
  # will accept any number of params
304
333
  # return type Any/Incomplete
@@ -309,14 +338,12 @@ class Stubber:
309
338
  first = "self, "
310
339
  # class method - add function decoration
311
340
  if "bound_method" in item_type_txt or "bound_method" in item_repr:
312
- s = "{}@classmethod\n".format(indent) + "{}def {}(cls, *args, **kwargs) -> {}:\n".format(
313
- indent, item_name, ret
314
- )
341
+ s = "{}@classmethod\n".format(indent) + "{}def {}(cls, *args, **kwargs) -> {}:\n".format(indent, item_name, ret)
315
342
  else:
316
343
  s = "{}def {}({}*args, **kwargs) -> {}:\n".format(indent, item_name, first, ret)
317
344
  s += indent + " ...\n\n"
318
345
  fp.write(s)
319
- self.log.debug("\n" + s)
346
+ log.debug("\n" + s)
320
347
  elif item_type_txt == "<class 'module'>":
321
348
  # Skip imported modules
322
349
  # fp.write("# import {}\n".format(item_name))
@@ -344,10 +371,10 @@ class Stubber:
344
371
  t = "Incomplete"
345
372
  s = "{0}{1} : {2} ## {3} = {4}\n".format(indent, item_name, t, item_type_txt, item_repr)
346
373
  fp.write(s)
347
- self.log.debug("\n" + s)
374
+ log.debug("\n" + s)
348
375
  else:
349
376
  # keep only the name
350
- self.log.debug("# all other, type = '{0}'".format(item_type_txt))
377
+ log.debug("# all other, type = '{0}'".format(item_type_txt))
351
378
  fp.write("# all other, type = '{0}'\n".format(item_type_txt))
352
379
 
353
380
  fp.write(indent + item_name + " # type: Incomplete\n")
@@ -371,10 +398,9 @@ class Stubber:
371
398
 
372
399
  def clean(self, path: str = None): # type: ignore
373
400
  "Remove all files from the stub folder"
374
- wdt.feed()
375
401
  if path is None:
376
402
  path = self.path
377
- self.log.info("Clean/remove files in folder: {}".format(path))
403
+ log.info("Clean/remove files in folder: {}".format(path))
378
404
  try:
379
405
  os.stat(path) # TEMP workaround mpremote listdir bug -
380
406
  items = os.listdir(path)
@@ -394,12 +420,9 @@ class Stubber:
394
420
 
395
421
  def report(self, filename: str = "modules.json"):
396
422
  "create json with list of exported modules"
397
- wdt.feed()
398
- self.log.info(
399
- "Created stubs for {} modules on board {}\nPath: {}".format(len(self._report), self._fwid, self.path)
400
- )
423
+ log.info("Created stubs for {} modules on board {}\nPath: {}".format(len(self._report), self._fwid, self.path))
401
424
  f_name = "{}/{}".format(self.path, filename)
402
- self.log.info("Report file: {}".format(f_name))
425
+ log.info("Report file: {}".format(f_name))
403
426
  gc.collect()
404
427
  try:
405
428
  # write json by node to reduce memory requirements
@@ -411,9 +434,9 @@ class Stubber:
411
434
  first = False
412
435
  self.write_json_end(f)
413
436
  used = self._start_free - gc.mem_free() # type: ignore
414
- self.log.info("Memory used: {0} Kb".format(used // 1024))
437
+ log.trace("Memory used: {0} Kb".format(used // 1024))
415
438
  except OSError:
416
- self.log.error("Failed to create the report.")
439
+ log.error("Failed to create the report.")
417
440
 
418
441
  def write_json_header(self, f):
419
442
  f.write("{")
@@ -599,79 +622,16 @@ def version_str(version: tuple): # -> str:
599
622
  return v_str
600
623
 
601
624
 
602
- def read_boardname(info, desc: str = ""):
603
- info["board"] = info["board"].replace(" ", "_")
604
- found = False
605
- for filename in [d + "/board_name.txt" for d in LIBS]:
606
- wdt.feed()
607
- # print("look up the board name in the file", filename)
608
- if file_exists(filename):
609
- with open(filename, "r") as file:
610
- data = file.read()
611
- if data:
612
- info["board"] = data.strip()
613
- found = True
614
- break
615
- if not found:
616
- print("Board not found, guessing board name")
617
- descr = ""
618
- # descr = desc or info["board"].strip()
619
- # if "with " + info["cpu"].upper() in descr:
620
- # # remove the with cpu part
621
- # descr = descr.split("with " + info["cpu"].upper())[0].strip()
622
- info["board"] = descr
623
-
624
-
625
- # def read_boardname(info, desc: str = ""):
626
- # wdt.feed()
627
- # # print("look up the board name in the file", filename)
628
- # if file_exists(filename):
629
- # descr = desc or info["board"].strip()
630
- # pos = descr.rfind(" with")
631
- # if pos != -1:
632
- # short_descr = descr[:pos].strip()
633
- # else:
634
- # short_descr = ""
635
- # print("searching info file: {} for: '{}' or '{}'".format(filename, descr, short_descr))
636
- # if find_board(info, descr, filename, short_descr):
637
- # found = True
638
- # break
639
- # if not found:
640
- # print("Board not found, guessing board name")
641
- # descr = desc or info["board"].strip()
642
- # if "with " + info["cpu"].upper() in descr:
643
- # # remove the with cpu part
644
- # descr = descr.split("with " + info["cpu"].upper())[0].strip()
645
- # info["board"] = descr
646
- # info["board"] = info["board"].replace(" ", "_")
647
- # gc.collect()
648
-
649
-
650
- # def find_board(info: dict, descr: str, filename: str, short_descr: str):
651
- # "Find the board in the provided board_info.csv file"
652
- # short_hit = ""
653
- # with open(filename, "r") as file:
654
- # # ugly code to make testable in python and micropython
655
- # # TODO: This is VERY slow on micropython whith MPREMOTE mount on esp32 (2-3 minutes to read file)
656
- # while 1:
657
- # line = file.readline()
658
- # if not line:
659
- # break
660
- # descr_, board_ = line.split(",")[0].strip(), line.split(",")[1].strip()
661
- # if descr_ == descr:
662
- # info["board"] = board_
663
- # return True
664
- # elif short_descr and descr_ == short_descr:
665
- # if "with" in short_descr:
666
- # # Good enough - no need to trawl the entire file
667
- # info["board"] = board_
668
- # return True
669
- # # good enough if not found in the rest of the file (but slow)
670
- # short_hit = board_
671
- # if short_hit:
672
- # info["board"] = short_hit
673
- # return True
674
- # 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
675
635
 
676
636
 
677
637
  def get_root() -> str: # sourcery skip: use-assigned-variable
@@ -772,12 +732,6 @@ def main():
772
732
 
773
733
 
774
734
  if __name__ == "__main__" or is_micropython():
775
- try:
776
- log = logging.getLogger("stubber")
777
- logging.basicConfig(level=logging.INFO)
778
- # logging.basicConfig(level=logging.DEBUG)
779
- except NameError:
780
- pass
781
735
  if not file_exists("no_auto_stubber.txt"):
782
736
  try:
783
737
  gc.threshold(4 * 1024) # type: ignore