Skip to content

Commit db35262

Browse files
committed
initial
1 parent e084708 commit db35262

File tree

2 files changed

+91
-0
lines changed

2 files changed

+91
-0
lines changed

13-interlude_ast.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import ast
2+
3+
4+
CODE = """
5+
import sys
6+
7+
print('Hello world')
8+
"""
9+
10+
11+
class StrUpper(ast.NodeTransformer):
12+
def visit_Str(self, node):
13+
# Replace each string with a call to <string>.upper()
14+
new_node = ast.Call(
15+
func=ast.Attribute(value=node, attr='upper', ctx=ast.Load()),
16+
args=[],
17+
keywords=[])
18+
return new_node
19+
20+
21+
tree = ast.parse(CODE)
22+
print('---')
23+
print(ast.dump(tree))
24+
print('---')
25+
exec(compile(tree, filename='', mode='exec'))
26+
27+
tree = StrUpper().visit(tree)
28+
ast.fix_missing_locations(tree)
29+
print('---')
30+
print(ast.dump(tree))
31+
print('---')
32+
exec(compile(tree, filename='', mode='exec'))

14-ast.py

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
import ast
2+
3+
CODE = """
4+
from dataclasses import dataclass
5+
6+
7+
class TypeChecker:
8+
required_type = object
9+
10+
def __init__(self, name=None):
11+
self.name = name
12+
13+
def __get__(self, instance, owner=None):
14+
return instance.__dict__[self.name]
15+
16+
def __set__(self, instance, value):
17+
assert isinstance(value, self.required_type), \
18+
f'Booooo! Expecting a {self.required_type.__name__}'
19+
instance.__dict__[self.name] = value
20+
21+
22+
def typed(cls):
23+
for var_name, var_type in cls.__annotations__.items():
24+
class Checker(TypeChecker):
25+
required_type = var_type
26+
setattr(cls, var_name, Checker(var_name))
27+
return cls
28+
29+
30+
@dataclass
31+
class Point:
32+
x: int
33+
y: int
34+
35+
36+
p = Point(1, 2)
37+
print(p)
38+
p.x = 'foo'
39+
print(p)
40+
"""
41+
42+
43+
class DecorateClasses(ast.NodeTransformer):
44+
def visit_ClassDef(self, node):
45+
if not [True for dec in node.decorator_list if dec.id == 'dataclass']:
46+
# Not a dataclass
47+
return node
48+
dec = ast.Name(id='typed', ctx=ast.Load())
49+
node.decorator_list.insert(0, dec)
50+
return node
51+
52+
53+
tree = ast.parse(CODE)
54+
exec(compile(tree, filename='', mode='exec'))
55+
56+
print('---')
57+
tree = DecorateClasses().visit(tree)
58+
ast.fix_missing_locations(tree)
59+
exec(compile(tree, filename='', mode='exec'))

0 commit comments

Comments
 (0)