micropython-stubber 1.14.1__py3-none-any.whl → 1.15.1__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 (50) hide show
  1. micropython_stubber-1.15.1.dist-info/METADATA +244 -0
  2. {micropython_stubber-1.14.1.dist-info → micropython_stubber-1.15.1.dist-info}/RECORD +49 -46
  3. stubber/__init__.py +1 -1
  4. stubber/basicgit.py +27 -14
  5. stubber/board/createstubs.py +34 -36
  6. stubber/board/createstubs_db.py +35 -35
  7. stubber/board/createstubs_db_min.py +195 -193
  8. stubber/board/createstubs_db_mpy.mpy +0 -0
  9. stubber/board/createstubs_info.py +73 -42
  10. stubber/board/createstubs_lvgl.py +35 -35
  11. stubber/board/createstubs_lvgl_min.py +88 -87
  12. stubber/board/createstubs_lvgl_mpy.mpy +0 -0
  13. stubber/board/createstubs_mem.py +44 -40
  14. stubber/board/createstubs_mem_min.py +179 -174
  15. stubber/board/createstubs_mem_mpy.mpy +0 -0
  16. stubber/board/createstubs_min.py +75 -74
  17. stubber/board/createstubs_mpy.mpy +0 -0
  18. stubber/board/info.py +183 -0
  19. stubber/codemod/enrich.py +28 -16
  20. stubber/commands/build_cmd.py +3 -3
  21. stubber/commands/get_core_cmd.py +17 -5
  22. stubber/commands/get_docstubs_cmd.py +23 -8
  23. stubber/commands/get_frozen_cmd.py +62 -9
  24. stubber/commands/get_lobo_cmd.py +13 -3
  25. stubber/commands/merge_cmd.py +7 -4
  26. stubber/commands/publish_cmd.py +5 -4
  27. stubber/commands/stub_cmd.py +2 -1
  28. stubber/commands/variants_cmd.py +0 -1
  29. stubber/freeze/common.py +2 -2
  30. stubber/freeze/freeze_folder.py +1 -1
  31. stubber/freeze/get_frozen.py +1 -1
  32. stubber/minify.py +43 -28
  33. stubber/publish/bump.py +1 -1
  34. stubber/publish/candidates.py +61 -17
  35. stubber/publish/defaults.py +44 -0
  36. stubber/publish/merge_docstubs.py +19 -56
  37. stubber/publish/package.py +44 -37
  38. stubber/publish/pathnames.py +51 -0
  39. stubber/publish/publish.py +5 -4
  40. stubber/publish/stubpacker.py +55 -33
  41. stubber/rst/lookup.py +7 -16
  42. stubber/rst/reader.py +39 -8
  43. stubber/stubs_from_docs.py +5 -8
  44. stubber/utils/post.py +34 -40
  45. stubber/utils/repos.py +32 -17
  46. stubber/utils/stubmaker.py +22 -14
  47. micropython_stubber-1.14.1.dist-info/METADATA +0 -217
  48. {micropython_stubber-1.14.1.dist-info → micropython_stubber-1.15.1.dist-info}/LICENSE +0 -0
  49. {micropython_stubber-1.14.1.dist-info → micropython_stubber-1.15.1.dist-info}/WHEEL +0 -0
  50. {micropython_stubber-1.14.1.dist-info → micropython_stubber-1.15.1.dist-info}/entry_points.txt +0 -0
@@ -1,23 +1,24 @@
1
- w='pyb'
2
- v='{}/{}'
3
- u='logging'
4
- t='sys'
5
- s='method'
6
- r='function'
7
- q='bool'
8
- p='str'
9
- o='float'
10
- n='int'
11
- m='port'
12
- l=NameError
13
- k=sorted
14
- j=NotImplementedError
15
- b='pycom'
16
- a=',\n'
17
- Z='dict'
18
- Y='list'
19
- X='tuple'
20
- W='micropython'
1
+ x='pyb'
2
+ w='{}/{}'
3
+ v='logging'
4
+ u='sys'
5
+ t='method'
6
+ s='function'
7
+ r='bool'
8
+ q='str'
9
+ p='float'
10
+ o='int'
11
+ n='port'
12
+ m=NameError
13
+ l=sorted
14
+ k=NotImplementedError
15
+ c='pycom'
16
+ b=',\n'
17
+ a='dict'
18
+ Z='list'
19
+ Y='tuple'
20
+ X='micropython'
21
+ W='stubber'
21
22
  V=open
22
23
  U=repr
23
24
  S='_'
@@ -39,32 +40,32 @@ F=OSError
39
40
  D='version'
40
41
  B=''
41
42
  import gc as C,os,sys
42
- from ujson import dumps as c
43
+ from ujson import dumps as d
43
44
  try:from machine import reset
44
45
  except N:pass
45
- try:from collections import OrderedDict as d
46
- except N:from ucollections import OrderedDict as d
47
- __version__='v1.14.1'
48
- x=2
46
+ try:from collections import OrderedDict as e
47
+ except N:from ucollections import OrderedDict as e
48
+ __version__='v1.15.1'
49
49
  y=2
