Skip to content

Commit

Permalink
Merge branch 'master' into feature/05-attempt-II
Browse files Browse the repository at this point in the history
  • Loading branch information
CodeSteak committed Dec 4, 2021
2 parents 46e7b07 + 384e3f7 commit a45ec8c
Show file tree
Hide file tree
Showing 8 changed files with 66 additions and 4 deletions.
11 changes: 9 additions & 2 deletions python/deps/untypy/untypy/impl/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
from .protocol import ProtocolFactory
from .sequence import SequenceFactory
from .simple import SimpleFactory
from .string_forward_refs import StringForwardRefFactory
from .tuple import TupleFactory
from .union import UnionFactory
from ..error import Location, UntypyAttributeError
Expand All @@ -37,17 +38,20 @@
GeneratorFactory(),
IteratorFactory(),
InterfaceFactory(),
StringForwardRefFactory(), # resolve types passed as strings
# must come last
SimpleFactory()
]


class DefaultCreationContext(CreationContext):

def __init__(self, typevars: Dict[TypeVar, Any], declared_location: Location, checkedpkgprefixes: List[str]):
def __init__(self, typevars: Dict[TypeVar, Any], declared_location: Location,
checkedpkgprefixes: List[str], eval_context: Optional[Any] = None):
self.typevars = typevars
self.declared = declared_location
self.checkedpkgprefixes = checkedpkgprefixes
self._eval_context = eval_context

def declared_location(self) -> Location:
return self.declared
Expand Down Expand Up @@ -75,7 +79,7 @@ def all_typevars(self) -> List[TypeVar]:
def with_typevars(self, typevars: Dict[TypeVar, Any]) -> CreationContext:
tv = self.typevars.copy()
tv.update(typevars)
return DefaultCreationContext(tv, self.declared, self.checkedpkgprefixes)
return DefaultCreationContext(tv, self.declared, self.checkedpkgprefixes, self._eval_context)

def should_be_inheritance_checked(self, annotation: type) -> bool:
m = inspect.getmodule(annotation)
Expand All @@ -88,3 +92,6 @@ def should_be_inheritance_checked(self, annotation: type) -> bool:
return True

return False

def eval_context(self):
return self._eval_context
14 changes: 14 additions & 0 deletions python/deps/untypy/untypy/impl/string_forward_refs.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
from typing import Any, Optional

from untypy.interfaces import TypeChecker, TypeCheckerFactory, CreationContext


class StringForwardRefFactory(TypeCheckerFactory):
def create_from(self, annotation: Any, ctx: CreationContext) -> Optional[TypeChecker]:
if type(annotation) is str:
eval_args = [annotation, globals()]
local = ctx.eval_context()
if local is not None:
eval_args.append(local)
annotation = eval(*eval_args)
return ctx.find_checker(annotation)
3 changes: 3 additions & 0 deletions python/deps/untypy/untypy/interfaces.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ def with_typevars(self, typevars: dict[TypeVar, Any]) -> CreationContext:
def should_be_inheritance_checked(self, annotation: type) -> bool:
raise NotImplementedError

def eval_context(self):
raise NotImplementedError


class ExecutionContext:
def wrap(self, err: UntypyTypeError) -> UntypyTypeError:
Expand Down
5 changes: 3 additions & 2 deletions python/deps/untypy/untypy/patching/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@ def patch_class(clas: type, cfg: Config):
file="<not found>",
line_no=0,
line_span=1
), checkedpkgprefixes=cfg.checkedprefixes)
), checkedpkgprefixes=cfg.checkedprefixes,
)

setattr(clas, '__patched', True)

Expand All @@ -55,7 +56,7 @@ def wrap_function(fn: FunctionType, cfg: Config) -> Callable:
return TypedFunctionBuilder(fn, DefaultCreationContext(
typevars=dict(),
declared_location=WrappedFunction.find_location(fn),
checkedpkgprefixes=cfg.checkedprefixes)).build()
checkedpkgprefixes=cfg.checkedprefixes, eval_context=fn.__globals__)).build()
else:
return fn

Expand Down
1 change: 1 addition & 0 deletions python/fileTests
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@ checkWithOutputAux yes 0 test-data/testForwardRef1.py
checkWithOutputAux yes 1 test-data/testForwardRef2.py
checkWithOutputAux yes 0 test-data/testForwardRef3.py
checkWithOutputAux yes 1 test-data/testForwardRef4.py
checkWithOutputAux yes 1 test-data/testForwardRef5.py
checkWithOutputAux yes 1 test-data/testTypesReturn.py
checkWithOutputAux yes 1 test-data/testMissingReturn.py
checkWithOutputAux yes 1 test-data/testTypesSequence1.py
Expand Down
12 changes: 12 additions & 0 deletions python/test-data/testForwardRef5.err
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
Traceback (most recent call last):
File "test-data/testForwardRef5.py", line 23, in <module>
for car in garage.cars:
WyppTypeError: got value of wrong type
given: 'Not A Car'
expected: value of type Car

context: record constructor Garage(cars: list[Car]) -> Self
^^^
declared at: test-data/testForwardRef5.py:9
caused by: test-data/testForwardRef5.py:23
| for car in garage.cars:
Empty file.
24 changes: 24 additions & 0 deletions python/test-data/testForwardRef5.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# See https://github.com/skogsbaer/write-your-python-program/issues/62

from wypp import *

@record
class Car:
color: str

@record
class Garage:
cars: list['Car']

class CarManager:
def store(self, car : set['Car'], garage :'Garage') -> 'CarManager':
return self

garage = Garage(cars=[Car(color='red'), Car(color='blue')])
for car in garage.cars:
pass

# trigger error
garage = Garage(cars=[Car(color='red'), "Not A Car"])
for car in garage.cars:
pass

0 comments on commit a45ec8c

Please sign in to comment.