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.
- micropython_stubber-1.15.1.dist-info/METADATA +244 -0
- {micropython_stubber-1.14.1.dist-info → micropython_stubber-1.15.1.dist-info}/RECORD +49 -46
- stubber/__init__.py +1 -1
- stubber/basicgit.py +27 -14
- stubber/board/createstubs.py +34 -36
- stubber/board/createstubs_db.py +35 -35
- stubber/board/createstubs_db_min.py +195 -193
- stubber/board/createstubs_db_mpy.mpy +0 -0
- stubber/board/createstubs_info.py +73 -42
- stubber/board/createstubs_lvgl.py +35 -35
- stubber/board/createstubs_lvgl_min.py +88 -87
- stubber/board/createstubs_lvgl_mpy.mpy +0 -0
- stubber/board/createstubs_mem.py +44 -40
- stubber/board/createstubs_mem_min.py +179 -174
- stubber/board/createstubs_mem_mpy.mpy +0 -0
- stubber/board/createstubs_min.py +75 -74
- stubber/board/createstubs_mpy.mpy +0 -0
- stubber/board/info.py +183 -0
- stubber/codemod/enrich.py +28 -16
- stubber/commands/build_cmd.py +3 -3
- stubber/commands/get_core_cmd.py +17 -5
- stubber/commands/get_docstubs_cmd.py +23 -8
- stubber/commands/get_frozen_cmd.py +62 -9
- stubber/commands/get_lobo_cmd.py +13 -3
- stubber/commands/merge_cmd.py +7 -4
- stubber/commands/publish_cmd.py +5 -4
- stubber/commands/stub_cmd.py +2 -1
- stubber/commands/variants_cmd.py +0 -1
- stubber/freeze/common.py +2 -2
- stubber/freeze/freeze_folder.py +1 -1
- stubber/freeze/get_frozen.py +1 -1
- stubber/minify.py +43 -28
- stubber/publish/bump.py +1 -1
- stubber/publish/candidates.py +61 -17
- stubber/publish/defaults.py +44 -0
- stubber/publish/merge_docstubs.py +19 -56
- stubber/publish/package.py +44 -37
- stubber/publish/pathnames.py +51 -0
- stubber/publish/publish.py +5 -4
- stubber/publish/stubpacker.py +55 -33
- stubber/rst/lookup.py +7 -16
- stubber/rst/reader.py +39 -8
- stubber/stubs_from_docs.py +5 -8
- stubber/utils/post.py +34 -40
- stubber/utils/repos.py +32 -17
- stubber/utils/stubmaker.py +22 -14
- micropython_stubber-1.14.1.dist-info/METADATA +0 -217
- {micropython_stubber-1.14.1.dist-info → micropython_stubber-1.15.1.dist-info}/LICENSE +0 -0
- {micropython_stubber-1.14.1.dist-info → micropython_stubber-1.15.1.dist-info}/WHEEL +0 -0
- {micropython_stubber-1.14.1.dist-info → micropython_stubber-1.15.1.dist-info}/entry_points.txt +0 -0
@@ -1,20 +1,21 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
1
|
+
u='{}/{}'
|
2
|
+
t='method'
|
3
|
+
s='function'
|
4
|
+
r='bool'
|
5
|
+
q='str'
|
6
|
+
p='float'
|
7
|
+
o='int'
|
8
|
+
n='micropython'
|
9
|
+
m='port'
|
10
|
+
l=Exception
|
11
|
+
k=NameError
|
12
|
+
j=sorted
|
13
|
+
i=NotImplementedError
|
14
14
|
A=',\n'
|
15
|
-
|
16
|
-
|
17
|
-
|
15
|
+
a='dict'
|
16
|
+
Z='list'
|
17
|
+
Y='tuple'
|
18
|
+
X='stubber'
|
18
19
|
W=open
|
19
20
|
V=repr
|
20
21
|
T='_'
|
@@ -31,37 +32,37 @@ J=print
|
|
31
32
|
I=AttributeError
|
32
33
|
H=False
|
33
34
|
G='/'
|
34
|
-
E=
|
35
|
-
D=
|
35
|
+
E='version'
|
36
|
+
D=None
|
36
37
|
F=OSError
|
37
38
|
B=''
|
38
39
|
import gc as C,os,sys
|
39
|
-
from ujson import dumps as
|
40
|
+
from ujson import dumps as b
|
40
41
|
try:from machine import reset
|
41
42
|
except P:pass
|
42
|
-
try:from collections import OrderedDict as
|
43
|
-
except P:from ucollections import OrderedDict as
|
44
|
-
__version__='v1.
|
45
|
-
u=2
|
43
|
+
try:from collections import OrderedDict as c
|
44
|
+
except P:from ucollections import OrderedDict as c
|
45
|
+
__version__='v1.15.0'
|
46
46
|
v=2
|
47
|
-
w=
|
47
|
+
w=2
|
48
|
+
x=[L,'/lib','/sd/lib','/flash/lib','lib']
|
48
49
|
from time import sleep
|
49
50
|
class Stubber:
|
50
|
-
def __init__(A,path=
|
51
|
+
def __init__(A,path=D,firmware_id=D):
|
51
52
|
B=firmware_id
|
52
53
|
try:
|
53
|
-
if os.uname().release=='1.13.0'and os.uname().version<'v1.13-103':raise
|
54
|
+
if os.uname().release=='1.13.0'and os.uname().version<'v1.13-103':raise i('MicroPython 1.13.0 cannot be stubbed')
|
54
55
|
except I:pass
|
55
|
-
A._report=[];A.info=_info();J('Port: {}'.format(A.info[
|
56
|
+
A.log=D;A.log=logging.getLogger(X);A._report=[];A.info=_info();J('Port: {}'.format(A.info[m]));J('Board: {}'.format(A.info[K]));C.collect()
|
56
57
|
if B:A._fwid=B.lower()
|
57
|
-
elif A.info[N]==
|
58
|
+
elif A.info[N]==n:A._fwid='{family}-{ver}-{port}-{board}'.format(**A.info)
|
58
59
|
else:A._fwid='{family}-{ver}-{port}'.format(**A.info)
|
59
60
|
A._start_free=C.mem_free()
|
60
61
|
if path:
|
61
62
|
if path.endswith(G):path=path[:-1]
|
62
63
|
else:path=get_root()
|
63
64
|
A.path='{}/stubs/{}'.format(path,A.flat_fwid).replace('//',G)
|
64
|
-
try:
|
65
|
+
try:d(path+G)
|
65
66
|
except F:J('error creating stub folder {}'.format(path))
|
66
67
|
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=[]
|
67
68
|
def get_obj_attributes(L,item_instance):
|
@@ -72,15 +73,15 @@ class Stubber:
|
|
72
73
|
E=getattr(H,A)
|
73
74
|
try:F=V(type(E)).split("'")[1]
|
74
75
|
except R:F=B
|
75
|
-
if F in{
|
76
|
-
elif F in{
|
76
|
+
if F in{o,p,q,r,Y,Z,a}:G=1
|
77
|
+
elif F in{s,t}:G=2
|
77
78
|
elif F in'class':G=3
|
78
79
|
else:G=4
|
79
80
|
D.append((A,V(E),V(type(E)),E,G))
|
80
81
|
except I as K:J.append("Couldn't get attribute '{}' from object '{}', Err: {}".format(A,H,K))
|
81
82
|
except MemoryError as K:sleep(1);reset()
|
82
|
-
D=
|
83
|
-
def add_modules(A,modules):A.modules=
|
83
|
+
D=j([A for A in D if not A[0].startswith('__')],key=lambda x:x[4]);C.collect();return D,J
|
84
|
+
def add_modules(A,modules):A.modules=j(set(A.modules)|set(modules))
|
84
85
|
def create_all_stubs(A):
|
85
86
|
C.collect()
|
86
87
|
for B in A.modules:A.create_one_stub(B)
|
@@ -92,17 +93,17 @@ class Stubber:
|
|
92
93
|
try:D=A.create_module_stub(B,E)
|
93
94
|
except F:return H
|
94
95
|
C.collect();return D
|
95
|
-
def create_module_stub(I,module_name,file_name=
|
96
|
-
|
97
|
-
if
|
98
|
-
else:K=
|
96
|
+
def create_module_stub(I,module_name,file_name=D):
|
97
|
+
E=file_name;A=module_name
|
98
|
+
if E is D:K=A.replace(L,T)+'.py';E=I.path+G+K
|
99
|
+
else:K=E.split(G)[-1]
|
99
100
|
if G in A:A=A.replace(G,L)
|
100
|
-
M=
|
101
|
-
try:M=__import__(A,
|
101
|
+
M=D
|
102
|
+
try:M=__import__(A,D,D,'*');Q=C.mem_free();J('Stub module: {:<25} to file: {:<70} mem:{:>5}'.format(A,K,Q))
|
102
103
|
except P:return H
|
103
|
-
|
104
|
-
with W(
|
105
|
-
I._report.append('{{"module": "{}", "file": "{}"}}'.format(A,
|
104
|
+
d(E)
|
105
|
+
with W(E,'w')as N:R=str(I.info).replace('OrderedDict(',B).replace('})','}');U='"""\nModule: \'{0}\' on {1}\n"""\n# MCU: {2}\n# Stubber: {3}\n'.format(A,I._fwid,R,__version__);N.write(U);N.write('from typing import Any\nfrom _typeshed import Incomplete\n\n');I.write_object_stub(N,M,A,B)
|
106
|
+
I._report.append('{{"module": "{}", "file": "{}"}}'.format(A,E.replace('\\',G)))
|
106
107
|
if A not in{'os','sys','logging','gc'}:
|
107
108
|
try:del M
|
108
109
|
except (F,S):pass
|
@@ -117,23 +118,23 @@ class Stubber:
|
|
117
118
|
for (E,K,G,T,f) in R:
|
118
119
|
if E in['classmethod','staticmethod','BaseException',O]:continue
|
119
120
|
if E[0].isdigit():continue
|
120
|
-
if G=="<class 'type'>"and M(D)<=
|
121
|
+
if G=="<class 'type'>"and M(D)<=w*4:
|
121
122
|
U=B;V=E.endswith(O)or E.endswith('Error')or E in['KeyboardInterrupt','StopIteration','SystemExit']
|
122
123
|
if V:U=O
|
123
124
|
A='\n{}class {}({}):\n'.format(D,E,U)
|
124
125
|
if V:A+=D+' ...\n';H.write(A);return
|
125
126
|
H.write(A);L.write_object_stub(H,T,'{0}.{1}'.format(obj_name,E),D+' ',Q+1);A=D+' def __init__(self, *argv, **kwargs) -> None:\n';A+=D+' ...\n\n';H.write(A)
|
126
|
-
elif any((A in G for A in[s,
|
127
|
-
W=b;
|
128
|
-
if Q>0:
|
127
|
+
elif any((A in G for A in[t,s,'closure'])):
|
128
|
+
W=b;X=B
|
129
|
+
if Q>0:X='self, '
|
129
130
|
if c in G or c in K:A='{}@classmethod\n'.format(D)+'{}def {}(cls, *args, **kwargs) -> {}:\n'.format(D,E,W)
|
130
|
-
else:A='{}def {}({}*args, **kwargs) -> {}:\n'.format(D,E,
|
131
|
+
else:A='{}def {}({}*args, **kwargs) -> {}:\n'.format(D,E,X,W)
|
131
132
|
A+=D+' ...\n\n';H.write(A)
|
132
133
|
elif G=="<class 'module'>":0
|
133
134
|
elif G.startswith("<class '"):
|
134
135
|
I=G[8:-2];A=B
|
135
|
-
if I in[
|
136
|
-
elif I in[Z,Y
|
136
|
+
if I in[q,o,p,r,'bytearray','bytes']:A=d.format(D,E,K,I)
|
137
|
+
elif I in[a,Z,Y]:e={a:'{}',Z:'[]',Y:'()'};A=d.format(D,E,e[I],I)
|
137
138
|
else:
|
138
139
|
if I not in['object','set','frozenset']:I=b
|
139
140
|
A='{0}{1} : {2} ## {3} = {4}\n'.format(D,E,I,G,K)
|
@@ -141,25 +142,25 @@ class Stubber:
|
|
141
142
|
else:H.write("# all other, type = '{0}'\n".format(G));H.write(D+E+' # type: Incomplete\n')
|
142
143
|
del R;del N
|
143
144
|
try:del E,K,G,T
|
144
|
-
except (F,S,
|
145
|
+
except (F,S,k):pass
|
145
146
|
@property
|
146
147
|
def flat_fwid(self):
|
147
148
|
A=self._fwid;B=' .()/\\:$'
|
148
149
|
for C in B:A=A.replace(C,T)
|
149
150
|
return A
|
150
|
-
def clean(B,path=
|
151
|
-
if path is
|
151
|
+
def clean(B,path=D):
|
152
|
+
if path is D:path=B.path
|
152
153
|
J('Clean/remove files in folder: {}'.format(path))
|
153
154
|
try:os.stat(path);C=os.listdir(path)
|
154
155
|
except (F,I):return
|
155
|
-
for
|
156
|
-
A=
|
156
|
+
for E in C:
|
157
|
+
A=u.format(path,E)
|
157
158
|
try:os.remove(A)
|
158
159
|
except F:
|
159
160
|
try:B.clean(A);os.rmdir(A)
|
160
161
|
except F:pass
|
161
162
|
def report(A,filename='modules.json'):
|
162
|
-
J('Created stubs for {} modules on board {}\nPath: {}'.format(M(A._report),A._fwid,A.path));E=
|
163
|
+
J('Created stubs for {} modules on board {}\nPath: {}'.format(M(A._report),A._fwid,A.path));E=u.format(A.path,filename);C.collect()
|
163
164
|
try:
|
164
165
|
with W(E,'w')as B:
|
165
166
|
A.write_json_header(B);D=O
|
@@ -167,12 +168,12 @@ class Stubber:
|
|
167
168
|
A.write_json_end(B)
|
168
169
|
I=A._start_free-C.mem_free()
|
169
170
|
except F:J('Failed to create the report.')
|
170
|
-
def write_json_header(C,f):B='firmware';f.write('{');f.write(
|
171
|
+
def write_json_header(C,f):B='firmware';f.write('{');f.write(b({B:C.info})[1:-1]);f.write(A);f.write(b({X:{E:__version__},'stubtype':B})[1:-1]);f.write(A);f.write('"modules" :[\n')
|
171
172
|
def write_json_node(B,f,n,first):
|
172
173
|
if not first:f.write(A)
|
173
174
|
f.write(n)
|
174
175
|
def write_json_end(A,f):f.write('\n]}')
|
175
|
-
def
|
176
|
+
def d(path):
|
176
177
|
A=C=0
|
177
178
|
while A!=-1:
|
178
179
|
A=path.find(G,C)
|
@@ -180,7 +181,7 @@ def c(path):
|
|
180
181
|
B=path[0]if A==0 else path[:A]
|
181
182
|
try:H=os.stat(B)
|
182
183
|
except F as D:
|
183
|
-
if D.args[0]==
|
184
|
+
if D.args[0]==v:
|
184
185
|
try:os.mkdir(B)
|
185
186
|
except F as E:J('failed to create folder {}'.format(B));raise E
|
186
187
|
C=A+1
|
@@ -190,20 +191,20 @@ def U(s):
|
|
190
191
|
if A in s:s=s.split(A,1)[0]
|
191
192
|
return s.split('-')[1]if'-'in s else B
|
192
193
|
def _info():
|
193
|
-
h='ev3-pybricks';g='pycom';
|
194
|
-
try:A[
|
194
|
+
h='ev3-pybricks';g='pycom';d='pycopy';b='GENERIC';a='arch';Z='cpu';Y='ver';V='with';G='mpy';F='build';A=c({N:sys.implementation.name,E:B,F:B,Y:B,m:'stm32'if sys.platform.startswith('pyb')else sys.platform,K:b,Z:B,G:B,a:B})
|
195
|
+
try:A[E]=L.join([str(A)for A in sys.implementation.version])
|
195
196
|
except I:pass
|
196
197
|
try:W=sys.implementation._machine if'_machine'in Q(sys.implementation)else os.uname().machine;A[K]=W.strip();A[Z]=W.split(V)[1].strip();A[G]=sys.implementation._mpy if'_mpy'in Q(sys.implementation)else sys.implementation.mpy if G in Q(sys.implementation)else B
|
197
198
|
except (I,R):pass
|
198
199
|
C.collect()
|
199
|
-
for J in [A+'/board_info.csv'for A in
|
200
|
-
if
|
200
|
+
for J in [A+'/board_info.csv'for A in x]:
|
201
|
+
if f(J):
|
201
202
|
H=A[K].strip()
|
202
|
-
if
|
203
|
+
if e(A,H,J):break
|
203
204
|
if V in H:
|
204
205
|
H=H.split(V)[0].strip()
|
205
|
-
if
|
206
|
-
A[K]=
|
206
|
+
if e(A,H,J):break
|
207
|
+
A[K]=b
|
207
208
|
A[K]=A[K].replace(' ',T);C.collect()
|
208
209
|
try:
|
209
210
|
A[F]=U(os.uname()[3])
|
@@ -211,21 +212,21 @@ def _info():
|
|
211
212
|
if not A[F]and';'in sys.version:A[F]=U(sys.version.split(';')[1])
|
212
213
|
except (I,R):pass
|
213
214
|
if A[F]and M(A[F])>5:A[F]=B
|
214
|
-
if A[
|
215
|
-
try:i=os.uname();A[
|
215
|
+
if A[E]==B and sys.platform not in('unix','win32'):
|
216
|
+
try:i=os.uname();A[E]=i.release
|
216
217
|
except (R,I,TypeError):pass
|
217
|
-
for (j,k,
|
218
|
-
try:o=__import__(k,
|
218
|
+
for (j,k,l) in [(d,d,'const'),(g,g,'FAT'),(h,'pybricks.hubs','EV3Brick')]:
|
219
|
+
try:o=__import__(k,D,D,l);A[N]=j;del o;break
|
219
220
|
except (P,S):pass
|
220
221
|
if A[N]==h:A['release']='2.0.0'
|
221
|
-
if A[N]==
|
222
|
-
if A[
|
222
|
+
if A[N]==n:
|
223
|
+
if A[E]and A[E].endswith('.0')and A[E]>='1.10.0'and A[E]<='1.19.9':A[E]=A[E][:-2]
|
223
224
|
if G in A and A[G]:
|
224
|
-
O=int(A[G]);X=[
|
225
|
+
O=int(A[G]);X=[D,'x86','x64','armv6','armv6m','armv7m','armv7em','armv7emsp','armv7emdp','xtensa','xtensawin'][O>>10]
|
225
226
|
if X:A[a]=X
|
226
227
|
A[G]='v{}.{}'.format(O&255,O>>8&3)
|
227
|
-
A[Y]=f"v{A[
|
228
|
-
def
|
228
|
+
A[Y]=f"v{A[E]}-{A[F]}"if A[F]else f"v{A[E]}";return A
|
229
|
+
def e(info,board_descr,filename):
|
229
230
|
with W(filename,'r')as B:
|
230
231
|
while 1:
|
231
232
|
A=B.readline()
|
@@ -241,36 +242,36 @@ def get_root():
|
|
241
242
|
try:C=os.stat(B);break
|
242
243
|
except F:continue
|
243
244
|
return B
|
244
|
-
def
|
245
|
+
def f(filename):
|
245
246
|
try:
|
246
247
|
if os.stat(filename)[0]>>14:return O
|
247
248
|
return H
|
248
249
|
except F:return H
|
249
|
-
def
|
250
|
+
def g():sys.exit(1)
|
250
251
|
def read_path():
|
251
252
|
path=B
|
252
253
|
if M(sys.argv)==3:
|
253
254
|
A=sys.argv[1].lower()
|
254
255
|
if A in('--path','-p'):path=sys.argv[2]
|
255
|
-
else:
|
256
|
-
elif M(sys.argv)==2:
|
256
|
+
else:g()
|
257
|
+
elif M(sys.argv)==2:g()
|
257
258
|
return path
|
258
|
-
def
|
259
|
-
try:A=bytes('abc',encoding='utf8');B=
|
260
|
-
except (
|
259
|
+
def h():
|
260
|
+
try:A=bytes('abc',encoding='utf8');B=h.__module__;return H
|
261
|
+
except (i,I):return O
|
261
262
|
def main():
|
262
263
|
D='lvgl'
|
263
264
|
try:import lvgl as A
|
264
|
-
except
|
265
|
+
except l:return
|
265
266
|
B=D
|
266
267
|
try:B='lvgl-{0}_{1}_{2}-{3}-{4}'.format(A.version_major(),A.version_minor(),A.version_patch(),A.version_info(),sys.platform)
|
267
|
-
except
|
268
|
+
except l:B='lvgl-{0}_{1}_{2}_{3}-{4}'.format(8,1,0,'dev',sys.platform)
|
268
269
|
finally:stubber=Stubber(firmware_id=B)
|
269
270
|
stubber.clean();stubber.modules=['io','lodepng','rtch',D];C.collect();stubber.create_all_stubs();stubber.report()
|
270
|
-
if __name__=='__main__'or
|
271
|
-
try:logging.basicConfig(level=logging.INFO)
|
272
|
-
except
|
273
|
-
if not
|
271
|
+
if __name__=='__main__'or h():
|
272
|
+
try:y=logging.getLogger(X);logging.basicConfig(level=logging.INFO)
|
273
|
+
except k:pass
|
274
|
+
if not f('no_auto_stubber.txt'):
|
274
275
|
try:C.threshold(4*1024);C.enable()
|
275
276
|
except BaseException:pass
|
276
277
|
main()
|
Binary file
|
stubber/board/createstubs_mem.py
CHANGED
@@ -9,7 +9,7 @@
|
|
9
9
|
- cross compilation, using mpy-cross,
|
10
10
|
to avoid the compilation step on the micropython device
|
11
11
|
|
12
|
-
This variant was generated from createstubs.py by micropython-stubber v1.
|
12
|
+
This variant was generated from createstubs.py by micropython-stubber v1.15.1
|
13
13
|
"""
|
14
14
|
# Copyright (c) 2019-2023 Jos Verlinde
|
15
15
|
# pylint: disable= invalid-name, missing-function-docstring, import-outside-toplevel, logging-not-lazy
|
@@ -30,7 +30,7 @@ try:
|
|
30
30
|
except ImportError:
|
31
31
|
from ucollections import OrderedDict # type: ignore
|
32
32
|
|
33
|
-
__version__ = "v1.
|
33
|
+
__version__ = "v1.15.1"
|
34
34
|
ENOENT = 2
|
35
35
|
_MAX_CLASS_LEVEL = 2 # Max class nesting
|
36
36
|
LIBS = [".", "/lib", "/sd/lib", "/flash/lib", "lib"]
|
@@ -46,12 +46,12 @@ class Stubber:
|
|
46
46
|
raise NotImplementedError("MicroPython 1.13.0 cannot be stubbed")
|
47
47
|
except AttributeError:
|
48
48
|
pass
|
49
|
-
|
50
|
-
self.
|
49
|
+
self.log = None
|
50
|
+
self.log = logging.getLogger("stubber")
|
51
51
|
self._report = [] # type: list[str]
|
52
52
|
self.info = _info()
|
53
|
-
self.
|
54
|
-
self.
|
53
|
+
self.log.info("Port: {}".format(self.info["port"]))
|
54
|
+
self.log.info("Board: {}".format(self.info["board"]))
|
55
55
|
gc.collect()
|
56
56
|
if firmware_id:
|
57
57
|
self._fwid = firmware_id.lower()
|
@@ -69,11 +69,11 @@ class Stubber:
|
|
69
69
|
path = get_root()
|
70
70
|
|
71
71
|
self.path = "{}/stubs/{}".format(path, self.flat_fwid).replace("//", "/")
|
72
|
-
self.
|
72
|
+
self.log.debug(self.path)
|
73
73
|
try:
|
74
74
|
ensure_folder(path + "/")
|
75
75
|
except OSError:
|
76
|
-
self.
|
76
|
+
self.log.error("error creating stub folder {}".format(path))
|
77
77
|
self.problematic = [
|
78
78
|
"upip",
|
79
79
|
"upysh",
|
@@ -98,11 +98,11 @@ class Stubber:
|
|
98
98
|
# name_, repr_(value), type as text, item_instance
|
99
99
|
_result = []
|
100
100
|
_errors = []
|
101
|
-
self.
|
101
|
+
self.log.debug("get attributes {} {}".format(repr(item_instance), item_instance))
|
102
102
|
for name in dir(item_instance):
|
103
103
|
if name.startswith("_") and not name in self.modules:
|
104
104
|
continue
|
105
|
-
self.
|
105
|
+
self.log.debug("get attribute {}".format(name))
|
106
106
|
try:
|
107
107
|
val = getattr(item_instance, name)
|
108
108
|
# name , item_repr(value) , type as text, item_instance, order
|
@@ -138,18 +138,18 @@ class Stubber:
|
|
138
138
|
|
139
139
|
def create_all_stubs(self):
|
140
140
|
"Create stubs for all configured modules"
|
141
|
-
self.
|
141
|
+
self.log.info("Start micropython-stubber v{} on {}".format(__version__, self._fwid))
|
142
142
|
gc.collect()
|
143
143
|
for module_name in self.modules:
|
144
144
|
self.create_one_stub(module_name)
|
145
|
-
self.
|
145
|
+
self.log.info("Finally done")
|
146
146
|
|
147
147
|
def create_one_stub(self, module_name: str):
|
148
148
|
if module_name in self.problematic:
|
149
|
-
self.
|
149
|
+
self.log.warning("Skip module: {:<25} : Known problematic".format(module_name))
|
150
150
|
return False
|
151
151
|
if module_name in self.excluded:
|
152
|
-
self.
|
152
|
+
self.log.warning("Skip module: {:<25} : Excluded".format(module_name))
|
153
153
|
return False
|
154
154
|
|
155
155
|
file_name = "{}/{}.py".format(self.path, module_name.replace(".", "/"))
|
@@ -184,10 +184,10 @@ class Stubber:
|
|
184
184
|
try:
|
185
185
|
new_module = __import__(module_name, None, None, ("*"))
|
186
186
|
m1 = gc.mem_free() # type: ignore
|
187
|
-
self.
|
187
|
+
self.log.info("Stub module: {:<25} to file: {:<70} mem:{:>5}".format(module_name, fname, m1))
|
188
188
|
|
189
189
|
except ImportError:
|
190
|
-
self.
|
190
|
+
self.log.warning("Skip module: {:<25} {:<79}".format(module_name, "Module not found."))
|
191
191
|
return False
|
192
192
|
|
193
193
|
# Start a new file
|
@@ -207,11 +207,11 @@ class Stubber:
|
|
207
207
|
try:
|
208
208
|
del new_module
|
209
209
|
except (OSError, KeyError): # lgtm [py/unreachable-statement]
|
210
|
-
self.
|
210
|
+
self.log.warning("could not del new_module")
|
211
211
|
try:
|
212
212
|
del sys.modules[module_name]
|
213
213
|
except KeyError:
|
214
|
-
self.
|
214
|
+
self.log.debug("could not del sys.modules[{}]".format(module_name))
|
215
215
|
gc.collect()
|
216
216
|
return True
|
217
217
|
|
@@ -219,14 +219,14 @@ class Stubber:
|
|
219
219
|
"Write a module/object stub to an open file. Can be called recursive."
|
220
220
|
gc.collect()
|
221
221
|
if object_expr in self.problematic:
|
222
|
-
self.
|
222
|
+
self.log.warning("SKIPPING problematic module:{}".format(object_expr))
|
223
223
|
return
|
224
224
|
|
225
|
-
# self.
|
225
|
+
# self.log.debug("DUMP : {}".format(object_expr))
|
226
226
|
items, errors = self.get_obj_attributes(object_expr)
|
227
227
|
|
228
228
|
if errors:
|
229
|
-
self.
|
229
|
+
self.log.error(errors)
|
230
230
|
|
231
231
|
for item_name, item_repr, item_type_txt, item_instance, _ in items:
|
232
232
|
# name_, repr_(value), type as text, item_instance, order
|
@@ -234,11 +234,11 @@ class Stubber:
|
|
234
234
|
# do not create stubs for these primitives
|
235
235
|
continue
|
236
236
|
if item_name[0].isdigit():
|
237
|
-
self.
|
237
|
+
self.log.warning("NameError: invalid name {}".format(item_name))
|
238
238
|
continue
|
239
239
|
# Class expansion only on first 3 levels (bit of a hack)
|
240
240
|
if item_type_txt == "<class 'type'>" and len(indent) <= _MAX_CLASS_LEVEL * 4:
|
241
|
-
self.
|
241
|
+
self.log.debug("{0}class {1}:".format(indent, item_name))
|
242
242
|
superclass = ""
|
243
243
|
is_exception = (
|
244
244
|
item_name.endswith("Exception")
|
@@ -261,7 +261,7 @@ class Stubber:
|
|
261
261
|
# write classdef
|
262
262
|
fp.write(s)
|
263
263
|
# first write the class literals and methods
|
264
|
-
self.
|
264
|
+
self.log.debug("# recursion over class {0}".format(item_name))
|
265
265
|
self.write_object_stub(
|
266
266
|
fp,
|
267
267
|
item_instance,
|
@@ -275,7 +275,7 @@ class Stubber:
|
|
275
275
|
s += indent + " ...\n\n"
|
276
276
|
fp.write(s)
|
277
277
|
elif any(word in item_type_txt for word in ["method", "function", "closure"]):
|
278
|
-
self.
|
278
|
+
self.log.debug("# def {1} function/method/closure, type = '{0}'".format(item_type_txt, item_name))
|
279
279
|
# module Function or class method
|
280
280
|
# will accept any number of params
|
281
281
|
# return type Any/Incomplete
|
@@ -291,7 +291,7 @@ class Stubber:
|
|
291
291
|
s = "{}def {}({}*args, **kwargs) -> {}:\n".format(indent, item_name, first, ret)
|
292
292
|
s += indent + " ...\n\n"
|
293
293
|
fp.write(s)
|
294
|
-
self.
|
294
|
+
self.log.debug("\n" + s)
|
295
295
|
elif item_type_txt == "<class 'module'>":
|
296
296
|
# Skip imported modules
|
297
297
|
# fp.write("# import {}\n".format(item_name))
|
@@ -317,10 +317,10 @@ class Stubber:
|
|
317
317
|
# Requires Python 3.6 syntax, which is OK for the stubs/pyi
|
318
318
|
s = "{0}{1} : {2} ## {3} = {4}\n".format(indent, item_name, t, item_type_txt, item_repr)
|
319
319
|
fp.write(s)
|
320
|
-
self.
|
320
|
+
self.log.debug("\n" + s)
|
321
321
|
else:
|
322
322
|
# keep only the name
|
323
|
-
self.
|
323
|
+
self.log.debug("# all other, type = '{0}'".format(item_type_txt))
|
324
324
|
fp.write("# all other, type = '{0}'\n".format(item_type_txt))
|
325
325
|
|
326
326
|
fp.write(indent + item_name + " # type: Incomplete\n")
|
@@ -346,7 +346,7 @@ class Stubber:
|
|
346
346
|
"Remove all files from the stub folder"
|
347
347
|
if path is None:
|
348
348
|
path = self.path
|
349
|
-
self.
|
349
|
+
self.log.info("Clean/remove files in folder: {}".format(path))
|
350
350
|
try:
|
351
351
|
os.stat(path) # TEMP workaround mpremote listdir bug -
|
352
352
|
items = os.listdir(path)
|
@@ -366,9 +366,9 @@ class Stubber:
|
|
366
366
|
|
367
367
|
def report(self, filename: str = "modules.json"):
|
368
368
|
"create json with list of exported modules"
|
369
|
-
self.
|
369
|
+
self.log.info("Created stubs for {} modules on board {}\nPath: {}".format(len(self._report), self._fwid, self.path))
|
370
370
|
f_name = "{}/{}".format(self.path, filename)
|
371
|
-
self.
|
371
|
+
self.log.info("Report file: {}".format(f_name))
|
372
372
|
gc.collect()
|
373
373
|
try:
|
374
374
|
# write json by node to reduce memory requirements
|
@@ -380,9 +380,9 @@ class Stubber:
|
|
380
380
|
first = False
|
381
381
|
self.write_json_end(f)
|
382
382
|
used = self._start_free - gc.mem_free() # type: ignore
|
383
|
-
self.
|
383
|
+
self.log.info("Memory used: {0} Kb".format(used // 1024))
|
384
384
|
except OSError:
|
385
|
-
self.
|
385
|
+
self.log.error("Failed to create the report.")
|
386
386
|
|
387
387
|
def write_json_header(self, f):
|
388
388
|
f.write("{")
|
@@ -417,7 +417,7 @@ def ensure_folder(path: str):
|
|
417
417
|
try:
|
418
418
|
os.mkdir(p)
|
419
419
|
except OSError as e2:
|
420
|
-
|
420
|
+
log.error("failed to create folder {}".format(p))
|
421
421
|
raise e2
|
422
422
|
# next level deep
|
423
423
|
start = i + 1
|
@@ -647,19 +647,23 @@ def main():
|
|
647
647
|
stubber.modules = [] # avoid duplicates
|
648
648
|
for p in LIBS:
|
649
649
|
try:
|
650
|
+
_1 = gc.mem_free() # type: ignore
|
650
651
|
with open(p + "/modulelist.txt") as f:
|
651
|
-
print("
|
652
|
-
|
652
|
+
print("Debug: List of modules: " + p + "/modulelist.txt")
|
653
|
+
line = f.readline()
|
654
|
+
while line:
|
653
655
|
line = line.strip()
|
654
656
|
if len(line) > 0 and line[0] != "#":
|
655
657
|
stubber.modules.append(line)
|
656
|
-
|
658
|
+
line = f.readline()
|
659
|
+
gc.collect() # type: ignore
|
660
|
+
print("Debug: Used memory to load modulelist.txt: " + str(_1 - gc.mem_free()) + " bytes") # type: ignore
|
657
661
|
break
|
658
|
-
except
|
662
|
+
except Exception:
|
659
663
|
pass
|
660
664
|
if not stubber.modules:
|
661
665
|
stubber.modules = ["micropython"]
|
662
|
-
|
666
|
+
print("Could not find modulelist.txt, using default modules")
|
663
667
|
|
664
668
|
gc.collect()
|
665
669
|
|
@@ -669,7 +673,7 @@ def main():
|
|
669
673
|
|
670
674
|
if __name__ == "__main__" or is_micropython():
|
671
675
|
try:
|
672
|
-
|
676
|
+
log = logging.getLogger("stubber")
|
673
677
|
logging.basicConfig(level=logging.INFO)
|
674
678
|
# logging.basicConfig(level=logging.DEBUG)
|
675
679
|
except NameError:
|