50
- z=[K,'/lib','/sd/lib','/flash/lib','lib']
50
+ z=2
51
+ A0=[K,'/lib','/sd/lib','/flash/lib','lib']
51
52
  from time import sleep
52
53
  class Stubber:
53
54
  def __init__(A,path=E,firmware_id=E):
54
55
  B=firmware_id
55
56
  try:
56
- if os.uname().release=='1.13.0'and os.uname().version<'v1.13-103':raise j('MicroPython 1.13.0 cannot be stubbed')
57
+ if os.uname().release=='1.13.0'and os.uname().version<'v1.13-103':raise k('MicroPython 1.13.0 cannot be stubbed')
57
58
  except H:pass
58
- A._report=[];A.info=_info();J('Port: {}'.format(A.info[m]));J('Board: {}'.format(A.info[I]));C.collect()
59
+ A.log=E;A.log=logging.getLogger(W);A._report=[];A.info=_info();J('Port: {}'.format(A.info[n]));J('Board: {}'.format(A.info[I]));C.collect()
59
60
  if B:A._fwid=B.lower()
60
- elif A.info[L]==W:A._fwid='{family}-{ver}-{port}-{board}'.format(**A.info)
61
+ elif A.info[L]==X:A._fwid='{family}-{ver}-{port}-{board}'.format(**A.info)
61
62
  else:A._fwid='{family}-{ver}-{port}'.format(**A.info)
62
63
  A._start_free=C.mem_free()
63
64
  if path:
64
65
  if path.endswith(G):path=path[:-1]
65
66
  else:path=get_root()
66
67
  A.path='{}/stubs/{}'.format(path,A.flat_fwid).replace('//',G)
67
- try:e(path+G)
68
+ try:f(path+G)
68
69
  except F:J('error creating stub folder {}'.format(path))
69
70
  A.problematic=['upip','upysh','webrepl_setup','http_client','http_client_ssl','http_server','http_server_ssl'];A.excluded=['webrepl','_webrepl','port_diag','example_sub_led.py','example_pub_button.py'];A.modules=[]
70
71
  def get_obj_attributes(L,item_instance):
@@ -75,15 +76,15 @@ class Stubber:
75
76
  E=getattr(I,A)
76
77
  try:F=U(type(E)).split("'")[1]
77
78
  except P:F=B
78
- if F in{n,o,p,q,X,Y,Z}:G=1
79
- elif F in{r,s}:G=2
79
+ if F in{o,p,q,r,Y,Z,a}:G=1
80
+ elif F in{s,t}:G=2
80
81
  elif F in'class':G=3
81
82
  else:G=4
82
83
  D.append((A,U(E),U(type(E)),E,G))
83
84
  except H as K:J.append("Couldn't get attribute '{}' from object '{}', Err: {}".format(A,I,K))
84
85
  except MemoryError as K:sleep(1);reset()
85
- D=k([A for A in D if not A[0].startswith('__')],key=lambda x:x[4]);C.collect();return D,J
86
- def add_modules(A,modules):A.modules=k(set(A.modules)|set(modules))
86
+ D=l([A for A in D if not A[0].startswith('__')],key=lambda x:x[4]);C.collect();return D,J
87
+ def add_modules(A,modules):A.modules=l(set(A.modules)|set(modules))
87
88
  def create_all_stubs(A):
88
89
  C.collect()
89
90
  for B in A.modules:A.create_one_stub(B)
@@ -103,10 +104,10 @@ class Stubber:
103
104
  J=E
104
105
  try:J=__import__(D,E,E,'*');T=C.mem_free()
105
106
  except N:return A
106
- e(H)
107
+ f(H)
107
108
  with V(H,'w')as L:P=str(I.info).replace('OrderedDict(',B).replace('})','}');R='"""\nModule: \'{0}\' on {1}\n"""\n# MCU: {2}\n# Stubber: {3}\n'.format(D,I._fwid,P,__version__);L.write(R);L.write('from typing import Any\nfrom _typeshed import Incomplete\n\n');I.write_object_stub(L,J,D,B)
108
109
  I._report.append('{{"module": "{}", "file": "{}"}}'.format(D,H.replace('\\',G)))
109
- if D not in{'os',t,u,'gc'}:
110
+ if D not in{'os',u,v,'gc'}:
110
111
  try:del J
111
112
  except (F,Q):pass
112
113
  try:del sys.modules[D]
@@ -120,23 +121,23 @@ class Stubber:
120
121
  for (E,K,G,T,f) in S:
121
122
  if E in['classmethod','staticmethod','BaseException',N]:continue
122
123
  if E[0].isdigit():continue
123
- if G=="<class 'type'>"and R(D)<=y*4:
124
+ if G=="<class 'type'>"and R(D)<=z*4:
124
125
  U=B;V=E.endswith(N)or E.endswith('Error')or E in['KeyboardInterrupt','StopIteration','SystemExit']
125
126
  if V:U=N
126
127
  A='\n{}class {}({}):\n'.format(D,E,U)
127
128
  if V:A+=D+' ...\n';H.write(A);return
