mirror of https://github.com/exaloop/codon.git
Updates - January 2024 (#530)
* Add bz2 * Support 'b' prefix on str * List.index() throws an exception if item not found This is consistent with Python. Added find() method that returns -1 similar to str (although this does not exist in Python's list). * Update complex64 str and repr * Fix tests * Add 'default' arg to min() and max()pull/536/head
parent
d23c8c7a75
commit
c8bc944a50
codon/cir/transform/parallel
stdlib
internal
test/core
|
@ -205,13 +205,14 @@ struct Reduction {
|
|||
break;
|
||||
case Kind::MIN:
|
||||
case Kind::MAX: {
|
||||
// signature is (tuple of args, key, default)
|
||||
auto name = (kind == Kind::MIN ? "min" : "max");
|
||||
auto *tup = util::makeTuple({lhs, arg});
|
||||
auto *none = (*M->getNoneType())();
|
||||
auto *fn = M->getOrRealizeFunc(name, {tup->getType(), none->getType()}, {},
|
||||
builtinModule);
|
||||
auto *fn = M->getOrRealizeFunc(
|
||||
name, {tup->getType(), none->getType(), none->getType()}, {}, builtinModule);
|
||||
seqassertn(fn, "{} function not found", name);
|
||||
result = util::call(fn, {tup, none});
|
||||
result = util::call(fn, {tup, none, none});
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
@ -452,8 +453,8 @@ struct ReductionIdentifier : public util::Operator {
|
|||
if (!util::isCallOf(item, rf.name, {type, type}, type, /*method=*/true))
|
||||
continue;
|
||||
} else {
|
||||
if (!util::isCallOf(item, rf.name, {M->getTupleType({type, type}), noneType},
|
||||
type,
|
||||
if (!util::isCallOf(item, rf.name,
|
||||
{M->getTupleType({type, type}), noneType, noneType}, type,
|
||||
/*method=*/false))
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
# Copyright (C) 2022-2023 Exaloop Inc. <https://exaloop.io>
|
||||
|
||||
from internal.file import bzFile
|
||||
|
||||
def open(path: str, mode: str = "r") -> bzFile:
|
||||
return bzFile(path, mode)
|
|
@ -71,14 +71,14 @@ class Dict:
|
|||
yield (self.keys[i], self.values[i])
|
||||
|
||||
def __contains__(self, key: K) -> bool:
|
||||
return self.keys.index(key) != -1
|
||||
return self.keys.find(key) != -1
|
||||
|
||||
def __getitem__(self, key: K) -> V:
|
||||
i = self.keys.index(key)
|
||||
i = self.keys.find(key)
|
||||
return self.values[i]
|
||||
|
||||
def __setitem__(self, key: K, val: V):
|
||||
i = self.keys.index(key)
|
||||
i = self.keys.find(key)
|
||||
if i != -1:
|
||||
self.values[i] = val
|
||||
else:
|
||||
|
|
|
@ -39,9 +39,11 @@ class __internal__:
|
|||
def print(*args):
|
||||
print(*args, flush=True, file=_C.seq_stdout())
|
||||
|
||||
def min(*args, key=None):
|
||||
def min(*args, key=None, default=None):
|
||||
if staticlen(args) == 0:
|
||||
compile_error("min expected at least 1 argument, got 0")
|
||||
compile_error("min() expected at least 1 argument, got 0")
|
||||
elif staticlen(args) > 1 and default is not None:
|
||||
compile_error("min() 'default' argument only allowed for iterables")
|
||||
elif staticlen(args) == 1:
|
||||
x = args[0].__iter__()
|
||||
if not x.done():
|
||||
|
@ -58,7 +60,10 @@ def min(*args, key=None):
|
|||
return s
|
||||
else:
|
||||
x.destroy()
|
||||
raise ValueError("min() arg is an empty sequence")
|
||||
if default is None:
|
||||
raise ValueError("min() arg is an empty sequence")
|
||||
else:
|
||||
return default
|
||||
elif staticlen(args) == 2:
|
||||
a, b = args
|
||||
if key is None:
|
||||
|
@ -76,9 +81,11 @@ def min(*args, key=None):
|
|||
m = i
|
||||
return m
|
||||
|
||||
def max(*args, key=None):
|
||||
def max(*args, key=None, default=None):
|
||||
if staticlen(args) == 0:
|
||||
compile_error("max expected at least 1 argument, got 0")
|
||||
compile_error("max() expected at least 1 argument, got 0")
|
||||
elif staticlen(args) > 1 and default is not None:
|
||||
compile_error("max() 'default' argument only allowed for iterables")
|
||||
elif staticlen(args) == 1:
|
||||
x = args[0].__iter__()
|
||||
if not x.done():
|
||||
|
@ -95,7 +102,10 @@ def max(*args, key=None):
|
|||
return s
|
||||
else:
|
||||
x.destroy()
|
||||
raise ValueError("max() arg is an empty sequence")
|
||||
if default is None:
|
||||
raise ValueError("max() arg is an empty sequence")
|
||||
else:
|
||||
return default
|
||||
elif staticlen(args) == 2:
|
||||
a, b = args
|
||||
if key is None:
|
||||
|
|
|
@ -708,6 +708,37 @@ def gzseek(a: cobj, b: int, c: i32) -> int:
|
|||
def gzflush(a: cobj, b: i32) -> i32:
|
||||
pass
|
||||
|
||||
# <bzlib.h>
|
||||
@nocapture
|
||||
@C
|
||||
def BZ2_bzopen(a: cobj, b: cobj) -> cobj:
|
||||
pass
|
||||
|
||||
@nocapture
|
||||
@C
|
||||
def BZ2_bzread(a: cobj, b: cobj, c: i32) -> i32:
|
||||
pass
|
||||
|
||||
@nocapture
|
||||
@C
|
||||
def BZ2_bzwrite(a: cobj, b: cobj, c: i32) -> i32:
|
||||
pass
|
||||
|
||||
@nocapture
|
||||
@C
|
||||
def BZ2_bzflush(a: cobj) -> i32:
|
||||
pass
|
||||
|
||||
@nocapture
|
||||
@C
|
||||
def BZ2_bzclose(a: cobj) -> None:
|
||||
pass
|
||||
|
||||
@nocapture
|
||||
@C
|
||||
def BZ2_bzerror(a: cobj, b: Ptr[i32]) -> cobj:
|
||||
pass
|
||||
|
||||
# <string.h>
|
||||
@pure
|
||||
@C
|
||||
|
|
|
@ -245,12 +245,162 @@ class gzFile:
|
|||
self.buf = cobj()
|
||||
self.sz = 0
|
||||
|
||||
def _bz_errcheck(stream: cobj):
|
||||
errnum = i32(0)
|
||||
msg = _C.BZ2_bzerror(stream, __ptr__(errnum))
|
||||
if errnum < i32(0):
|
||||
raise IOError(f"bzip2 error: {str(msg, _C.strlen(msg))}")
|
||||
|
||||
class bzFile:
|
||||
sz: int
|
||||
buf: Ptr[byte]
|
||||
fp: cobj
|
||||
|
||||
def __init__(self, fp: cobj):
|
||||
self.fp = fp
|
||||
self._reset()
|
||||
|
||||
def __init__(self, path: str, mode: str):
|
||||
self.fp = _C.BZ2_bzopen(path.c_str(), mode.c_str())
|
||||
if not self.fp:
|
||||
raise IOError(f"file {path} could not be opened")
|
||||
self._reset()
|
||||
|
||||
def _getline(self) -> int:
|
||||
if not self.buf:
|
||||
self.sz = 128
|
||||
self.buf = Ptr[byte](self.sz)
|
||||
|
||||
offset = 0
|
||||
while True:
|
||||
m = self._gets(self.buf + offset, self.sz - offset)
|
||||
if m == 0:
|
||||
if offset == 0:
|
||||
return -1
|
||||
break
|
||||
elif m < 0:
|
||||
_bz_errcheck(self.fp)
|
||||
if offset == 0:
|
||||
return -1
|
||||
break
|
||||
|
||||
offset += m
|
||||
|
||||
if self.buf[offset - 1] == byte(10): # '\n'
|
||||
break
|
||||
|
||||
oldsz = self.sz
|
||||
self.sz *= 2
|
||||
self.buf = realloc(self.buf, self.sz, oldsz)
|
||||
|
||||
return offset
|
||||
|
||||
def __iter__(self) -> Generator[str]:
|
||||
for a in self._iter():
|
||||
yield a.__ptrcopy__()
|
||||
|
||||
def __enter__(self):
|
||||
pass
|
||||
|
||||
def __exit__(self):
|
||||
self.close()
|
||||
|
||||
def close(self):
|
||||
if self.fp:
|
||||
_C.BZ2_bzclose(self.fp)
|
||||
self.fp = cobj()
|
||||
if self.buf:
|
||||
free(self.buf)
|
||||
self._reset()
|
||||
|
||||
def readlines(self) -> List[str]:
|
||||
return [l for l in self]
|
||||
|
||||
def write(self, s: str):
|
||||
self._ensure_open()
|
||||
_C.BZ2_bzwrite(self.fp, s.ptr, i32(len(s)))
|
||||
_bz_errcheck(self.fp)
|
||||
|
||||
def __file_write_gen__(self, g: Generator[T], T: type):
|
||||
for s in g:
|
||||
self.write(str(s))
|
||||
|
||||
def read(self, sz: int = -1) -> str:
|
||||
self._ensure_open()
|
||||
if sz < 0:
|
||||
buf = _strbuf()
|
||||
for a in self._iter():
|
||||
buf.append(a)
|
||||
return buf.__str__()
|
||||
buf = Ptr[byte](sz)
|
||||
ret = _C.BZ2_bzread(self.fp, buf, i32(sz))
|
||||
_bz_errcheck(self.fp)
|
||||
return str(buf, int(ret))
|
||||
|
||||
def flush(self):
|
||||
self._ensure_open()
|
||||
_C.BZ2_bzflush(self.fp)
|
||||
_bz_errcheck(self.fp)
|
||||
|
||||
def _iter(self) -> Generator[str]:
|
||||
self._ensure_open()
|
||||
while True:
|
||||
rd = self._getline()
|
||||
if rd != -1:
|
||||
yield str(self.buf, rd)
|
||||
else:
|
||||
break
|
||||
|
||||
def _iter_trim_newline(self) -> Generator[str]:
|
||||
self._ensure_open()
|
||||
while True:
|
||||
rd = self._getline()
|
||||
if rd != -1:
|
||||
if self.buf[rd - 1] == byte(10):
|
||||
rd -= 1
|
||||
yield str(self.buf, rd)
|
||||
else:
|
||||
break
|
||||
|
||||
def _ensure_open(self):
|
||||
if not self.fp:
|
||||
raise IOError("I/O operation on closed file")
|
||||
|
||||
def _reset(self):
|
||||
self.buf = cobj()
|
||||
self.sz = 0
|
||||
|
||||
def _gets(self, buf: cobj, sz: int):
|
||||
if sz <= 0:
|
||||
return 0
|
||||
|
||||
fp = self.fp
|
||||
b = byte(0)
|
||||
i = 0
|
||||
|
||||
while i < sz - 1:
|
||||
status = _C.BZ2_bzread(fp, __ptr__(b), i32(1))
|
||||
if status == i32(0):
|
||||
break
|
||||
elif status < i32(0):
|
||||
return -1
|
||||
|
||||
buf[i] = b
|
||||
i += 1
|
||||
if b == byte(10):
|
||||
break
|
||||
|
||||
return i
|
||||
|
||||
def open(path: str, mode: str = "r") -> File:
|
||||
return File(path, mode)
|
||||
|
||||
def gzopen(path: str, mode: str = "r") -> gzFile:
|
||||
return gzFile(path, mode)
|
||||
|
||||
def bzopen(path: str, mode: str = "r") -> gzFile:
|
||||
return bzFile(path, mode)
|
||||
|
||||
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
|
||||
|
|
|
@ -333,6 +333,14 @@ class List:
|
|||
self.len = 0
|
||||
|
||||
def index(self, x: T) -> int:
|
||||
i = 0
|
||||
for a in self:
|
||||
if a == x:
|
||||
return i
|
||||
i += 1
|
||||
raise ValueError(f"{x} is not in list")
|
||||
|
||||
def find(self, x: T) -> int:
|
||||
i = 0
|
||||
for a in self:
|
||||
if a == x:
|
||||
|
|
|
@ -499,7 +499,7 @@ class complex64:
|
|||
phase += other.imag * log(vabs)
|
||||
return complex64(len * cos(phase), len * sin(phase))
|
||||
|
||||
def __repr__(self) -> str:
|
||||
def _str(self, include_type: bool) -> str:
|
||||
@pure
|
||||
@llvm
|
||||
def copysign(x: f32, y: f32) -> f32:
|
||||
|
@ -515,14 +515,27 @@ class complex64:
|
|||
ret float %y
|
||||
|
||||
if self.real == f32(0.0) and copysign(f32(1.0), self.real) == f32(1.0):
|
||||
return f"complex64({self.imag}j)"
|
||||
if include_type:
|
||||
return f"complex64({self.imag}j)"
|
||||
else:
|
||||
return f"{self.imag}j"
|
||||
else:
|
||||
sign = "+"
|
||||
if self.imag < f32(0.0) or (
|
||||
self.imag == f32(0.0) and copysign(f32(1.0), self.imag) == f32(-1.0)
|
||||
):
|
||||
sign = "-"
|
||||
return f"complex64({self.real}{sign}{fabs(self.imag)}j)"
|
||||
|
||||
if include_type:
|
||||
return f"complex64({self.real}{sign}{fabs(self.imag)}j)"
|
||||
else:
|
||||
return f"({self.real}{sign}{fabs(self.imag)}j)"
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return self._str(include_type=True)
|
||||
|
||||
def __str__(self) -> str:
|
||||
return self._str(include_type=False)
|
||||
|
||||
def conjugate(self) -> complex64:
|
||||
return complex64(self.real, -self.imag)
|
||||
|
|
|
@ -146,3 +146,7 @@ class str:
|
|||
str.memcpy(p + n, i.ptr, i.len)
|
||||
n += i.len
|
||||
return str(p, total)
|
||||
|
||||
def __prefix_b__(s: str, N: Static[int]):
|
||||
# Currently a no-op, as Codon str's are just bytes
|
||||
return s
|
||||
|
|
|
@ -4,6 +4,218 @@
|
|||
def test_min_max():
|
||||
neg = lambda x: -x
|
||||
|
||||
assert min(42, 24) == 24
|
||||
assert max(42, 24) == 42
|
||||
assert min([42, 24]) == 24
|
||||
assert max([42, 24]) == 42
|
||||
assert min(1, 2, 3, 2, 1, 0, -1, 1, 2) == -1
|
||||
assert max(1, 2, 3, 2, 1, 0, -1, 1, 2) == 3
|
||||
assert min([1, 2, 3, 2, 1, 0, -1, 1, 2]) == -1
|
||||
assert max([1, 2, 3, 2, 1, 0, -1, 1, 2]) == 3
|
||||
|
||||
assert min(42, 24, key=neg) == 42
|
||||
assert max(42, 24, key=neg) == 24
|
||||
assert min([42, 24], key=neg) == 42
|
||||
assert max([42, 24], key=neg) == 24
|
||||
assert min(1, 2, 3, 2, 1, 0, -1, 1, 2, key=neg) == 3
|
||||
assert max(1, 2, 3, 2, 1, 0, -1, 1, 2, key=neg) == -1
|
||||
assert min([1, 2, 3, 2, 1, 0, -1, 1, 2], key=neg) == 3
|
||||
assert max([1, 2, 3, 2, 1, 0, -1, 1, 2], key=neg) == -1
|
||||
|
||||
assert min([42, 24], default=100) == 24
|
||||
assert max([42, 24], default=100) == 42
|
||||
assert min([1, 2, 3, 2, 1, 0, -1, 1, 2], default=100) == -1
|
||||
assert max([1, 2, 3, 2, 1, 0, -1, 1, 2], default=100) == 3
|
||||
|
||||
assert min([42, 24], default=100, key=neg) == 42
|
||||
assert max([42, 24], default=100, key=neg) == 24
|
||||
assert min([1, 2, 3, 2, 1, 0, -1, 1, 2], default=100, key=neg) == 3
|
||||
assert max([1, 2, 3, 2, 1, 0, -1, 1, 2], default=100, key=neg) == -1
|
||||
|
||||
assert max([2, 1, 1, 1, 1]) == 2
|
||||
assert max([1, 2, 1, 1, 1]) == 2
|
||||
assert max([1, 1, 2, 1, 1]) == 2
|
||||
assert max([1, 1, 1, 2, 1]) == 2
|
||||
assert max([1, 1, 1, 1, 2]) == 2
|
||||
assert max([2, 1, 1, 1]) == 2
|
||||
assert max([1, 2, 1, 1]) == 2
|
||||
assert max([1, 1, 2, 1]) == 2
|
||||
assert max([1, 1, 1, 2]) == 2
|
||||
assert max([2, 1, 1]) == 2
|
||||
assert max([1, 2, 1]) == 2
|
||||
assert max([1, 1, 2]) == 2
|
||||
assert max([2, 1]) == 2
|
||||
assert max([1, 2]) == 2
|
||||
|
||||
assert max([2, 1, 1, 1, 1], key=neg) == 1
|
||||
assert max([1, 2, 1, 1, 1], key=neg) == 1
|
||||
assert max([1, 1, 2, 1, 1], key=neg) == 1
|
||||
assert max([1, 1, 1, 2, 1], key=neg) == 1
|
||||
assert max([1, 1, 1, 1, 2], key=neg) == 1
|
||||
assert max([2, 1, 1, 1], key=neg) == 1
|
||||
assert max([1, 2, 1, 1], key=neg) == 1
|
||||
assert max([1, 1, 2, 1], key=neg) == 1
|
||||
assert max([1, 1, 1, 2], key=neg) == 1
|
||||
assert max([2, 1, 1], key=neg) == 1
|
||||
assert max([1, 2, 1], key=neg) == 1
|
||||
assert max([1, 1, 2], key=neg) == 1
|
||||
assert max([2, 1], key=neg) == 1
|
||||
assert max([1, 2], key=neg) == 1
|
||||
|
||||
assert min([2, 1, 1, 1, 1]) == 1
|
||||
assert min([1, 2, 1, 1, 1]) == 1
|
||||
assert min([1, 1, 2, 1, 1]) == 1
|
||||
assert min([1, 1, 1, 2, 1]) == 1
|
||||
assert min([1, 1, 1, 1, 2]) == 1
|
||||
assert min([2, 1, 1, 1]) == 1
|
||||
assert min([1, 2, 1, 1]) == 1
|
||||
assert min([1, 1, 2, 1]) == 1
|
||||
assert min([1, 1, 1, 2]) == 1
|
||||
assert min([2, 1, 1]) == 1
|
||||
assert min([1, 2, 1]) == 1
|
||||
assert min([1, 1, 2]) == 1
|
||||
assert min([2, 1]) == 1
|
||||
assert min([1, 2]) == 1
|
||||
|
||||
assert min([2, 1, 1, 1, 1], key=neg) == 2
|
||||
assert min([1, 2, 1, 1, 1], key=neg) == 2
|
||||
assert min([1, 1, 2, 1, 1], key=neg) == 2
|
||||
assert min([1, 1, 1, 2, 1], key=neg) == 2
|
||||
assert min([1, 1, 1, 1, 2], key=neg) == 2
|
||||
assert min([2, 1, 1, 1], key=neg) == 2
|
||||
assert min([1, 2, 1, 1], key=neg) == 2
|
||||
assert min([1, 1, 2, 1], key=neg) == 2
|
||||
assert min([1, 1, 1, 2], key=neg) == 2
|
||||
assert min([2, 1, 1], key=neg) == 2
|
||||
assert min([1, 2, 1], key=neg) == 2
|
||||
assert min([1, 1, 2], key=neg) == 2
|
||||
assert min([2, 1], key=neg) == 2
|
||||
assert min([1, 2], key=neg) == 2
|
||||
|
||||
assert max([0, 1, 1, 1, 1]) == 1
|
||||
assert max([1, 0, 1, 1, 1]) == 1
|
||||
assert max([1, 1, 0, 1, 1]) == 1
|
||||
assert max([1, 1, 1, 0, 1]) == 1
|
||||
assert max([1, 1, 1, 1, 0]) == 1
|
||||
assert max([0, 1, 1, 1]) == 1
|
||||
assert max([1, 0, 1, 1]) == 1
|
||||
assert max([1, 1, 0, 1]) == 1
|
||||
assert max([1, 1, 1, 0]) == 1
|
||||
assert max([0, 1, 1]) == 1
|
||||
assert max([1, 0, 1]) == 1
|
||||
assert max([1, 1, 0]) == 1
|
||||
assert max([0, 1]) == 1
|
||||
assert max([1, 0]) == 1
|
||||
|
||||
assert max([0, 1, 1, 1, 1], key=neg) == 0
|
||||
assert max([1, 0, 1, 1, 1], key=neg) == 0
|
||||
assert max([1, 1, 0, 1, 1], key=neg) == 0
|
||||
assert max([1, 1, 1, 0, 1], key=neg) == 0
|
||||
assert max([1, 1, 1, 1, 0], key=neg) == 0
|
||||
assert max([0, 1, 1, 1], key=neg) == 0
|
||||
assert max([1, 0, 1, 1], key=neg) == 0
|
||||
assert max([1, 1, 0, 1], key=neg) == 0
|
||||
assert max([1, 1, 1, 0], key=neg) == 0
|
||||
assert max([0, 1, 1], key=neg) == 0
|
||||
assert max([1, 0, 1], key=neg) == 0
|
||||
assert max([1, 1, 0], key=neg) == 0
|
||||
assert max([0, 1], key=neg) == 0
|
||||
assert max([1, 0], key=neg) == 0
|
||||
|
||||
assert min([0, 1, 1, 1, 1]) == 0
|
||||
assert min([1, 0, 1, 1, 1]) == 0
|
||||
assert min([1, 1, 0, 1, 1]) == 0
|
||||
assert min([1, 1, 1, 0, 1]) == 0
|
||||
assert min([1, 1, 1, 1, 0]) == 0
|
||||
assert min([0, 1, 1, 1]) == 0
|
||||
assert min([1, 0, 1, 1]) == 0
|
||||
assert min([1, 1, 0, 1]) == 0
|
||||
assert min([1, 1, 1, 0]) == 0
|
||||
assert min([0, 1, 1]) == 0
|
||||
assert min([1, 0, 1]) == 0
|
||||
assert min([1, 1, 0]) == 0
|
||||
assert min([0, 1]) == 0
|
||||
assert min([1, 0]) == 0
|
||||
|
||||
assert min([0, 1, 1, 1, 1], key=neg) == 1
|
||||
assert min([1, 0, 1, 1, 1], key=neg) == 1
|
||||
assert min([1, 1, 0, 1, 1], key=neg) == 1
|
||||
assert min([1, 1, 1, 0, 1], key=neg) == 1
|
||||
assert min([1, 1, 1, 1, 0], key=neg) == 1
|
||||
assert min([0, 1, 1, 1], key=neg) == 1
|
||||
assert min([1, 0, 1, 1], key=neg) == 1
|
||||
assert min([1, 1, 0, 1], key=neg) == 1
|
||||
assert min([1, 1, 1, 0], key=neg) == 1
|
||||
assert min([0, 1, 1], key=neg) == 1
|
||||
assert min([1, 0, 1], key=neg) == 1
|
||||
assert min([1, 1, 0], key=neg) == 1
|
||||
assert min([0, 1], key=neg) == 1
|
||||
assert min([1, 0], key=neg) == 1
|
||||
|
||||
assert min([0, 1, 1, 1, 1], default=99) == 0
|
||||
assert min([1, 0, 1, 1, 1], default=99) == 0
|
||||
assert min([1, 1, 0, 1, 1], default=99) == 0
|
||||
assert min([1, 1, 1, 0, 1], default=99) == 0
|
||||
assert min([1, 1, 1, 1, 0], default=99) == 0
|
||||
assert min([0, 1, 1, 1], default=99) == 0
|
||||
assert min([1, 0, 1, 1], default=99) == 0
|
||||
assert min([1, 1, 0, 1], default=99) == 0
|
||||
assert min([1, 1, 1, 0], default=99) == 0
|
||||
assert min([0, 1, 1], default=99) == 0
|
||||
assert min([1, 0, 1], default=99) == 0
|
||||
assert min([1, 1, 0], default=99) == 0
|
||||
assert min([0, 1], default=99) == 0
|
||||
assert min([1, 0], default=99) == 0
|
||||
assert min(List[int](), default=99) == 99
|
||||
|
||||
assert min([0, 1, 1, 1, 1], key=neg, default=99) == 1
|
||||
assert min([1, 0, 1, 1, 1], key=neg, default=99) == 1
|
||||
assert min([1, 1, 0, 1, 1], key=neg, default=99) == 1
|
||||
assert min([1, 1, 1, 0, 1], key=neg, default=99) == 1
|
||||
assert min([1, 1, 1, 1, 0], key=neg, default=99) == 1
|
||||
assert min([0, 1, 1, 1], key=neg, default=99) == 1
|
||||
assert min([1, 0, 1, 1], key=neg, default=99) == 1
|
||||
assert min([1, 1, 0, 1], key=neg, default=99) == 1
|
||||
assert min([1, 1, 1, 0], key=neg, default=99) == 1
|
||||
assert min([0, 1, 1], key=neg, default=99) == 1
|
||||
assert min([1, 0, 1], key=neg, default=99) == 1
|
||||
assert min([1, 1, 0], key=neg, default=99) == 1
|
||||
assert min([0, 1], key=neg, default=99) == 1
|
||||
assert min([1, 0], key=neg, default=99) == 1
|
||||
assert min(List[int](), key=neg, default=99) == 99
|
||||
|
||||
assert max([0, 1, 1, 1, 1], default=99) == 1
|
||||
assert max([1, 0, 1, 1, 1], default=99) == 1
|
||||
assert max([1, 1, 0, 1, 1], default=99) == 1
|
||||
assert max([1, 1, 1, 0, 1], default=99) == 1
|
||||
assert max([1, 1, 1, 1, 0], default=99) == 1
|
||||
assert max([0, 1, 1, 1], default=99) == 1
|
||||
assert max([1, 0, 1, 1], default=99) == 1
|
||||
assert max([1, 1, 0, 1], default=99) == 1
|
||||
assert max([1, 1, 1, 0], default=99) == 1
|
||||
assert max([0, 1, 1], default=99) == 1
|
||||
assert max([1, 0, 1], default=99) == 1
|
||||
assert max([1, 1, 0], default=99) == 1
|
||||
assert max([0, 1], default=99) == 1
|
||||
assert max([1, 0], default=99) == 1
|
||||
assert max(List[int](), default=99) == 99
|
||||
|
||||
assert max([0, 1, 1, 1, 1], key=neg, default=99) == 0
|
||||
assert max([1, 0, 1, 1, 1], key=neg, default=99) == 0
|
||||
assert max([1, 1, 0, 1, 1], key=neg, default=99) == 0
|
||||
assert max([1, 1, 1, 0, 1], key=neg, default=99) == 0
|
||||
assert max([1, 1, 1, 1, 0], key=neg, default=99) == 0
|
||||
assert max([0, 1, 1, 1], key=neg, default=99) == 0
|
||||
assert max([1, 0, 1, 1], key=neg, default=99) == 0
|
||||
assert max([1, 1, 0, 1], key=neg, default=99) == 0
|
||||
assert max([1, 1, 1, 0], key=neg, default=99) == 0
|
||||
assert max([0, 1, 1], key=neg, default=99) == 0
|
||||
assert max([1, 0, 1], key=neg, default=99) == 0
|
||||
assert max([1, 1, 0], key=neg, default=99) == 0
|
||||
assert max([0, 1], key=neg, default=99) == 0
|
||||
assert max([1, 0], key=neg, default=99) == 0
|
||||
assert max(List[int](), key=neg, default=99) == 99
|
||||
|
||||
assert max(2, 1, 1, 1, 1) == 2
|
||||
assert max(1, 2, 1, 1, 1) == 2
|
||||
assert max(1, 1, 2, 1, 1) == 2
|
||||
|
@ -329,6 +541,82 @@ def test_int_format():
|
|||
k = Int[128](0x7fffffffffffffff)
|
||||
assert (str(k), bin(k), oct(k), hex(k)) == ('9223372036854775807', '0b111111111111111111111111111111111111111111111111111111111111111', '0o777777777777777777777', '0x7fffffffffffffff')
|
||||
|
||||
@test
|
||||
def test_complex_format():
|
||||
import math
|
||||
|
||||
assert str(complex(1.1, 2.2)) == '(1.1+2.2j)'
|
||||
assert str(complex(11.0, -22.0)) == '(11-22j)'
|
||||
assert str(complex(-111.0, 222.0)) == '(-111+222j)'
|
||||
assert str(complex(-1111.0, -2222.0)) == '(-1111-2222j)'
|
||||
assert str(complex(1.0, 0.0)) == '(1+0j)'
|
||||
assert str(complex(0.0, 1.0)) == '1j'
|
||||
assert str(complex(-0.0, 1.0)) == '(-0+1j)'
|
||||
assert str(complex(0.0, -1.0)) == '-1j'
|
||||
assert str(complex(-0.0, -1.0)) == '(-0-1j)'
|
||||
assert str(complex(0.0, 0.0)) == '0j'
|
||||
assert str(complex(0.0, -0.0)) == '-0j'
|
||||
assert str(complex(-0.0, 0.0)) == '(-0+0j)'
|
||||
assert str(complex(-0.0, -0.0)) == '(-0-0j)'
|
||||
assert str(complex(math.inf, math.inf)) == '(inf+infj)'
|
||||
assert str(complex(-math.inf, math.nan)) == '(-inf+nanj)'
|
||||
assert str(complex(math.nan, -math.inf)) == '(nan-infj)'
|
||||
assert str(complex(math.nan, math.nan)) == '(nan+nanj)'
|
||||
|
||||
assert repr(complex(1.1, 2.2)) == '(1.1+2.2j)'
|
||||
assert repr(complex(11.0, -22.0)) == '(11-22j)'
|
||||
assert repr(complex(-111.0, 222.0)) == '(-111+222j)'
|
||||
assert repr(complex(-1111.0, -2222.0)) == '(-1111-2222j)'
|
||||
assert repr(complex(1.0, 0.0)) == '(1+0j)'
|
||||
assert repr(complex(0.0, 1.0)) == '1j'
|
||||
assert repr(complex(-0.0, 1.0)) == '(-0+1j)'
|
||||
assert repr(complex(0.0, -1.0)) == '-1j'
|
||||
assert repr(complex(-0.0, -1.0)) == '(-0-1j)'
|
||||
assert repr(complex(0.0, 0.0)) == '0j'
|
||||
assert repr(complex(0.0, -0.0)) == '-0j'
|
||||
assert repr(complex(-0.0, 0.0)) == '(-0+0j)'
|
||||
assert repr(complex(-0.0, -0.0)) == '(-0-0j)'
|
||||
assert repr(complex(math.inf, math.inf)) == '(inf+infj)'
|
||||
assert repr(complex(-math.inf, math.nan)) == '(-inf+nanj)'
|
||||
assert repr(complex(math.nan, -math.inf)) == '(nan-infj)'
|
||||
assert repr(complex(math.nan, math.nan)) == '(nan+nanj)'
|
||||
|
||||
assert str(complex64(1.1, 2.2)) == '(1.1+2.2j)'
|
||||
assert str(complex64(11.0, -22.0)) == '(11-22j)'
|
||||
assert str(complex64(-111.0, 222.0)) == '(-111+222j)'
|
||||
assert str(complex64(-1111.0, -2222.0)) == '(-1111-2222j)'
|
||||
assert str(complex64(1.0, 0.0)) == '(1+0j)'
|
||||
assert str(complex64(0.0, 1.0)) == '1j'
|
||||
assert str(complex64(-0.0, 1.0)) == '(-0+1j)'
|
||||
assert str(complex64(0.0, -1.0)) == '-1j'
|
||||
assert str(complex64(-0.0, -1.0)) == '(-0-1j)'
|
||||
assert str(complex64(0.0, 0.0)) == '0j'
|
||||
assert str(complex64(0.0, -0.0)) == '-0j'
|
||||
assert str(complex64(-0.0, 0.0)) == '(-0+0j)'
|
||||
assert str(complex64(-0.0, -0.0)) == '(-0-0j)'
|
||||
assert str(complex64(math.inf, math.inf)) == '(inf+infj)'
|
||||
assert str(complex64(-math.inf, math.nan)) == '(-inf+nanj)'
|
||||
assert str(complex64(math.nan, -math.inf)) == '(nan-infj)'
|
||||
assert str(complex64(math.nan, math.nan)) == '(nan+nanj)'
|
||||
|
||||
assert repr(complex64(1.1, 2.2)) == 'complex64(1.1+2.2j)'
|
||||
assert repr(complex64(11.0, -22.0)) == 'complex64(11-22j)'
|
||||
assert repr(complex64(-111.0, 222.0)) == 'complex64(-111+222j)'
|
||||
assert repr(complex64(-1111.0, -2222.0)) == 'complex64(-1111-2222j)'
|
||||
assert repr(complex64(1.0, 0.0)) == 'complex64(1+0j)'
|
||||
assert repr(complex64(0.0, 1.0)) == 'complex64(1j)'
|
||||
assert repr(complex64(-0.0, 1.0)) == 'complex64(-0+1j)'
|
||||
assert repr(complex64(0.0, -1.0)) == 'complex64(-1j)'
|
||||
assert repr(complex64(-0.0, -1.0)) == 'complex64(-0-1j)'
|
||||
assert repr(complex64(0.0, 0.0)) == 'complex64(0j)'
|
||||
assert repr(complex64(0.0, -0.0)) == 'complex64(-0j)'
|
||||
assert repr(complex64(-0.0, 0.0)) == 'complex64(-0+0j)'
|
||||
assert repr(complex64(-0.0, -0.0)) == 'complex64(-0-0j)'
|
||||
assert repr(complex64(math.inf, math.inf)) == 'complex64(inf+infj)'
|
||||
assert repr(complex64(-math.inf, math.nan)) == 'complex64(-inf+nanj)'
|
||||
assert repr(complex64(math.nan, -math.inf)) == 'complex64(nan-infj)'
|
||||
assert repr(complex64(math.nan, math.nan)) == 'complex64(nan+nanj)'
|
||||
|
||||
class A:
|
||||
def __len__(self):
|
||||
return 42
|
||||
|
@ -463,7 +751,7 @@ def test_num_from_str():
|
|||
assert str(e) == "could not convert string to float: ''"
|
||||
|
||||
@test
|
||||
def test_files(open_fn):
|
||||
def test_files(open_fn, append_allowed: bool = True):
|
||||
path = 'build/testfile.txt'
|
||||
f = open_fn(path, 'w')
|
||||
f.write('hello\nworld\n')
|
||||
|
@ -475,21 +763,24 @@ def test_files(open_fn):
|
|||
with open_fn(path) as f:
|
||||
assert f.read(3) == 'hel'
|
||||
assert f.read() == 'lo\nworld\n'
|
||||
f.seek(0, 0)
|
||||
assert f.tell() == 0
|
||||
assert f.read() == 'hello\nworld\n'
|
||||
if hasattr(f, "seek"):
|
||||
f.seek(0, 0)
|
||||
assert f.tell() == 0
|
||||
assert f.read() == 'hello\nworld\n'
|
||||
|
||||
try:
|
||||
f.tell()
|
||||
assert False
|
||||
except IOError:
|
||||
pass
|
||||
if hasattr(f, "tell"):
|
||||
try:
|
||||
f.tell()
|
||||
assert False
|
||||
except IOError:
|
||||
pass
|
||||
|
||||
try:
|
||||
f.seek(0, 0)
|
||||
assert False
|
||||
except IOError:
|
||||
pass
|
||||
if hasattr(f, "seek"):
|
||||
try:
|
||||
f.seek(0, 0)
|
||||
assert False
|
||||
except IOError:
|
||||
pass
|
||||
|
||||
try:
|
||||
f.flush()
|
||||
|
@ -497,10 +788,16 @@ def test_files(open_fn):
|
|||
except IOError:
|
||||
pass
|
||||
|
||||
f = open_fn(path, 'a')
|
||||
f.write('goodbye')
|
||||
f.flush()
|
||||
f.close()
|
||||
if append_allowed:
|
||||
f = open_fn(path, 'a')
|
||||
f.write('goodbye')
|
||||
f.flush()
|
||||
f.close()
|
||||
else:
|
||||
f = open_fn(path, 'w')
|
||||
f.write('hello\nworld\ngoodbye')
|
||||
f.flush()
|
||||
f.close()
|
||||
|
||||
with open_fn(path) as f:
|
||||
assert [line for line in f] == ['hello\n', 'world\n', 'goodbye']
|
||||
|
@ -513,6 +810,7 @@ test_min_max()
|
|||
test_map_filter()
|
||||
test_gen_builtins()
|
||||
test_int_format()
|
||||
test_complex_format()
|
||||
test_reversed()
|
||||
test_divmod()
|
||||
test_pow()
|
||||
|
@ -520,6 +818,8 @@ test_num_from_str()
|
|||
test_files(open)
|
||||
import gzip
|
||||
test_files(gzip.open)
|
||||
import bz2
|
||||
test_files(bz2.open, append_allowed=False)
|
||||
|
||||
|
||||
# Codon-specific
|
||||
|
|
|
@ -255,6 +255,11 @@ def test_list():
|
|||
l5 *= 2
|
||||
assert l5 == [11, 22, 55, 33, 1, 2, 11, 22, 55, 33, 1, 2]
|
||||
assert l5.index(33) == 3
|
||||
try:
|
||||
l5.index(0)
|
||||
assert False
|
||||
except ValueError as e:
|
||||
assert str(e) == '0 is not in list'
|
||||
l5 *= 0
|
||||
assert len(l5) == 0
|
||||
|
||||
|
|
Loading…
Reference in New Issue