pull/13/head
Ishak Numanagić 2022-02-16 16:51:16 +01:00
parent ce268c81a3
commit 8d72ff8cfa
49 changed files with 525 additions and 641 deletions

View File

@ -3,7 +3,7 @@
def _heapify(
arr: Array[T], begin: int, end: int, keyf: Callable[[T], S], T: type, S: type
) -> void:
):
"""
Makes the array a heap from [begin, end).
"""
@ -24,7 +24,7 @@ def _heapify(
def _heap_sort(
arr: Array[T], begin: int, end: int, keyf: Callable[[T], S], T: type, S: type
) -> void:
):
if end - begin < 2:
return
@ -46,7 +46,7 @@ def _heap_sort(
def heap_sort_array(
collection: Array[T], size: int, keyf: Callable[[T], S], T: type, S: type
) -> void:
):
"""
Heap Sort
Sorts the array inplace.
@ -56,7 +56,7 @@ def heap_sort_array(
def heap_sort_inplace(
collection: List[T], keyf: Callable[[T], S], T: type, S: type
) -> void:
):
"""
Heap Sort
Sorts the list inplace.

View File

@ -3,7 +3,7 @@
def _insertion_sort(
arr: Array[T], begin: int, end: int, keyf: Callable[[T], S], T: type, S: type
) -> void:
):
i = begin + 1
while i < end:
x = arr[i]
@ -17,7 +17,7 @@ def _insertion_sort(
def insertion_sort_array(
collection: Array[T], size: int, keyf: Callable[[T], S], T: type, S: type
) -> void:
):
"""
Insertion Sort
Sorts the array inplace.
@ -27,7 +27,7 @@ def insertion_sort_array(
def insertion_sort_inplace(
collection: List[T], keyf: Callable[[T], S], T: type, S: type
) -> void:
):
"""
Insertion Sort
Sorts the list inplace.

View File

@ -162,14 +162,14 @@ def _partition_right(
def _sort2(
arr: Array[T], i: int, j: int, keyf: Callable[[T], S], T: type, S: type
) -> void:
):
if keyf(arr[j]) < keyf(arr[i]):
arr[i], arr[j] = arr[j], arr[i]
def _sort3(
arr: Array[T], i: int, j: int, k: int, keyf: Callable[[T], S], T: type, S: type
) -> void:
):
_sort2(arr, i, j, keyf)
_sort2(arr, j, k, keyf)
_sort2(arr, i, j, keyf)
@ -184,7 +184,7 @@ def _pdq_sort(
leftmost: bool,
T: type,
S: type,
) -> void:
):
while True:
size = end - begin
if size < INSERTION_SORT_THRESHOLD:
@ -292,7 +292,7 @@ def _pdq_sort(
def pdq_sort_array(
collection: Array[T], size: int, keyf: Callable[[T], S], T: type, S: type
) -> void:
):
"""
Pattern-defeating Quicksort
By Orson Peters, published at https://github.com/orlp/pdqsort
@ -304,7 +304,7 @@ def pdq_sort_array(
def pdq_sort_inplace(
collection: List[T], keyf: Callable[[T], S], T: type, S: type
) -> void:
):
"""
Pattern-defeating Quicksort
By Orson Peters, published at https://github.com/orlp/pdqsort

View File