128
129
  H.write(A);L.write_object_stub(H,T,'{0}.{1}'.format(obj_name,E),D+' ',P+1);A=D+' def __init__(self, *argv, **kwargs) -> None:\n';A+=D+' ...\n\n';H.write(A)
129
- elif any((A in G for A in[s,r,'closure'])):
130
- W=b;a=B
131
- if P>0:a='self, '
130
+ elif any((A in G for A in[t,s,'closure'])):
131
+ W=b;X=B
132
+ if P>0:X='self, '
132
133
  if c in G or c in K:A='{}@classmethod\n'.format(D)+'{}def {}(cls, *args, **kwargs) -> {}:\n'.format(D,E,W)
133
- else:A='{}def {}({}*args, **kwargs) -> {}:\n'.format(D,E,a,W)
134
+ else:A='{}def {}({}*args, **kwargs) -> {}:\n'.format(D,E,X,W)
134
135
  A+=D+' ...\n\n';H.write(A)
135
136
  elif G=="<class 'module'>":0
136
137
  elif G.startswith("<class '"):
137
138
  I=G[8:-2];A=B
138
- if I in[p,n,o,q,'bytearray','bytes']:A=d.format(D,E,K,I)
139
- elif I in[Z,Y,X]:e={Z:'{}',Y:'[]',X:'()'};A=d.format(D,E,e[I],I)
139
+ if I in[q,o,p,r,'bytearray','bytes']:A=d.format(D,E,K,I)
140
+ elif I in[a,Z,Y]:e={a:'{}',Z:'[]',Y:'()'};A=d.format(D,E,e[I],I)
140
141
  else:
141
142
  if I not in['object','set','frozenset']:I=b
142
143
  A='{0}{1} : {2} ## {3} = {4}\n'.format(D,E,I,G,K)
@@ -144,7 +145,7 @@ class Stubber:
144
145
  else:H.write("# all other, type = '{0}'\n".format(G));H.write(D+E+' # type: Incomplete\n')
145
146
  del S;del M
146
147
  try:del E,K,G,T
147
- except (F,Q,l):pass
148
+ except (F,Q,m):pass
148
149
  @property
149
150
  def flat_fwid(self):
150
151
  A=self._fwid;B=' .()/\\:$'
@@ -156,13 +157,13 @@ class Stubber:
156
157
  try:os.stat(path);C=os.listdir(path)
157
158
  except (F,H):return
158
159
  for D in C:
159
- A=v.format(path,D)
160
+ A=w.format(path,D)
160
161
  try:os.remove(A)
161
162
  except F:
162
163
  try:B.clean(A);os.rmdir(A)
163
164
  except F:pass
164
165
  def report(B,filename='modules.json'):
165
- G=v.format(B.path,filename);C.collect()
166
+ G=w.format(B.path,filename);C.collect()
166
167
  try:
167
168
  with V(G,'w')as D:
168
169
  B.write_json_header(D);E=M
@@ -170,12 +171,12 @@ class Stubber:
170
171
  B.write_json_end(D)
171
172
  I=B._start_free-C.mem_free()
172
173
  except F:J('Failed to create the report.')
173
- def write_json_header(B,f):A='firmware';f.write('{');f.write(c({A:B.info})[1:-1]);f.write(a);f.write(c({'stubber':{D:__version__},'stubtype':A})[1:-1]);f.write(a);f.write('"modules" :[\n')
174
+ def write_json_header(B,f):A='firmware';f.write('{');f.write(d({A:B.info})[1:-1]);f.write(b);f.write(d({W:{D:__version__},'stubtype':A})[1:-1]);f.write(b);f.write('"modules" :[\n')
174
175
  def write_json_node(A,f,n,first):
175
- if not first:f.write(a)
176
+ if not first:f.write(b)
176
177
  f.write(n)
177
178
  def write_json_end(A,f):f.write('\n]}')
178
- def e(path):
179
+ def f(path):
179
180
  A=C=0
180
181
  while A!=-1:
181
182
  A=path.find(G,C)
@@ -183,7 +184,7 @@ def e(path):
183
184
  B=path[0]if A==0 else path[:A]
184
185
  try:H=os.stat(B)
185
186
  except F as D:
186
- if D.args[0]==x:
187
+ if D.args[0]==y:
187
188
  try:os.mkdir(B)
188
189
  except F as E:J('failed to create folder {}'.format(B));raise E
189
190
  C=A+1
@@ -193,20 +194,20 @@ def T(s):
193
194
  if A in s:s=s.split(A,1)[0]
194
195
  return s.split('-')[1]if'-'in s else B
195
196
  def _info():
196
- i='ev3-pybricks';h='pycopy';e='GENERIC';c='arch';a='cpu';Z='ver';V='with';G='mpy';F='build';A=d({L:sys.implementation.name,D:B,F:B,Z:B,m:'stm32'if sys.platform.startswith(w)else sys.platform,I:e,a:B,G:B,c:B})
197
+ i='ev3-pybricks';f='pycopy';d='GENERIC';b='arch';a='cpu';Z='ver';V='with';G='mpy';F='build';A=e({L:sys.implementation.name,D:B,F:B,Z:B,n:'stm32'if sys.platform.startswith(x)else sys.platform,I:d,a:B,G:B,b:B})
197
198
  try:A[D]=K.join([str(A)for A in sys.implementation.version])
