Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

pyre v0.0.27 #186

Merged
merged 1 commit into from
Jul 2, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions WDL/Lint.py
Original file line number Diff line number Diff line change
Expand Up @@ -275,9 +275,9 @@ def expr(self, obj: Expr.Base) -> Any:
msg = "{} argument of {}() = :{}:".format(str(F_i), F.name, str(arg_i.type))
self.add(pt, msg, arg_i.pos)
elif obj.function_name == "size":
if not isinstance(obj.arguments[0].type, Type.File) and not (
isinstance(obj.arguments[0].type, Type.Array)
and isinstance(obj.arguments[0].type.item_type, Type.File)
arg0ty = obj.arguments[0].type
if not isinstance(arg0ty, Type.File) and not (
isinstance(arg0ty, Type.Array) and isinstance(arg0ty.item_type, Type.File)
):
self.add(
pt,
Expand Down Expand Up @@ -719,7 +719,7 @@ def decl(self, obj: Tree.Decl) -> Any:
while not isinstance(tw, (Tree.Task, Tree.Workflow)):
tw = getattr(tw, "parent")
assert isinstance(tw, (Tree.Task, Tree.Workflow))
if tw.inputs is not None and obj not in tw.inputs:
if isinstance(tw.inputs, list) and obj not in tw.inputs:
self.add(
obj,
"unnecessary optional quantifier (?) for non-input {} {}".format(
Expand Down
81 changes: 38 additions & 43 deletions WDL/StdLib.py
Original file line number Diff line number Diff line change
Expand Up @@ -448,20 +448,15 @@ class _Size(EagerFunction):
def infer_type(self, expr: "Expr.Apply") -> Type.Base:
if not expr.arguments:
raise Error.WrongArity(expr, 1)
if not expr.arguments[0].type.coerces(Type.File(optional=True)):
if isinstance(expr.arguments[0].type, Type.Array):
if expr.arguments[0].type.optional or not expr.arguments[0].type.item_type.coerces(
Type.File(optional=True)
):
arg0ty = expr.arguments[0].type
if not arg0ty.coerces(Type.File(optional=True)):
if isinstance(arg0ty, Type.Array):
if arg0ty.optional or not arg0ty.item_type.coerces(Type.File(optional=True)):
raise Error.StaticTypeMismatch(
expr.arguments[0],
Type.Array(Type.File(optional=True)),
expr.arguments[0].type,
expr.arguments[0], Type.Array(Type.File(optional=True)), arg0ty
)
else:
raise Error.StaticTypeMismatch(
expr.arguments[0], Type.File(optional=True), expr.arguments[0].type
)
raise Error.StaticTypeMismatch(expr.arguments[0], Type.File(optional=True), arg0ty)
if len(expr.arguments) == 2:
if expr.arguments[1].type != Type.String():
raise Error.StaticTypeMismatch(
Expand Down Expand Up @@ -505,17 +500,14 @@ class _SelectFirst(EagerFunction):
def infer_type(self, expr: "Expr.Apply") -> Type.Base:
if len(expr.arguments) != 1:
raise Error.WrongArity(expr, 1)
if not isinstance(expr.arguments[0].type, Type.Array) or (
expr.arguments[0]._check_quant and expr.arguments[0].type.optional
arg0ty = expr.arguments[0].type
if not isinstance(arg0ty, Type.Array) or (
expr.arguments[0]._check_quant and arg0ty.optional
):
raise Error.StaticTypeMismatch(
expr.arguments[0], Type.Array(Type.Any()), expr.arguments[0].type
)
if isinstance(expr.arguments[0].type.item_type, Type.Any):
raise Error.StaticTypeMismatch(expr.arguments[0], Type.Array(Type.Any()), arg0ty)
if isinstance(arg0ty.item_type, Type.Any):
raise Error.IndeterminateType(expr.arguments[0], "can't infer item type of empty array")
ty = expr.arguments[0].type.item_type
assert isinstance(ty, Type.Base)
return ty.copy(optional=False)
return arg0ty.item_type.copy(optional=False)

def _call_eager(self, expr: "Expr.Apply", arguments: List[Value.Base]) -> Value.Base:
arr = arguments[0].coerce(Type.Array(Type.Any()))
Expand All @@ -530,17 +522,14 @@ class _SelectAll(EagerFunction):
def infer_type(self, expr: "Expr.Apply") -> Type.Base:
if len(expr.arguments) != 1:
raise Error.WrongArity(expr, 1)
if not isinstance(expr.arguments[0].type, Type.Array) or (
expr.arguments[0]._check_quant and expr.arguments[0].type.optional
arg0ty = expr.arguments[0].type
if not isinstance(arg0ty, Type.Array) or (
expr.arguments[0]._check_quant and arg0ty.optional
):
raise Error.StaticTypeMismatch(
expr.arguments[0], Type.Array(Type.Any()), expr.arguments[0].type
)
if isinstance(expr.arguments[0].type.item_type, Type.Any):
raise Error.StaticTypeMismatch(expr.arguments[0], Type.Array(Type.Any()), arg0ty)
if isinstance(arg0ty.item_type, Type.Any):
raise Error.IndeterminateType(expr.arguments[0], "can't infer item type of empty array")
ty = expr.arguments[0].type.item_type
assert isinstance(ty, Type.Base)
return Type.Array(ty.copy(optional=False))
return Type.Array(arg0ty.item_type.copy(optional=False))

def _call_eager(self, expr: "Expr.Apply", arguments: List[Value.Base]) -> Value.Base:
arr = arguments[0].coerce(Type.Array(Type.Any()))
Expand Down Expand Up @@ -609,19 +598,23 @@ def _call_eager(self, expr: "Expr.Apply", arguments: List[Value.Base]) -> Value.

class _Flatten(EagerFunction):
# t array array -> t array
# TODO: if any of the input arrays are statically nonempty then so is output
def infer_type(self, expr: "Expr.Apply") -> Type.Base:
if len(expr.arguments) != 1:
raise Error.WrongArity(expr, 1)
expr.arguments[0].typecheck(Type.Array(Type.Any()))
# TODO: won't handle implicit coercion from T to Array[T]
assert isinstance(expr.arguments[0].type, Type.Array)
if expr.arguments[0].type.item_type is None:
arg0ty = expr.arguments[0].type
assert isinstance(arg0ty, Type.Array)
if isinstance(arg0ty.item_type, Type.Any):
return Type.Array(Type.Any())
if not isinstance(expr.arguments[0].type.item_type, Type.Array):
if not isinstance(arg0ty.item_type, Type.Array) or (
expr._check_quant and arg0ty.item_type.optional
):
raise Error.StaticTypeMismatch(
expr.arguments[0], Type.Array(Type.Array(Type.Any())), expr.arguments[0].type
expr.arguments[0], Type.Array(Type.Array(Type.Any())), arg0ty
)
return Type.Array(expr.arguments[0].type.item_type.item_type)
return Type.Array(arg0ty.item_type.item_type)

def _call_eager(self, expr: "Expr.Apply", arguments: List[Value.Base]) -> Value.Base:
ty = self.infer_type(expr)
Expand All @@ -634,19 +627,23 @@ def _call_eager(self, expr: "Expr.Apply", arguments: List[Value.Base]) -> Value.

class _Transpose(EagerFunction):
# t array array -> t array array
# TODO: if any of the input arrays are statically nonempty then so is output
def infer_type(self, expr: "Expr.Apply") -> Type.Base:
if len(expr.arguments) != 1:
raise Error.WrongArity(expr, 1)
expr.arguments[0].typecheck(Type.Array(Type.Any()))
# TODO: won't handle implicit coercion from T to Array[T]
assert isinstance(expr.arguments[0].type, Type.Array)
if expr.arguments[0].type.item_type is None:
arg0ty = expr.arguments[0].type
assert isinstance(arg0ty, Type.Array)
if isinstance(arg0ty.item_type, Type.Any):
return Type.Array(Type.Any())
if not isinstance(expr.arguments[0].type.item_type, Type.Array):
if not isinstance(arg0ty.item_type, Type.Array) or (
expr._check_quant and arg0ty.item_type.optional
):
raise Error.StaticTypeMismatch(
expr.arguments[0], Type.Array(Type.Array(Type.Any())), expr.arguments[0].type
expr.arguments[0], Type.Array(Type.Array(Type.Any())), arg0ty
)
return expr.arguments[0].type
return Type.Array(Type.Array(arg0ty.item_type.item_type))

def _call_eager(self, expr: "Expr.Apply", arguments: List[Value.Base]) -> Value.Base:
ty = self.infer_type(expr)
Expand Down Expand Up @@ -703,11 +700,9 @@ def infer_type(self, expr: "Expr.Apply") -> Type.Base:
raise Error.WrongArity(expr, 2)
expr.arguments[0].typecheck(Type.String())
expr.arguments[1].typecheck(Type.Array(Type.String()))
arg1ty = expr.arguments[1].type
return Type.Array(
Type.String(),
nonempty=(
isinstance(expr.arguments[1].type, Type.Array) and expr.arguments[1].type.nonempty
),
Type.String(), nonempty=(isinstance(arg1ty, Type.Array) and arg1ty.nonempty)
)

def _call_eager(self, expr: "Expr.Apply", arguments: List[Value.Base]) -> Value.Base:
Expand Down
14 changes: 7 additions & 7 deletions WDL/Tree.py
Original file line number Diff line number Diff line change
Expand Up @@ -379,12 +379,11 @@ def resolve(self, doc: TVDocument, call_names: Optional[Set[str]] = None) -> Non
callee_doc = imp.doc
if callee_doc:
assert isinstance(callee_doc, Document)
if callee_doc.workflow and callee_doc.workflow.name == self.callee_id[-1]:
if not callee_doc.workflow.complete_calls or (
callee_doc.workflow.outputs is None and callee_doc.workflow.effective_outputs
):
wf = callee_doc.workflow
if isinstance(wf, Workflow) and wf.name == self.callee_id[-1]:
if not wf.complete_calls or (wf.outputs is None and wf.effective_outputs):
raise Error.UncallableWorkflow(self, ".".join(self.callee_id))
self.callee = callee_doc.workflow
self.callee = wf
else:
for task in callee_doc.tasks:
if task.name == self.callee_id[-1]:
Expand Down Expand Up @@ -555,7 +554,7 @@ def add_to_type_env(
# seen as Array[T] outside)
inner_type_env: Env.Types = []
for elt in self.elements:
inner_type_env = elt.add_to_type_env(struct_typedefs, inner_type_env)
inner_type_env = elt.add_to_type_env(struct_typedefs, inner_type_env) # pyre-ignore
# Subtlety: if the scatter array is statically nonempty, then so too
# are the arrayized values.
nonempty = isinstance(self.expr._type, Type.Array) and self.expr._type.nonempty
Expand Down Expand Up @@ -1183,6 +1182,7 @@ def _build_workflow_type_env(
child_outer_type_env = type_env
for sibling in self.elements:
if sibling is not child:
# pyre-ignore
child_outer_type_env = sibling.add_to_type_env(
doc.struct_typedefs, child_outer_type_env
)
Expand All @@ -1197,7 +1197,7 @@ def _build_workflow_type_env(

# finally, populate self._type_env with all our children
for child in self.elements:
type_env = child.add_to_type_env(doc.struct_typedefs, type_env)
type_env = child.add_to_type_env(doc.struct_typedefs, type_env) # pyre-ignore
self._type_env = type_env


Expand Down
8 changes: 4 additions & 4 deletions WDL/runtime/task.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
from types import FrameType
from requests.exceptions import ReadTimeout
import docker
from .. import Error, Type, Env, Expr, Value, StdLib, Task, Tree, _util
from .. import Error, Type, Env, Expr, Value, StdLib, Tree, _util
from .error import *


Expand Down Expand Up @@ -287,7 +287,7 @@ def _run(self, logger: logging.Logger, command: str) -> int:


def run_local_task(
task: Task,
task: Tree.Task,
posix_inputs: Env.Values,
task_id: Optional[str] = None,
parent_dir: Optional[str] = None,
Expand Down Expand Up @@ -360,7 +360,7 @@ def run_local_task(


def _eval_task_inputs(
logger: logging.Logger, task: Task, posix_inputs: Env.Values, container: TaskContainer
logger: logging.Logger, task: Tree.Task, posix_inputs: Env.Values, container: TaskContainer
) -> Env.Values:
# Map all the provided input Files to in-container paths
# First make a pass to collect all the host paths and pass them to the
Expand Down Expand Up @@ -434,7 +434,7 @@ def map_files(v: Value.Base) -> Value.Base:


def _eval_task_outputs(
logger: logging.Logger, task: Task, env: Env.Values, container: TaskContainer
logger: logging.Logger, task: Tree.Task, env: Env.Values, container: TaskContainer
) -> Env.Values:

outputs = []
Expand Down
2 changes: 1 addition & 1 deletion requirements.dev.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Packages needed for miniwdl development, in addition to those in
# requirements.txt which are needed for miniwdl to run in common use.
pyre-check==0.0.22
pyre-check==0.0.27
black==19.3b0
pylint
sphinx
Expand Down