retracesoftware-proxy 0.1.3__py3-none-any.whl → 0.1.6__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.
@@ -68,7 +68,6 @@
68
68
  ],
69
69
 
70
70
  "preload": [
71
-
72
71
  ],
73
72
 
74
73
  "predicates": {
@@ -436,6 +436,9 @@ class Patcher:
436
436
 
437
437
  def __call__(self, module):
438
438
 
439
+ # if module.__name__ == 'locale':
440
+ # utils.sigtrap(None)
441
+
439
442
  if not hasattr(module, '__retrace__'):
440
443
  configs = list(self.configs(module))
441
444
 
@@ -484,6 +487,10 @@ def install(mode):
484
487
  else:
485
488
  raise Exception(f'mode: {mode} unsupported')
486
489
 
490
+ importlib.import_module('locale')
491
+ importlib.import_module('calendar')
492
+ importlib.import_module('_strptime')
493
+
487
494
  config = load_config('config.json')
488
495
 
489
496
  states = [x for x in config['states'] if isinstance(x, str)]
@@ -514,12 +521,15 @@ def install(mode):
514
521
 
515
522
  def at_exit(): thread_state.value = 'disabled'
516
523
 
524
+ # print(f'MODULES: {list(sys.modules.keys())}')
525
+
517
526
  with thread_state.select('internal'):
518
527
 
519
528
  atexit.register(lambda: at_exit)
520
529
 
521
- for module in sys.modules.values():
522
- patcher(module)
530
+ for key, module in sys.modules.items():
531
+ if not key.startswith('retracesoftware'):
532
+ patcher(module)
523
533
 
524
534
  for library in config.get('preload', []):
525
535
  importlib.import_module(library)
@@ -56,10 +56,14 @@ class Tracer:
56
56
  if name in self.config:
57
57
  self.writer(name, message)
58
58
 
59
+ def stacktrace(self):
60
+ self.writer('stacktrace', utils.stacktrace())
61
+
59
62
  def __call__(self, name, func = None):
60
63
  if name in self.config:
61
64
  if name.endswith('.call'):
62
65
  def write_call(*args, **kwargs):
66
+ # self.stacktrace()
63
67
  self.writer(name, args[0].__name__, args[1:], kwargs)
64
68
 
65
69
  return functional.firstof(write_call, func) if func else write_call
@@ -55,6 +55,9 @@ class ProxySystem:
55
55
  def on_ext_error(self, err_type, err_value, err_traceback):
56
56
  pass
57
57
 
58
+ # def stacktrace(self):
59
+ # self.tracer.stacktrace()
60
+
58
61
  def __init__(self, thread_state, immutable_types, tracer):
59
62
 
60
63
  self.thread_state = thread_state
@@ -78,7 +81,7 @@ class ProxySystem:
78
81
  on_result = tracer('proxy.int.result'),
79
82
  on_error = tracer('proxy.int.error'),
80
83
  )