198
199
  except H:pass
199
- try:X=sys.implementation._machine if'_machine'in O(sys.implementation)else os.uname().machine;A[I]=X.strip();A[a]=X.split(V)[1].strip();A[G]=sys.implementation._mpy if'_mpy'in O(sys.implementation)else sys.implementation.mpy if G in O(sys.implementation)else B
200
+ try:W=sys.implementation._machine if'_machine'in O(sys.implementation)else os.uname().machine;A[I]=W.strip();A[a]=W.split(V)[1].strip();A[G]=sys.implementation._mpy if'_mpy'in O(sys.implementation)else sys.implementation.mpy if G in O(sys.implementation)else B
200
201
  except (H,P):pass
201
202
  C.collect()
202
- for M in [A+'/board_info.csv'for A in z]:
203
- if g(M):
203
+ for M in [A+'/board_info.csv'for A in A0]:
204
+ if h(M):
204
205
  J=A[I].strip()
205
- if f(A,J,M):break
206
+ if g(A,J,M):break
206
207
  if V in J:
207
208
  J=J.split(V)[0].strip()
208
- if f(A,J,M):break
209
- A[I]=e
209
+ if g(A,J,M):break
210
+ A[I]=d
210
211
  A[I]=A[I].replace(' ',S);C.collect()
211
212
  try:
212
213
  A[F]=T(os.uname()[3])
@@ -217,18 +218,18 @@ def _info():
217
218
  if A[D]==B and sys.platform not in('unix','win32'):
218
219
  try:j=os.uname();A[D]=j.release
219
220
  except (P,H,TypeError):pass
220
- for (k,l,n) in [(h,h,'const'),(b,b,'FAT'),(i,'pybricks.hubs','EV3Brick')]:
221
- try:o=__import__(l,E,E,n);A[L]=k;del o;break
221
+ for (k,l,m) in [(f,f,'const'),(c,c,'FAT'),(i,'pybricks.hubs','EV3Brick')]:
222
+ try:o=__import__(l,E,E,m);A[L]=k;del o;break
222
223
  except (N,Q):pass
223
224
  if A[L]==i:A['release']='2.0.0'
224
- if A[L]==W:
225
+ if A[L]==X:
225
226
  if A[D]and A[D].endswith('.0')and A[D]>='1.10.0'and A[D]<='1.19.9':A[D]=A[D][:-2]
226
227
  if G in A and A[G]:
227
228
  U=int(A[G]);Y=[E,'x86','x64','armv6','armv6m','armv7m','armv7em','armv7emsp','armv7emdp','xtensa','xtensawin'][U>>10]
228
- if Y:A[c]=Y
229
+ if Y:A[b]=Y
229
230
  A[G]='v{}.{}'.format(U&255,U>>8&3)
230
231
  A[Z]=f"v{A[D]}-{A[F]}"if A[F]else f"v{A[D]}";return A
231
- def f(info,board_descr,filename):
232
+ def g(info,board_descr,filename):
232
233
  with V(filename,'r')as C:
233
234
  while 1:
234
235
  B=C.readline()
@@ -244,28 +245,28 @@ def get_root():
244
245
  try:C=os.stat(B);break
245
246
  except F:continue
246
247
  return B
247
- def g(filename):
248
+ def h(filename):
248
249
  try:
249
250
  if os.stat(filename)[0]>>14:return M
250
251
  return A
251
252
  except F:return A
252
- def h():sys.exit(1)
253
+ def i():sys.exit(1)
253
254
  def read_path():
254
255
  path=B
255
256
  if R(sys.argv)==3:
256
257
  A=sys.argv[1].lower()
257
258
  if A in('--path','-p'):path=sys.argv[2]
258
- else:h()
259
- elif R(sys.argv)==2:h()
259
+ else:i()
260
+ elif R(sys.argv)==2:i()
260
261
  return path
