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 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139
|
import sys
import re
python_version = sys.version_info[0]
python_subversion = sys.version_info[1]
string_instance = str if python_version == 3 else basestring
class BaronError(Exception):
pass
class FlexibleIterator():
def __init__(self, sequence):
self.sequence = sequence
self.position = -1
def __iter__(self):
return self
def next(self):
return self.__next__()
def __next__(self):
self.position += 1
if self.position == len(self.sequence):
raise StopIteration
return self.sequence[self.position]
def next_starts_with(self, sentence):
size_of_choice = len(sentence)
return self.sequence[self.position + 1: self.position + 1 + size_of_choice] == sentence
def next_in(self, choice):
if self.position + 1 >= len(self.sequence):
return False
return self.sequence[self.position + 1] in choice
def show_next(self, at=1):
if self.position + at >= len(self.sequence):
return None
return self.sequence[self.position + at]
def rest_of_the_sequence(self):
return self.sequence[self.position + 1:]
def end(self):
return self.position == (len(self.sequence) - 1)
def grab(self, test):
to_return = ""
current = None
while self.show_next() is not None and test(self):
current = next(self)
to_return += current
return to_return
def grab_string(self, test):
to_return = ""
current = None
escaped = False
while self.show_next() is not None and (escaped or test(self)):
current = next(self)
to_return += current
if escaped:
escaped = False
elif current == "\\":
escaped = True
return to_return
def create_node_from_token(token, **kwargs):
result = {"type": token.name.lower(), "value": token.value}
if kwargs:
result.update(kwargs)
return result
def create_node(name, value, **kwargs):
result = {"type": name, "value": value}
if kwargs:
result.update(kwargs)
return result
newline_regex = re.compile("(\r\n|\n|\r)")
def is_newline(text):
return newline_regex.match(text)
def split_on_newlines(text):
newlines = newline_regex.finditer(text)
if not newlines:
yield text
else:
current_position = 0
for newline in newlines:
yield text[current_position:newline.start(1)]
yield text[newline.start(1):newline.end(1)]
current_position = newline.end(1)
yield text[current_position:]
# Thanks to
# https://github.com/nvie/rq/commit/282f4be9316d608ebbacd6114aab1203591e8f95
if python_version >= 3 or python_subversion >= 7:
from functools import total_ordering
else:
def total_ordering(cls):
"""Class decorator that fills in missing ordering methods"""
convert = {
'__lt__': [('__gt__', lambda self, other: other < self),
('__le__', lambda self, other: not other < self),
('__ge__', lambda self, other: not self < other)],
'__le__': [('__ge__', lambda self, other: other <= self),
('__lt__', lambda self, other: not other <= self),
('__gt__', lambda self, other: not self <= other)],
'__gt__': [('__lt__', lambda self, other: other > self),
('__ge__', lambda self, other: not other > self),
('__le__', lambda self, other: not self > other)],
'__ge__': [('__le__', lambda self, other: other >= self),
('__gt__', lambda self, other: not other >= self),
('__lt__', lambda self, other: not self >= other)]
}
roots = set(dir(cls)) & set(convert)
if not roots:
raise ValueError('must define at least one ordering operation: < > <= >=') # noqa
root = max(roots) # prefer __lt__ to __le__ to __gt__ to __ge__
for opname, opfunc in convert[root]:
if opname not in roots:
opfunc.__name__ = opname
opfunc.__doc__ = getattr(int, opname).__doc__
setattr(cls, opname, opfunc)
return cls
|