Skip to content

Commit 303afab

Browse files
committed
Add missing _annotate.py
1 parent 4f917c2 commit 303afab

File tree

2 files changed

+79
-1
lines changed

2 files changed

+79
-1
lines changed
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
from types import MethodType
2+
import pydantic
3+
from amaranth.lib import meta
4+
from typing import Any, Annotated, NamedTuple, Self, TypeVar
5+
from typing_extensions import TypedDict, is_typeddict
6+
_T_TypedDict = TypeVar('_T_TypedDict')
7+
8+
def amaranth_annotate(modeltype: type['_T_TypedDict'], schema_id: str, member='__chipflow_annotation__', decorate_object = False):
9+
if not is_typeddict(modeltype):
10+
raise TypeError(f'''amaranth_annotate must be passed a TypedDict, not {modeltype}''')
11+
if hasattr(modeltype, '__pydantic_config__'):
12+
config = getattr(modeltype, '__pydantic_config__')
13+
config['arbitrary_types_allowed'] = True
14+
else:
15+
config = pydantic.ConfigDict()
16+
config['arbitrary_types_allowed'] = True
17+
setattr(modeltype, '__pydantic_config__', config)
18+
PydanticModel = pydantic.TypeAdapter(modeltype)
19+
20+
def annotation_schema():
21+
schema = PydanticModel.json_schema()
22+
schema['$schema'] = 'https://json-schema.org/draft/2020-12/schema'
23+
schema['$id'] = schema_id
24+
return schema
25+
26+
class Annotation:
27+
'Generated annotation class'
28+
schema = annotation_schema()
29+
30+
def __init__(self, parent):
31+
self.parent = parent
32+
33+
def origin(self):
34+
return self.parent
35+
36+
def as_json(self):
37+
return PydanticModel.dump_python(getattr(self.parent, member))
38+
39+
def decorate_class(klass):
40+
if hasattr(klass, 'annotations'):
41+
old_annotations = klass.annotations
42+
else:
43+
old_annotations = None
44+
45+
def annotations(self, obj):
46+
if old_annotations:
47+
annotations = old_annotations(self, obj)
48+
else:
49+
annotations = super(klass, obj).annotations(obj)
50+
annotation = Annotation(self)
51+
return annotations + (annotation,)
52+
53+
klass.annotations = annotations
54+
return klass
55+
56+
def decorate_obj(obj):
57+
if hasattr(obj, 'annotations'):
58+
old_annotations = obj.annotations
59+
else:
60+
old_annotations = None
61+
62+
def annotations(self = None, origin = None):
63+
if old_annotations:
64+
annotations = old_annotations(origin)
65+
else:
66+
annotations = super(obj.__class__, obj).annotations(obj)
67+
annotation = Annotation(self)
68+
return annotations + (annotation,)
69+
70+
setattr(obj, 'annotations', MethodType(annotations, obj))
71+
return obj
72+
73+
if decorate_object:
74+
return decorate_obj
75+
else:
76+
return decorate_class
77+

chipflow_lib/platforms/_signatures.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# SPDX-License-Identifier: BSD-2-Clause
22

33
import re
4+
from typing import List, Tuple, Any
45
from typing_extensions import Unpack, TypedDict
56

67
from amaranth.lib import wiring
@@ -15,7 +16,7 @@
1516

1617
class SimInterface(TypedDict):
1718
uid: str
18-
parameters: dict
19+
parameters: List[Tuple[str, Any]]
1920

2021
class SimData(TypedDict):
2122
file_name: str

0 commit comments

Comments
 (0)