261
- def i():
262
- try:B=bytes('abc',encoding='utf8');C=i.__module__;return A
263
- except (j,H):return M
264
- def main():stubber=Stubber(path=read_path());stubber.clean();stubber.modules=['WM8960','_OTA','_asyncio','_boot_fat','_coap','_espnow','_flash_control_OTA','_main_pybytes','_mqtt','_mqtt_core','_msg_handl','_onewire','_periodical_pin','_pybytes','_pybytes_ca','_pybytes_config','_pybytes_config_reader','_pybytes_connection','_pybytes_constants','_pybytes_debug','_pybytes_library','_pybytes_machine_learning','_pybytes_main','_pybytes_protocol','_pybytes_pyconfig','_pybytes_pymesh_config','_rp2','_terminal','_thread','_uasyncio','_urequest','adcfft','aioble/__init__','aioble/central','aioble/client','aioble/core','aioble/device','aioble/l2cap','aioble/peripheral','aioble/security','aioble/server','aioespnow','ak8963','apa102','apa106','array','asyncio/__init__','asyncio/core','asyncio/event','asyncio/funcs','asyncio/lock','asyncio/stream','binascii','bluetooth','breakout_as7262','breakout_bh1745','breakout_bme280','breakout_bme68x','breakout_bmp280','breakout_dotmatrix','breakout_encoder','breakout_icp10125','breakout_ioexpander','breakout_ltr559','breakout_matrix11x7','breakout_mics6814','breakout_msa301','breakout_paa5100','breakout_pmw3901','breakout_potentiometer','breakout_rgbmatrix5x5','breakout_rtc','breakout_scd41','breakout_sgp30','breakout_trackball','breakout_vl53l5cx','btree','cmath','collections','crypto','cryptolib','curl','deflate','dht','display','display_driver_utils','ds18x20','encoder','errno','esp','esp32','espidf','espnow','flashbdev','framebuf','freesans20','fs_driver','functools','galactic','gc','gfx_pack','gsm','hashlib','heapq','hub75','ili9341','ili9XXX','imagetools','inisetup','interstate75','io','jpegdec','json','lcd160cr','lodepng',u,'lsm6dsox','lv_colors','lv_utils','lvgl','lwip','machine','math','microWebSocket','microWebSrv','microWebTemplate',W,'mip','mip/__init__','motor','mpu6500','mpu9250','neopixel','network','ntptime','onewire','os','pcf85063a','picoexplorer','picographics','picokeypad','picoscroll','picounicorn','picowireless','pimoroni','pimoroni_bus','pimoroni_i2c','plasma','platform',w,b,'pye','qrcode','queue','random','requests','rp2','rtch','samd','select','servo','socket','ssd1306','ssh','ssl','stm','struct',t,'time','tpcalib','uarray','uasyncio/__init__','uasyncio/core','uasyncio/event','uasyncio/funcs','uasyncio/lock','uasyncio/stream','uasyncio/tasks','ubinascii','ubluetooth','ucollections','ucrypto','ucryptolib','uctypes','uerrno','uftpd','uhashlib','uheapq','uio','ujson','ulab','ulab/approx','ulab/compare','ulab/fft','ulab/filter','ulab/linalg','ulab/numerical','ulab/poly','ulab/user','ulab/vector','umachine','umqtt/__init__','umqtt/robust','umqtt/simple','uos','uplatform','uqueue','urandom','ure','urequests','urllib/urequest','uselect','usocket','ussl','ustruct','usys','utelnetserver','utime','utimeq','uwebsocket','uzlib',D,'websocket','websocket_helper','wipy','writer','xpt2046','ymodem','zephyr','zlib'];C.collect();stubber.create_all_stubs();stubber.report()
265
- if __name__=='__main__'or i():
266
- try:logging.basicConfig(level=logging.INFO)
267
- except l:pass
268
- if not g('no_auto_stubber.txt'):
262
+ def j():
263
+ try:B=bytes('abc',encoding='utf8');C=j.__module__;return A
264
+ except (k,H):return M
265
+ def main():stubber=Stubber(path=read_path());stubber.clean();stubber.modules=['WM8960','_OTA','_asyncio','_boot_fat','_coap','_espnow','_flash_control_OTA','_main_pybytes','_mqtt','_mqtt_core','_msg_handl','_onewire','_periodical_pin','_pybytes','_pybytes_ca','_pybytes_config','_pybytes_config_reader','_pybytes_connection','_pybytes_constants','_pybytes_debug','_pybytes_library','_pybytes_machine_learning','_pybytes_main','_pybytes_protocol','_pybytes_pyconfig','_pybytes_pymesh_config','_rp2','_terminal','_thread','_uasyncio','_urequest','adcfft','aioble/__init__','aioble/central','aioble/client','aioble/core','aioble/device','aioble/l2cap','aioble/peripheral','aioble/security','aioble/server','aioespnow','ak8963','apa102','apa106','array','asyncio/__init__','asyncio/core','asyncio/event','asyncio/funcs','asyncio/lock','asyncio/stream','binascii','bluetooth','breakout_as7262','breakout_bh1745','breakout_bme280','breakout_bme68x','breakout_bmp280','breakout_dotmatrix','breakout_encoder','breakout_icp10125','breakout_ioexpander','breakout_ltr559','breakout_matrix11x7','breakout_mics6814','breakout_msa301','breakout_paa5100','breakout_pmw3901','breakout_potentiometer','breakout_rgbmatrix5x5','breakout_rtc','breakout_scd41','breakout_sgp30','breakout_trackball','breakout_vl53l5cx','btree','cmath','collections','crypto','cryptolib','curl','deflate','dht','display','display_driver_utils','ds18x20','encoder','errno','esp','esp32','espidf','espnow','flashbdev','framebuf','freesans20','fs_driver','functools','galactic','gc','gfx_pack','gsm','hashlib','heapq','hub75','ili9341','ili9XXX','imagetools','inisetup','interstate75','io','jpegdec','json','lcd160cr','lodepng',v,'lsm6dsox','lv_colors','lv_utils','lvgl','lwip','machine','math','microWebSocket','microWebSrv','microWebTemplate',X,'mip','mip/__init__','motor','mpu6500','mpu9250','neopixel','network','ntptime','onewire','os','pcf85063a','picoexplorer','picographics','picokeypad','picoscroll','picounicorn','picowireless','pimoroni','pimoroni_bus','pimoroni_i2c','plasma','platform',x,c,'pye','qrcode','queue','random','requests','rp2','rtch','samd','select','servo','socket','ssd1306','ssh','ssl','stm','struct',u,'time','tpcalib','uarray','uasyncio/__init__','uasyncio/core','uasyncio/event','uasyncio/funcs','uasyncio/lock','uasyncio/stream','uasyncio/tasks','ubinascii','ubluetooth','ucollections','ucrypto','ucryptolib','uctypes','uerrno','uftpd','uhashlib','uheapq','uio','ujson','ulab','ulab/approx','ulab/compare','ulab/fft','ulab/filter','ulab/linalg','ulab/numerical','ulab/poly','ulab/user','ulab/vector','umachine','umqtt/__init__','umqtt/robust','umqtt/simple','uos','uplatform','uqueue','urandom','ure','urequests','urllib/urequest','uselect','usocket','ussl','ustruct','usys','utelnetserver','utime','utimeq','uwebsocket','uzlib',D,'websocket','websocket_helper','wipy','writer','xpt2046','ymodem','zephyr','zlib'];C.collect();stubber.create_all_stubs();stubber.report()
266
+ if __name__=='__main__'or j():
267
+ try:A1=logging.getLogger(W);logging.basicConfig(level=logging.INFO)
268
+ except m:pass
269
+ if not h('no_auto_stubber.txt'):
269
270
  try:C.threshold(4*1024);C.enable()
