Skip to content

Commit

Permalink
fix: forward-refs
Browse files Browse the repository at this point in the history
  • Loading branch information
michael-0acf4 committed May 7, 2024
1 parent f198d1d commit 06d2cd1
Show file tree
Hide file tree
Showing 5 changed files with 52 additions and 20 deletions.
8 changes: 7 additions & 1 deletion libs/metagen/src/mdk_python/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,13 @@ fn render_types(tera: &tera::Tera, required: &RequiredObjects) -> anyhow::Result
.memo
.types_in_order()
.iter()
.map(|repr| repr.def.to_owned())
.filter_map(|gen| {
if gen.def.is_some() {
Some(serde_json::to_value(gen.to_owned()).unwrap())
} else {
None
}
})
.collect::<Vec<_>>();
context.insert("types", &types);
tera.render("types_template", &context)
Expand Down
4 changes: 2 additions & 2 deletions libs/metagen/src/mdk_python/static/main.py.jinja
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{% if t_input != t_output %}
from {{ type_mod_name }}_types import Struct, {{ t_input }}, {{ t_output }}
from .{{ type_mod_name }}_types import Struct, {{ t_input }}, {{ t_output }}
{% else %}
from {{ type_mod_name }}_types import Struct, {{ t_input }}
from .{{ type_mod_name }}_types import Struct, {{ t_input }}
{% endif %}

def handle(inp: {{ t_input }}) -> {{ t_output }}:
Expand Down
55 changes: 40 additions & 15 deletions libs/metagen/src/mdk_python/static/types.py.jinja
Original file line number Diff line number Diff line change
@@ -1,25 +1,50 @@
import json
from typing import List, Dict, Optional, Union
from typing import List, Union, get_origin, ForwardRef
from dataclasses import dataclass, asdict, fields

FORWARD_REFS = {}

class Struct:
def new(dt_class, val: any):
try:
ftypes = {f.name: f.type for f in fields(dt_class)}
attrs = {}
for f in val:
fval = val[f]
if type(fval) is list:
print(f"hint {ftypes[f].__args__[0]}")
attrs[f] = [Struct.new(ftypes[f].__args__[0], v) for v in fval]
def try_new(dt_class, val: any):
ftypes = {f.name: f.type for f in fields(dt_class)}
attrs = {}
for f in val:
serialized = False
fval = val[f]
ftype = ftypes[f]
if get_origin(ftype) == list:
hint = ftype.__args__[0]
klass = FORWARD_REFS[hint.__forward_arg__] if type(hint) is ForwardRef else hint
attrs[f] = [Struct.new(klass, v) for v in fval]
serialized = True
elif get_origin(ftype) is Union:
for variant in ftype.__args__:
if not serialized:
try:
klass = FORWARD_REFS[variant.__forward_arg__]
attrs[f] = Struct.try_new(klass, fval)
serialized = True
except:
pass

if not serialized:
if type(ftype) is str and ftype in FORWARD_REFS:
klass = FORWARD_REFS[ftype]
attrs[f] = Struct.new(klass, fval)
else:
attrs[f] = Struct.new(ftypes[f], val[f])
return dt_class(**attrs)
attrs[f] = Struct.new(ftype, fval)
return dt_class(**attrs)
def new(dt_class: any, val: any):
try:
return Struct.try_new(dt_class, val)
except:
return val
def repr(self):
return asdict(self)


{% for type in types -%}
{{ type }}
{%- endfor -%}

{{ type.def }}
FORWARD_REFS['{{ type.hint }}'] = {{ type.hint }}

{% endfor -%}
2 changes: 1 addition & 1 deletion libs/metagen/src/mdk_python/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ pub fn visit_type(
TypeNode::Optional { data, .. } => {
let item = &tg.types[data.item as usize];
let item_hint = visit_type(tera, memo, item, tg)?.hint;
format!("Optional[{item_hint}]")
format!("Union[{item_hint}, None]")
}
TypeNode::List { data, .. } => {
let item = &tg.types[data.items as usize];
Expand Down
3 changes: 2 additions & 1 deletion libs/metagen/src/mdk_python/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@
// SPDX-License-Identifier: MPL-2.0

use indexmap::IndexMap;
use serde::Serialize;

#[derive(Debug, Clone)]
#[derive(Debug, Clone, Serialize)]
pub struct TypeGenerated {
/// Type representation: int, str, class name, ..
pub hint: String,
Expand Down

0 comments on commit 06d2cd1

Please sign in to comment.