Initialisation du repository de Beta
This commit is contained in:
commit
14985f6dbb
9469 changed files with 1903273 additions and 0 deletions
|
|
@ -0,0 +1,68 @@
|
|||
from .utils import _toposort, groupby
|
||||
|
||||
class AmbiguityWarning(Warning):
|
||||
pass
|
||||
|
||||
|
||||
def supercedes(a, b):
|
||||
""" A is consistent and strictly more specific than B """
|
||||
return len(a) == len(b) and all(map(issubclass, a, b))
|
||||
|
||||
|
||||
def consistent(a, b):
|
||||
""" It is possible for an argument list to satisfy both A and B """
|
||||
return (len(a) == len(b) and
|
||||
all(issubclass(aa, bb) or issubclass(bb, aa)
|
||||
for aa, bb in zip(a, b)))
|
||||
|
||||
|
||||
def ambiguous(a, b):
|
||||
""" A is consistent with B but neither is strictly more specific """
|
||||
return consistent(a, b) and not (supercedes(a, b) or supercedes(b, a))
|
||||
|
||||
|
||||
def ambiguities(signatures):
|
||||
""" All signature pairs such that A is ambiguous with B """
|
||||
signatures = list(map(tuple, signatures))
|
||||
return {(a, b) for a in signatures for b in signatures
|
||||
if hash(a) < hash(b)
|
||||
and ambiguous(a, b)
|
||||
and not any(supercedes(c, a) and supercedes(c, b)
|
||||
for c in signatures)}
|
||||
|
||||
|
||||
def super_signature(signatures):
|
||||
""" A signature that would break ambiguities """
|
||||
n = len(signatures[0])
|
||||
assert all(len(s) == n for s in signatures)
|
||||
|
||||
return [max([type.mro(sig[i]) for sig in signatures], key=len)[0]
|
||||
for i in range(n)]
|
||||
|
||||
|
||||
def edge(a, b, tie_breaker=hash):
|
||||
""" A should be checked before B
|
||||
|
||||
Tie broken by tie_breaker, defaults to ``hash``
|
||||
"""
|
||||
if supercedes(a, b):
|
||||
if supercedes(b, a):
|
||||
return tie_breaker(a) > tie_breaker(b)
|
||||
else:
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def ordering(signatures):
|
||||
""" A sane ordering of signatures to check, first to last
|
||||
|
||||
Topoological sort of edges as given by ``edge`` and ``supercedes``
|
||||
"""
|
||||
signatures = list(map(tuple, signatures))
|
||||
edges = [(a, b) for a in signatures for b in signatures if edge(a, b)]
|
||||
edges = groupby(lambda x: x[0], edges)
|
||||
for s in signatures:
|
||||
if s not in edges:
|
||||
edges[s] = []
|
||||
edges = {k: [b for a, b in v] for k, v in edges.items()}
|
||||
return _toposort(edges)
|
||||
Loading…
Add table
Add a link
Reference in a new issue