270
271
  except BaseException:pass
271
272
  main()
Binary file
stubber/board/info.py ADDED
@@ -0,0 +1,183 @@
1
+ import gc
2
+ import logging
3
+ import os
4
+ import sys
5
+
6
+ LIBS = [".", "/lib", "/sd/lib", "/flash/lib", "lib"]
7
+ # from ujson import dumps
8
+
9
+ try:
10
+ from machine import reset # type: ignore
11
+ except ImportError:
12
+ pass
13
+
14
+ try:
15
+ from collections import OrderedDict
16
+ except ImportError:
17
+ from ucollections import OrderedDict # type: ignore
18
+
19
+
20
+ def _info(): # type:() -> dict[str, str]
21
+ info = OrderedDict(
22
+ {
23
+ "family": sys.implementation.name,
24
+ "version": "",
25
+ "build": "",
26
+ "ver": "",
27
+ "port": "stm32"
28
+ if sys.platform.startswith("pyb")
29
+ else sys.platform, # port: esp32 / win32 / linux / stm32
30
+ "board": "GENERIC",
31
+ "cpu": "",
32
+ "mpy": "",
33
+ "arch": "",
34
+ }
35
+ )
36
+ try:
37
+ info["version"] = ".".join([str(n) for n in sys.implementation.version])
38
+ except AttributeError:
39
+ pass
40
+ try:
41
+ machine = (
42
+ sys.implementation._machine
43
+ if "_machine" in dir(sys.implementation)
44
+ else os.uname().machine
45
+ )
46
+ info["board"] = machine.strip()
47
+ info["cpu"] = machine.split("with")[1].strip()
48
+ info["mpy"] = (
49
+ sys.implementation._mpy
50
+ if "_mpy" in dir(sys.implementation)
51
+ else sys.implementation.mpy
52
+ if "mpy" in dir(sys.implementation)
53
+ else ""
54
+ )
55
+ except (AttributeError, IndexError):
56
+ pass
57
+ gc.collect()
58
+ for filename in [d + "/board_info.csv" for d in LIBS]:
59
+ print("Check file:", filename)
60
+ if file_exists(filename):
61
+ print("Found board info file: {}".format(filename))
62
+ b = info["board"].strip()
63
+ if find_board(info, b, filename):
64
+ break
65
+ if "with" in b:
66
+ b = b.split("with")[0].strip()
67
+ if find_board(info, b, filename):
68
+ break
69
+ info["board"] = "GENERIC"
70
+ break
71
+ info["board"] = info["board"].replace(" ", "_")
72
+ gc.collect()
73
+
74
+ try:
75
+ # extract build from uname().version if available
76
+ info["build"] = _build(os.uname()[3])
77
+ if not info["build"]:
78
+ # extract build from uname().release if available
79
+ info["build"] = _build(os.uname()[2])
80
+ if not info["build"] and ";" in sys.version:
81
+ # extract build from uname().release if available
82
+ info["build"] = _build(sys.version.split(";")[1])
83
+ except (AttributeError, IndexError):
84
+ pass
85
+ # avoid build hashes
86
+ if info["build"] and len(info["build"]) > 5:
87
+ info["build"] = ""
88
+
89
+ if info["version"] == "" and sys.platform not in ("unix", "win32"):
90
+ try:
91
+ u = os.uname()
92
+ info["version"] = u.release
93
+ except (IndexError, AttributeError, TypeError):
94
+ pass
95
+ # detect families
96
+ for fam_name, mod_name, mod_thing in [
97
+ ("pycopy", "pycopy", "const"),
98
+ ("pycom", "pycom", "FAT"),
99
+ ("ev3-pybricks", "pybricks.hubs", "EV3Brick"),
100
+ ]:
101
+ try:
102
+ _t = __import__(mod_name, None, None, (mod_thing))
103
+ info["family"] = fam_name
104
+ del _t
105
+ break
106
+ except (ImportError, KeyError):
107
+ pass
108
+
109
+ if info["family"] == "ev3-pybricks":
110
+ info["release"] = "2.0.0"
111
+
112
+ if info["family"] == "micropython":
113
+ if (
114
+ info["version"]
115
+ and info["version"].endswith(".0")
116
+ and info["version"]
117
+ >= "1.10.0" # versions from 1.10.0 to 1.20.0 do not have a micro .0
118
+ and info["version"] <= "1.19.9"
119
+ ):
120
+ # drop the .0 for newer releases
121
+ info["version"] = info["version"][:-2]
122
+
123
+ # spell-checker: disable
124
+ if "mpy" in info and info["mpy"]: # mpy on some v1.11+ builds
125
+ sys_mpy = int(info["mpy"])
126
+ # .mpy architecture
127
+ arch = [
128
+ None,
129
+ "x86",
130
+ "x64",
131
+ "armv6",
132
+ "armv6m",
133
+ "armv7m",
134
+ "armv7em",
135
+ "armv7emsp",
136
+ "armv7emdp",
137
+ "xtensa",
138
+ "xtensawin",
139
+ ][sys_mpy >> 10]
140
+ if arch:
141
+ info["arch"] = arch
142
+ # .mpy version.minor
143
+ info["mpy"] = "v{}.{}".format(sys_mpy & 0xFF, sys_mpy >> 8 & 3)
144
+ # simple to use version[-build] string
145
+ info["ver"] = f"v{info['version']}-{info['build']}" if info["build"] else f"v{info['version']}"
146
+
147
+ return info
148
+
149
+
150
+ def find_board(info: dict, board_descr: str, filename: str):
151
+ print("Find board '{}' in the provided board_info.csv file".format(board_descr))
152
+ with open(filename, "r") as file:
153
+ # ugly code to make testable in python and micropython
154
+ while 1:
155
+ line = file.readline()
156
+ if not line:
157
+ break
158
+ descr_, board_ = line.split(",")[0].strip(), line.split(",")[1].strip()
159
+ if descr_ == board_descr:
160
+ info["board"] = board_
161
+ return True
162
+ return False
163
+
164
+
165
+ def file_exists(filename: str):
166
+ try:
167
+ if os.stat(filename)[0] >> 14:
168
+ return True
169
+ return False
170
+ except OSError:
171
+ return False
172
+
173
+
174
+ def _build(s):
175
+ # extract a build nr from a string
176
+ if not s:
177
+ return ""
178
+ if " on " in s:
179
+ s = s.split(" on ", 1)[0]
180
+ return s.split("-")[1] if "-" in s else ""
181
+
182
+
183
+ print(f"info: {_info()}")
stubber/codemod/enrich.py CHANGED
@@ -1,5 +1,5 @@
1
1
  """
2
- Enrich firmware stubs by copying docstrings and parameter infromation from doc-stubs or python source code.
2
+ Enrich firmware stubs by copying docstrings and parameter information from doc-stubs or python source code.
3
3
  Both (.py or .pyi) files are supported.
4
4
  """