81
-
84
+
82
85
  ext_spec = SimpleNamespace(
83
86
  apply = thread_state.wrap('external', functional.apply),
84
87
  proxy = proxyfactory(thread_state.wrap('disabled', self.dynamic_ext_proxytype)),
@@ -92,9 +95,9 @@ class ProxySystem:
92
95
  def gateway(name, internal = functional.apply, external = functional.apply):
93
96
  default = tracer(name, unproxy_execute)
94
97
  return thread_state.dispatch(default, internal = internal, external = external)
95
-
96
- self.ext_handler = self.wrap_int_to_ext(int2ext)
97
- self.int_handler = self.wrap_ext_to_int(ext2int)
98
+
99
+ self.ext_handler = self.wrap_int_to_ext(int2ext)
100
+ self.int_handler = self.wrap_ext_to_int(ext2int)
98
101
 
99
102
  self.ext_dispatch = gateway('proxy.int.disabled.event', internal = self.ext_handler)
100
103
  self.int_dispatch = gateway('proxy.ext.disabled.event', external = self.int_handler)
@@ -145,17 +148,21 @@ class ProxySystem:
145
148
  if utils.is_extendable(cls):
146
149
  return self.extend_type(cls)
147
150
  else:
148
- return instantiable_dynamic_proxytype(
149
- handler = self.ext_dispatch,
150
- cls = cls,
151
- thread_state = self.thread_state,
152
- create_stub = self.create_stub())
153
-
151
+ return self.proxy_function(cls)
152
+
153
+ # return instantiable_dynamic_proxytype(
154
+ # handler = self.ext_dispatch,
155
+ # cls = cls,
156
+ # thread_state = self.thread_state,
157
+ # create_stub = self.create_stub())
158
+
159
+ def basetype(self, cls):
160
+ return cls
161
+
154
162
  def extend_type(self, cls):
155
-
156
163
  extended = extending_proxytype(
157
164
  cls = cls,
158
- base = Stub if self.create_stub() else cls,
165
+ base = self.basetype(cls),
159
166
  thread_state = self.thread_state,
160
167
  ext_handler = self.ext_dispatch,
161
168
  int_handler = self.int_dispatch,
@@ -168,7 +175,7 @@ class ProxySystem:
168
175
  def function_target(self, obj): return obj
169
176
 
170
177
  def proxy_function(self, obj):
171
- return utils.wrapped_function(handler = self.ext_handler, target = obj)
178
+ return utils.wrapped_function(handler = self.ext_handler, target = obj)
172
179
 
173
180
  def __call__(self, obj):
174
181
  assert not isinstance(obj, BaseException)
@@ -228,16 +228,17 @@ def dynamic_proxytype(handler, cls):
228
228
 
229
229
  target_type = functional.sequence(utils.unwrap, functional.typeof)
230
230
  spec['__class__'] = property(target_type)
231
-
232
- name = f'retrace.proxied.{cls.__module__}.{cls.__name__}'
231
+ spec['__name__'] = cls.__name__
232
+ spec['__module__'] = cls.__module__
233
+ # name = f'retrace.proxied.{cls.__module__}.{cls.__name__}'
233
234
 
234
- return type(name, (utils.Wrapped, DynamicProxy), spec)
235
+ return type(cls.__name__, (utils.Wrapped, DynamicProxy), spec)
235
236
 
236
237
  def dynamic_from_extended(cls):
237
238
 
238
239
  base = cls.__base__
239
240
 
240
- name = f'retrace.proxied.{base.__module__}.{base.__name__}'
241
+ name = f'retrace.proxied1.{base.__module__}.{base.__name__}'
241
242
 
242
243
  spec = dict(cls.__dict__)
243
244
 
@@ -313,7 +314,7 @@ def create_unproxied_type(cls):
313
314
 
314
315
  bases = tuple(map(unproxy_type, cls.__bases__))
315
316
  slots = dict(cls.__dict__)
316
- del slots['__init_subclass__']
317
+ # del slots['__init_subclass__']
317
318
  return type(cls.__name__, tuple(bases), slots)
318
319
 
319
320
  def extending_proxytype(cls, base, thread_state, ext_handler, int_handler, on_subclass_new):
@@ -323,7 +324,7 @@ def extending_proxytype(cls, base, thread_state, ext_handler, int_handler, on_su
323
324
  assert not issubclass(cls, ExtendingProxy)
324
325
 
325
326
  def init_subclass(subclass, **kwargs):
326
- print(f'In init_subclass: {subclass} {kwargs}')
327
+ # print(f'In init_subclass: {subclass} {subclass.__mro__} {kwargs}')
327
328
  unproxied = create_unproxied_type(subclass)
328
329
  subclass.__retrace_unproxied__ = unproxied
329
330
 
@@ -347,7 +348,7 @@ def extending_proxytype(cls, base, thread_state, ext_handler, int_handler, on_su
347
348
  for name,value in superdict(cls).items():
348
349
  if name not in blacklist:
349
350
  if is_method_descriptor(value):
350
- slots[name] = wrap(getattr(cls, name))
351
+ slots[name] = wrap(getattr(base, name))
351
352
  elif is_descriptor(value):
352
353
  descriptors.append(name)
353
354
 
@@ -362,11 +363,13 @@ def extending_proxytype(cls, base, thread_state, ext_handler, int_handler, on_su
362
363
  def unproxied__new__(subclass, *args, **kwargs):
363
364
  return subclass.__retrace_unproxied__(*args, **kwargs)
364
365
 
366
+ assert callable(base.__new__)
367
+
365
368
  extended.__new__ = thread_state.dispatch(unproxied__new__, internal = base.__new__)
366
369
 
367
370
  assert not issubclass(extended.__retrace_unproxied__, ExtendingProxy)
368
371
  assert extended.__dict__['__retrace_unproxied__'] is extended.__retrace_unproxied__
369
- print(f'FOO: {extended} {id(extended)} {id(extended.__retrace_unproxied__)}')
372
+ # print(f'FOO: {extended} {id(extended)} {id(extended.__retrace_unproxied__)}')
370
373
  # breakpoint()
371
374
 
372
375
  return extended
@@ -116,10 +116,13 @@ class RecordProxySystem(ProxySystem):
116
116
 
117
117
  self.on_int_call = functional.mapargs(transform = serialize, function = self.writer.handle('CALL'))
118
118
 
119
- self.on_ext_result = functional.if_then_else(
120
- functional.isinstanceof(str),
121
- self.writer.handle('RESULT'),
122
- functional.sequence(serialize, self.writer))
119
+ # self.on_ext_result = functional.if_then_else(
120
+ # functional.isinstanceof(str),
121
+ # self.writer.handle('RESULT'),
122
+ # functional.sequence(serialize, self.writer))
123
+
124
+ self.on_ext_result = functional.sequence(serialize,
125
+ self.writer.handle('RESULT'))
123
126
 
124
127
  self.on_ext_error = write_error
125
128
 
@@ -131,23 +134,25 @@ class RecordProxySystem(ProxySystem):
131
134
 
132
135
  proxytype = super().dynamic_ext_proxytype(cls)
133
136
 
134
- blacklist = ['__class__', '__dict__', '__module__', '__doc__']
137
+ ref = self.writer.handle(StubRef(proxytype))
138
+
139
+ # blacklist = ['__class__', '__dict__', '__module__', '__doc__']
135
140
 
136
- methods = []
137
- members = []
141
+ # methods = []
142
+ # members = []
138
143
 
139
- for key,value in proxytype.__dict__.items():
140
- if key not in blacklist:
141
- if utils.is_method_descriptor(value):
142
- methods.append(key)
143
- elif not key.startswith("__retrace"):
144
- members.append(key)
144
+ # for key,value in proxytype.__dict__.items():
145
+ # if key not in blacklist:
146
+ # if utils.is_method_descriptor(value):
147
+ # methods.append(key)
148
+ # elif not key.startswith("__retrace"):
149
+ # members.append(key)
145
150
 
146
- ref = self.writer.handle(StubRef(
147
- name = cls.__name__,
148
- module = cls.__module__,
149
- methods = methods,
150
- members = members))
151
+ # ref = self.writer.handle(StubRef(
152
+ # name = cls.__name__,
153
+ # module = cls.__module__,
154
+ # methods = methods,
155
+ # members = members))
151
156
 
152
157
  # list(proxytype.__dict__.keys())
153
158
 
@@ -13,6 +13,9 @@ from retracesoftware.proxy.stubfactory import StubFactory, StubFunction
13
13
  import os
14
14
  import weakref
15
15
  import traceback
16
+ import pprint
17
+ from itertools import count, islice
18
+
16
19
  # we can have a dummy method descriptor, its has a __name__ and when called, returns the next element
17
20
 
18
21
  # for types, we can patch the __new__ method
@@ -22,12 +25,63 @@ import traceback
22
25
  class ReplayError(RetraceError):
23
26
  pass
24
27
 
28
+ def count_matching(*lists):
29
+ count = 0
30
+ for slice in zip(*lists):
31
+ if len(set(slice)) == 1:
32
+ count += 1
33
+ else:
34
+ break
35
+
36
+ return count
37
+
38
+ def on_stack_mismatch(last_matching, record, replay):
39
+ # print('Common:')
40
+ # for index, common, replay, record in zip(count(), last_matching_stack, args[0], record):
41
+ # if common == replay == record:
42
+ # print(common)
43
+ if last_matching:
44
+ matching = count_matching(reversed(last_matching),
45
+ reversed(record),
46
+ reversed(replay))
47
+
48
+ print('Common stacktrace:')
49
+ for line in reversed(list(islice(reversed(last_matching), matching))):
50
+ print(line)
51
+
52
+ print('last matching stacktrace:')
53
+ for line in islice(last_matching, 0, len(last_matching) - matching):
54
+ print(line)
55
+
56
+ print('Replay stacktrace:')
57
+ for line in islice(replay, 0, len(replay) - matching):
58
+ print(line)
59
+
60
+ print('Record stacktrace:')
61
+ for line in islice(record, 0, len(record) - matching):
62
+ print(line)
63
+ else:
64
+ matching = count_matching(reversed(record), reversed(replay))
65
+
66
+ print('Common stacktrace:')
67
+ for line in reversed(list(islice(reversed(record), matching))):
68
+ print(line)
69
+
70
+ print('Replay stacktrace:')
71
+ for line in islice(replay, 0, len(replay) - matching):
72
+ print(line)
73
+
74
+ print('Record stacktrace:')
75
+ for line in islice(record, 0, len(record) - matching):
76
+ print(line)
77
+
78
+
25
79
  class ReplayProxySystem(ProxySystem):
26
80
 
27
- def stubtype(self, cls):
28
- assert not issubclass(cls, Proxy)
81
+ # def stubtype(self, cls):
82
+ # assert not issubclass(cls, Proxy)
29
83
 
30
- return dynamic_proxytype(handler = self.ext_handler, cls = cls)
84
+ # return dynamic_proxytype(handler = self.ext_handler, cls = cls)
31
85
 
32
86
  def create_stub(self): return True
33
87
 
@@ -57,6 +111,7 @@ class ReplayProxySystem(ProxySystem):
57
111
 
58
112
  elif next == 'RESULT':
59
113
  return self.messages()
114
+
60
115
  elif next == 'ERROR':
61
116
  err_type = self.messages()
62
117
  err_value = self.messages()
@@ -94,6 +149,9 @@ class ReplayProxySystem(ProxySystem):
94
149
 
95
150
  return super().proxy_function(func)
96
151
 
152
+ def basetype(self, cls):
153
+ return self.stub_factory.create_stubtype(StubRef(cls))
154
+
97
155
  def __init__(self,
98
156
  thread_state,
99
157
  immutable_types,
@@ -135,11 +193,20 @@ class ReplayProxySystem(ProxySystem):
135
193
  # debug = debug_level(config)
136
194
 
137
195
  # int_refs = {}
138
-
196
+ last_matching_stack = None
197
+
139
198
  def read_required(required):
140
199
  obj = readnext()
141
200
  if obj != required:
142
- print(f'Replay: {required} Record: {obj}')
201
+ if last_matching_stack:
202
+ for line in last_matching_stack:
203
+ print(line)
204
+
205
+ print('---------------------------------')
206
+ print(f'Replay: {required}')
207
+ print('---------------------------------')
208
+ print(f'Record: {obj}')
209
+ print('---------------------------------')
143
210
  for i in range(5):
144
211
  print(readnext())
145
212
 
@@ -149,13 +216,24 @@ class ReplayProxySystem(ProxySystem):
149
216
 
150
217
  def trace_writer(name, *args):
151
218
  with thread_state.select('disabled'):
152
- print(f'Trace: {name} {args}')
153
-
154
219
  read_required('TRACE')
155
220
  read_required(name)
156
221
 
157
- for arg in args:
158
- read_required(arg)
222
+ if name == 'stacktrace':
223
+ record = readnext()
224
+ if args[0] == record:
225
+ nonlocal last_matching_stack
226
+ last_matching_stack = args[0]
227
+ else:
228
+ on_stack_mismatch(
229
+ last_matching= last_matching_stack,
230
+ record = record,
231
+ replay = args[0])
232
+ os._exit(1)
233
+ else:
234
+ print(f'Trace: {name} {args}')
235
+ for arg in args:
236
+ read_required(arg)
159
237
 
160
238
  # self.tracer = Tracer(tracing_config, writer = trace_writer)
161
239
  # self.immutable_types = immutable_types
@@ -13,12 +13,30 @@ class ExtendedRef:
13
13
  self.module = module
14
14
 
15
15
  class StubRef:
16
- def __init__(self, module, name, methods, members):
17
- self.name = name
18
- self.module = module
16
+ def __init__(self, cls):
17
+ blacklist = ['__class__', '__dict__', '__module__', '__doc__', '__new__']
18
+
19
+ methods = []
20
+ members = []
21
+
22
+ for key,value in cls.__dict__.items():
23
+ if key not in blacklist:
24
+ if utils.is_method_descriptor(value):
25
+ methods.append(key)
26
+ elif not key.startswith("__retrace"):
27
+ members.append(key)
28
+
29
+ self.name = cls.__name__
30
+ self.module = cls.__module__
19
31
  self.methods = methods
20
32
  self.members = members
21
33
 
34
+ # def __init__(self, module, name, methods, members):
35
+ # self.name = name
36
+ # self.module = module
37
+ # self.methods = methods
38
+ # self.members = members
39
+
22
40
  def __str__(self):
23
41
  return f'StubRef(module = {self.module}, name = {self.name}, methods = {self.methods}, members = {self.members})'
24
42
 
@@ -108,6 +126,7 @@ class StubFactory:
108
126
  slots = {
109
127
  '__module__': spec.module,
110
128
  '__qualname__': spec.name,
129
+ '__name__': spec.name,
111
130
  }
112
131
 
113
132
  for method in spec.methods:
@@ -130,11 +149,8 @@ class StubFactory:
130
149
  return stubtype
131
150
 
132
151
  def __call__(self, spec):
133
- print(f'In stubFactory.__call__ {spec}')
134
152
  if spec not in self.cache:
135
153
  self.cache[spec] = self.create_stubtype(spec)
136
154
 
137
155
  stubtype = self.cache[spec]
138
- stub = stubtype.__new__(stubtype)
139
- print(f'In stubFactory created new')
140
- return stub
156
+ return stubtype.__new__(stubtype)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: retracesoftware_proxy
3
- Version: 0.1.3
3
+ Version: 0.1.6
4
4
  License: Apache-2.0
5
5
  Requires-Dist: retracesoftware_utils
6
6
  Requires-Dist: retracesoftware_functional
@@ -1,27 +1,27 @@
1
1
  retracesoftware/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
- retracesoftware/config.json,sha256=zhi3DZKG0pIT3Mh2EUXlzQai-U6YrknueOjMJLwNKxY,8281
2
+ retracesoftware/config.json,sha256=fzfxZF6ES2NuPO9u9fNX8xMZ5rKZStxAHovsVTSJYzs,8276
3
3
  retracesoftware/install/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
4
  retracesoftware/install/config.py,sha256=EzE5ifQF2lo--hu2njI4T0FJ-zlnWDJV6i7x0DMkVTw,1364
5
5
  retracesoftware/install/edgecases.py,sha256=NR3lyvad9sRsyeDv_Ya8V4xMgPsMPOi9rMcnFOJGOEA,6330
6
6
  retracesoftware/install/globals.py,sha256=F8XvIoZQQ10gSRalk30dvdKllxlwxkaggYY6FogLDxY,510
7
7
  retracesoftware/install/install.py,sha256=HCD_ji8XCr96b5fNzNdL_8qcEp0Jf05Em7T6GA6u8HU,4969
8
- retracesoftware/install/patcher.py,sha256=zSDmaVmgwTteF-ysMjHFbum793mt93J0gVHDOnYg2uM,17286
8
+ retracesoftware/install/patcher.py,sha256=5tRC8XmJW0_loqX1Nqad1rkG--LlX46YwgbbMTbgASc,17598
9
9
  retracesoftware/install/predicate.py,sha256=tX7NQc0rGkyyHYO3mduYHcJHbw1wczT53m_Dpkzo6do,2679
10
10
  retracesoftware/install/record.py,sha256=tseF_jV4k4HLPTgBPJdjcahl4EQqagoiisMAdGNC52Q,3257
11
11
  retracesoftware/install/references.py,sha256=A-G651IDOfuo00MkbAdpbIQh_15ChvJ7uAVTSmE6zd4,1721
12
12
  retracesoftware/install/replay.py,sha256=VUiHvQK3mgAJEGmtE2TFs9kXzxdWtsjibEcGkhZVCVE,1830
13
- retracesoftware/install/tracer.py,sha256=NFilwwtopDrEXjh4ZLkwyIgvPvzApQYC6BA78B11WTQ,4675
13
+ retracesoftware/install/tracer.py,sha256=Oqh8BhZVQVo1COfSGkFCipZGPB2Dv1b4DK3xBvloRew,4796
14
14
  retracesoftware/install/typeutils.py,sha256=_a1PuwdCsYjG1Nkd77V-flqYtwbD4RkJVKn6Z-xABL4,1813
15
15
  retracesoftware/proxy/__init__.py,sha256=ZlDZIuUmKFsE9Tvfd2EKGabTepqv8nrbr5pQhCM3IKc,193
16
16
  retracesoftware/proxy/gateway.py,sha256=xESohWXkiNm4ZutU0RgWUwxjxcBWRQ4rQyxIGQXv_F4,1590
17
17
  retracesoftware/proxy/proxyfactory.py,sha256=qhOqDfMJnLDNkQs26JqDB431MwjjRhGQi8xupJ45asg,12272
18
- retracesoftware/proxy/proxysystem.py,sha256=eUYinugkA2EZgTkxcXcdDntQmK5HCQp5oOwRzfhosx4,6698
19
- retracesoftware/proxy/proxytype.py,sha256=iKN57FPRrACgYIFEDsCMvROA_tuhuGtZVguOxGlzVEE,12246
20
- retracesoftware/proxy/record.py,sha256=YEwfqldpb1MQGi6EngPxdbmjbCIjbz9EQCZuXubLSy4,7503
21
- retracesoftware/proxy/replay.py,sha256=4DxEuBlQSA6e-vB401JVfJV9Dgfesf5qbuBQBD-ApkA,7847
22
- retracesoftware/proxy/stubfactory.py,sha256=6dvDnbClDY1tDLIDvPYOPxuCIGsg3TYa1qf2SqrmAvg,4114
18
+ retracesoftware/proxy/proxysystem.py,sha256=W2v0Tj0tJeAt_bg9LljQm2iwWpjNIbqUTQ92WK22TF8,6861
19
+ retracesoftware/proxy/proxytype.py,sha256=0jbiH8DWgyf7GCPpJMxSzWKvE7kyw1l7SSR7fIXkKDc,12389
20
+ retracesoftware/proxy/record.py,sha256=ZsJV0o-Qy874VFObtsfkSF8u9gvyUSee0UPpf9Jq6Es,7734
21
+ retracesoftware/proxy/replay.py,sha256=RVsezEZcy4bFdPQAAztfEHz6adm8t5lBDMhpnNAqeok,10510
22
+ retracesoftware/proxy/stubfactory.py,sha256=UnRDQHgWv2xTYaMPZPXvsa7WBh10CyItc_hsQdtOhcM,4607
23
23
  retracesoftware/proxy/thread.py,sha256=-SvnyVbANkmX2lLRpOvFtkpdpAoF6DhnnYdOOs7Q8vo,1379
24
- retracesoftware_proxy-0.1.3.dist-info/METADATA,sha256=J7wYAHin2b8ikm4VVMN9YfzRDZ9VEg43dpEbvqm0BXw,202
25
- retracesoftware_proxy-0.1.3.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
26
- retracesoftware_proxy-0.1.3.dist-info/top_level.txt,sha256=hYHsR6txLidmqvjBMITpIHvmJJbmoCAgr76-IpZPRz8,16
27
- retracesoftware_proxy-0.1.3.dist-info/RECORD,,
24
+ retracesoftware_proxy-0.1.6.dist-info/METADATA,sha256=NrUK4_HsArWTs-zDxMXZ5GRD3bEw8iOsbb_mpvl8Mfg,202
25
+ retracesoftware_proxy-0.1.6.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
26
+ retracesoftware_proxy-0.1.6.dist-info/top_level.txt,sha256=hYHsR6txLidmqvjBMITpIHvmJJbmoCAgr76-IpZPRz8,16
27
+ retracesoftware_proxy-0.1.6.dist-info/RECORD,,