Skip to content

Commit

Permalink
Fix static errors
Browse files Browse the repository at this point in the history
  • Loading branch information
mandel committed Feb 6, 2025
1 parent 5ad78cd commit 0de1a79
Show file tree
Hide file tree
Showing 9 changed files with 328 additions and 192 deletions.
14 changes: 8 additions & 6 deletions src/pdl/pdl.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
empty_block_location,
get_default_model_parameters,
)
from .pdl_future import PdlDict
from .pdl_interpreter import InterpreterState, process_prog
from .pdl_parser import parse_file, parse_str
from .pdl_runner import exec_docker
Expand Down Expand Up @@ -51,7 +52,7 @@ class InterpreterConfig(TypedDict, total=False):
def exec_program(
prog: Program,
config: Optional[InterpreterConfig] = None,
scope: Optional[ScopeType] = None,
scope: Optional[ScopeType | dict[str, Any]] = None,
loc: Optional[LocationType] = None,
output: Literal["result", "all"] = "result",
) -> Any:
Expand All @@ -70,7 +71,8 @@ def exec_program(
logging.basicConfig(filename="log.txt", encoding="utf-8", format="", filemode="w")
config = config or {}
state = InterpreterState(**config)
scope = scope or {}
if not isinstance(scope, PdlDict):
scope = PdlDict(scope or {})
loc = loc or empty_block_location
result, _, scope, trace = process_prog(state, scope, prog, loc)
match output:
Expand All @@ -85,7 +87,7 @@ def exec_program(
def exec_dict(
prog: dict[str, Any],
config: Optional[InterpreterConfig] = None,
scope: Optional[ScopeType] = None,
scope: Optional[ScopeType | dict[str, Any]] = None,
loc: Optional[LocationType] = None,
output: Literal["result", "all"] = "result",
) -> Any:
Expand All @@ -109,7 +111,7 @@ def exec_dict(
def exec_str(
prog: str,
config: Optional[InterpreterConfig] = None,
scope: Optional[ScopeType] = None,
scope: Optional[ScopeType | dict[str, Any]] = None,
output: Literal["result", "all"] = "result",
) -> Any:
"""Execute a PDL program given as YAML string.
Expand All @@ -131,7 +133,7 @@ def exec_str(
def exec_file(
prog: str | Path,
config: Optional[InterpreterConfig] = None,
scope: Optional[ScopeType] = None,
scope: Optional[ScopeType | dict[str, Any]] = None,
output: Literal["result", "all"] = "result",
) -> Any:
"""Execute a PDL program given as YAML file.
Expand Down Expand Up @@ -276,7 +278,7 @@ def main():
pdl_file,
args.log,
InterpreterState(**config),
initial_scope,
PdlDict(initial_scope),
trace_file,
)

Expand Down
30 changes: 4 additions & 26 deletions src/pdl/pdl_ast.py
Original file line number Diff line number Diff line change
@@ -1,41 +1,19 @@
"""PDL programs are represented by the Pydantic data structure defined in this file.
"""

from asyncio import Task
from enum import StrEnum
from typing import Any, Literal, Optional, Sequence, TypeAlias, Union

from pydantic import BaseModel, ConfigDict, Field, RootModel

from .pdl_future import PdlDict, PdlList
from .pdl_schema_utils import pdltype_to_jsonschema

ScopeType: TypeAlias = dict[str, Any]
ScopeType: TypeAlias = PdlDict[str, Any]


Message: TypeAlias = dict[str, Any]
Messages: TypeAlias = list[Message]


class LazyMessage:
def __init__(self, task: Task[Message, Any]):
self.task = task

async def get(self) -> Message:
msg, _ = await self.task
return msg


class LazyMessages:
pass


class LazyRawResponse:
def __init__(self, task: Task[Message, Any]):
self.task = task

async def get(self) -> Message:
_, response = await self.task
return response
Message: TypeAlias = PdlDict[str, Any]
Messages: TypeAlias = PdlList[Message]


class BlockKind(StrEnum):
Expand Down
105 changes: 105 additions & 0 deletions src/pdl/pdl_future.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@

from abc import abstractmethod
import asyncio
from collections.abc import Mapping, Sequence
from concurrent.futures import Future
from typing import Callable, Generic, TypeVar, Union


FutureDataT = TypeVar("FutureDataT")

class PdlFuture(Generic[FutureDataT]):
@abstractmethod
def result(self) -> FutureDataT:
pass

PdlConstT = TypeVar("PdlConstT")

class PdlConst(PdlFuture[PdlConstT]):
def __init__(self, data: PdlConstT):
self.data = data

def result(self) -> PdlConstT:
v = self.data
if isinstance(v, Future):
v = v.result()
if isinstance(v, PdlFuture):
v = v.result()
return v # pyright: ignore


PdlListElemT = TypeVar("PdlListElemT")

class PdlList(Sequence[PdlListElemT], PdlFuture[list[PdlListElemT]]):
def __init__(self, data: list[PdlListElemT]):
self.data = data

def __getitem__(self, index: int | slice): # pyright: ignore
if isinstance(index, slice):
assert False, "'PdlArray' object does not support slice index"
v = self.data[index]
print(f"XXXX {index}: {v}")
if isinstance(v, Future):
v = v.result()
if isinstance(v, PdlFuture):
v = v.result()
return v

def __len__(self):
return len(self.data)

def __repr__(self):
return self.result().__repr__()

def result(self):
return list(self)



PdlDictKeyT = TypeVar("PdlDictKeyT")
PdlDictElemT = TypeVar("PdlDictElemT")


class PdlDict(Mapping[PdlDictKeyT, PdlDictElemT], PdlFuture[dict[PdlDictKeyT, PdlDictElemT]]):
def __init__(self, data: dict[PdlDictKeyT, PdlDictElemT] | Future[dict[PdlDictKeyT, PdlDictElemT]]):
if isinstance(data, Future):
self._data = None
self._future_data = data
else:
self._data = data

@property
def data(self):
if self._data is None:
self._data = self._future_data.result()
return self._data

def __getitem__(self, key): # pyright: ignore
v = self.data[key]
print(f"XXXX {key}: {v}")
if isinstance(v, Future):
v = v.result()
if isinstance(v, PdlFuture):
v = v.result()
return v

def __iter__(self):
return iter(self.data)

def __len__(self):
return len(self.data)

def __repr__(self):
return self.result().__repr__()

def __or__(self, value: Union["PdlDict", dict]):
if isinstance(value, PdlDict):
d = value.data
else:
d = value
return PdlDict(self.data | d)


def result(self): # pyright: ignore
return dict(self)

Loading

0 comments on commit 0de1a79

Please sign in to comment.