ovld 0.4.3__py3-none-any.whl → 0.4.4__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.
- ovld/__init__.py +1 -0
- ovld/abc.py +48 -0
- ovld/core.py +16 -28
- ovld/dependent.py +131 -55
- ovld/mro.py +30 -60
- ovld/recode.py +63 -50
- ovld/typemap.py +9 -31
- ovld/types.py +282 -72
- ovld/utils.py +36 -0
- ovld/version.py +1 -1
- {ovld-0.4.3.dist-info → ovld-0.4.4.dist-info}/METADATA +1 -1
- ovld-0.4.4.dist-info/RECORD +14 -0
- ovld-0.4.3.dist-info/RECORD +0 -13
- {ovld-0.4.3.dist-info → ovld-0.4.4.dist-info}/WHEEL +0 -0
- {ovld-0.4.3.dist-info → ovld-0.4.4.dist-info}/licenses/LICENSE +0 -0
ovld/types.py
CHANGED
@@ -2,11 +2,12 @@ import inspect
|
|
2
2
|
import sys
|
3
3
|
import typing
|
4
4
|
from dataclasses import dataclass
|
5
|
+
from functools import partial
|
5
6
|
from typing import Protocol, runtime_checkable
|
6
7
|
|
7
|
-
from ovld.utils import UsageError
|
8
|
-
|
9
8
|
from .mro import Order, TypeRelationship, subclasscheck, typeorder
|
9
|
+
from .typemap import TypeMap
|
10
|
+
from .utils import UsageError, clsstring
|
10
11
|
|
11
12
|
try:
|
12
13
|
from types import UnionType
|
@@ -14,62 +15,129 @@ except ImportError: # pragma: no cover
|
|
14
15
|
UnionType = None
|
15
16
|
|
16
17
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
t
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
18
|
+
class TypeNormalizer:
|
19
|
+
def __init__(self, generic_handlers=None):
|
20
|
+
self.generic_handlers = generic_handlers or TypeMap()
|
21
|
+
|
22
|
+
def register_generic(self, generic, handler=None):
|
23
|
+
if handler is None:
|
24
|
+
return partial(self.register_generic, generic)
|
25
|
+
else:
|
26
|
+
self.generic_handlers.register(generic, handler)
|
27
|
+
|
28
|
+
def __call__(self, t, fn):
|
29
|
+
from .dependent import DependentType
|
30
|
+
|
31
|
+
if isinstance(t, str):
|
32
|
+
t = eval(t, getattr(fn, "__globals__", {}))
|
33
|
+
|
34
|
+
if t is type:
|
35
|
+
t = type[object]
|
36
|
+
elif t is typing.Any:
|
37
|
+
t = object
|
38
|
+
elif t is inspect._empty:
|
39
|
+
t = object
|
40
|
+
elif isinstance(t, typing._AnnotatedAlias):
|
41
|
+
t = t.__origin__
|
42
|
+
|
43
|
+
origin = getattr(t, "__origin__", None)
|
44
|
+
if UnionType and isinstance(t, UnionType):
|
45
|
+
return self(t.__args__, fn)
|
46
|
+
elif origin is type:
|
47
|
+
return t
|
48
|
+
elif origin and getattr(t, "__args__", None) is None:
|
49
|
+
return t
|
50
|
+
elif origin is not None:
|
51
|
+
try:
|
52
|
+
results = self.generic_handlers[origin]
|
53
|
+
results = list(results.items())
|
54
|
+
results.sort(key=lambda x: x[1], reverse=True)
|
55
|
+
assert results
|
56
|
+
rval = results[0][0](self, t, fn)
|
57
|
+
if isinstance(origin, type) and hasattr(rval, "with_bound"):
|
58
|
+
rval = rval.with_bound(origin)
|
59
|
+
return rval
|
60
|
+
except KeyError: # pragma: no cover
|
61
|
+
raise TypeError(f"ovld does not understand generic type {t}")
|
62
|
+
elif isinstance(t, tuple):
|
63
|
+
return Union[tuple(self(t2, fn) for t2 in t)]
|
64
|
+
elif isinstance(t, DependentType) and not t.bound:
|
65
|
+
raise UsageError(
|
66
|
+
f"Dependent type {t} has not been given a type bound. Please use Dependent[<bound>, {t}] instead."
|
67
|
+
)
|
68
|
+
else:
|
69
|
+
return t
|
70
|
+
|
71
|
+
|
72
|
+
normalize_type = TypeNormalizer()
|
73
|
+
|
74
|
+
|
75
|
+
@normalize_type.register_generic(typing.Union)
|
76
|
+
def _(self, t, fn):
|
77
|
+
return self(t.__args__, fn)
|
55
78
|
|
56
79
|
|
57
80
|
class MetaMC(type):
|
58
|
-
def __new__(T, name,
|
59
|
-
return super().__new__(T, name, (), {"
|
81
|
+
def __new__(T, name, handler):
|
82
|
+
return super().__new__(T, name, (), {"_handler": handler})
|
83
|
+
|
84
|
+
def __init__(cls, name, handler):
|
85
|
+
cls.__args__ = getattr(handler, "__args__", ())
|
60
86
|
|
61
|
-
def
|
62
|
-
|
87
|
+
def codegen(cls):
|
88
|
+
return cls._handler.codegen()
|
63
89
|
|
64
90
|
def __type_order__(cls, other):
|
65
|
-
|
91
|
+
return cls._handler.__type_order__(other)
|
92
|
+
|
93
|
+
def __is_supertype__(cls, other):
|
94
|
+
return cls._handler.__is_supertype__(other)
|
95
|
+
|
96
|
+
def __is_subtype__(cls, other): # pragma: no cover
|
97
|
+
return cls._handler.__is_subtype__(other)
|
98
|
+
|
99
|
+
def __subclasscheck__(cls, sub):
|
100
|
+
return cls._handler.__subclasscheck__(sub)
|
101
|
+
|
102
|
+
def __instancecheck__(cls, obj):
|
103
|
+
return cls._handler.__instancecheck__(obj)
|
104
|
+
|
105
|
+
def __eq__(cls, other):
|
106
|
+
return (
|
107
|
+
type(cls) is type(other)
|
108
|
+
and type(cls._handler) is type(other._handler)
|
109
|
+
and cls._handler == other._handler
|
110
|
+
)
|
111
|
+
|
112
|
+
def __hash__(cls):
|
113
|
+
return hash(cls._handler)
|
114
|
+
|
115
|
+
def __and__(cls, other):
|
116
|
+
return Intersection[cls, other]
|
117
|
+
|
118
|
+
def __rand__(cls, other):
|
119
|
+
return Intersection[other, cls]
|
120
|
+
|
121
|
+
def __str__(self):
|
122
|
+
return str(self._handler)
|
123
|
+
|
124
|
+
__repr__ = __str__
|
125
|
+
|
126
|
+
|
127
|
+
class SingleFunctionHandler:
|
128
|
+
def __init__(self, handler, args):
|
129
|
+
self.handler = handler
|
130
|
+
self.args = self.__args__ = args
|
131
|
+
|
132
|
+
def __type_order__(self, other):
|
133
|
+
results = self.handler(other, *self.args)
|
66
134
|
if isinstance(results, TypeRelationship):
|
67
135
|
return results.order
|
68
136
|
else:
|
69
137
|
return NotImplemented
|
70
138
|
|
71
|
-
def __is_supertype__(
|
72
|
-
results =
|
139
|
+
def __is_supertype__(self, other):
|
140
|
+
results = self.handler(other, *self.args)
|
73
141
|
if isinstance(results, bool):
|
74
142
|
return results
|
75
143
|
elif isinstance(results, TypeRelationship):
|
@@ -77,15 +145,22 @@ class MetaMC(type):
|
|
77
145
|
else: # pragma: no cover
|
78
146
|
return NotImplemented
|
79
147
|
|
80
|
-
def __is_subtype__(
|
81
|
-
results =
|
148
|
+
def __is_subtype__(self, other): # pragma: no cover
|
149
|
+
results = self.handler(other, *self.args)
|
82
150
|
if isinstance(results, TypeRelationship):
|
83
151
|
return results.subtype
|
84
|
-
else:
|
152
|
+
else:
|
85
153
|
return NotImplemented
|
86
154
|
|
87
|
-
def __subclasscheck__(
|
88
|
-
return
|
155
|
+
def __subclasscheck__(self, sub):
|
156
|
+
return self.__is_supertype__(sub)
|
157
|
+
|
158
|
+
def __instancecheck__(self, obj):
|
159
|
+
return issubclass(type(obj), self)
|
160
|
+
|
161
|
+
def __str__(self):
|
162
|
+
args = ", ".join(map(clsstring, self.__args__))
|
163
|
+
return f"{self.handler.__name__}[{args}]"
|
89
164
|
|
90
165
|
|
91
166
|
def class_check(condition):
|
@@ -99,7 +174,7 @@ def class_check(condition):
|
|
99
174
|
condition: A function that takes a class as an argument and returns
|
100
175
|
True or False depending on whether it matches some condition.
|
101
176
|
"""
|
102
|
-
return MetaMC(condition.__name__, condition)
|
177
|
+
return MetaMC(condition.__name__, SingleFunctionHandler(condition, ()))
|
103
178
|
|
104
179
|
|
105
180
|
def parametrized_class_check(fn):
|
@@ -118,14 +193,10 @@ def parametrized_class_check(fn):
|
|
118
193
|
if not isinstance(arg, tuple):
|
119
194
|
arg = (arg,)
|
120
195
|
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
return repr(x)
|
126
|
-
|
127
|
-
name = f"{fn.__name__}[{', '.join(map(arg_to_str, arg))}]"
|
128
|
-
return MetaMC(name, lambda sub: fn(sub, *arg))
|
196
|
+
if isinstance(fn, type):
|
197
|
+
return MetaMC(fn.__name__, fn(*arg))
|
198
|
+
else:
|
199
|
+
return MetaMC(fn.__name__, SingleFunctionHandler(fn, arg))
|
129
200
|
|
130
201
|
_C.__name__ = fn.__name__
|
131
202
|
_C.__qualname__ = fn.__qualname__
|
@@ -140,6 +211,56 @@ def _getcls(ref):
|
|
140
211
|
return curr
|
141
212
|
|
142
213
|
|
214
|
+
class AllMC(type):
|
215
|
+
def __type_order__(self, other):
|
216
|
+
return Order.MORE
|
217
|
+
|
218
|
+
def __is_subtype__(self, other):
|
219
|
+
return True
|
220
|
+
|
221
|
+
def __is_supertype__(self, other):
|
222
|
+
return False
|
223
|
+
|
224
|
+
def __subclasscheck__(self, other): # pragma: no cover
|
225
|
+
return False
|
226
|
+
|
227
|
+
def __isinstance__(self, other): # pragma: no cover
|
228
|
+
return False
|
229
|
+
|
230
|
+
|
231
|
+
class All(metaclass=AllMC):
|
232
|
+
"""All is the empty/void/bottom type -- it acts as a subtype of all types.
|
233
|
+
|
234
|
+
It is basically the opposite of Any: nothing is an instance of All. The main
|
235
|
+
place you want to use All is as a wildcard in contravariant settings, e.g.
|
236
|
+
all 2-argument functions are instances of Callable[[All, All], Any] because
|
237
|
+
the arguments are contravariant.
|
238
|
+
"""
|
239
|
+
|
240
|
+
|
241
|
+
class WhateverMC(AllMC):
|
242
|
+
def __is_supertype__(self, other):
|
243
|
+
return True
|
244
|
+
|
245
|
+
def __subclasscheck__(self, other): # pragma: no cover
|
246
|
+
return True
|
247
|
+
|
248
|
+
def __isinstance__(self, other): # pragma: no cover
|
249
|
+
return True
|
250
|
+
|
251
|
+
|
252
|
+
class Whatever(metaclass=WhateverMC):
|
253
|
+
"""This type is a superclass and a subclass of everything.
|
254
|
+
|
255
|
+
It's not a coherent type, more like a convenience.
|
256
|
+
|
257
|
+
It'll match anything anywhere, so you can write e.g.
|
258
|
+
Callable[[Whatever, Whatever], Whatever] to match any function of
|
259
|
+
two arguments. Any only works in covariant settings, and All only
|
260
|
+
works in contravariant settings.
|
261
|
+
"""
|
262
|
+
|
263
|
+
|
143
264
|
class Deferred:
|
144
265
|
"""Represent a class from an external module without importing it.
|
145
266
|
|
@@ -168,7 +289,7 @@ class Deferred:
|
|
168
289
|
else:
|
169
290
|
return False
|
170
291
|
|
171
|
-
return MetaMC(f"Deferred[{ref}]", check)
|
292
|
+
return MetaMC(f"Deferred[{ref}]", SingleFunctionHandler(check, ()))
|
172
293
|
|
173
294
|
|
174
295
|
@parametrized_class_check
|
@@ -191,16 +312,105 @@ def StrictSubclass(cls, base_cls):
|
|
191
312
|
|
192
313
|
|
193
314
|
@parametrized_class_check
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
315
|
+
class Union:
|
316
|
+
def __init__(self, *types):
|
317
|
+
self.__args__ = self.types = types
|
318
|
+
|
319
|
+
def codegen(self):
|
320
|
+
from .dependent import combine, generate_checking_code
|
321
|
+
|
322
|
+
template = " or ".join("{}" for t in self.types)
|
323
|
+
return combine(
|
324
|
+
template, [generate_checking_code(t) for t in self.types]
|
325
|
+
)
|
326
|
+
|
327
|
+
def __type_order__(self, other):
|
328
|
+
if other is Union:
|
329
|
+
return Order.LESS
|
330
|
+
classes = self.types
|
331
|
+
compare = [
|
332
|
+
x for t in classes if (x := typeorder(t, other)) is not Order.NONE
|
333
|
+
]
|
334
|
+
if not compare:
|
335
|
+
return Order.NONE
|
336
|
+
elif any(x is Order.MORE or x is Order.SAME for x in compare):
|
337
|
+
return Order.MORE
|
338
|
+
else:
|
339
|
+
return Order.LESS
|
340
|
+
|
341
|
+
def __is_supertype__(self, other):
|
342
|
+
return any(subclasscheck(other, t) for t in self.types)
|
343
|
+
|
344
|
+
def __is_subtype__(self, other):
|
345
|
+
if other is Union:
|
346
|
+
return True
|
347
|
+
return NotImplemented # pragma: no cover
|
348
|
+
|
349
|
+
def __subclasscheck__(self, sub):
|
350
|
+
return self.__is_supertype__(sub)
|
351
|
+
|
352
|
+
def __instancecheck__(self, obj):
|
353
|
+
return any(isinstance(obj, t) for t in self.types)
|
354
|
+
|
355
|
+
def __eq__(self, other):
|
356
|
+
return self.__args__ == other.__args__
|
357
|
+
|
358
|
+
def __hash__(self):
|
359
|
+
return hash(self.__args__)
|
360
|
+
|
361
|
+
def __str__(self):
|
362
|
+
return " | ".join(map(clsstring, self.__args__))
|
363
|
+
|
364
|
+
|
365
|
+
@parametrized_class_check
|
366
|
+
class Intersection:
|
367
|
+
def __init__(self, *types):
|
368
|
+
self.__args__ = self.types = types
|
369
|
+
|
370
|
+
def codegen(self):
|
371
|
+
from .dependent import combine, generate_checking_code
|
372
|
+
|
373
|
+
template = " and ".join("{}" for t in self.types)
|
374
|
+
return combine(
|
375
|
+
template, [generate_checking_code(t) for t in self.types]
|
376
|
+
)
|
377
|
+
|
378
|
+
def __type_order__(self, other):
|
379
|
+
if other is Intersection:
|
380
|
+
return Order.LESS
|
381
|
+
classes = self.types
|
382
|
+
compare = [
|
383
|
+
x for t in classes if (x := typeorder(t, other)) is not Order.NONE
|
384
|
+
]
|
385
|
+
if not compare:
|
386
|
+
return Order.NONE
|
387
|
+
elif any(x is Order.LESS or x is Order.SAME for x in compare):
|
388
|
+
return Order.LESS
|
389
|
+
else:
|
390
|
+
return Order.MORE
|
391
|
+
|
392
|
+
def __is_supertype__(self, other):
|
393
|
+
return all(subclasscheck(other, t) for t in self.types)
|
394
|
+
|
395
|
+
def __is_subtype__(self, other): # pragma: no cover
|
396
|
+
if other is Intersection:
|
397
|
+
return True
|
398
|
+
return NotImplemented
|
399
|
+
|
400
|
+
def __subclasscheck__(self, sub):
|
401
|
+
return self.__is_supertype__(sub)
|
402
|
+
|
403
|
+
def __instancecheck__(self, obj):
|
404
|
+
return all(isinstance(obj, t) for t in self.types)
|
405
|
+
|
406
|
+
def __eq__(self, other):
|
407
|
+
return self.__args__ == other.__args__
|
408
|
+
|
409
|
+
def __hash__(self):
|
410
|
+
return hash(self.__args__)
|
411
|
+
|
412
|
+
def __str__(self):
|
413
|
+
return " & ".join(map(clsstring, self.__args__))
|
204
414
|
|
205
415
|
|
206
416
|
@parametrized_class_check
|
ovld/utils.py
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
"""Miscellaneous utilities."""
|
2
2
|
|
3
3
|
import functools
|
4
|
+
import typing
|
4
5
|
|
5
6
|
|
6
7
|
class Named:
|
@@ -60,6 +61,41 @@ class Unusable:
|
|
60
61
|
raise UsageError(self.__message)
|
61
62
|
|
62
63
|
|
64
|
+
class GenericAliasMC(type):
|
65
|
+
def __instancecheck__(cls, obj):
|
66
|
+
return hasattr(obj, "__origin__")
|
67
|
+
|
68
|
+
|
69
|
+
class GenericAlias(metaclass=GenericAliasMC):
|
70
|
+
pass
|
71
|
+
|
72
|
+
|
73
|
+
def clsstring(cls):
|
74
|
+
if cls is object:
|
75
|
+
return "*"
|
76
|
+
elif args := typing.get_args(cls):
|
77
|
+
origin = typing.get_origin(cls) or cls
|
78
|
+
args = ", ".join(map(clsstring, args))
|
79
|
+
return f"{origin.__name__}[{args}]"
|
80
|
+
else:
|
81
|
+
r = repr(cls)
|
82
|
+
if r.startswith("<class "):
|
83
|
+
return cls.__name__
|
84
|
+
else:
|
85
|
+
return r
|
86
|
+
|
87
|
+
|
88
|
+
def subtler_type(obj):
|
89
|
+
if isinstance(obj, GenericAlias):
|
90
|
+
return type[obj]
|
91
|
+
elif obj is typing.Any:
|
92
|
+
return type[object]
|
93
|
+
elif isinstance(obj, type):
|
94
|
+
return type[obj]
|
95
|
+
else:
|
96
|
+
return type(obj)
|
97
|
+
|
98
|
+
|
63
99
|
__all__ = [
|
64
100
|
"BOOTSTRAP",
|
65
101
|
"MISSING",
|
ovld/version.py
CHANGED
@@ -1 +1 @@
|
|
1
|
-
version = "0.4.
|
1
|
+
version = "0.4.4"
|
@@ -0,0 +1,14 @@
|
|
1
|
+
ovld/__init__.py,sha256=GEhOdG64GPUY5Y5BMnaik7UMgcq12mWVhxN9quIonYw,1476
|
2
|
+
ovld/abc.py,sha256=4qpZyYwI8dWgY1Oiv5FhdKg2uzNcyWxIpGmGJVcjXrs,1177
|
3
|
+
ovld/core.py,sha256=vzrYgUdagsQH6gbw32kzYzd-MvnCE3O9LjUyc-vVk1M,25366
|
4
|
+
ovld/dependent.py,sha256=vvWjjOHNtw8PegZVDj1fRKpyp6SCg1WdOWoXNxZSVrk,9288
|
5
|
+
ovld/mro.py,sha256=0cJK_v-POCiuwjluwf8fWeQ3G-2chEUv3KYe57GC61Q,4552
|
6
|
+
ovld/recode.py,sha256=NWAM0qyOQqXgVCZxtmhtnkygWe-NV5FRwdXGtqikGTg,18494
|
7
|
+
ovld/typemap.py,sha256=PH5dy8ddVCcqj2TkQbgsM7fmCdHsJT9WGXFPn4JZsCA,13131
|
8
|
+
ovld/types.py,sha256=EZNv8pThbo47KBULYM3R0R3sM2C5LC4DWraXZImkiNs,12877
|
9
|
+
ovld/utils.py,sha256=BsE7MmW5sfnO4Ym8hcEL8JNZZ1JIX_pgVRAAidh_8_w,2085
|
10
|
+
ovld/version.py,sha256=Qk6wsgzl7cSMWWZ902odoQ-wBV5Fda2ShX82NN7uHzM,18
|
11
|
+
ovld-0.4.4.dist-info/METADATA,sha256=wUsEDZyoQPooCN7P7q4MyObKAeSjg7DqpR-vRne5BW8,7713
|
12
|
+
ovld-0.4.4.dist-info/WHEEL,sha256=1yFddiXMmvYK7QYTqtRNtX66WJ0Mz8PYEiEUoOUUxRY,87
|
13
|
+
ovld-0.4.4.dist-info/licenses/LICENSE,sha256=cSwNTIzd1cbI89xt3PeZZYJP2y3j8Zus4bXgo4svpX8,1066
|
14
|
+
ovld-0.4.4.dist-info/RECORD,,
|
ovld-0.4.3.dist-info/RECORD
DELETED
@@ -1,13 +0,0 @@
|
|
1
|
-
ovld/__init__.py,sha256=_MJizMQ-Ise8c53GCsC7f-MOhp-qcUd0bpvu8LUFp8M,1444
|
2
|
-
ovld/core.py,sha256=glexOiRU0ajoxFAQN6d69ToL6_cPvyv05Z7LEHqrJj8,25701
|
3
|
-
ovld/dependent.py,sha256=HZbn2uU1uby9D-5qmDSjwdUpIJPdBXYrCW82lpTrBS4,7289
|
4
|
-
ovld/mro.py,sha256=eNU8rMG3hVOA1h7cd2lo4mmXQQbAGI5ISERllOO8_Js,5598
|
5
|
-
ovld/recode.py,sha256=zxhyotuc73qzuN4NEN_rKxaqoA0SOH7KFtE2l_CRBFs,17963
|
6
|
-
ovld/typemap.py,sha256=gw8XvB-N_15Dr0-am0v17x1seNjYK5AxvUT9L36mWic,13630
|
7
|
-
ovld/types.py,sha256=zR5_W3iFZb5LfktjrGfCMa1-eAwlF-AyBeTwAX3JayU,6795
|
8
|
-
ovld/utils.py,sha256=V6Y8oZ6ojq8JaODL1rMZbU5L9QG0YSqHNYmpIFiwy3M,1294
|
9
|
-
ovld/version.py,sha256=qGkDKQTrLXZ0o-aafthub4OFvdwOI_7GN29zXzZj8zg,18
|
10
|
-
ovld-0.4.3.dist-info/METADATA,sha256=JxkPMmizv16TxE_gBQKClp29o8d_10FgFYsPVQ2Tvf0,7713
|
11
|
-
ovld-0.4.3.dist-info/WHEEL,sha256=1yFddiXMmvYK7QYTqtRNtX66WJ0Mz8PYEiEUoOUUxRY,87
|
12
|
-
ovld-0.4.3.dist-info/licenses/LICENSE,sha256=cSwNTIzd1cbI89xt3PeZZYJP2y3j8Zus4bXgo4svpX8,1066
|
13
|
-
ovld-0.4.3.dist-info/RECORD,,
|
File without changes
|
File without changes
|