5
5
 
@@ -10,7 +10,6 @@ from libcst.codemod import CodemodContext, diff_code, exec_transform_with_pretty
10
10
  from libcst.tool import _default_config # type: ignore
11
11
  from loguru import logger as log
12
12
 
13
- # from stubber.codemod.merge_docstub import MergeCommand
14
13
  import stubber.codemod.merge_docstub as merge_docstub
15
14
  from stubber.utils.post import run_black
16
15
 
@@ -20,14 +19,16 @@ from stubber.utils.post import run_black
20
19
  #########################################################################################
21
20
 
22
21
 
23
- def enrich_file(target_path: Path, docstub_path: Path, diff: bool = False, write_back: bool = False) -> Optional[str]:
22
+ def enrich_file(
23
+ target_path: Path, docstub_path: Path, diff: bool = False, write_back: bool = False
24
+ ) -> Optional[str]:
24
25
  """
25
26
  Enrich a firmware stubs using the doc-stubs in another folder.
26
27
  Both (.py or .pyi) files are supported.
27
28
 
28
29
  Parameters:
29
30
  source_path: the path to the firmware stub to enrich
30
- docstub_path: the path to the folder containg the doc-stubs
31
+ docstub_path: the path to the folder containing the doc-stubs
31
32
  diff: if True, return the diff between the original and the enriched source file
32
33
  write_back: if True, write the enriched source file back to the source_path
33
34
 
@@ -43,10 +44,13 @@ def enrich_file(target_path: Path, docstub_path: Path, diff: bool = False, write
43
44
  for ext in [".py", ".pyi"]:
44
45
  candidates = list(docstub_path.rglob(target_path.stem + ext))
45
46
  if target_path.stem[0].lower() == "u":
46
- # also look for candidates without leading u
47
+ # also look for candidates without leading u ( usys.py <- sys.py)
48
+ candidates += list(docstub_path.rglob(target_path.stem[1:] + ext))
49
+ elif target_path.stem[0] == "_":
50
+ # also look for candidates without leading _ ( _rp2.py <- rp2.py )
47
51
  candidates += list(docstub_path.rglob(target_path.stem[1:] + ext))
48
52
  else:
49
- # also look for candidates with leading u
53
+ # also look for candidates with leading u ( sys.py <- usys.py)
50
54
  candidates += list(docstub_path.rglob("u" + target_path.stem + ext))
51
55
 
52
56
  for docstub_file in candidates:
@@ -54,18 +58,18 @@ def enrich_file(target_path: Path, docstub_path: Path, diff: bool = False, write
54
58
  break
55
59
  else:
56
60
  docstub_file = None
57
- if docstub_file is None:
61
+ if not docstub_file:
58
62
  raise FileNotFoundError(f"No doc-stub file found for {target_path}")
59
63
 
60
64
  log.debug(f"Merge {target_path} from {docstub_file}")
61
65
  # read source file
62
- oldcode = target_path.read_text()
66
+ old_code = target_path.read_text()
63
67
 
64
68
  codemod_instance = merge_docstub.MergeCommand(context, stub_file=docstub_file)
65
69
  if not (
66
- newcode := exec_transform_with_prettyprint(
70
+ new_code := exec_transform_with_prettyprint(
67
71
  codemod_instance,
68
- oldcode,
72
+ old_code,
69
73
  # include_generated=False,
70
74
  generated_code_marker=config["generated_code_marker"],
71
75
  # format_code=not args.no_format,
@@ -77,21 +81,29 @@ def enrich_file(target_path: Path, docstub_path: Path, diff: bool = False, write
77
81
  if write_back:
78
82
  log.trace(f"Write back enriched file {target_path}")
79
83
  # write updated code to file
80
- target_path.write_text(newcode, encoding="utf-8")
81
- return diff_code(oldcode, newcode, 5, filename=target_path.name) if diff else newcode
84
+ target_path.write_text(new_code, encoding="utf-8")
85
+ return diff_code(old_code, new_code, 5, filename=target_path.name) if diff else new_code
82
86
 
83
87
 
84
88
  def enrich_folder(
85
- source_folder: Path, docstub_path: Path, show_diff: bool = False, write_back: bool = False, require_docstub: bool = False
89
+ source_path: Path,
90
+ docstub_path: Path,
91
+ show_diff: bool = False,
92
+ write_back: bool = False,
93
+ require_docstub: bool = False,
86
94
  ) -> int:
87
95
  """\
