mirror of
https://github.com/erg-lang/erg.git
synced 2025-08-04 18:58:30 +00:00
fix: Python 3.9 bugs
This commit is contained in:
parent
f157673c59
commit
75c1ac733c
8 changed files with 105 additions and 40 deletions
|
@ -7,7 +7,7 @@ from _erg_contains_operator import contains_operator
|
|||
class Array(list):
|
||||
def try_new(arr): # -> Result[Array]
|
||||
if isinstance(arr, list):
|
||||
return Array(a)
|
||||
return Array(arr)
|
||||
else:
|
||||
return Error("not a list")
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
from _erg_result import is_ok
|
||||
from _erg_range import Range
|
||||
from _erg_type import is_type, isinstance
|
||||
from _erg_type import is_type, _isinstance
|
||||
|
||||
from collections import namedtuple
|
||||
|
||||
|
@ -10,22 +10,22 @@ def contains_operator(y, elem) -> bool:
|
|||
return elem.type_check(y)
|
||||
# 1 in Int
|
||||
elif is_type(y):
|
||||
if isinstance(elem, y):
|
||||
if _isinstance(elem, y):
|
||||
return True
|
||||
elif hasattr(y, "try_new") and is_ok(y.try_new(elem)):
|
||||
return True
|
||||
# TODO: trait check
|
||||
return False
|
||||
# [1] in [Int]
|
||||
elif isinstance(y, list) and isinstance(elem, list) and (
|
||||
len(y) == 0 or is_type(y[0]) or isinstance(y[0], Range)
|
||||
elif _isinstance(y, list) and _isinstance(elem, list) and (
|
||||
len(y) == 0 or is_type(y[0]) or _isinstance(y[0], Range)
|
||||
):
|
||||
type_check = all(map(lambda x: contains_operator(x[0], x[1]), zip(y, elem)))
|
||||
len_check = len(elem) <= len(y)
|
||||
return type_check and len_check
|
||||
# (1, 2) in (Int, Int)
|
||||
elif isinstance(y, tuple) and isinstance(elem, tuple) and (
|
||||
len(y) == 0 or is_type(y[0]) or isinstance(y[0], Range)
|
||||
elif _isinstance(y, tuple) and _isinstance(elem, tuple) and (
|
||||
len(y) == 0 or is_type(y[0]) or _isinstance(y[0], Range)
|
||||
):
|
||||
if not hasattr(elem, "__iter__"):
|
||||
return False
|
||||
|
@ -33,7 +33,7 @@ def contains_operator(y, elem) -> bool:
|
|||
len_check = len(elem) <= len(y)
|
||||
return type_check and len_check
|
||||
# {1: 2} in {Int: Int}
|
||||
elif isinstance(y, dict) and isinstance(elem, dict) and (
|
||||
elif _isinstance(y, dict) and _isinstance(elem, dict) and (
|
||||
len(y) == 0 or is_type(next(iter(y.keys())))
|
||||
):
|
||||
if len(y) == 1:
|
||||
|
@ -46,7 +46,7 @@ def contains_operator(y, elem) -> bool:
|
|||
type_check = True # contains_operator(next(iter(y.keys())), x[next(iter(x.keys()))])
|
||||
len_check = True # It can be True even if either elem or y has the larger number of elems
|
||||
return type_check and len_check
|
||||
elif isinstance(elem, list):
|
||||
elif _isinstance(elem, list):
|
||||
from _erg_array import Array
|
||||
return contains_operator(y, Array(elem))
|
||||
else:
|
||||
|
|
|
@ -9,6 +9,12 @@ class Int(int):
|
|||
else:
|
||||
return Error("not an integer")
|
||||
|
||||
def bit_count(self):
|
||||
if hasattr(int, "bit_count"):
|
||||
return int.bit_count(self)
|
||||
else:
|
||||
return bin(self).count("1")
|
||||
|
||||
def succ(self):
|
||||
return Int(self + 1)
|
||||
|
||||
|
|
|
@ -1,21 +1,33 @@
|
|||
from typing import _GenericAlias, Union
|
||||
try:
|
||||
from types import UnionType
|
||||
except ImportError:
|
||||
class UnionType:
|
||||
from typing import Union
|
||||
|
||||
class UnionType:
|
||||
__origin__ = Union
|
||||
__args__: list # list[type]
|
||||
def __init__(self, *args):
|
||||
self.__args__ = args
|
||||
|
||||
def is_type(x) -> bool:
|
||||
return isinstance(x, type) or \
|
||||
isinstance(x, _GenericAlias) or \
|
||||
isinstance(x, UnionType)
|
||||
class FakeGenericAlias:
|
||||
__origin__: type
|
||||
__args__: list # list[type]
|
||||
def __init__(self, origin, *args):
|
||||
self.__origin__ = origin
|
||||
self.__args__ = args
|
||||
try:
|
||||
from types import GenericAlias
|
||||
except ImportError:
|
||||
GenericAlias = FakeGenericAlias
|
||||
|
||||
def is_type(x) -> bool:
|
||||
return isinstance(x, (type, GenericAlias, UnionType))
|
||||
|
||||
instanceof = isinstance
|
||||
# The behavior of `builtins.isinstance` depends on the Python version.
|
||||
def isinstance(obj, classinfo) -> bool:
|
||||
if instanceof(classinfo, _GenericAlias) and classinfo.__origin__ == Union:
|
||||
return any(instanceof(obj, t) for t in classinfo.__args__)
|
||||
def _isinstance(obj, classinfo) -> bool:
|
||||
if isinstance(classinfo, (GenericAlias, UnionType)):
|
||||
if classinfo.__origin__ == Union:
|
||||
return any(isinstance(obj, t) for t in classinfo.__args__)
|
||||
else:
|
||||
return isinstance(obj, classinfo.__origin__)
|
||||
elif is_type(classinfo):
|
||||
return isinstance(obj, classinfo)
|
||||
else:
|
||||
return instanceof(obj, classinfo)
|
||||
return False
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue