Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
mlin committed Jun 2, 2024
1 parent d4866ff commit f505eff
Showing 1 changed file with 17 additions and 12 deletions.
29 changes: 17 additions & 12 deletions WDL/Expr.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,12 @@
.. inheritance-diagram:: WDL.Expr
"""
from abc import ABC, abstractmethod
from typing import List, Optional, Dict, Tuple, Union, Iterable
from typing import List, Optional, Dict, Tuple, Union, Iterable, Set, TYPE_CHECKING
import regex
from .Error import SourcePosition, SourceNode
from . import Type, Value, Env, Error, StdLib
if TYPE_CHECKING:
from . import Tree


class Base(SourceNode, ABC):
Expand Down Expand Up @@ -73,9 +75,9 @@ def infer_type(
for child in self.children:
assert isinstance(child, Base)
errors.try1(
lambda child=child: child.infer_type(
(lambda child: lambda: child.infer_type(
type_env, stdlib, check_quant, struct_types
)
))(child)
)
# invoke derived-class logic. we pass check_quant, stdlib, and struct_types hackily through
# instance variables since only some subclasses use them.
Expand Down Expand Up @@ -135,7 +137,7 @@ def literal(self) -> Optional[Value.Base]:
result can be an instance of ``WDL.Value.Null`` which is distinct from None.
"""
if isinstance(self, (Boolean, Int, Float)):
return self._eval(Env.Bindings(), None) # pyre-fixme
return self._eval(Env.Bindings(), None) # type: ignore
return None


Expand Down Expand Up @@ -277,6 +279,7 @@ def rewrite_adds(ch: Base):
if isinstance(ch, Apply) and ch.function_name == "_add":
ch.function_name = "_interpolation_add"
for ch2 in ch.children:
assert isinstance(ch2, Base)
rewrite_adds(ch2)

rewrite_adds(self.expr)
Expand Down Expand Up @@ -345,7 +348,7 @@ def _eval_impl(self, env: Env.Bindings[Value.Base], stdlib: StdLib.Base) -> Valu

def _eval(self, env: Env.Bindings[Value.Base], stdlib: StdLib.Base) -> Value.String:
ans = self._eval_impl(env, stdlib)
placeholder_regex: regex.Pattern = getattr(stdlib, "_placeholder_regex", None)
placeholder_regex: Optional[regex.Pattern] = getattr(stdlib, "_placeholder_regex", None)
if placeholder_regex and not placeholder_regex.fullmatch(ans.value):
raise Error.InputError(
"Task command placeholder value forbidden by configuration [task_runtime] placeholder_regex"
Expand Down Expand Up @@ -402,9 +405,9 @@ def children(self) -> Iterable[SourceNode]:
def _infer_type(self, type_env: Env.Bindings[Type.Base]) -> Type.Base:
return Type.String()

def typecheck(self, expected: Optional[Type.Base]) -> Base:
def typecheck(self, expected: Type.Base) -> Base:
""""""
return super().typecheck(expected) # pyre-ignore
return super().typecheck(expected)

def _eval(self, env: Env.Bindings[Value.Base], stdlib: StdLib.Base) -> Value.String:
""""""
Expand All @@ -427,16 +430,18 @@ def _eval(self, env: Env.Bindings[Value.Base], stdlib: StdLib.Base) -> Value.Str
if self.command:
return Value.String("".join(ans))
delim = self.parts[0]
assert isinstance(delim, str)
assert delim in ("'", '"', "{", "<<<")
delim2 = self.parts[-1]
assert isinstance(delim2, str)
assert delim2 in ("'", '"', "}", ">>>") and len(delim) == len(delim2)
return Value.String("".join(ans)[len(delim) : -len(delim)])

@property
def literal(self) -> Optional[Value.Base]:
if next((p for p in self.parts if not isinstance(p, str)), None):
return None
return self._eval(Env.Bindings(), None) # pyre-fixme
return self._eval(Env.Bindings(), None) # type: ignore


class Array(Base):
Expand Down Expand Up @@ -476,12 +481,12 @@ def _infer_type(self, type_env: Env.Bindings[Type.Base]) -> Type.Base:
raise Error.IndeterminateType(self, "unable to unify array item types")
return Type.Array(item_type, optional=False, nonempty=True)

def typecheck(self, expected: Optional[Type.Base]) -> Base:
def typecheck(self, expected: Type.Base) -> Base:
""""""
if not self.items and isinstance(expected, Type.Array):
# the literal empty array satisfies any array type
return self
return super().typecheck(expected) # pyre-ignore
return super().typecheck(expected)

def _eval(self, env: Env.Bindings[Value.Base], stdlib: StdLib.Base) -> Value.Array:
""""""
Expand Down Expand Up @@ -594,7 +599,7 @@ def _infer_type(self, type_env: Env.Bindings[Type.Base]) -> Type.Base:
)
if isinstance(vty, Type.Any):
raise Error.IndeterminateType(self, "unable to unify map value types")
literal_keys = None
literal_keys: Optional[Set[str]] = None
if kty == Type.String():
# If the keys are string constants, record them in the Type object
# for potential later use in struct coercion. (Normally the Type
Expand Down Expand Up @@ -720,7 +725,7 @@ def _eval(self, env: Env.Bindings[Value.Base], stdlib: StdLib.Base) -> Value.Bas
if isinstance(self.type, Type.StructInstance):
assert self.type.members
ans[k] = ans[k].coerce(self.type.members[k])
return Value.Struct(self.type, ans)
return Value.Struct(self.type, ans) # type: ignore

@property
def literal(self) -> Optional[Value.Base]:
Expand Down

0 comments on commit f505eff

Please sign in to comment.