fix and and or

This commit is contained in:
Khaleel Al-Adhami 2025-01-16 13:48:42 -08:00
parent d0208e678c
commit 076cfea6ae
3 changed files with 83 additions and 37 deletions

View File

@ -860,6 +860,10 @@ def infallible_issubclass(cls: Any, class_or_tuple: Any, /) -> bool:
Returns:
Whether the class is a subclass of the other class or tuple of classes.
"""
if cls is class_or_tuple or (
isinstance(class_or_tuple, tuple) and cls in class_or_tuple
):
return True
try:
return issubclass(cls, class_or_tuple)
except TypeError:
@ -876,6 +880,8 @@ def typehint_issubclass(possible_subclass: Any, possible_superclass: Any) -> boo
Returns:
Whether the type hint is a subclass of the other type hint.
"""
if possible_subclass is possible_superclass:
return True
if possible_superclass is Any:
return True
if possible_subclass is Any:
@ -956,7 +962,7 @@ def typehint_issubclass(possible_subclass: Any, possible_superclass: Any) -> boo
return True
# Check if the origin of both types is the same (e.g., list for List[int])
if not safe_issubclass(
if not infallible_issubclass(
provided_type_origin or possible_subclass,
accepted_type_origin or possible_superclass,
):
@ -968,5 +974,5 @@ def typehint_issubclass(possible_subclass: Any, possible_superclass: Any) -> boo
return all(
typehint_issubclass(provided_arg, accepted_arg)
for provided_arg, accepted_arg in zip(provided_args, accepted_args)
if accepted_arg is not Any
if accepted_arg is not Any and not isinstance(accepted_arg, TypeVar)
)

View File

@ -3261,37 +3261,14 @@ def and_operation(a: Var | Any, b: Var | Any) -> Var:
Returns:
The result of the logical AND operation.
"""
return _and_operation(a, b) # type: ignore
from .function import ArgsFunctionOperation
a = Var.create(a)
b = Var.create(b)
@var_operation
def _and_operation(a: Var, b: Var):
"""Perform a logical AND operation on two variables.
Args:
a: The first variable.
b: The second variable.
Returns:
The result of the logical AND operation.
"""
def type_computer(*args: Var):
if not args:
return (ReflexCallable[[Any, Any], Any], type_computer)
if len(args) == 1:
return (
ReflexCallable[[Any], Any],
functools.partial(type_computer, args[0]),
)
return (
ReflexCallable[[], unionize(args[0]._var_type, args[1]._var_type)],
None,
)
return var_operation_return(
js_expression=f"({a} && {b})",
type_computer=type_computer,
return _or_func_operation(
ArgsFunctionOperation.create((), a, _var_type=ReflexCallable[[], a._var_type]),
ArgsFunctionOperation.create((), b, _var_type=ReflexCallable[[], b._var_type]),
)
@ -3305,11 +3282,65 @@ def or_operation(a: Var | Any, b: Var | Any) -> Var:
Returns:
The result of the logical OR operation.
"""
return _or_operation(a, b) # type: ignore
from .function import ArgsFunctionOperation
a = Var.create(a)
b = Var.create(b)
return _or_func_operation(
ArgsFunctionOperation.create((), a, _var_type=ReflexCallable[[], a._var_type]),
ArgsFunctionOperation.create((), b, _var_type=ReflexCallable[[], b._var_type]),
)
T_LOGICAL = TypeVar("T_LOGICAL")
U_LOGICAL = TypeVar("U_LOGICAL")
@var_operation
def _or_operation(a: Var, b: Var):
def _and_func_operation(
a: Var[ReflexCallable[[], T_LOGICAL]], b: Var[ReflexCallable[[], U_LOGICAL]]
) -> CustomVarOperationReturn[ReflexCallable[[], Union[T_LOGICAL, U_LOGICAL]]]:
"""Perform a logical AND operation on two variables.
Args:
a: The first variable.
b: The second variable.
Returns:
The result of the logical AND operation.
"""
def type_computer(*args: Var):
if not args:
return (
ReflexCallable[[ReflexCallable[[], Any], ReflexCallable[[], Any]], Any],
type_computer,
)
if len(args) == 1:
return (
ReflexCallable[[ReflexCallable[[], Any]], Any],
functools.partial(type_computer, args[0]),
)
a_return_type = unwrap_reflex_callalbe(args[0]._var_type)[1]
b_return_type = unwrap_reflex_callalbe(args[1]._var_type)[1]
return (
ReflexCallable[[], unionize(a_return_type, b_return_type)],
None,
)
return var_operation_return(
js_expression=f"({a}() && {b}())",
type_computer=type_computer,
)
@var_operation
def _or_func_operation(
a: Var[ReflexCallable[[], T_LOGICAL]], b: Var[ReflexCallable[[], U_LOGICAL]]
) -> CustomVarOperationReturn[ReflexCallable[[], Union[T_LOGICAL, U_LOGICAL]]]:
"""Perform a logical OR operation on two variables.
Args:
@ -3322,19 +3353,26 @@ def _or_operation(a: Var, b: Var):
def type_computer(*args: Var):
if not args:
return (ReflexCallable[[Any, Any], Any], type_computer)
return (
ReflexCallable[[ReflexCallable[[], Any], ReflexCallable[[], Any]], Any],
type_computer,
)
if len(args) == 1:
return (
ReflexCallable[[Any], Any],
ReflexCallable[[ReflexCallable[[], Any]], Any],
functools.partial(type_computer, args[0]),
)
a_return_type = unwrap_reflex_callalbe(args[0]._var_type)[1]
b_return_type = unwrap_reflex_callalbe(args[1]._var_type)[1]
return (
ReflexCallable[[], unionize(args[0]._var_type, args[1]._var_type)],
ReflexCallable[[], unionize(a_return_type, b_return_type)],
None,
)
return var_operation_return(
js_expression=f"({a} || {b})",
js_expression=f"({a}() || {b}())",
type_computer=type_computer,
)

View File

@ -751,6 +751,7 @@ class ArgsFunctionOperation(CachedVarOperation, FunctionVar[CALLABLE_TYPE]):
Returns:
The function var.
"""
return_expr = Var.create(return_expr)
return cls(
_js_expr="",
_var_type=_var_type,
@ -829,6 +830,7 @@ class ArgsFunctionOperationBuilder(
Returns:
The function var.
"""
return_expr = Var.create(return_expr)
return cls(
_js_expr="",
_var_type=_var_type,