88
96
  Enrich a folder with containing firmware stubs using the doc-stubs in another folder.
89
97
 
90
98
  Returns the number of files enriched.
91
99
  """
100
+ if not source_path.exists():
101
+ raise FileNotFoundError(f"Source folder {source_path} does not exist")
102
+ if not docstub_path.exists():
103
+ raise FileNotFoundError(f"Docstub folder {docstub_path} does not exist")
92
104
  count = 0
93
105
  # list all the .py and .pyi files in the source folder
94
- source_files = sorted(list(source_folder.rglob("**/*.py")) + list(source_folder.rglob("**/*.pyi")))
106
+ source_files = sorted(list(source_path.rglob("**/*.py")) + list(source_path.rglob("**/*.pyi")))
95
107
  for source_file in source_files:
96
108
  try:
97
109
  diff = enrich_file(source_file, docstub_path, diff=True, write_back=write_back)
@@ -104,7 +116,7 @@ def enrich_folder(
104
116
  if require_docstub:
105
117
  raise (FileNotFoundError(f"No doc-stub file found for {source_file}")) from e
106
118
  # run black on the destination folder
107
- # no Autoflake as this removes some relevan (unused) imports
108
- run_black(source_folder)
119
+ run_black(source_path)
120
+ # DO NOT run Autoflake as this removes some relevant (unused) imports
109
121
 
110
122
  return count
@@ -7,7 +7,7 @@ from loguru import logger as log
7
7
  from tabulate import tabulate
8
8
 
9
9
  from stubber.commands.cli import stubber_cli
10
- from stubber.publish.package import GENERIC_U
10
+ from stubber.publish.defaults import GENERIC_U
11
11
  from stubber.publish.publish import build_multiple
12
12
  from stubber.utils.config import CONFIG
13
13
 
@@ -29,7 +29,7 @@ from stubber.utils.config import CONFIG
29
29
  "-p",
30
30
  "ports",
31
31
  multiple=True,
32
- default=["auto"],
32
+ default=["all"],
33
33
  show_default=True,
34
34
  help="multiple: ",
35
35
  )
@@ -38,7 +38,7 @@ from stubber.utils.config import CONFIG
38
38
  "-b",
39
39
  "boards",
40
40
  multiple=True,
41
- default=[GENERIC_U], # or "auto" ?
41
+ default=[GENERIC_U], # or "all" ?
42
42
  show_default=True,
43
43
  help="multiple: ",
44
44
  )