@ -32,11 +32,11 @@ def _med3(
)
def _swap(i: int, j: int, a: Array[T], T: type) -> void:
def _swap(i: int, j: int, a: Array[T], T: type):
a[i], a[j] = a[j], a[i]
def _vecswap(i: int, j: int, n: int, a: Array[T], T: type) -> void:
def _vecswap(i: int, j: int, n: int, a: Array[T], T: type):
while n > 0:
_swap(i, j, a)
i += 1
@ -45,14 +45,14 @@ def _vecswap(i: int, j: int, n: int, a: Array[T], T: type) -> void:
def _qsort(
arr: Array[T], frm: int, cnt: int, keyf: Callable[[T], S], T: type, S: type
) -> void:
arr: Array[T], frm: int, cnt: int, key: Callable[[T], S], T: type, S: type
):
if cnt <= 7:
i = frm + 1
while i < frm + cnt:
j = i
while j > frm and not (
keyf(arr[j - 1]) < keyf(arr[j]) or keyf(arr[j - 1]) == keyf(arr[j])
key(arr[j - 1]) < key(arr[j]) or key(arr[j - 1]) == key(arr[j])
):
_swap(j, j - 1, arr)
j -= 1
@ -65,10 +65,10 @@ def _qsort(
if cnt > 40:
s = cnt // 8
lo = _med3(lo, lo + s, lo + 2 * s, arr, keyf)
mid = _med3(mid - s, mid, mid + s, arr, keyf)
hi = _med3(hi - 2 * s, hi - s, hi, arr, keyf)
mid = _med3(lo, mid, hi, arr, keyf)
lo = _med3(lo, lo + s, lo + 2 * s, arr, key)
mid = _med3(mid - s, mid, mid + s, arr, key)
hi = _med3(hi - 2 * s, hi - s, hi, arr, key)
mid = _med3(lo, mid, hi, arr, key)
_swap(frm, mid, arr)
a = frm
@ -78,15 +78,15 @@ def _qsort(
while True:
while b <= c and (
keyf(arr[b]) < keyf(arr[frm]) or keyf(arr[b]) == keyf(arr[frm])
key(arr[b]) < key(arr[frm]) or key(arr[b]) == key(arr[frm])
):
if keyf(arr[b]) == keyf(arr[frm]):
if key(arr[b]) == key(arr[frm]):
_swap(a, b, arr)
a += 1
b += 1
while c >= b and not keyf(arr[c]) < keyf(arr[frm]):
if keyf(arr[c]) == keyf(arr[frm]):
while c >= b and not key(arr[c]) < key(arr[frm]):
if key(arr[c]) == key(arr[frm]):
_swap(c, d, arr)
d -= 1
c -= 1
@ -106,44 +106,44 @@ def _qsort(
span = b - a
if span > 1:
_qsort(arr, frm, span, keyf)
_qsort(arr, frm, span, key)
span = d - c
if span > 1:
_qsort(arr, hi - span, span, keyf)
_qsort(arr, hi - span, span, key)
def qsort_array(
collection: Array[T], size: int, keyf: Callable[[T], S], T: type, S: type
) -> void:
collection: Array[T], size: int, key: Callable[[T], S], T: type, S: type
):
"""
Pattern-defeating Quicksort
By Orson Peters, published at https://github.com/orlp/pdqsort
Sorts the array inplace.
"""
_qsort(collection, 0, size, keyf)
_qsort(collection, 0, size, key)
def qsort_inplace(
collection: List[T], keyf: Callable[[T], S], T: type, S: type
) -> void:
collection: List[T], key: Callable[[T], S], T: type, S: type
):
"""
Pattern-defeating Quicksort
By Orson Peters, published at https://github.com/orlp/pdqsort
Sorts the list inplace.
"""
qsort_array(collection.arr, collection.len, keyf)
qsort_array(collection.arr, collection.len, key)
def qsort(collection: List[T], keyf: Callable[[T], S], T: type, S: type) -> List[T]:
def qsort(collection: List[T], key: Callable[[T], S], T: type, S: type) -> List[T]:
"""
Pattern-defeating Quicksort
By Orson Peters, published at https://github.com/orlp/pdqsort
Returns a sorted list.
"""
newlst = copy(collection)
qsort_inplace(newlst, keyf)
return newlst
collection = collection[:]
qsort_inplace(collection, key)
return collection

View File

@ -86,16 +86,13 @@ def string_search_rabin_karp(
yield len(text) - len(pattern)
def computeLPArray(pattern: str, len_pat: int) -> List[int]:
def compute_lp_array(pattern: str, len_pat: int) -> List[int]:
"""
Return a list containing the length of the maximum matching
proper prefix of the pattern[0, 1, ..., i]
"""
len = 0 # length of the previous longest prefix
lp = List[
int
]() # longest proper prefix will hold the longest prefix values for pattern
lp.append(0)
lp = [0] # longest proper prefix will hold the longest prefix values for pattern
i = 1
while i < len_pat:
@ -112,7 +109,7 @@ def computeLPArray(pattern: str, len_pat: int) -> List[int]:
return lp
def string_search_KMP(text: str, pattern: str) -> Generator[int]:
def string_search_kmp(text: str, pattern: str) -> Generator[int]:
"""
Knuth-Morris-Pratt algorithm
Return a list containing the position of each index
@ -123,7 +120,7 @@ def string_search_KMP(text: str, pattern: str) -> Generator[int]:
yield i
return
lp_array = computeLPArray(pattern, len(pattern))
lp_array = compute_lp_array(pattern, len(pattern))
i, j = 0, 0 # indices for text and pattern
while i < len(text):
if pattern[j] == text[i]:
@ -148,7 +145,7 @@ def replace_interleave(self, new: str, maxcount: int) -> str:
"""
j = 0
res = List[str]()
res = []
# insert the new string for maxcount <= len(self) times.
for i in range(len(self)):
if i + 1 > maxcount:
@ -168,7 +165,7 @@ def replace_delete_substring(self, old: str, new: str, maxcount: int) -> str:
Returns a string deleting any instances of the 'old' string in self and
replaceing it with the 'new' string.
"""
li = list(string_search_KMP(self, old))
li = list(string_search_kmp(self, old))
# no matches
if len(li) == 0:
@ -185,7 +182,7 @@ def replace_delete_substring(self, old: str, new: str, maxcount: int) -> str:
assert result_len >= 0
j = li[0]
res = List[str]()
res = []
res.append(self[0:j])
# replace the old substring with the new substring

View File

@ -42,6 +42,8 @@
#
# 8. By copying, installing or otherwise using Python 3.10.2, Licensee agrees
# to be bound by the terms and conditions of this License Agreement.
#
# Timsort by Tim Peters, published at https://github.com/python/cpython/blob/master/Objects/listobject.c#L2187
BLOCK_SIZE = 64
CACHELINE_SIZE = 64
@ -94,7 +96,7 @@ def _merge_compute_minrun(n: int) -> int:
return n + r
def _reverse_sortslice(arr: Array[T], begin: int, end: int, T: type) -> void:
def _reverse_sortslice(arr: Array[T], begin: int, end: int, T: type):
if end - begin < 2:
return
arr[begin], arr[end - 1] = arr[end - 1], arr[begin]
@ -186,7 +188,7 @@ def _merge_with_gallop(
keyf: Callable[[T], S],
T: type,
S: type,
) -> void:
):
min_gallop = MIN_GALLOP
combined = Array[T](a[1] + b[1])
@ -284,7 +286,7 @@ def _merge_at(
keyf: Callable[[T], S],
T: type,
S: type,
) -> void:
):
start_a, len_a = a
start_b, len_b = b
@ -308,7 +310,7 @@ def _merge_collapse(
keyf: Callable[[T], S],
T: type,
S: type,
) -> void:
):
if len(stack) <= 1:
return
@ -357,7 +359,7 @@ def _final_merge(
keyf: Callable[[T], S],
T: type,
S: type,
) -> void:
):
while len(stack) > 1:
C = stack.pop()
B = stack.pop()
@ -367,7 +369,7 @@ def _final_merge(
def _tim_sort(
arr: Array[T], begin: int, end: int, keyf: Callable[[T], S], T: type, S: type
) -> void:
):
if end - begin < 2:
return
@ -393,35 +395,17 @@ def _tim_sort(
def tim_sort_array(
collection: Array[T], size: int, keyf: Callable[[T], S], T: type, S: type
) -> void:
"""
Timsort
By Tim Peters, published at https://github.com/python/cpython/blob/master/Objects/listobject.c#L2187
Sorts the array inplace.
"""
):
_tim_sort(collection, 0, size, keyf)
def tim_sort_inplace(
collection: List[T], keyf: Callable[[T], S], T: type, S: type
) -> void:
"""
Timsort
By Tim Peters, published at https://github.com/python/cpython/blob/master/Objects/listobject.c#L2187
Sorts the list inplace.
"""
):
tim_sort_array(collection.arr, collection.len, keyf)
def tim_sort(collection: List[T], keyf: Callable[[T], S], T: type, S: type) -> List[T]:
"""
Timsort
By Tim Peters, published at https://github.com/python/cpython/blob/master/Objects/listobject.c#L2187
Returns a sorted list.
"""
newlst = list(collection)
tim_sort_inplace(newlst, keyf)
return newlst

View File

@ -61,8 +61,7 @@ def bisect_left(
"""
if lo < 0:
raise ValueError("lo must be non-negative")
if hi is None:
hi = len(a)
hi: int = len(a) if hi is None else hi
while lo < hi:
mid = (lo + hi) // 2
if a[mid] < x:
@ -89,8 +88,7 @@ def bisect_right(
"""
if lo < 0:
raise ValueError("lo must be non-negative")
if hi is None:
hi = len(a)
hi: int = len(a) if hi is None else hi
while lo < hi:
mid = (lo + hi) // 2
if x < a[mid]:
@ -102,7 +100,7 @@ def bisect_right(
def insort_left(
a: List[T], x: S, lo: int = 0, hi: Optional[int] = None, T: type, S: type
) -> void:
):
"""
Insert item x in list a, and keep it sorted assuming a is sorted.
@ -117,7 +115,7 @@ def insort_left(
def insort_right(
a: List[T], x: S, lo: int = 0, hi: Optional[int] = None, T: type, S: type
) -> void:
):
"""
Insert item x in list a, and keep it sorted assuming a is sorted.

View File

@ -1,26 +1,28 @@
# (c) 2022 Exaloop Inc. All rights reserved.
from internal.types.optional import unwrap
class deque:
T: type
_arr: Array[T]
_head: int
_tail: int
_maxlen: int
T: type
def __init__(self, arr: Array[T], head: int, tail: int, maxlen: int) -> void:
def __init__(self, arr: Array[T], head: int, tail: int, maxlen: int):
self._arr = arr
self._head = head
self._tail = tail
self._maxlen = maxlen
def __init__(self) -> void:
def __init__(self):
self._arr = Array[T](16)
self._head = 0
self._tail = 0
self._maxlen = -1
def __init__(self, maxlen: int) -> void:
def __init__(self, maxlen: int):
cap = 1
while cap < maxlen:
cap *= 2
@ -29,7 +31,7 @@ class deque:
self._tail = 0
self._maxlen = maxlen
def __init__(self, it: Generator[T]) -> void:
def __init__(self, it: Generator[T]):
self._arr = Array[T](16)
self._head = 0
self._tail = 0
@ -41,7 +43,7 @@ class deque:
def maxlen(self) -> int:
return self._maxlen
def _double_cap(self) -> void:
def _double_cap(self):
p = self._head
n = len(self._arr)
r = n - p
@ -55,7 +57,7 @@ class deque:
self._head = 0
self._tail = n
def _check_not_empty(self) -> void:
def _check_not_empty(self):
if not self:
raise IndexError("pop from an empty deque")
@ -65,7 +67,7 @@ class deque:
def __len__(self) -> int:
return (self._tail - self._head) & (len(self._arr) - 1)
def appendleft(self, x: T) -> void:
def appendleft(self, x: T):
self._head = (self._head - 1) & (len(self._arr) - 1)
self._arr[self._head] = x
if self._maxlen >= 0 and len(self) > self._maxlen:
@ -73,7 +75,7 @@ class deque:
if self._head == self._tail:
self._double_cap()
def append(self, x: T) -> void:
def append(self, x: T):
self._arr[self._tail] = x
self._tail = (self._tail + 1) & (len(self._arr) - 1)
if self._maxlen >= 0 and len(self) > self._maxlen:
@ -92,7 +94,7 @@ class deque:
self._tail = (self._tail - 1) & (len(self._arr) - 1)
return self._arr[self._tail]
def clear(self) -> void:
def clear(self):
self._head = 0
self._tail = 0
@ -120,7 +122,7 @@ class deque:
def __repr__(self) -> str:
return repr(List[T](iter(self)))
def _idx_check(self, idx: int, msg: str) -> void:
def _idx_check(self, idx: int, msg: str):
if self._head == self._tail or idx >= len(self) or idx < 0:
raise IndexError(msg)
@ -145,9 +147,9 @@ class deque:
@tuple
class _CounterItem:
T: type
element: T
count: int
T: type
def __eq__(self, other: _CounterItem[T]) -> bool:
return self.count == other.count
@ -171,17 +173,14 @@ class _CounterItem:
class Counter(Dict[T, int]):
T: type
def _add(self, element: T) -> void:
self.increment(element)
def __init__(self, elements: Generator[T]) -> void:
def __init__(self, elements: Generator[T]):
self._init()
self.update(elements)
def __init__(self, other: Counter[T]) -> void:
def __init__(self, other: Counter[T]):
self._init_from(other)
def __init__(self, other: Dict[T, int]) -> void:
def __init__(self, other: Dict[T, int]):
self._init_from(other)
def elements(self) -> Generator[T]:
@ -202,14 +201,14 @@ class Counter(Dict[T, int]):
else:
from heapq import heapify, heapreplace
n: int = ~n
n: int = n
if n == 1:
top: Optional[_CounterItem] = None
for t in self.items():
if top is None or t[1] > top.count:
top = t
return [~top]
return [unwrap(top)]
if n <= 0:
return List[_CounterItem](capacity=0)
@ -227,31 +226,31 @@ class Counter(Dict[T, int]):
result.sort(reverse=True)
return result
def subtract(self, elements: Generator[T]) -> void:
def subtract(self, elements: Generator[T]):
for a in elements:
self.increment(a, -1)
def subtract(self, other: Counter[T]) -> void:
def subtract(self, other: Counter[T]):
for k, v in other.items():
self.increment(k, -v)
def subtract(self, other: Dict[T, int]) -> void:
def subtract(self, other: Dict[T, int]):
for k, v in other.items():
self.increment(k, -v)
def update(self, elements: Generator[T]) -> void:
def update(self, elements: Generator[T]):
for a in elements:
self._add(a)
self.increment(a)
def update(self, other: Counter[T]) -> void:
def update(self, other: Counter[T]):
for k, v in other.items():
self.increment(k, by=v)
def update(self, other: Dict[T, int]) -> void:
def update(self, other: Dict[T, int]):
for k, v in other.items():
self.increment(k, by=v)
def update(self) -> void:
def update(self):
pass
def total(self) -> int:
@ -263,7 +262,7 @@ class Counter(Dict[T, int]):
def __getitem__(self, key: T) -> int:
return self.get(key, 0)
def __delitem__(self, key: T) -> void:
def __delitem__(self, key: T):
x = self._kh_get(key)
if x != self._kh_end():
self._kh_del(x)
@ -282,11 +281,6 @@ class Counter(Dict[T, int]):
def __copy__(self) -> Counter[T]:
return Counter[T](self)
def _del_non_positives(self) -> void:
for k, v in self.items():
if v <= 0:
del self[k]
def __iadd__(self, other: Counter[T]) -> Counter[T]:
for k, v in other.items():
self.increment(k, by=v)
@ -348,13 +342,18 @@ class Counter(Dict[T, int]):
result |= other
return result
def __dict_do_op_throws__[F, Z](self, key: T, other: Z, op: F):
def __dict_do_op_throws__(self, key: T, other: Z, op: F, F: type, Z: type):
self.__dict_do_op__(key, other, 0, op)
def _del_non_positives(self):
for k, v in self.items():
if v <= 0:
del self[k]
@extend
class Dict:
def __init__(self: Dict[K, int], other: Counter[K]) -> void:
def __init__(self: Dict[K, int], other: Counter[K]):
self._init_from(other)

View File

@ -179,12 +179,12 @@ def _iso_week1_monday(year: int) -> int:
return week1_monday
def _check_delta_day_range(days: int) -> void:
def _check_delta_day_range(days: int):
if not (-MAX_DELTA_DAYS <= days <= MAX_DELTA_DAYS):
raise OverflowError(f"days={days}; must have magnitude <= {MAX_DELTA_DAYS}")
def _check_date_args(year: int, month: int, day: int) -> void:
def _check_date_args(year: int, month: int, day: int):
if not (MINYEAR <= year <= MAXYEAR):
raise ValueError(f"year {year} is out of range")
if not (1 <= month <= 12):
@ -193,7 +193,7 @@ def _check_date_args(year: int, month: int, day: int) -> void:
raise ValueError("day is out of range for month")
def _check_time_args(hour: int, minute: int, second: int, microsecond: int) -> void:
def _check_time_args(hour: int, minute: int, second: int, microsecond: int):
if not (0 <= hour <= 23):
raise ValueError("hour must be in 0..23")
if not (0 <= minute <= 59):
@ -295,7 +295,7 @@ def _parse_digits(digits: str, num_digits: int) -> Tuple[str, int]:
return str(p, len(digits) - num_digits), var
def _isoformat_error(s: str) -> void:
def _isoformat_error(s: str):
raise ValueError(f"Invalid isoformat string: {s}")

View File

@ -68,10 +68,10 @@ import os
class GetoptError:
_hdr: ExcHeader
def __init__(self) -> void:
def __init__(self):
self._hdr = ("GetoptError", "", "", "", 0, 0)
def __init__(self, message: str) -> void:
def __init__(self, message: str):
self._hdr = ("GetoptError", message, "", "", 0, 0)
@property
@ -79,9 +79,6 @@ class GetoptError:
return self._hdr.msg
# Return:
# has_arg?
# full option name
def long_has_args(opt: str, longopts: List[str]) -> Tuple[bool, str]:
possibilities = [o for o in longopts if o.startswith(opt)]
if not possibilities:
@ -122,7 +119,7 @@ def do_longs(
optarg, args = args[0], args[1:]
elif optarg != "":
raise GetoptError(f"option --{opt} must not have an argument")
opts.append(("--" + opt, optarg))
opts.append((f"--{opt}", optarg))
return opts, args
@ -145,7 +142,7 @@ def do_shorts(
raise GetoptError(f"option -{opt} requires argument")
optstring, args = args[0], args[1:]
optarg, optstring = optstring, ""
opts.append(("-" + opt, optarg))
opts.append((f"-{opt}", optarg))
return opts, args

View File

@ -1,11 +1,9 @@
# (c) 2022 Exaloop Inc. All rights reserved.
# TODO: heapq.merge
# 'heap' is a heap at all indices >= startpos, except possibly for pos. pos
# is the index of a leaf with a possibly out-of-order value. Restore the
# heap invariant.
def _siftdown(heap: List[T], startpos: int, pos: int, T: type) -> void:
def _siftdown(heap: List[T], startpos: int, pos: int, T: type):
newitem = heap[pos]
# Follow the path to the root, moving parents down until finding a place
# newitem fits.
@ -20,7 +18,7 @@ def _siftdown(heap: List[T], startpos: int, pos: int, T: type) -> void:
heap[pos] = newitem
def _siftup(heap: List[T], pos: int, T: type) -> void:
def _siftup(heap: List[T], pos: int, T: type):
endpos = len(heap)
startpos = pos
newitem = heap[pos]
@ -41,7 +39,7 @@ def _siftup(heap: List[T], pos: int, T: type) -> void:
_siftdown(heap, startpos, pos)
def _siftdown_max(heap: List[T], startpos: int, pos: int, T: type) -> void:
def _siftdown_max(heap: List[T], startpos: int, pos: int, T: type):
"Maxheap variant of _siftdown"
newitem = heap[pos]
# Follow the path to the root, moving parents down until finding a place
@ -57,7 +55,7 @@ def _siftdown_max(heap: List[T], startpos: int, pos: int, T: type) -> void:
heap[pos] = newitem
def _siftup_max(heap: List[T], pos: int, T: type) -> void:
def _siftup_max(heap: List[T], pos: int, T: type):
"Maxheap variant of _siftup"
endpos = len(heap)
startpos = pos
@ -79,7 +77,7 @@ def _siftup_max(heap: List[T], pos: int, T: type) -> void:
_siftdown_max(heap, startpos, pos)
def heappush(heap: List[T], item: T, T: type) -> void:
def heappush(heap: List[T], item: T, T: type):
"""Push item onto heap, maintaining the heap invariant."""
heap.append(item)
_siftdown(heap, 0, len(heap) - 1)
@ -119,7 +117,7 @@ def heappushpop(heap: List[T], item: T, T: type) -> T:
return item
def heapify(x: List[T], T: type) -> void:
def heapify(x: List[T], T: type):
"""Transform list into a heap, in-place, in $O(len(x))$ time."""
n = len(x)
# Transform bottom-up. The largest index there's any point to looking at
@ -150,7 +148,7 @@ def _heapreplace_max(heap: List[T], item: T, T: type) -> T:
return returnitem
def _heapify_max(x: List[T], T: type) -> void:
def _heapify_max(x: List[T], T: type):
"""Transform list into a maxheap, in-place, in O(len(x)) time."""
n = len(x)
for i in reversed(range(n // 2)):

View File

@ -24,7 +24,7 @@ import internal.c_stubs as _C
def next(g: Generator[T], default: Optional[T] = None, T: type) -> T:
if g.done():
if default:
return ~default
return unwrap(default)
else:
raise StopIteration()
return g.next()
@ -34,16 +34,16 @@ from C import seq_print_full(str, cobj)
class Set:
T: type
items: List[T]
T: type
def __init__(self) -> void:
self.items = List[T]()
def __init__(self):
self.items = []
def __iter__(self) -> Generator[T]:
yield from self.items
def add(self, what: T) -> void:
def add(self, what: T):
if what not in self.items:
self.items.append(what)
@ -55,14 +55,14 @@ class Set:
class Dict:
K: type
V: type
keys: List[K]
values: List[V]
K: type
V: type
def __init__(self) -> void:
self.keys = List[K]()
self.values = List[V]()
def __init__(self):
self.keys = []
self.values = []
def __iter__(self) -> Generator[K]:
yield from self.keys
@ -78,7 +78,7 @@ class Dict:
i = self.keys.index(key)
return self.values[i]
def __setitem__(self, key: K, val: V) -> void:
def __setitem__(self, key: K, val: V):
i = self.keys.index(key)
if i != -1:
self.values[i] = val
@ -94,7 +94,7 @@ class Dict:
if n == 0:
return "{}"
else:
lst = List[str]()
lst = []
lst.append("{")
first = True
for k, v in self.items():
@ -128,7 +128,7 @@ class str:
raise ValueError("nope")
def __repr__(self) -> str:
return "'" + self + "'"
return f"'{self}'"
from internal.builtin import *

View File

@ -1,6 +1,7 @@
# (c) 2022 Exaloop Inc. All rights reserved.
from internal.gc import alloc_atomic, free
from internal.types.optional import unwrap
@tuple
@ -19,7 +20,7 @@ def id(x) -> int:
_stdout = _C.seq_stdout()
def print(*args, sep: str = " ", end: str = "\n", file=_stdout, flush: bool = False) -> void:
def print(*args, sep: str = " ", end: str = "\n", file=_stdout, flush: bool = False):
"""
Print args to the text stream file.
"""
@ -134,7 +135,7 @@ def ord(s: str) -> int:
"""
if len(s) != 1:
raise TypeError(
"ord() expected a character, but string of length " + str(len(s)) + " found"
f"ord() expected a character, but string of length {len(s)} found"
)
return int(s.ptr[0])
@ -162,7 +163,7 @@ def next(g: Generator[T], default: Optional[T] = None, T: type) -> T:
"""
if g.done():
if default:
return ~default
return unwrap(default)
else:
raise StopIteration()
return g.next()
@ -367,7 +368,7 @@ class int:
if end != p + n:
raise ValueError(
"invalid literal for int() with base " + str(base) + ": " + s
f"invalid literal for int() with base {base}: {s}"
)
return result

View File

@ -49,6 +49,6 @@ def dlsym(lib, name: str, Fn: type) -> Fn:
return Fn(fn)
def dlclose(handle: cobj) -> void:
def dlclose(handle: cobj):
if c_dlclose(handle) != i32(0):
raise CError(dlerror())

View File

@ -8,25 +8,25 @@ class File:
buf: Ptr[byte]
fp: cobj
def __init__(self, fp: cobj) -> void:
def __init__(self, fp: cobj):
self.fp = fp
self._reset()
def __init__(self, path: str, mode: str) -> void:
def __init__(self, path: str, mode: str):
self.fp = _C.fopen(path.c_str(), mode.c_str())
if not self.fp:
raise IOError("file " + path + " could not be opened")
raise IOError(f"file {path} could not be opened")
self._reset()
def _errcheck(self, msg: str) -> void:
def _errcheck(self, msg: str):
err = int(_C.ferror(self.fp))
if err:
raise IOError("file I/O error: " + msg)
raise IOError(f"file I/O error: {msg}")
def __enter__(self) -> void:
def __enter__(self):
pass
def __exit__(self) -> void:
def __exit__(self):
self.close()
def __iter__(self) -> Generator[str]:
@ -36,12 +36,12 @@ class File:
def readlines(self) -> List[str]:
return [l for l in self]
def write(self, s: str) -> void:
def write(self, s: str):
self._ensure_open()
_C.fwrite(s.ptr, 1, len(s), self.fp)
self._errcheck("error in write")
def __file_write_gen__(self, g: Generator[T], T: type) -> void:
def __file_write_gen__(self, g: Generator[T], T: type):
for s in g:
self.write(str(s))
@ -57,14 +57,14 @@ class File:
self._errcheck("error in tell")
return ret
def seek(self, offset: int, whence: int) -> void:
def seek(self, offset: int, whence: int):
_C.fseek(self.fp, offset, i32(whence))
self._errcheck("error in seek")
def flush(self) -> void:
def flush(self):
_C.fflush(self.fp)
def close(self) -> void:
def close(self):
if self.fp:
_C.fclose(self.fp)
self.fp = cobj()
@ -72,11 +72,11 @@ class File:
_C.free(self.buf)
self._reset()
def _ensure_open(self) -> void:
def _ensure_open(self):
if not self.fp:
raise IOError("I/O operation on closed file")
def _reset(self) -> void:
def _reset(self):
self.buf = Ptr[byte]()
self.sz = 0
@ -105,11 +105,11 @@ class File:
break
def _gz_errcheck(stream: cobj) -> void:
def _gz_errcheck(stream: cobj):
errnum = i32(0)
msg = _C.gzerror(stream, __ptr__(errnum))
if msg and msg[0]:
raise IOError("zlib error: " + str(msg, _C.strlen(msg)))
raise IOError(f"zlib error: {str(msg, _C.strlen(msg))}")
class gzFile:
@ -117,14 +117,14 @@ class gzFile:
buf: Ptr[byte]
fp: cobj
def __init__(self, fp: cobj) -> void:
def __init__(self, fp: cobj):
self.fp = fp
self._reset()
def __init__(self, path: str, mode: str) -> void:
def __init__(self, path: str, mode: str):
self.fp = _C.gzopen(path.c_str(), mode.c_str())
if not self.fp:
raise IOError("file " + path + " could not be opened")
raise IOError(f"file {path} could not be opened")
self._reset()
def _getline(self) -> int:
@ -154,13 +154,13 @@ class gzFile:
for a in self._iter():
yield a.__ptrcopy__()
def __enter__(self) -> void:
def __enter__(self):
pass
def __exit__(self) -> void:
def __exit__(self):
self.close()
def close(self) -> void:
def close(self):
if self.fp:
_C.gzclose(self.fp)
self.fp = cobj()
@ -171,12 +171,12 @@ class gzFile:
def readlines(self) -> List[str]:
return [l for l in self]
def write(self, s: str) -> void:
def write(self, s: str):
self._ensure_open()
_C.gzwrite(self.fp, s.ptr, u32(len(s)))
_gz_errcheck(self.fp)
def __file_write_gen__(self, g: Generator[T], T: type) -> void:
def __file_write_gen__(self, g: Generator[T], T: type):
for s in g:
self.write(str(s))
@ -185,7 +185,7 @@ class gzFile:
_gz_errcheck(self.fp)
return ret
def seek(self, offset: int, whence: int) -> void:
def seek(self, offset: int, whence: int):
_C.gzseek(self.fp, offset, i32(whence))
_gz_errcheck(self.fp)
@ -209,11 +209,11 @@ class gzFile:
else:
break
def _ensure_open(self) -> void:
def _ensure_open(self):
if not self.fp:
raise IOError("I/O operation on closed file")
def _reset(self) -> void:
def _reset(self):
self.buf = cobj()
self.sz = 0
@ -227,6 +227,9 @@ def gzopen(path: str, mode: str = "r") -> gzFile:
def is_binary(path: str) -> bool:
# https://stackoverflow.com/questions/898669/how-can-i-detect-if-a-file-is-binary-non-text-in-python/7392391#7392391
# Can get both false positive and false negatives, but still is a
# clever approach that works for the large majority of files
textchars = {7, 8, 9, 10, 12, 13, 27} | set(iter(range(0x20, 0x100))) - {0x7F}
with open(path, "rb") as f:
header = f.read(1024)

View File

@ -34,7 +34,7 @@ class __internal__:
if idx < 0:
idx += len
if idx < 0 or idx >= len:
raise IndexError("tuple index " + str(idx) + " out of range 0.." + str(len))
raise IndexError(f"tuple index {idx} out of range 0..{len}")
return idx
def tuple_getitem(t: T, idx: int, T: type, E: type) -> E:
@ -73,19 +73,16 @@ class __internal__:
ret i{=T} %0
def seq_assert(file: str, line: int, msg: str) -> AssertionError:
s = "Assert failed"
if msg:
s += ": " + msg
s += " (" + file + ":" + line.__repr__() + ")"
s = f": {msg}" if msg else ""
s = f"Assert failed{s} ({file}:{line.__repr__()})"
return AssertionError(s)
def seq_assert_test(file: str, line: int, msg: str) -> void:
s = "\033[1;31mTEST FAILED:\033[0m " + file + " (line " + str(line) + ")"
if msg:
s += ": " + msg
seq_print(s + "\n")
def seq_assert_test(file: str, line: int, msg: str):
s = f": {msg}" if msg else ""
s = f"\033[1;31mTEST FAILED:\033[0m {file} (line {line}){s}\n"
seq_print(s)
def check_errno(prefix: str) -> void:
def check_errno(prefix: str):
msg = seq_check_errno()
if msg:
raise OSError(prefix + msg)

View File

@ -13,19 +13,19 @@ def __ac_iseither(flag: Ptr[u32], i: int) -> int:
return int(flag[i >> 4] >> u32((i & 0xF) << 1)) & 3
def __ac_set_isdel_false(flag: Ptr[u32], i: int) -> void:
def __ac_set_isdel_false(flag: Ptr[u32], i: int):
flag[i >> 4] &= u32(~(1 << ((i & 0xF) << 1)))
def __ac_set_isempty_false(flag: Ptr[u32], i: int) -> void:
def __ac_set_isempty_false(flag: Ptr[u32], i: int):
flag[i >> 4] &= u32(~(2 << ((i & 0xF) << 1)))
def __ac_set_isboth_false(flag: Ptr[u32], i: int) -> void:
def __ac_set_isboth_false(flag: Ptr[u32], i: int):
flag[i >> 4] &= u32(~(3 << ((i & 0xF) << 1)))
def __ac_set_isdel_true(flag: Ptr[u32], i: int) -> void:
def __ac_set_isdel_true(flag: Ptr[u32], i: int):
flag[i >> 4] |= u32(1 << ((i & 0xF) << 1))

View File

@ -77,12 +77,12 @@ def __codon_repr__(fig):
_PY_INITIALIZED = False
def init() -> void:
def init():
global _PY_INITIALIZED
if _PY_INITIALIZED:
return
LD = os.getenv("CODON_PYTHON", default="libpython." + dlext())
LD = os.getenv("CODON_PYTHON", default=f"libpython.{dlext()}")
hnd = dlopen(LD, RTLD_LOCAL | RTLD_NOW)
global PyUnicode_AsEncodedString
@ -163,7 +163,7 @@ def init() -> void:
_PY_INITIALIZED = True
def ensure_initialized() -> void:
def ensure_initialized():
if not _PY_INITIALIZED:
init()
# raise ValueError("Python not initialized; make sure to 'import python'")
@ -215,7 +215,7 @@ class pyobj:
pyobj(obj).decref()
return str.from_ptr(bts)
def exc_check() -> void:
def exc_check():
ptype, pvalue, ptraceback = cobj(), cobj(), cobj()
PyErr_Fetch(__ptr__(ptype), __ptr__(pvalue), __ptr__(ptraceback))
if ptype != cobj():
@ -236,15 +236,15 @@ class pyobj:
pyobj.exc_check()
return _retval
def incref(self) -> void:
def incref(self):
Py_IncRef(self.p)
def decref(self) -> void:
def decref(self):
Py_DecRef(self.p)
def __call__(self, *args, **kwargs) -> pyobj:
names = iter(kwargs.__dict__())
kws = Dict[str, pyobj]()
kws = dict[str, pyobj]()
if staticlen(kwargs) > 0:
kws = {next(names): i.__to_py__() for i in kwargs}
return pyobj.exc_wrap(
@ -256,7 +256,7 @@ class pyobj:
pyobj.exc_check()
return pyobj(t)
def _tuple_set(self, idx: int, val: pyobj) -> void:
def _tuple_set(self, idx: int, val: pyobj):
PyTuple_SetItem(self.p, idx, val.p)
pyobj.exc_check()
@ -273,7 +273,7 @@ class pyobj:
_PY_MODULE_CACHE[name] = m
return m
def _exec(code: str) -> void:
def _exec(code: str):
ensure_initialized()
PyRun_SimpleString(code.c_str())
@ -388,7 +388,7 @@ class Dict:
return pyobj(pydict)
def __from_py__(d: pyobj) -> Dict[K, V]:
b = Dict[K, V]()
b = dict[K, V]()
pos = 0
k_ptr = cobj()
v_ptr = cobj()

View File

@ -27,7 +27,7 @@ def sorted(
def _sort_list(
self: List[T], key: Callable[[T], S], algorithm: str, T: type, S: type
) -> void:
):
if algorithm == "tim":
tim_sort_inplace(self, key)
elif algorithm == "pdq":
@ -39,7 +39,7 @@ def _sort_list(
elif algorithm == "quick":
qsort_inplace(self, key)
else:
raise ValueError("Algorithm '" + algorithm + "' does not exist")
raise ValueError(f"Algorithm '{algorithm}' does not exist")
@extend
@ -49,11 +49,11 @@ class List:
key=Optional[int](),
algorithm: Optional[str] = None,
reverse: bool = False,
) -> void:
alg = ~algorithm if algorithm else "tim"
):
algorithm: str = algorithm if algorithm else "tim"
if isinstance(key, Optional):
_sort_list(self, lambda x: x, alg)
_sort_list(self, lambda x: x, algorithm)
else:
_sort_list(self, key, alg)
_sort_list(self, key, algorithm)
if reverse:
self.reverse()

View File

@ -142,7 +142,7 @@ class str:
def join(self, l: Generator[str]) -> str:
if len(self) == 0:
return str.cat(list(l))
v = List[str]()
v = []
for a in l:
v.append(a)
v.append(self)
@ -561,7 +561,7 @@ class str:
if width <= len(self):
return self
s = List[str]()
s = []
if self and (self[0] == "+" or self[0] == "-"):
# move sign to beginning of string
s.append(self[0])
@ -577,7 +577,7 @@ class str:
s.append(self)
return "".join(s)
def count(self, sub: str, start: int = 0, end: int = 0x7FFFFFFFFFFFFFFF) -> int:
def count(self, sub: str, start: int = 0, end: Optional[int] = None) -> int:
"""
str.count(sub[, start[, end]]) -> int
@ -585,13 +585,14 @@ class str:
bytes str[start:end]. Optional arguments start and end are interpreted
as in slice notation.
"""
end: int = end if end is not None else len(self)
start, end = self._correct_indices(start, end)
count = 0
for _ in algorithms.filter_overlaps(self[start:end]._search(sub), len(sub)):
count += 1
return count
def find(self, sub: str, start: int = 0, end: int = 0x7FFFFFFFFFFFFFFF) -> int:
def find(self, sub: str, start: int = 0, end: Optional[int] = None) -> int:
"""
str.find(sub [,start [,end]]) -> int
@ -601,6 +602,7 @@ class str:
Return -1 on failure.
"""
end: int = end if end is not None else len(self)
start, end = self._correct_indices(start, end)
pos = str._getfirst(self[start:end]._search(sub))
@ -615,7 +617,7 @@ class str:
return pos + start # add start position because of truncation
def rfind(self, sub: str, start: int = 0, end: int = 0x7FFFFFFFFFFFFFFF) -> int:
def rfind(self, sub: str, start: int = 0, end: Optional[int] = None) -> int:
"""
str.rfind(sub [,start [,end]]) -> int
@ -625,6 +627,7 @@ class str:
Return -1 on failure.
"""
end: int = end if end is not None else len(self)
start, end = self._correct_indices(start, end)
pos = str._getfirst(self[start:end]._rsearch(sub))
@ -772,16 +775,16 @@ class str:
return self._split_whitespace(
maxsplit if maxsplit >= 0 else 0x7FFFFFFFFFFFFFFF
)
sepx = ~sep
sep: str = sep
li = list(algorithms.filter_overlaps(self._search(sepx), len(sepx)))
str_split = List[str]()
li = list(algorithms.filter_overlaps(self._search(sep), len(sep)))
str_split = []
# no delimiter found
if len(li) == 0:
return [self]
if len(sepx) > len(self):
if len(sep) > len(self):
return [self]
if maxsplit == 0:
@ -805,11 +808,11 @@ class str:
if li[j] - 1 == prev:
str_split.append("")
else:
str_split.append(self[prev + len(sepx) : li[j]])
str_split.append(self[prev + len(sep) : li[j]])
prev = li[j]
if prev != len(self):
str_split.append(self[prev + len(sepx) :])
str_split.append(self[prev + len(sep) :])
return str_split
@ -827,17 +830,17 @@ class str:
return self._rsplit_whitespace(
maxsplit if maxsplit >= 0 else 0x7FFFFFFFFFFFFFFF
)
sepx = ~sep
sep: str = sep
li = list(
algorithms.rfilter_overlaps(reversed(list(self._search(sepx))), len(sepx))
algorithms.rfilter_overlaps(reversed(list(self._search(sep))), len(sep))
)
str_split = List[str]()
str_split = []
end_of_li = len(li) - 1
if len(li) == 0:
return [self]
if len(sepx) > len(self):
if len(sep) > len(self):
return [self]
if maxsplit == 0:
return [self]
@ -848,10 +851,10 @@ class str:
prev = li[0]
# append first part of string
# if sep is found in the last index, add '' to separate
if prev == len(self) - len(sepx):
if prev == len(self) - len(sep):
str_split.append("")
else:
str_split.append(self[prev + len(sepx) :])
str_split.append(self[prev + len(sep) :])
# split the rest of the string according to separator
if len(li) > 1 and maxsplit > 1:
@ -860,7 +863,7 @@ class str:
if li[j] + 1 == prev:
str_split.append("")
else:
str_split.append(self[li[j] + len(sepx) : prev])
str_split.append(self[li[j] + len(sep) : prev])
prev = li[j]
if prev != 0:
@ -882,7 +885,7 @@ class str:
Line breaks are not included in the resulting list unless keepends
is given and true.
"""
line_split = List[str]()
line_split = []
prev = 0
for i in range(len(self)):
@ -953,7 +956,7 @@ class str:
return line_split
def startswith(
self, prefix: str, start: int = 0, end: int = 0x7FFFFFFFFFFFFFFF
self, prefix: str, start: int = 0, end: Optional[int] = None
) -> bool:
"""
str.startswith(prefix[, start[, end]]) -> bool
@ -962,6 +965,7 @@ class str:
With optional start, test str beginning at that position.
With optional end, stop comparing str at that position.
"""
end: int = end if end is not None else len(self)
if end < 0:
end += len(self)
elif start < 0:
@ -981,9 +985,7 @@ class str:
return prefix == self[start : start + len(prefix)]
def endswith(
self, suffix: str, start: int = 0, end: int = 0x7FFFFFFFFFFFFFFF
) -> bool:
def endswith(self, suffix: str, start: int = 0, end: Optional[int] = None) -> bool:
"""
str.endswith(prefix[, start[, end]]) -> bool
@ -991,6 +993,7 @@ class str:
With optional start, test str beginning at that position.
With optional end, stop comparing str at that position.
"""
end: int = end if end is not None else len(self)
if end < 0:
end += len(self)
elif start < 0:
@ -1015,12 +1018,13 @@ class str:
return suffix == self[start : start + len(suffix)]
def index(self, sub: str, start: int = 0, end: int = 0x7FFFFFFFFFFFFFFF) -> int:
def index(self, sub: str, start: int = 0, end: Optional[int] = None) -> int:
"""
str.index(sub [,start [,end]]) -> int
Like str.find() but raise ValueError when the substring is not found.
"""
end: int = end if end is not None else len(self)
start, end = self._correct_indices(start, end)
i = self.find(sub, start, end)
if i == -1:
@ -1028,12 +1032,13 @@ class str:
else:
return i
def rindex(self, sub: str, start: int = 0, end: int = 0x7FFFFFFFFFFFFFFF) -> int:
def rindex(self, sub: str, start: int = 0, end: Optional[int] = None) -> int:
"""
str.index(sub [,start [,end]]) -> int
Like str.find() but raise ValueError when the substring is not found.
"""
end: int = end if end is not None else len(self)
start, end = self._correct_indices(start, end)
i = self.rfind(sub, start, end)
if i == -1:
@ -1086,7 +1091,7 @@ class str:
incr = 0
i = 0 # chars up to and including most recent \n or \r
j = 0 # chars since most recent \n or \r (use in tab calculations)
u = List[str]()
u = []
j = 0 # same as first pass
# create output string and fill it
@ -1147,7 +1152,7 @@ class str:
if len(pattern) <= 5:
yield from algorithms.string_search_slow(self, pattern)
else:
yield from algorithms.string_search_KMP(self, pattern)
yield from algorithms.string_search_kmp(self, pattern)
def _rsearch(self, pattern: str) -> Generator[int]:
if len(pattern) == 1:

View File

@ -11,8 +11,6 @@ def _dict_hash(key) -> int:
class Dict:
K: type
V: type
_n_buckets: int
_size: int
_n_occupied: int
@ -22,9 +20,12 @@ class Dict:
_keys: Ptr[K]
_vals: Ptr[V]
K: type
V: type
# Magic methods
def _init(self) -> void:
def _init(self):
self._n_buckets = 0
self._size = 0
self._n_occupied = 0
@ -33,7 +34,7 @@ class Dict:
self._keys = Ptr[K]()
self._vals = Ptr[V]()
def _init_from(self, other) -> void:
def _init_from(self, other):
n = other._n_buckets
if n == 0:
@ -57,15 +58,15 @@ class Dict:
self._keys = keys_copy
self._vals = vals_copy
def __init__(self) -> void:
def __init__(self):
self._init()
def __init__(self, g: Generator[Tuple[K, V]]) -> void:
def __init__(self, g: Generator[Tuple[K, V]]):
self._init()
for k, v in g:
self[k] = v
def __init__(self, other: Dict[K, V]) -> void:
def __init__(self, other: Dict[K, V]):
self._init_from(other)
def __getitem__(self, key: K) -> V:
@ -74,11 +75,11 @@ class Dict:
return self._vals[x]
raise KeyError(str(key))
def __setitem__(self, key: K, val: V) -> void:
def __setitem__(self, key: K, val: V):
ret, x = self._kh_put(key)
self._vals[x] = val
def __delitem__(self, key: K) -> void:
def __delitem__(self, key: K):
x = self._kh_get(key)
if x != self._kh_end():
self._kh_del(x)
@ -134,7 +135,7 @@ class Dict:
if n == 0:
return "{}"
else:
lst = List[str]()
lst = []
lst.append("{")
first = True
for k, v in self.items():
@ -150,7 +151,7 @@ class Dict:
# Helper methods
def resize(self, new_n_buckets: int) -> void:
def resize(self, new_n_buckets: int):
self._kh_resize(new_n_buckets)
def get(self, key: K, s: V) -> V:
@ -164,25 +165,25 @@ class Dict:
return val
return self._vals[x]
def increment(self, key: K, by: T = 1, T: type) -> void:
def increment(self, key: K, by: T = 1, T: type):
ret, x = self._kh_put(key)
if ret != 0: # i.e. key not present
self._vals[x] = by
else:
self._vals[x] += by
def __dict_do_op_throws__(self, key: K, other: Z, op: F, F: type, Z: type) -> void:
def __dict_do_op_throws__(self, key: K, other: Z, op: F, F: type, Z: type):
x = self._kh_get(key)
if x == self._kh_end():
raise KeyError(str(key))
else:
self._vals[x] = op(self._vals[x], other)
def __dict_do_op__(self, key: K, other: Z, dflt: V, op: F, F: type, Z: type) -> void:
def __dict_do_op__(self, key: K, other: Z, dflt: V, op: F, F: type, Z: type):
ret, x = self._kh_put(key)
self._vals[x] = op(dflt if ret != 0 else self._vals[x], other)
def update(self, other: Dict[K, V]) -> void:
def update(self, other: Dict[K, V]):
for k, v in other.items():
self[k] = v
@ -199,7 +200,7 @@ class Dict:
return (k, self.pop(k))
raise KeyError("dictionary is empty")
def clear(self) -> void:
def clear(self):
self._kh_clear()
def items(self) -> Generator[Tuple[K, V]]:
@ -225,7 +226,7 @@ class Dict:
# Internal helpers
def _kh_clear(self) -> void:
def _kh_clear(self):
if self._flags:
i = 0
n = khash.__ac_fsize(self._n_buckets)
@ -253,7 +254,7 @@ class Dict:
else:
return 0
def _kh_resize(self, new_n_buckets: int) -> void:
def _kh_resize(self, new_n_buckets: int):
HASH_UPPER = 0.77
new_flags = Ptr[u32]()
j = 1
@ -383,7 +384,7 @@ class Dict:
return (ret, x)
def _kh_del(self, x: int) -> void:
def _kh_del(self, x: int):
if x != self._n_buckets and not khash.__ac_iseither(self._flags, x):
khash.__ac_set_isdel_true(self._flags, x)
self._size -= 1

View File

@ -5,34 +5,34 @@ import internal.gc as gc
@extend
class List:
def __init__(self) -> void:
def __init__(self):
self.arr = Array[T](10)
self.len = 0
def __init__(self, it: Generator[T]) -> void:
def __init__(self, it: Generator[T]):
self.arr = Array[T](10)
self.len = 0
for i in it:
self.append(i)
def __init__(self, other: List[T]) -> void:
def __init__(self, other: List[T]):
self.arr = Array[T](other.len)
self.len = 0
for i in other:
self.append(i)
def __init__(self, capacity: int) -> void:
def __init__(self, capacity: int):
self.arr = Array[T](capacity)
self.len = 0
def __init__(self, dummy: bool, other) -> void:
def __init__(self, dummy: bool, other):
"""Dummy __init__ used for list comprehension optimization"""
if hasattr(other, "__len__"):
self.__init__(other.__len__())
else:
self.__init__()
def __init__(self, arr: Array[T], len: int) -> void:
def __init__(self, arr: Array[T], len: int):
self.arr = arr
self.len = len
@ -48,13 +48,13 @@ class List:
self._idx_check(idx, "list index out of range")
return self.arr[idx]
def __setitem__(self, idx: int, val: T) -> void:
def __setitem__(self, idx: int, val: T):
if idx < 0:
idx += self.__len__()
self._idx_check(idx, "list assignment index out of range")
self.arr[idx] = val
def __delitem__(self, idx: int) -> void:
def __delitem__(self, idx: int):
if idx < 0:
idx += self.__len__()
self._idx_check(idx, "list assignment index out of range")
@ -87,7 +87,7 @@ class List:
other.append(self.arr[i])
return other
def __setitem__(self, s: Slice, other) -> void:
def __setitem__(self, s: Slice, other):
if s.start is None and s.stop is None and s.step is None:
self.clear()
for a in other:
@ -132,7 +132,7 @@ class List:
cur += step
i += 1
def __delitem__(self, s: Slice) -> void:
def __delitem__(self, s: Slice):
if s.start is None and s.stop is None and s.step is None:
self.clear()
else:
@ -268,16 +268,16 @@ class List:
# Helper functions
def append(self, x: T) -> void:
def append(self, x: T):
self._resize_if_full()
self.arr[self.len] = x
self.len += 1
def extend(self, itr: Generator[T]) -> void:
def extend(self, itr: Generator[T]):
for a in itr:
self.append(a)
def insert(self, idx: int, x: T) -> void:
def insert(self, idx: int, x: T):
n = self.__len__()
if idx < 0:
idx += n
@ -312,7 +312,7 @@ class List:
i += 1
return False
def clear(self) -> void:
def clear(self):
self.len = 0
def index(self, x: T) -> int:
@ -330,7 +330,7 @@ class List:
count += 1
return count
def reverse(self) -> void:
def reverse(self):
i = 0
while i < self.len // 2:
j = self.len - i - 1
@ -344,15 +344,15 @@ class List:
# Internal helpers
def _idx_check(self, idx: int, msg: str) -> void:
def _idx_check(self, idx: int, msg: str):
if idx >= self.len or idx < 0:
raise IndexError(msg)
def _resize(self, new_cap: int) -> void:
def _resize(self, new_cap: int):
p = Ptr[T](gc.realloc(self.arr.ptr.as_byte(), new_cap * gc.sizeof(T)))
self.arr = Array[T](p, new_cap)
def _resize_if_full(self) -> void:
def _resize_if_full(self):
if self.len == self.arr.len:
new_cap = (1 + 3 * self.len) // 2
self._resize(new_cap)
@ -364,7 +364,7 @@ class List:
seed ^= v.__hash__() + 0x9E3779B9 + (seed << 6) + (seed >> 2)
return seed
def _assign_slice(self, ilow: int, ihigh: int, v: Ptr[T], n: int) -> void:
def _assign_slice(self, ilow: int, ihigh: int, v: Ptr[T], n: int):
a = self
L = a.len

View File

@ -12,7 +12,6 @@ def _set_hash(key) -> int:
class Set:
K: type
_n_buckets: int
_size: int
_n_occupied: int
@ -21,8 +20,10 @@ class Set:
_flags: Ptr[u32]
_keys: Ptr[K]
K: type
# Magic methods
def _init(self) -> void:
def _init(self):
self._n_buckets = 0
self._size = 0
self._n_occupied = 0
@ -30,10 +31,10 @@ class Set:
self._flags = Ptr[u32]()
self._keys = Ptr[K]()
def __init__(self) -> void:
def __init__(self):
self._init()
def __init__(self, g: Generator[K]) -> void:
def __init__(self, g: Generator[K]):
self._init()
for a in g:
self.add(a)
@ -133,7 +134,7 @@ class Set:
if n == 0:
return "{}"
else:
lst = List[str]()
lst = []
lst.append("{")
first = True
for k in self:
@ -147,17 +148,17 @@ class Set:
# Helper methods
def resize(self, new_n_buckets: int) -> void:
def resize(self, new_n_buckets: int):
self._kh_resize(new_n_buckets)
def add(self, key: K) -> void:
def add(self, key: K):
self._kh_put(key)
def update(self, other: Set[K]) -> void:
def update(self, other: Set[K]):
for k in other:
self.add(k)
def remove(self, key: K) -> void:
def remove(self, key: K):
x = self._kh_get(key)
if x != self._kh_end():
self._kh_del(x)
@ -171,7 +172,7 @@ class Set:
self.remove(a)
return a
def discard(self, key: K) -> void:
def discard(self, key: K):
x = self._kh_get(key)
if x != self._kh_end():
self._kh_del(x)
@ -183,7 +184,7 @@ class Set:
s.add(a)
return s
def difference_update(self, other: Set[K]) -> void:
def difference_update(self, other: Set[K]):
for a in other:
self.discard(a)
@ -196,7 +197,7 @@ class Set:
s.add(a)
return s
def intersection_update(self, other: Set[K]) -> void:
def intersection_update(self, other: Set[K]):
for a in self:
if a not in other:
self.discard(a)
@ -211,7 +212,7 @@ class Set:
s.add(a)
return s
def symmetric_difference_update(self, other: Set[K]) -> void:
def symmetric_difference_update(self, other: Set[K]):
for a in other:
if a in self:
self.discard(a)
@ -249,7 +250,7 @@ class Set:
def issuperset(self, other: Set[K]) -> bool:
return other.issubset(self)
def clear(self) -> void:
def clear(self):
self._kh_clear()
def copy(self) -> Set[K]:
@ -257,7 +258,7 @@ class Set:
# Internal helpers
def _kh_clear(self) -> void:
def _kh_clear(self):
if self._flags:
i = 0
n = khash.__ac_fsize(self._n_buckets)
@ -285,7 +286,7 @@ class Set:
else:
return 0
def _kh_resize(self, new_n_buckets: int) -> void:
def _kh_resize(self, new_n_buckets: int):
HASH_UPPER = 0.77
new_flags = Ptr[u32]()
j = 1
@ -406,7 +407,7 @@ class Set:
return (ret, x)
def _kh_del(self, x: int) -> void:
def _kh_del(self, x: int):
if x != self._n_buckets and not khash.__ac_iseither(self._flags, x):
khash.__ac_set_isdel_true(self._flags, x)
self._size -= 1

View File

@ -16,10 +16,10 @@ class ExcHeader:
class OSError:
_hdr: ExcHeader
def __init__(self) -> void:
def __init__(self):
self._hdr = ("OSError", "", "", "", 0, 0)
def __init__(self, message: str) -> void:
def __init__(self, message: str):
self._hdr = ("OSError", message, "", "", 0, 0)
@property
@ -30,10 +30,10 @@ class OSError:
class IOError:
_hdr: ExcHeader
def __init__(self) -> void:
def __init__(self):
self._hdr = ("IOError", "", "", "", 0, 0)
def __init__(self, message: str) -> void:
def __init__(self, message: str):
self._hdr = ("IOError", message, "", "", 0, 0)
@property
@ -44,10 +44,10 @@ class IOError:
class ValueError:
_hdr: ExcHeader
def __init__(self) -> void:
def __init__(self):
self._hdr = ("ValueError", "", "", "", 0, 0)
def __init__(self, message: str) -> void:
def __init__(self, message: str):
self._hdr = ("ValueError", message, "", "", 0, 0)
@property
@ -58,10 +58,10 @@ class ValueError:
class IndexError:
_hdr: ExcHeader
def __init__(self) -> void:
def __init__(self):
self._hdr = ("IndexError", "", "", "", 0, 0)
def __init__(self, message: str) -> void:
def __init__(self, message: str):
self._hdr = ("IndexError", message, "", "", 0, 0)
@property
@ -72,10 +72,10 @@ class IndexError:
class KeyError:
_hdr: ExcHeader
def __init__(self) -> void:
def __init__(self):
self._hdr = ("KeyError", "", "", "", 0, 0)
def __init__(self, message: str) -> void:
def __init__(self, message: str):
self._hdr = ("KeyError", message, "", "", 0, 0)
@property
@ -86,10 +86,10 @@ class KeyError:
class OverflowError:
_hdr: ExcHeader
def __init__(self) -> void:
def __init__(self):
self._hdr = ("OverflowError", "", "", "", 0, 0)
def __init__(self, message: str) -> void:
def __init__(self, message: str):
self._hdr = ("OverflowError", message, "", "", 0, 0)
@property
@ -100,10 +100,10 @@ class OverflowError:
class CError:
_hdr: ExcHeader
def __init__(self) -> void:
def __init__(self):
self._hdr = ("CError", "", "", "", 0, 0)
def __init__(self, message: str) -> void:
def __init__(self, message: str):
self._hdr = ("CError", message, "", "", 0, 0)
@property
@ -115,7 +115,7 @@ class PyError:
_hdr: ExcHeader
pytype: str
def __init__(self, message: str, pytype: str) -> void:
def __init__(self, message: str, pytype: str):
self._hdr = ("PyError", message, "", "", 0, 0)
self.pytype = pytype
@ -127,10 +127,10 @@ class PyError:
class TypeError:
_hdr: ExcHeader
def __init__(self) -> void:
def __init__(self):
self._hdr = ("TypeError", "", "", "", 0, 0)
def __init__(self, message: str) -> void:
def __init__(self, message: str):
self._hdr = ("TypeError", message, "", "", 0, 0)
@property
@ -141,10 +141,10 @@ class TypeError:
class ZeroDivisionError:
_hdr: ExcHeader
def __init__(self) -> void:
def __init__(self):
self._hdr = ("ZeroDivisionError", "", "", "", 0, 0)
def __init__(self, message: str) -> void:
def __init__(self, message: str):
self._hdr = ("ZeroDivisionError", message, "", "", 0, 0)
@property
@ -155,10 +155,10 @@ class ZeroDivisionError:
class AttributeError:
_hdr: ExcHeader
def __init__(self) -> void:
def __init__(self):
self._hdr = ("AttributeError", "", "", "", 0, 0)
def __init__(self, message: str) -> void:
def __init__(self, message: str):
self._hdr = ("AttributeError", message, "", "", 0, 0)
@property
@ -169,10 +169,10 @@ class AttributeError:
class NotImplementedError:
_hdr: ExcHeader
def __init__(self) -> void:
def __init__(self):
self._hdr = ("NotImplementedError", "", "", "", 0, 0)
def __init__(self, message: str) -> void:
def __init__(self, message: str):
self._hdr = ("NotImplementedError", message, "", "", 0, 0)
@property
@ -183,10 +183,10 @@ class NotImplementedError:
class StopIteration:
_hdr: ExcHeader
def __init__(self) -> void:
def __init__(self):
self._hdr = ("StopIteration", "", "", "", 0, 0)
def __init__(self, message: str) -> void:
def __init__(self, message: str):
self._hdr = ("StopIteration", message, "", "", 0, 0)
@property
@ -197,10 +197,10 @@ class StopIteration:
class AssertionError:
_hdr: ExcHeader
def __init__(self) -> void:
def __init__(self):
self._hdr = ("AssertionError", "", "", "", 0, 0)
def __init__(self, message: str) -> void:
def __init__(self, message: str):
self._hdr = ("AssertionError", message, "", "", 0, 0)
@property
@ -212,19 +212,19 @@ class SystemExit:
_hdr: ExcHeader
_status: int
def __init__(self) -> void:
def __init__(self):
self._hdr = ("SystemExit", "", "", "", 0, 0)
self._status = 0
def __init__(self, status: int) -> void:
def __init__(self, status: int):
self._hdr = ("SystemExit", "", "", "", 0, 0)
self._status = status
def __init__(self, message: str) -> void:
def __init__(self, message: str):
self._hdr = ("SystemExit", message, "", "", 0, 0)
self._status = 0
def __init__(self, message: str, status: int) -> void:
def __init__(self, message: str, status: int):
self._hdr = ("SystemExit", message, "", "", 0, 0)
self._status = status

View File

@ -37,7 +37,7 @@ class float:
free(p)
if end != p + n:
raise ValueError("could not convert string to float: " + s)
raise ValueError(f"could not convert string to float: {s}")
return result

View File

@ -3,7 +3,7 @@
from internal.attributes import commutative, associative, distributive
def check_N(N: Static[int]) -> void:
def check_N(N: Static[int]):
if N <= 0:
compile_error("N must be greater than 0")
pass

View File

@ -43,6 +43,6 @@ optional = Optional
def unwrap(opt: Optional[T], T: type) -> T:
if not opt:
if opt is None:
raise ValueError("optional is None")
return ~opt

View File

@ -192,15 +192,15 @@ cobj = Ptr[byte]
@__internal__
@tuple
class Array:
T: type
len: int
ptr: Ptr[T]
T: type
class List:
T: type
arr: Array[T]
len: int
arr: Array[T]
T: type
@extend

View File

@ -92,14 +92,6 @@ class range:
def __repr__(self) -> str:
if self.step == 1:
return "range(" + str(self.start) + ", " + str(self.stop) + ")"
return f"range({self.start}, {self.stop})"
else:
return (
"range("
+ str(self.start)
+ ", "
+ str(self.stop)
+ ", "
+ str(self.step)
+ ")"
)
return f"range({self.start}, {self.stop}, {self.step})"

View File

@ -8,18 +8,18 @@ class Slice:
step: Optional[int]
def adjust_indices(self, length: int) -> Tuple[int, int, int, int]:
stepx = ~self.step if self.step else 1
startx = 0
stopx = 0
if stepx == 0:
step: int = self.step if self.step else 1
start: int = 0
stop: int = 0
if step == 0:
raise ValueError("slice step cannot be zero")
if stepx > 0:
startx = ~self.start if self.start else 0
stopx = ~self.stop if self.stop else length
if step > 0:
start = self.start if self.start else 0
stop = self.stop if self.stop else length
else:
startx = ~self.start if self.start else length - 1
stopx = ~self.stop if self.stop else -(length + 1)
return Slice.adjust_indices_helper(length, startx, stopx, stepx)
start = self.start if self.start else length - 1
stop = self.stop if self.stop else -(length + 1)
return Slice.adjust_indices_helper(length, start, stop, step)
def adjust_indices_helper(
length: int, start: int, stop: int, step: int

View File

@ -1,5 +1,7 @@
# (c) 2022 Exaloop Inc. All rights reserved.
from internal.types.optional import unwrap
# Infinite iterators
@ -46,13 +48,12 @@ def repeat(object: T, times: Optional[int] = None, T: type) -> Generator[T]:
@tuple
class accumulate:
"""
Make an iterator that returns accumulated sums, or accumulated results
of other binary functions (specified via the optional func argument).
"""
@inline
def __new__(iterable: Generator[T], func=lambda a, b: a + b, initial=0, T: type):
"""
Make an iterator that returns accumulated sums, or accumulated results
of other binary functions (specified via the optional func argument).
"""
total = initial
yield total
for element in iterable:
@ -61,10 +62,14 @@ class accumulate:
@inline
def __new__(iterable: Generator[T], func=lambda a, b: a + b, T: type):
"""
Make an iterator that returns accumulated sums, or accumulated results
of other binary functions (specified via the optional func argument).
"""
total = None
for element in iterable:
total = element if total is None else func(~total, element)
yield ~total
total = element if total is None else func(unwrap(total), element)
yield unwrap(total)
@tuple
@ -142,29 +147,28 @@ def groupby(iterable, key=Optional[int]()):
k = currvalue if isinstance(key, Optional) else key(currvalue)
if currkey is None:
currkey = k
if k != ~currkey:
yield ~currkey, group
if k != unwrap(currkey):
yield unwrap(currkey), group
currkey = k
group = []
group.append(currvalue)
if currkey is not None:
yield ~currkey, group
yield unwrap(currkey), group
@tuple
class islice:
"""
Make an iterator that returns selected elements from the iterable.
"""
def __new__(iterable: Generator[T], stop: Optional[int], T: type) -> Generator[T]:
if stop and ~stop < 0:
"""
Make an iterator that returns selected elements from the iterable.
"""
if stop and unwrap(stop) < 0:
raise ValueError(
"Indices for islice() must be None or an integer: 0 <= x <= sys.maxsize."
)
i = 0
for x in iterable:
if stop and i >= ~stop:
if stop and i >= unwrap(stop):
break
yield x
i += 1
@ -176,11 +180,14 @@ class islice:
step: Optional[int] = None,
T: type,
) -> Generator[T]:
"""
Make an iterator that returns selected elements from the iterable.
"""
from sys import maxsize
start: int = 0 if not start else ~start
stop: int = maxsize if not stop else ~stop
step: int = 1 if not step else ~step
start: int = 0 if not start else start
stop: int = maxsize if not stop else stop
step: int = 1 if not step else step
have_stop = False
if start < 0 or stop < 0:
@ -266,15 +273,14 @@ def tee(iterable: Generator[T], n: int = 2, T: type) -> List[Generator[T]]:
@tuple
class zip_longest:
"""
Make an iterator that aggregates elements from each of the iterables.
If the iterables are of uneven length, missing values are filled-in
with fillvalue. Iteration continues until the longest iterable is
exhausted.
"""
@inline
def __new__(*iterables, fillvalue):
"""
Make an iterator that aggregates elements from each of the iterables.
If the iterables are of uneven length, missing values are filled-in
with fillvalue. Iteration continues until the longest iterable is
exhausted.
"""
if staticlen(iterables) == 2:
a = iter(iterables[0])
b = iter(iterables[1])
@ -317,6 +323,13 @@ class zip_longest:
@inline
def __new__(*args):
"""
Make an iterator that aggregates elements from each of the iterables.
If the iterables are of uneven length, missing values are filled-in
with fillvalue. Iteration continues until the longest iterable is
exhausted.
"""
def get_next(it):
if it.__done__() or it.done():
return None
@ -422,7 +435,7 @@ def permutations(
pool: List[T], r: Optional[int], T: type
) -> Generator[List[T]]:
n = len(pool)
r: int = ~r if r else n
r: int = r if r else n
if r > n:
return
@ -445,7 +458,7 @@ def permutations(
if b == -1:
return
if r is not None and ~r < 0:
if r is not None and unwrap(r) < 0:
raise ValueError("r must be non-negative")
if hasattr(pool, "__getitem__") and hasattr(pool, "__len__"):
return permutations_helper(pool, r)
@ -455,12 +468,11 @@ def permutations(
@tuple
class product:
"""
Cartesian product of input iterables.
"""
@inline
def __new__(*args):
"""
Cartesian product of input iterables.
"""
if staticlen(args) == 0:
yield ()
else:
@ -471,6 +483,9 @@ class product:
@inline
def __new__(*args, repeat: int):
"""
Cartesian product of input iterables.
"""
if repeat < 0:
raise ValueError("repeat argument cannot be negative")
pools = [list(pool) for _ in range(repeat) for pool in args]

View File

@ -70,9 +70,9 @@ class Task:
@tuple
class TaskWithPrivates:
T: type
task: Task
data: T
T: type
_DEFAULT_IDENT = Ident()
@ -846,7 +846,7 @@ def _atomic_float_min(a: Ptr[float], b: float):
__kmpc_atomic_float8_min(_default_loc(), i32(get_thread_num()), a, b)
def _atomic_float_max(a: Ptr[float], b: float) -> void:
def _atomic_float_max(a: Ptr[float], b: float):
from C import __kmpc_atomic_float8_max(Ptr[Ident], i32, Ptr[float], float)
__kmpc_atomic_float8_max(_default_loc(), i32(get_thread_num()), a, b)

View File

@ -17,7 +17,7 @@ class EnvMap:
def __new__() -> EnvMap:
return (Dict[str, str](),)
def _init_if_needed(self) -> void:
def _init_if_needed(self):
if len(self._map) == 0:
env = _C.seq_env()
p = env[0]

View File

@ -4,7 +4,7 @@ from internal.file import _gz_errcheck
from internal.gc import sizeof, atomic
def pickle(x: T, jar: Jar, T: type) -> void:
def pickle(x: T, jar: Jar, T: type):
x.__pickle__(jar)
@ -12,7 +12,7 @@ def unpickle(jar: Jar, T: type) -> T:
return T.__unpickle__(jar)
def dump(x: T, f, T: type) -> void:
def dump(x: T, f, T: type):
x.__pickle__(f.fp)
@ -20,31 +20,31 @@ def load(f, T: type) -> T:
return T.__unpickle__(f.fp)
def _write_raw(jar: Jar, p: cobj, n: int) -> void:
def _write_raw(jar: Jar, p: cobj, n: int):
LIMIT = 0x7FFFFFFF
while n > 0:
b = n if n < LIMIT else LIMIT
status = int(_C.gzwrite(jar, p, u32(b)))
if status != b:
_gz_errcheck(jar)
raise IOError("pickle error: gzwrite returned " + str(status))
raise IOError(f"pickle error: gzwrite returned {status}")
p += b
n -= b
def _read_raw(jar: Jar, p: cobj, n: int) -> void:
def _read_raw(jar: Jar, p: cobj, n: int):
LIMIT = 0x7FFFFFFF
while n > 0:
b = n if n < LIMIT else LIMIT
status = int(_C.gzread(jar, p, u32(b)))
if status != b:
_gz_errcheck(jar)
raise IOError("pickle error: gzread returned " + str(status))
raise IOError(f"pickle error: gzread returned {status}")
p += b
n -= b
def _write(jar: Jar, x: T, T: type) -> void:
def _write(jar: Jar, x: T, T: type):
y = __ptr__(x)
_write_raw(jar, y.as_byte(), sizeof(T))
@ -61,7 +61,7 @@ def _read(jar: Jar, T: type) -> T:
@extend
class int:
def __pickle__(self, jar: Jar) -> void:
def __pickle__(self, jar: Jar):
_write(jar, self)
def __unpickle__(jar: Jar) -> int:
@ -70,7 +70,7 @@ class int:
@extend
class float:
def __pickle__(self, jar: Jar) -> void:
def __pickle__(self, jar: Jar):
_write(jar, self)
def __unpickle__(jar: Jar) -> float:
@ -79,7 +79,7 @@ class float:
@extend
class bool:
def __pickle__(self, jar: Jar) -> void:
def __pickle__(self, jar: Jar):
_write(jar, self)
def __unpickle__(jar: Jar) -> bool:
@ -88,7 +88,7 @@ class bool:
@extend
class byte:
def __pickle__(self, jar: Jar) -> void:
def __pickle__(self, jar: Jar):
_write(jar, self)
def __unpickle__(jar: Jar) -> byte:
@ -97,7 +97,7 @@ class byte:
@extend
class str:
def __pickle__(self, jar: Jar) -> void:
def __pickle__(self, jar: Jar):
_write(jar, self.len)
_write_raw(jar, self.ptr, self.len)
@ -110,7 +110,7 @@ class str:
@extend
class List:
def __pickle__(self, jar: Jar) -> void:
def __pickle__(self, jar: Jar):
n = len(self)
pickle(n, jar)
if atomic(T):
@ -132,7 +132,7 @@ class List:
@extend
class Dict:
def __pickle__(self, jar: Jar) -> void:
def __pickle__(self, jar: Jar):
import internal.khash as khash
if atomic(K) and atomic(V):
@ -156,7 +156,7 @@ class Dict:
def __unpickle__(jar: Jar) -> Dict[K, V]:
import internal.khash as khash
d = Dict[K, V]()
d = {}
if atomic(K) and atomic(V):
n_buckets = unpickle(jar, int)
size = unpickle(jar, int)
@ -192,7 +192,7 @@ class Dict:
@extend
class Set:
def __pickle__(self, jar: Jar) -> void:
def __pickle__(self, jar: Jar):
import internal.khash as khash
if atomic(K):
@ -214,7 +214,7 @@ class Set:
def __unpickle__(jar: Jar) -> Set[K]:
import internal.khash as khash
s = Set[K]()
s = set[K]()
if atomic(K):
n_buckets = unpickle(jar, int)
size = unpickle(jar, int)

View File

@ -35,7 +35,7 @@ class RandomGenerator:
def init_genrand(self, s: u32):
"""
init_genrand(u32) -> void
init_genrand(u32)
initializes state[N] with a seed
"""
@ -226,7 +226,7 @@ class Random:
def getstate(self):
return self.gen.getstate()
def setstate(self, state):
self.gen.setstate(state)

View File

@ -8,23 +8,21 @@ DEFAULT_LOAD_FACTOR = 1000
class SortedList:
T: type
_len: int
_load: int
_lists: List[List[T]]
_maxes: List[T]
_offset: int
# _index:
T: type
def __init__(self) -> void:
def __init__(self):
self._len = 0
self._load = DEFAULT_LOAD_FACTOR
self._lists = List[List[T]]()
self._maxes = List[T]()
# self._index = []
self._lists = []
self._maxes = []
self._offset = 0
def clear(self) -> void:
def clear(self):
"""
Remove all values from sorted list.
Runtime complexity: `O(n)`
@ -33,7 +31,6 @@ class SortedList:
self._lists.clear()
self._maxes.clear()
self._offset = 0
# self._index.clear()
@property
def left(self) -> T:
@ -41,7 +38,7 @@ class SortedList:
raise IndexError("list index out of range")
return self._lists[0][0]
def add(self, value: T) -> void:
def add(self, value: T):
"""
Add `value` to sorted list.
Runtime complexity: `O(log(n))` -- approximate.
@ -67,7 +64,7 @@ class SortedList:
self._maxes.append(value)
self._len += 1
def _expand(self, pos: int) -> void:
def _expand(self, pos: int):
"""
Split sublists with length greater than double the load-factor.
Updates the index when the sublist length is less than double the load
@ -86,7 +83,7 @@ class SortedList:
self._lists.insert(pos + 1, half)
_maxes.insert(pos + 1, half[-1])
def _delete(self, pos: int, idx: int) -> void:
def _delete(self, pos: int, idx: int):
"""
Delete value at the given `(pos, idx)`.
Combines lists that are less than half the load level.

View File

@ -147,12 +147,12 @@ def multimode(data: List[T], T: type):
elem = data[0]
counter = data.count(elem)
li = sorted(data)
mulmode = List[T]()
mulmode = []
for i in li:
curr_frequency = data.count(i)
if curr_frequency > counter:
mulmode = List[T]()
mulmode = []
mulmode.append(i)
counter = curr_frequency
elif curr_frequency == counter and i not in mulmode:
@ -188,7 +188,7 @@ def quantiles(
if method == "inclusive":
m = ld - 1
result = List[float]()
result = []
for i in range(1, n):
j = i * m // n
delta = (i * m) - (j * n)
@ -197,7 +197,7 @@ def quantiles(
return result
if method == "exclusive":
m = ld + 1
result = List[float]()
result = []
for i in range(1, n):
j = i * m // n # rescale i to m/n
j = 1 if j < 1 else ld - 1 if j > ld - 1 else j # clamp to 1 .. ld-1
@ -510,55 +510,22 @@ class NormalDist:
if _fabs(q) <= 0.425:
r = 0.180625 - q * q
# Hash sum: 55.88319_28806_14901_4439
num = (
(
(
(
(
(
(
2.5090809287301226727e3 * r
+ 3.3430575583588128105e4
)
* r
+ 6.7265770927008700853e4
)
* r
+ 4.5921953931549871457e4
)
* r
+ 1.3731693765509461125e4
)
* r
+ 1.9715909503065514427e3
)
* r
+ 1.3314166789178437745e2
)
* r
+ 3.3871328727963666080e0
) * q
den = (
(
(
(
(
(5.2264952788528545610e3 * r + 2.8729085735721942674e4)
* r
+ 3.9307895800092710610e4
)
* r
+ 2.1213794301586595867e4
)
* r
+ 5.3941960214247511077e3
)
* r
+ 6.8718700749205790830e2
)
* r
+ 4.2313330701600911252e1
) * r + 1.0
num = (((((((2.5090809287301226727e+3 * r +
3.3430575583588128105e+4) * r +
6.7265770927008700853e+4) * r +
4.5921953931549871457e+4) * r +
1.3731693765509461125e+4) * r +
1.9715909503065514427e+3) * r +
1.3314166789178437745e+2) * r +
3.3871328727963666080e+0) * q
den = (((((((5.2264952788528545610e+3 * r +
2.8729085735721942674e+4) * r +
3.9307895800092710610e+4) * r +
2.1213794301586595867e+4) * r +
5.3941960214247511077e+3) * r +
6.8718700749205790830e+2) * r +
4.2313330701600911252e+1) * r +
1.0)
x = num / den
return mu + (x * sigma)
r = p if q <= 0.0 else 1.0 - p
@ -566,105 +533,41 @@ class NormalDist:
if r <= 5.0:
r = r - 1.6
# Hash sum: 49.33206_50330_16102_89036
num = (
(
(
(
(
(
7.74545014278341407640e-4 * r
+ 2.27238449892691845833e-2
)
* r
+ 2.41780725177450611770e-1
)
* r
+ 1.27045825245236838258e0
)
* r
+ 3.64784832476320460504e0
)
* r
+ 5.76949722146069140550e0
)
* r
+ 4.63033784615654529590e0
) * r + 1.42343711074968357734e0
den = (
(
(
(
(
(
1.05075007164441684324e-9 * r
+ 5.47593808499534494600e-4
)
* r
+ 1.51986665636164571966e-2
)
* r
+ 1.48103976427480074590e-1
)
* r
+ 6.89767334985100004550e-1
)
* r
+ 1.67638483018380384940e0
)
* r
+ 2.05319162663775882187e0
) * r + 1.0
num = (((((((7.74545014278341407640e-4 * r +
2.27238449892691845833e-2) * r +
2.41780725177450611770e-1) * r +
1.27045825245236838258e+0) * r +
3.64784832476320460504e+0) * r +
5.76949722146069140550e+0) * r +
4.63033784615654529590e+0) * r +
1.42343711074968357734e+0)
den = (((((((1.05075007164441684324e-9 * r +
5.47593808499534494600e-4) * r +
1.51986665636164571966e-2) * r +
1.48103976427480074590e-1) * r +
6.89767334985100004550e-1) * r +
1.67638483018380384940e+0) * r +
2.05319162663775882187e+0) * r +
1.0)
else:
r = r - 5.0
# Hash sum: 47.52583_31754_92896_71629
num = (
(
(
(
(
(
2.01033439929228813265e-7 * r
+ 2.71155556874348757815e-5
)
* r
+ 1.24266094738807843860e-3
)
* r
+ 2.65321895265761230930e-2
)
* r
+ 2.96560571828504891230e-1
)
* r
+ 1.78482653991729133580e0
)
* r
+ 5.46378491116411436990e0
) * r + 6.65790464350110377720e0
den = (
(
(
(
(
(
2.04426310338993978564e-15 * r
+ 1.42151175831644588870e-7
)
* r
+ 1.84631831751005468180e-5
)
* r
+ 7.86869131145613259100e-4
)
* r
+ 1.48753612908506148525e-2
)
* r
+ 1.36929880922735805310e-1
)
* r
+ 5.99832206555887937690e-1
) * r + 1.0
num = (((((((2.01033439929228813265e-7 * r +
2.71155556874348757815e-5) * r +
1.24266094738807843860e-3) * r +
2.65321895265761230930e-2) * r +
2.96560571828504891230e-1) * r +
1.78482653991729133580e+0) * r +
5.46378491116411436990e+0) * r +
6.65790464350110377720e+0)
den = (((((((2.04426310338993978564e-15 * r +
1.42151175831644588870e-7) * r +
1.84631831751005468180e-5) * r +
7.86869131145613259100e-4) * r +
1.48753612908506148525e-2) * r +
1.36929880922735805310e-1) * r +
5.99832206555887937690e-1) * r +
1.0)
x = num / den
if q < 0.0:
x = -x

View File

@ -7,7 +7,7 @@ stdout = File(_C.seq_stdout())
stderr = File(_C.seq_stderr())
def exit(status: int = 0) -> void:
def exit(status: int = 0):
raise SystemExit(status)

View File

@ -13,13 +13,13 @@ class Lock:
raise ValueError("can't specify a timeout for a non-blocking call")
return _C.seq_lock_acquire(self.p, block, timeout)
def release(self) -> void:
def release(self):
_C.seq_lock_release(self.p)
def __enter__(self) -> void:
def __enter__(self):
self.acquire()
def __exit__(self) -> void:
def __exit__(self):
self.release()
@ -35,13 +35,13 @@ class RLock:
raise ValueError("can't specify a timeout for a non-blocking call")
return _C.seq_rlock_acquire(self.p, block, timeout)
def release(self) -> void:
def release(self):
_C.seq_rlock_release(self.p)
def __enter__(self) -> void:
def __enter__(self):
self.acquire()
def __exit__(self) -> void:
def __exit__(self):
self.release()

View File

@ -27,7 +27,7 @@ def perf_counter_ns() -> int:
return _C.seq_time_highres()
def sleep(secs: float) -> void:
def sleep(secs: float):
if secs < 0:
raise ValueError("sleep length must be non-negative")
_C.seq_sleep(secs)
@ -41,14 +41,14 @@ class TimeInterval:
start: int
msg: str
def __init__(self) -> void:
def __init__(self):
self.start = _C.seq_time()
self.msg = ""
def __enter__(self) -> void:
def __enter__(self):
self.start = _C.seq_time()
def __exit__(self) -> void:
def __exit__(self):
print(self.report(self.msg), file=stderr)
def report(self, msg="", memory=False) -> str:
@ -60,7 +60,7 @@ class TimeInterval:
def elapsed(self) -> float:
return float(_C.seq_time() - self.start) / 1e9
def tick(self, msg, memory=False) -> void:
def tick(self, msg, memory=False):
ret = self.report(msg)
self.start = _C.seq_time()
@ -199,7 +199,7 @@ _MIN = 0x8000000000000000
_MAX = 0x7FFFFFFFFFFFFFFF
def _overflow() -> void:
def _overflow():
raise OverflowError("timestamp too large")

View File

@ -5,28 +5,28 @@
class TestCase:
def fail(self, standard_message: str, special_message: str = "") -> void:
def fail(self, standard_message: str, special_message: str = ""):
print("TEST FAILED:", special_message if special_message else standard_message)
def assertTrue(self, obj, msg="") -> void:
def assertTrue(self, obj, msg=""):
if not bool(obj):
self.fail(f"expected object to be true: {obj}", msg)
def assertFalse(self, obj, msg="") -> void:
def assertFalse(self, obj, msg=""):
if bool(obj):
self.fail(f"expected object to be false: {obj}", msg)
def assertEqual(self, first, second, msg="") -> void:
def assertEqual(self, first, second, msg=""):
result = first == second
if not result:
self.fail(f"expected equality of:\n 1: {first}\n 2: {second}", msg)
def assertNotEqual(self, first, second, msg="") -> void:
def assertNotEqual(self, first, second, msg=""):
result = first != second
if not result:
self.fail(f"expected inequality of:\n 1: {first}\n 2: {second}", msg)
def assertSequenceEqual(self, seq1, seq2, msg="") -> void:
def assertSequenceEqual(self, seq1, seq2, msg=""):
len1 = len(seq1)
len2 = len(seq2)
if len1 != len2:
@ -43,27 +43,27 @@ class TestCase:
msg,
)
def assertIn(self, member, container, msg="") -> void:
def assertIn(self, member, container, msg=""):
if member not in container:
self.fail(f"expected {member} to be in {container}", msg)
def assertNotIn(self, member, container, msg="") -> void:
def assertNotIn(self, member, container, msg=""):
if member in container:
self.fail(f"expected {member} to not be in {container}", msg)
def assertIs(self, expr1, expr2, msg="") -> void:
def assertIs(self, expr1, expr2, msg=""):
if expr1 is not expr2:
self.fail(f"expected {expr1} to be identical to {expr2}", msg)
def assertIsNot(self, expr1, expr2, msg="") -> void:
def assertIsNot(self, expr1, expr2, msg=""):
if expr1 is expr2:
self.fail(f"expected {expr1} to not be identical to {expr2}", msg)
def assertIsNot(self, expr1, expr2, msg="") -> void:
def assertIsNot(self, expr1, expr2, msg=""):
if expr1 is expr2:
self.fail(f"expected {expr1} to not be identical to {expr2}", msg)
def assertCountEqual(self, first, second, msg="") -> void:
def assertCountEqual(self, first, second, msg=""):
from collections import Counter
first_seq, second_seq = list(first), list(second)
@ -74,27 +74,27 @@ class TestCase:
if first_counter != second_counter:
self.fail(f"expected equal counts:\n 1: {first}\n 2: {second}", msg)
def assertLess(self, a, b, msg="") -> void:
def assertLess(self, a, b, msg=""):
if not (a < b):
self.fail(f"expected less-than:\n 1: {a}\n 2: {b}", msg)
def assertLessEqual(self, a, b, msg="") -> void:
def assertLessEqual(self, a, b, msg=""):
if not (a <= b):
self.fail(f"expected less-than-or-equal:\n 1: {a}\n 2: {b}", msg)
def assertGreater(self, a, b, msg="") -> void:
def assertGreater(self, a, b, msg=""):
if not (a > b):
self.fail(f"expected greater-than:\n 1: {a}\n 2: {b}", msg)
def assertGreaterEqual(self, a, b, msg="") -> void:
def assertGreaterEqual(self, a, b, msg=""):
if not (a >= b):
self.fail(f"expected greater-than-or-equal:\n 1: {a}\n 2: {b}", msg)
def assertIsNone(self, obj, msg="") -> void:
def assertIsNone(self, obj, msg=""):
if obj is not None:
self.fail(f"expected {obj} to be None", msg)
def assertIsNotNone(self, obj, msg="") -> void:
def assertIsNotNone(self, obj, msg=""):
if obj is None:
self.fail(f"expected {obj} to not be None", msg)
@ -109,7 +109,7 @@ class TestCase:
def assertAlmostEqual(
self, first, second, places: int = 0, msg="", delta=None
) -> void:
):
if first == second:
# shortcut
return

View File

@ -19,8 +19,8 @@ def t2():
t2()
def g[T](a: T, b: optional[T] = None):
b_ = ~b if b else T()
return a, b_
b: T = b if b else T()
return a, b
@test
def t3():

View File

@ -6,7 +6,7 @@ def print_test[T](a: list[T], b: list[T]):
return
if len(a) != len(b):
print("FAILED: length of a (" + str(len(a)) + ") is not length of b (" + str(len(b)) + ")")
print(f"FAILED: length of a ({len(a)}) is not length of b ({len(b)})")
return
if len(a) == 0:
@ -15,7 +15,7 @@ def print_test[T](a: list[T], b: list[T]):
for i in range(len(a)):
if a[i] != b[i]:
print("FAILED: element " + str(i) + " of a is " + str(a[i]) + " and is not equal to the element in b " + str(b[i]))
print(f"FAILED: element {i} of a is {a[i]} and is not equal to the element in b {b[i]}")
return
print("PASSED")

View File

@ -704,7 +704,7 @@ class Node[T]:
children: List[Node[T]]
def __init__(self, data: T):
self.data = data
self.children = List[Node[T]]()
self.children = []
print Node(2).data #: 2
class Node2:
@ -712,7 +712,7 @@ class Node2:
children: List[Node2]
def __init__(self, data: int):
self.data = data
self.children = List[Node2]()
self.children = []
print Node2(3).data #: 3
#%% class_auto_init,barebones

View File

@ -636,7 +636,7 @@ print a.__class__ #: Array[int]
#%% typeof,barebones
a = 5
z = List[type(a)]()
z = []
z.append(6)
print z.__class__, z, type(1.1).__class__ #: List[int] [6] float

View File

@ -306,8 +306,8 @@ test_infinity_and_nan_constants()
@test
def test_user_object():
class MyComplexOS:
T: type
value: T
T: type
def __init__(self, value: T):
self.value = value

View File

@ -22,7 +22,7 @@ def test_heapify():
@test
def test_naive_nbest():
data = [randrange(2000) for i in range(1000)]
heap = List[int]()
heap = []
for item in data:
heapq.heappush(heap, item)
if len(heap) > 10:
@ -99,7 +99,7 @@ def test_heapsort():
heap = data[:]
heapq.heapify(heap)
else: # The rest of the time, use heappush
heap = List[int]()
heap = []
for item in data:
heapq.heappush(heap, item)
heap_sorted = [heapq.heappop(heap) for i in range(size)]
@ -206,6 +206,13 @@ def test_comparison_operator():
assert hsort(data, LT) == target
@test
def test_merge():
# assert [0, 1, 2, 3, 4, 5, 5, 7, 8, 10, 15, 20, 25] == list(heapq.merge([1,3,5,7], [0,2,4,8], [5,10,15,20], [], [25]))
# assert ['dog', 'cat', 'fish', 'horse', 'kangaroo'] == list(heapq.merge(['dog', 'horse'], ['cat', 'fish', 'kangaroo'], key=len))
pass
test_heapify()
test_naive_nbest()
test_nsmallest()
@ -216,3 +223,4 @@ test_heappushpop()
test_heappop_max()
test_heapsort()
# test_comparison_operator()
# test_merge()

View File

@ -186,41 +186,8 @@ def test_quantiles():
(6, [150.0, 200.0, 300.0, 400.0, 600.0]),
(8, [137.5, 175.0, 225.0, 300.0, 375.0, 500.0, 650.0]),
(10, [130.0, 160.0, 190.0, 240.0, 300.0, 360.0, 440.0, 560.0, 680.0]),
(
12,
[
125.0,
150.0,
175.0,
200.0,
250.0,
300.0,
350.0,
400.0,
500.0,
600.0,
700.0,
],
),
(
15,
[
120.0,
140.0,
160.0,
180.0,
200.0,
240.0,
280.0,
320.0,
360.0,
400.0,
480.0,
560.0,
640.0,
720.0,
],
),
(12, [125.0, 150.0, 175.0, 200.0, 250.0, 300.0, 350.0, 400.0, 500.0, 600.0, 700.0]),
(15, [120.0, 140.0, 160.0, 180.0, 200.0, 240.0, 280.0, 320.0, 360.0, 400.0, 480.0, 560.0, 640.0, 720.0])
]:
assert statistics.quantiles(data, n=n, method="inclusive") == expected

View File

@ -761,6 +761,26 @@ def test_repr():
assert repr("\"'") == "'\"\\''"
@test
def test_algorithms():
from algorithms.strings import *
assert [1, 2] == list(string_search_slow('abbba', 'bb'))
assert [2, 1] == list(rstring_search_slow('abbbc', 'bb'))
assert [0, 9, 11, 14] == list(string_search_slow('1214313141212 12', '12'))
assert [0, 9, 11, 14] == list(string_search_rabin_karp('1214313141212 12', '12', 1001))
assert [0, 9, 11, 14] == list(string_search_kmp('1214313141212 12', '12'))
assert [0, 9, 12] == list(string_search_slow('AABAACAADAABAABA', 'AABA'))
assert [0, 9, 12] == list(string_search_rabin_karp('AABAACAADAABAABA', 'AABA', 1001))
assert [0, 9, 12] == list(string_search_kmp('AABAACAADAABAABA', 'AABA'))
assert [10] == list(string_search_slow('ABABDABACDABABCABAB', 'ABABCABAB'))
assert [10] == list(string_search_rabin_karp('ABABDABACDABABCABAB', 'ABABCABAB', 101))
assert [10] == list(string_search_kmp('ABABDABACDABABCABAB', 'ABABCABAB'))
test_isdigit()
test_islower()
test_isupper()
@ -806,3 +826,4 @@ test_fstr()
test_slice()
test_join()
test_repr()
test_algorithms()