ovld 0.4.1__py3-none-any.whl → 0.4.2__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/core.py +12 -3
- ovld/recode.py +7 -5
- ovld/typemap.py +48 -21
- ovld/version.py +1 -1
- {ovld-0.4.1.dist-info → ovld-0.4.2.dist-info}/METADATA +1 -1
- ovld-0.4.2.dist-info/RECORD +13 -0
- ovld-0.4.1.dist-info/RECORD +0 -13
- {ovld-0.4.1.dist-info → ovld-0.4.2.dist-info}/WHEEL +0 -0
- {ovld-0.4.1.dist-info → ovld-0.4.2.dist-info}/licenses/LICENSE +0 -0
ovld/core.py
CHANGED
@@ -85,6 +85,7 @@ class Signature:
|
|
85
85
|
req_names: frozenset
|
86
86
|
vararg: bool
|
87
87
|
priority: float
|
88
|
+
tiebreak: int = 0
|
88
89
|
is_method: bool = False
|
89
90
|
arginfo: list[Arginfo] = field(
|
90
91
|
default_factory=list, hash=False, compare=False
|
@@ -393,8 +394,8 @@ class _Ovld:
|
|
393
394
|
)
|
394
395
|
else:
|
395
396
|
hlp = ""
|
396
|
-
for
|
397
|
-
hlp += f"* {
|
397
|
+
for c in possibilities:
|
398
|
+
hlp += f"* {c.handler.__name__} (priority: {c.priority}, specificity: {list(c.specificity)})\n"
|
398
399
|
return TypeError(
|
399
400
|
f"Ambiguous resolution in {self} for"
|
400
401
|
f" argument types [{typenames}]\n"
|
@@ -503,7 +504,15 @@ class _Ovld:
|
|
503
504
|
raise TypeError(
|
504
505
|
f"There is already a method for {sigstring(sig.types)}"
|
505
506
|
)
|
506
|
-
|
507
|
+
|
508
|
+
def _set(sig, fn):
|
509
|
+
if sig in self._defns:
|
510
|
+
# Push down the existing handler with a lower tiebreak
|
511
|
+
msig = replace(sig, tiebreak=sig.tiebreak - 1)
|
512
|
+
_set(msig, self._defns[sig])
|
513
|
+
self._defns[sig] = fn
|
514
|
+
|
515
|
+
_set(sig, fn)
|
507
516
|
|
508
517
|
self._update()
|
509
518
|
return self
|
ovld/recode.py
CHANGED
@@ -373,6 +373,7 @@ class NameConverter(ast.NodeTransformer):
|
|
373
373
|
self.call_next_sym = call_next_sym
|
374
374
|
self.ovld_mangled = ovld_mangled
|
375
375
|
self.code_mangled = code_mangled
|
376
|
+
self.count = count()
|
376
377
|
|
377
378
|
def visit_Name(self, node):
|
378
379
|
if node.id == self.recurse_sym:
|
@@ -396,15 +397,16 @@ class NameConverter(ast.NodeTransformer):
|
|
396
397
|
return self.generic_visit(node)
|
397
398
|
|
398
399
|
cn = node.func.id == self.call_next_sym
|
400
|
+
tmp = f"__TMP{next(self.count)}_"
|
399
401
|
|
400
402
|
def _make_lookup_call(key, arg):
|
401
403
|
value = ast.NamedExpr(
|
402
|
-
target=ast.Name(id=f"
|
404
|
+
target=ast.Name(id=f"{tmp}{key}", ctx=ast.Store()),
|
403
405
|
value=self.visit(arg),
|
404
406
|
)
|
405
407
|
if self.analysis.lookup_for(key) == "self.map.transform":
|
406
408
|
func = ast.Attribute(
|
407
|
-
value=ast.Name(id="
|
409
|
+
value=ast.Name(id=f"{tmp}M", ctx=ast.Load()),
|
408
410
|
attr="transform",
|
409
411
|
ctx=ast.Load(),
|
410
412
|
)
|
@@ -437,7 +439,7 @@ class NameConverter(ast.NodeTransformer):
|
|
437
439
|
type_parts.insert(0, ast.Name(id=self.code_mangled, ctx=ast.Load()))
|
438
440
|
method = ast.Subscript(
|
439
441
|
value=ast.NamedExpr(
|
440
|
-
target=ast.Name(id="
|
442
|
+
target=ast.Name(id=f"{tmp}M", ctx=ast.Store()),
|
441
443
|
value=ast.Attribute(
|
442
444
|
value=ast.Name(id=self.ovld_mangled, ctx=ast.Load()),
|
443
445
|
attr="map",
|
@@ -464,13 +466,13 @@ class NameConverter(ast.NodeTransformer):
|
|
464
466
|
new_node = ast.Call(
|
465
467
|
func=method,
|
466
468
|
args=[
|
467
|
-
ast.Name(id=f"
|
469
|
+
ast.Name(id=f"{tmp}{i}", ctx=ast.Load())
|
468
470
|
for i, arg in enumerate(node.args)
|
469
471
|
],
|
470
472
|
keywords=[
|
471
473
|
ast.keyword(
|
472
474
|
arg=kw.arg,
|
473
|
-
value=ast.Name(id=f"
|
475
|
+
value=ast.Name(id=f"{tmp}{kw.arg}", ctx=ast.Load()),
|
474
476
|
)
|
475
477
|
for kw in node.keywords
|
476
478
|
],
|
ovld/typemap.py
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
import inspect
|
2
2
|
import math
|
3
3
|
import typing
|
4
|
+
from dataclasses import dataclass
|
4
5
|
from itertools import count
|
5
6
|
from types import CodeType
|
6
7
|
|
@@ -69,6 +70,27 @@ class TypeMap(dict):
|
|
69
70
|
raise KeyError(obj_t)
|
70
71
|
|
71
72
|
|
73
|
+
@dataclass
|
74
|
+
class Candidate:
|
75
|
+
handler: object
|
76
|
+
priority: float
|
77
|
+
specificity: tuple
|
78
|
+
tiebreak: int
|
79
|
+
|
80
|
+
def sort_key(self):
|
81
|
+
return self.priority, sum(self.specificity), self.tiebreak
|
82
|
+
|
83
|
+
def dominates(self, other):
|
84
|
+
if self.priority > other.priority:
|
85
|
+
return True
|
86
|
+
elif self.specificity != other.specificity:
|
87
|
+
return all(
|
88
|
+
s1 >= s2 for s1, s2 in zip(self.specificity, other.specificity)
|
89
|
+
)
|
90
|
+
else:
|
91
|
+
return self.tiebreak > other.tiebreak
|
92
|
+
|
93
|
+
|
72
94
|
class MultiTypeMap(dict):
|
73
95
|
"""Represents a mapping from tuples of types to handlers.
|
74
96
|
|
@@ -91,6 +113,7 @@ class MultiTypeMap(dict):
|
|
91
113
|
def __init__(self, name="_ovld", key_error=KeyError):
|
92
114
|
self.maps = {}
|
93
115
|
self.priorities = {}
|
116
|
+
self.tiebreaks = {}
|
94
117
|
self.dependent = {}
|
95
118
|
self.type_tuples = {}
|
96
119
|
self.empty = MISSING
|
@@ -155,7 +178,12 @@ class MultiTypeMap(dict):
|
|
155
178
|
specificities.setdefault(c, []).append(results[c])
|
156
179
|
|
157
180
|
candidates = [
|
158
|
-
(
|
181
|
+
Candidate(
|
182
|
+
handler=c,
|
183
|
+
priority=self.priorities.get(c, 0),
|
184
|
+
specificity=tuple(specificities[c]),
|
185
|
+
tiebreak=self.tiebreaks.get(c, 0),
|
186
|
+
)
|
159
187
|
for c in candidates
|
160
188
|
]
|
161
189
|
|
@@ -164,33 +192,30 @@ class MultiTypeMap(dict):
|
|
164
192
|
# other possibilities on all arguments, so the sum of all specificities
|
165
193
|
# has to be greater.
|
166
194
|
# Note: priority is always more important than specificity
|
167
|
-
|
195
|
+
|
196
|
+
candidates.sort(key=Candidate.sort_key, reverse=True)
|
168
197
|
|
169
198
|
self.all[obj_t_tup] = {
|
170
|
-
getattr(c
|
199
|
+
getattr(c.handler, "__code__", None) for c in candidates
|
171
200
|
}
|
172
201
|
|
173
202
|
processed = set()
|
174
203
|
|
175
204
|
def _pull(candidates):
|
176
|
-
candidates = [
|
177
|
-
(c, a, b) for (c, a, b) in candidates if c not in processed
|
178
|
-
]
|
205
|
+
candidates = [c for c in candidates if c.handler not in processed]
|
179
206
|
if not candidates:
|
180
207
|
return
|
181
208
|
rval = [candidates[0]]
|
182
|
-
c1
|
183
|
-
for c2
|
184
|
-
if
|
185
|
-
spc1 != spc2 and all(s1 >= s2 for s1, s2 in zip(spc1, spc2))
|
186
|
-
):
|
209
|
+
c1 = candidates[0]
|
210
|
+
for c2 in candidates[1:]:
|
211
|
+
if c1.dominates(c2):
|
187
212
|
# Candidate 1 dominates candidate 2
|
188
213
|
continue
|
189
214
|
else:
|
190
|
-
processed.add(c2)
|
215
|
+
processed.add(c2.handler)
|
191
216
|
# Candidate 1 does not dominate candidate 2, so we add it
|
192
217
|
# to the list.
|
193
|
-
rval.append(
|
218
|
+
rval.append(c2)
|
194
219
|
yield rval
|
195
220
|
if len(rval) >= 1:
|
196
221
|
yield from _pull(candidates[1:])
|
@@ -212,6 +237,7 @@ class MultiTypeMap(dict):
|
|
212
237
|
self.empty = entry
|
213
238
|
|
214
239
|
self.priorities[handler] = sig.priority
|
240
|
+
self.tiebreaks[handler] = sig.tiebreak
|
215
241
|
self.type_tuples[handler] = obj_t_tup
|
216
242
|
self.dependent[handler] = any(
|
217
243
|
isinstance(t[1] if isinstance(t, tuple) else t, DependentType)
|
@@ -257,15 +283,16 @@ class MultiTypeMap(dict):
|
|
257
283
|
finished = False
|
258
284
|
rank = 1
|
259
285
|
for grp in self.mro(tuple(argt)):
|
260
|
-
grp.sort(key=lambda x: x
|
286
|
+
grp.sort(key=lambda x: x.handler.__name__)
|
261
287
|
match = [
|
262
288
|
dependent_match(
|
263
|
-
self.type_tuples[handler], [*args, *kwargs.items()]
|
289
|
+
self.type_tuples[c.handler], [*args, *kwargs.items()]
|
264
290
|
)
|
265
|
-
for
|
291
|
+
for c in grp
|
266
292
|
]
|
267
293
|
ambiguous = len([m for m in match if m]) > 1
|
268
|
-
for m,
|
294
|
+
for m, c in zip(match, grp):
|
295
|
+
handler = c.handler
|
269
296
|
color = "\033[0m"
|
270
297
|
if finished:
|
271
298
|
bullet = "--"
|
@@ -282,8 +309,8 @@ class MultiTypeMap(dict):
|
|
282
309
|
message = f"{handler.__name__} will be called first."
|
283
310
|
color = "\033[1;32m"
|
284
311
|
rank += 1
|
285
|
-
spec = ".".join(map(str,
|
286
|
-
lvl = f"[{
|
312
|
+
spec = ".".join(map(str, c.specificity))
|
313
|
+
lvl = f"[{c.priority}:{spec}]"
|
287
314
|
width = 2 * len(args) + 6
|
288
315
|
print(f"{color}{bullet} {lvl:{width}} {handler.__name__}")
|
289
316
|
co = handler.__code__
|
@@ -320,8 +347,8 @@ class MultiTypeMap(dict):
|
|
320
347
|
|
321
348
|
funcs = []
|
322
349
|
for group in reversed(results):
|
323
|
-
handlers = [
|
324
|
-
dependent = any(self.dependent[
|
350
|
+
handlers = [c.handler for c in group]
|
351
|
+
dependent = any(self.dependent[c.handler] for c in group)
|
325
352
|
if dependent:
|
326
353
|
nxt = self.wrap_dependent(
|
327
354
|
obj_t_tup, handlers, group, funcs[-1] if funcs else None
|
ovld/version.py
CHANGED
@@ -1 +1 @@
|
|
1
|
-
version = "0.4.
|
1
|
+
version = "0.4.2"
|
@@ -0,0 +1,13 @@
|
|
1
|
+
ovld/__init__.py,sha256=Vp9wbIy_opFmJx-vCcToQcIP3cWFIvgbfYHITyiwPLs,1305
|
2
|
+
ovld/core.py,sha256=glexOiRU0ajoxFAQN6d69ToL6_cPvyv05Z7LEHqrJj8,25701
|
3
|
+
ovld/dependent.py,sha256=QITsWu2uCwqkHE0tunETy8Jqwc272uoG5YM0I5yy0m4,7303
|
4
|
+
ovld/mro.py,sha256=rS0pCLLWwLUI0NdthpoJSrdvWR4-XgRfx1pLAvJde14,5586
|
5
|
+
ovld/recode.py,sha256=zxhyotuc73qzuN4NEN_rKxaqoA0SOH7KFtE2l_CRBFs,17963
|
6
|
+
ovld/typemap.py,sha256=gw8XvB-N_15Dr0-am0v17x1seNjYK5AxvUT9L36mWic,13630
|
7
|
+
ovld/types.py,sha256=Zeb7xhHbL4T7qIRHI-I_cjG61UIWrfZv_EwjwqhB-rY,6381
|
8
|
+
ovld/utils.py,sha256=V6Y8oZ6ojq8JaODL1rMZbU5L9QG0YSqHNYmpIFiwy3M,1294
|
9
|
+
ovld/version.py,sha256=OHlqRD04Kvw_CFYmiIVx7UuOJRTQKtAx1Bl4rkUYHJE,18
|
10
|
+
ovld-0.4.2.dist-info/METADATA,sha256=fV3vxTKRAjCUkRVNmzTW14VajGSl7P0b9NnG06cjUJk,7713
|
11
|
+
ovld-0.4.2.dist-info/WHEEL,sha256=1yFddiXMmvYK7QYTqtRNtX66WJ0Mz8PYEiEUoOUUxRY,87
|
12
|
+
ovld-0.4.2.dist-info/licenses/LICENSE,sha256=cSwNTIzd1cbI89xt3PeZZYJP2y3j8Zus4bXgo4svpX8,1066
|
13
|
+
ovld-0.4.2.dist-info/RECORD,,
|
ovld-0.4.1.dist-info/RECORD
DELETED
@@ -1,13 +0,0 @@
|
|
1
|
-
ovld/__init__.py,sha256=Vp9wbIy_opFmJx-vCcToQcIP3cWFIvgbfYHITyiwPLs,1305
|
2
|
-
ovld/core.py,sha256=S6YSbZk5ajKvdVqn5NyuduDAU_moBylZGmpNskQE7XI,25397
|
3
|
-
ovld/dependent.py,sha256=QITsWu2uCwqkHE0tunETy8Jqwc272uoG5YM0I5yy0m4,7303
|
4
|
-
ovld/mro.py,sha256=rS0pCLLWwLUI0NdthpoJSrdvWR4-XgRfx1pLAvJde14,5586
|
5
|
-
ovld/recode.py,sha256=Vc97Nv1j2GWuitLOzIuIhpscZ4gaOJQP3hLNp8SGTQ8,17890
|
6
|
-
ovld/typemap.py,sha256=U_BmXtts1oYVa6gI3cgGHMX5kFcCJY_mt_cjWvDo3jQ,12979
|
7
|
-
ovld/types.py,sha256=Zeb7xhHbL4T7qIRHI-I_cjG61UIWrfZv_EwjwqhB-rY,6381
|
8
|
-
ovld/utils.py,sha256=V6Y8oZ6ojq8JaODL1rMZbU5L9QG0YSqHNYmpIFiwy3M,1294
|
9
|
-
ovld/version.py,sha256=FBeN5tbWV0BpBmjJ3d3pzaNRlEg_Blp421Tbg8X3cAI,18
|
10
|
-
ovld-0.4.1.dist-info/METADATA,sha256=OOhqZjiT-T6jb-c0iATIElVxfZbZ62qDcuJQcxvHMQM,7713
|
11
|
-
ovld-0.4.1.dist-info/WHEEL,sha256=1yFddiXMmvYK7QYTqtRNtX66WJ0Mz8PYEiEUoOUUxRY,87
|
12
|
-
ovld-0.4.1.dist-info/licenses/LICENSE,sha256=cSwNTIzd1cbI89xt3PeZZYJP2y3j8Zus4bXgo4svpX8,1066
|
13
|
-
ovld-0.4.1.dist-info/RECORD,,
|
File without changes
|
File without changes
|