/
_utils.py
116 lines (94 loc) · 2.88 KB
/
_utils.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
import contextlib
import functools
import warnings
import linecache
import re
from collections import OrderedDict
from collections.abc import Iterable
from contextlib import contextmanager
from .utils import *
__all__ = ["flatten", "union" , "log2_int", "bits_for", "memoize", "final", "deprecated",
"get_linter_options", "get_linter_option"]
def flatten(i):
for e in i:
if isinstance(e, Iterable):
yield from flatten(e)
else:
yield e
def union(i, start=None):
r = start
for e in i:
if r is None:
r = e
else:
r |= e
return r
def memoize(f):
memo = OrderedDict()
@functools.wraps(f)
def g(*args):
if args not in memo:
memo[args] = f(*args)
return memo[args]
return g
def final(cls):
def init_subclass():
raise TypeError("Subclassing {}.{} is not supported"
.format(cls.__module__, cls.__name__))
cls.__init_subclass__ = init_subclass
return cls
def deprecated(message, stacklevel=2):
def decorator(f):
@functools.wraps(f)
def wrapper(*args, **kwargs):
warnings.warn(message, DeprecationWarning, stacklevel=stacklevel)
return f(*args, **kwargs)
return wrapper
return decorator
def _ignore_deprecated(f=None):
if f is None:
@contextlib.contextmanager
def context_like():
with warnings.catch_warnings():
warnings.filterwarnings(action="ignore", category=DeprecationWarning)
yield
return context_like()
else:
@functools.wraps(f)
def decorator_like(*args, **kwargs):
with warnings.catch_warnings():
warnings.filterwarnings(action="ignore", category=DeprecationWarning)
f(*args, **kwargs)
return decorator_like
def extend(cls):
def decorator(f):
if isinstance(f, property):
name = f.fget.__name__
else:
name = f.__name__
setattr(cls, name, f)
return decorator
def get_linter_options(filename):
first_line = linecache.getline(filename, 1)
if first_line:
match = re.match(r"^#\s*nmigen:\s*((?:\w+=\w+\s*)(?:,\s*\w+=\w+\s*)*)\n$", first_line)
if match:
return dict(map(lambda s: s.strip().split("=", 2), match.group(1).split(",")))
return dict()
def get_linter_option(filename, name, type, default):
options = get_linter_options(filename)
if name not in options:
return default
option = options[name]
if type is bool:
if option in ("1", "yes", "enable"):
return True
if option in ("0", "no", "disable"):
return False
return default
if type is int:
try:
return int(option, 0)
except ValueError:
return default
assert False