Skip to content

Commit

Permalink
IR progress
Browse files Browse the repository at this point in the history
  • Loading branch information
nx10 committed Sep 6, 2024
1 parent 0318a6f commit 6839478
Show file tree
Hide file tree
Showing 6 changed files with 38 additions and 25 deletions.
4 changes: 2 additions & 2 deletions src/styx/backend/python/documentation.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,15 +38,15 @@ def docs_to_docstring(docs: Documentation) -> str | None:
if len(docs.literature) == 1:
re += f"Literature: {docs.literature[0]}"

Check warning on line 39 in src/styx/backend/python/documentation.py

View check run for this annotation

Codecov / codecov/patch

src/styx/backend/python/documentation.py#L37-L39

Added lines #L37 - L39 were not covered by tests
else:
entries = '\n'.join(docs.literature)
entries = "\n".join(docs.literature)
re += f"Literature:\n{entries}"

Check warning on line 42 in src/styx/backend/python/documentation.py

View check run for this annotation

Codecov / codecov/patch

src/styx/backend/python/documentation.py#L41-L42

Added lines #L41 - L42 were not covered by tests

if docs.urls:
re = _ensure_double_linebreak_if_not_empty(re)
if len(docs.urls) == 1:
re += f"URL: {docs.urls[0]}"

Check warning on line 47 in src/styx/backend/python/documentation.py

View check run for this annotation

Codecov / codecov/patch

src/styx/backend/python/documentation.py#L45-L47

Added lines #L45 - L47 were not covered by tests
else:
entries = '\n'.join(docs.urls)
entries = "\n".join(docs.urls)
re += f"URLs:\n{entries}"

Check warning on line 50 in src/styx/backend/python/documentation.py

View check run for this annotation

Codecov / codecov/patch

src/styx/backend/python/documentation.py#L49-L50

Added lines #L49 - L50 were not covered by tests

if re:
Expand Down
34 changes: 19 additions & 15 deletions src/styx/backend/python/interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,7 @@ def _compile_struct(
metadata_symbol: str,
root_function: bool,
) -> None:
has_outputs = struct_has_outputs(param)
if has_outputs:
_compile_outputs_class(
param=param,
interface_module=interface_module,
lookup=lookup,
)
has_outputs = root_function or struct_has_outputs(param)

outputs_type = lookup.py_output_type[param.param.id_]

Expand All @@ -53,14 +47,14 @@ def _compile_struct(
name="run",
docstring_body="Build command line arguments. This method is called by the main command.",
return_type="list[str]",
return_descr=None,
return_descr="Command line arguments",
args=[
PyArg(name="self", type=None, default=None, docstring="The sub-command object."),
PyArg(name="execution", type="Execution", default=None, docstring="The execution object."),
],
)
struct_class = PyDataClass(

Check warning on line 56 in src/styx/backend/python/interface.py

View check run for this annotation

Codecov / codecov/patch

src/styx/backend/python/interface.py#L56

Added line #L56 was not covered by tests
name=lookup.py_type[param.param.id_],
name=lookup.py_struct_type[param.param.id_],
docstring=docs_to_docstring(param.param.docs),
methods=[func_cargs_building],
)
Expand All @@ -75,7 +69,6 @@ def _compile_struct(
PyArg(name="execution", type="Execution", default=None, docstring="The execution object."),
],
)
struct_class.methods.append(func_outputs)
pyargs = struct_class.fields

Check warning on line 72 in src/styx/backend/python/interface.py

View check run for this annotation

Codecov / codecov/patch

src/styx/backend/python/interface.py#L72

Added line #L72 was not covered by tests

# Collect param python symbols
Expand Down Expand Up @@ -110,10 +103,18 @@ def _compile_struct(

struct_compile_constraint_checks(func=func_cargs_building, struct=param, lookup=lookup)

func_cargs_building.body.extend([
"runner = runner or get_global_runner()",
f"execution = runner.start_execution({metadata_symbol})",
])
if has_outputs:
_compile_outputs_class(
param=param,
interface_module=interface_module,
lookup=lookup,
)

if root_function:
func_cargs_building.body.extend([
"runner = runner or get_global_runner()",
f"execution = runner.start_execution({metadata_symbol})",
])

_compile_cargs_building(param, lookup, func_cargs_building, access_via_self=not root_function)

Expand Down Expand Up @@ -141,10 +142,12 @@ def _compile_struct(
func_outputs.body.extend([

Check warning on line 142 in src/styx/backend/python/interface.py

View check run for this annotation

Codecov / codecov/patch

src/styx/backend/python/interface.py#L142

Added line #L142 was not covered by tests
"return ret",
])
struct_class.methods.append(func_outputs)
func_cargs_building.body.extend([

Check warning on line 146 in src/styx/backend/python/interface.py

View check run for this annotation

Codecov / codecov/patch

src/styx/backend/python/interface.py#L145-L146

Added lines #L145 - L146 were not covered by tests
"return cargs",
])
interface_module.funcs_and_classes.append(struct_class)
interface_module.exports.append(struct_class.name)

Check warning on line 150 in src/styx/backend/python/interface.py

View check run for this annotation

Codecov / codecov/patch

src/styx/backend/python/interface.py#L149-L150

Added lines #L149 - L150 were not covered by tests


def _compile_cargs_building(
Expand Down Expand Up @@ -209,6 +212,7 @@ def _compile_outputs_class(
outputs_class = PyDataClass(
name=lookup.py_output_type[param.param.id_],
docstring=f"Output object returned when calling `{lookup.py_type[param.param.id_]}(...)`.",
is_named_tuple=True,
)
outputs_class.fields.append(
PyArg(
Expand Down Expand Up @@ -243,7 +247,7 @@ def _compile_outputs_class(
)
)

interface_module.header.extend(blank_before(outputs_class.generate(True), 2))
interface_module.funcs_and_classes.append(outputs_class)
interface_module.exports.append(outputs_class.name)


Expand Down
15 changes: 10 additions & 5 deletions src/styx/backend/python/lookup.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ def _collect_py_symbol(param: ir.IStruct | ir.IParam, lookup_py_symbol: dict[ir.

self.param: dict[ir.IdType, ir.IParam] = {interface.command.param.id_: interface.command}
"""Find param object by its ID. IParam.id_ -> IParam"""
self.py_struct_type: dict[ir.IdType, str] = {interface.command.param.id_: function_symbol}
"""Find Python struct type by param id. IParam.id_ -> Python type
(this is different from py_type because of optionals and lists)"""
self.py_type: dict[ir.IdType, str] = {interface.command.param.id_: function_symbol}
"""Find Python type by param id. IParam.id_ -> Python type"""
self.py_symbol: dict[ir.IdType, str] = {}
Expand All @@ -58,10 +61,11 @@ def _collect_py_symbol(param: ir.IStruct | ir.IParam, lookup_py_symbol: dict[ir.
self.param[elem.param.id_] = elem

if isinstance(elem, ir.IStruct):
if elem.param.id_ not in self.py_type: # Struct unions may resolve these first
self.py_type[elem.param.id_] = package_scope.add_or_dodge(
if elem.param.id_ not in self.py_struct_type: # Struct unions may resolve these first
self.py_struct_type[elem.param.id_] = package_scope.add_or_dodge(

Check warning on line 65 in src/styx/backend/python/lookup.py

View check run for this annotation

Codecov / codecov/patch

src/styx/backend/python/lookup.py#L64-L65

Added lines #L64 - L65 were not covered by tests
python_pascalize(f"{interface.command.struct.name}_{elem.struct.name}")
)
self.py_type[elem.param.id_] = param_py_type(elem, self.py_struct_type)
self.py_output_type[elem.param.id_] = package_scope.add_or_dodge(

Check warning on line 69 in src/styx/backend/python/lookup.py

View check run for this annotation

Codecov / codecov/patch

src/styx/backend/python/lookup.py#L68-L69

Added lines #L68 - L69 were not covered by tests
python_pascalize(f"{interface.command.struct.name}_{elem.struct.name}_Outputs")
)
Expand All @@ -75,9 +79,10 @@ def _collect_py_symbol(param: ir.IStruct | ir.IParam, lookup_py_symbol: dict[ir.
)
elif isinstance(elem, ir.IStructUnion):
for alternative in elem.alts:
self.py_type[alternative.param.id_] = package_scope.add_or_dodge(
self.py_struct_type[alternative.param.id_] = package_scope.add_or_dodge(

Check warning on line 82 in src/styx/backend/python/lookup.py

View check run for this annotation

Codecov / codecov/patch

src/styx/backend/python/lookup.py#L81-L82

Added lines #L81 - L82 were not covered by tests
python_pascalize(f"{interface.command.struct.name}_{alternative.struct.name}")
)
self.py_type[elem.param.id_] = param_py_type(elem, self.py_type)
self.py_type[alternative.param.id_] = param_py_type(alternative, self.py_struct_type)
self.py_type[elem.param.id_] = param_py_type(elem, self.py_struct_type)

Check warning on line 86 in src/styx/backend/python/lookup.py

View check run for this annotation

Codecov / codecov/patch

src/styx/backend/python/lookup.py#L85-L86

Added lines #L85 - L86 were not covered by tests
else:
self.py_type[elem.param.id_] = param_py_type(elem, self.py_type)
self.py_type[elem.param.id_] = param_py_type(elem, self.py_struct_type)
5 changes: 3 additions & 2 deletions src/styx/backend/python/pycodegen/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -153,8 +153,9 @@ class PyDataClass(PyGen):
docstring: str
fields: list[PyArg] = field(default_factory=list)
methods: list[PyFunc] = field(default_factory=list)
is_named_tuple: bool = False

def generate(self, named_tuple: bool = False) -> LineBuffer:
def generate(self) -> LineBuffer:
# Sort fields so default arguments come last
self.fields.sort(key=lambda a: a.default is not None)

Expand All @@ -166,7 +167,7 @@ def _arg_docstring(arg: PyArg) -> LineBuffer:
args = concat([[f.declaration(), *_arg_docstring(f)] for f in self.fields])
methods = concat([method.generate() for method in self.methods], [""])

if not named_tuple:
if not self.is_named_tuple:
buf = [

Check warning on line 171 in src/styx/backend/python/pycodegen/core.py

View check run for this annotation

Codecov / codecov/patch

src/styx/backend/python/pycodegen/core.py#L171

Added line #L171 was not covered by tests
"@dataclasses.dataclass",
f"class {self.name}:",
Expand Down
3 changes: 2 additions & 1 deletion src/styx/backend/python/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ def _base() -> str:
if isinstance(param, ir.IInt):
if param.choices:
return f"typing.Literal[{', '.join(map(as_py_literal, param.choices))}]"

Check warning on line 39 in src/styx/backend/python/utils.py

View check run for this annotation

Codecov / codecov/patch

src/styx/backend/python/utils.py#L39

Added line #L39 was not covered by tests
return "str"
return "int"
if isinstance(param, ir.IFloat):
return "float"
if isinstance(param, ir.IFile):
Expand All @@ -55,6 +55,7 @@ def _base() -> str:
type_ = f"list[{type_}]"
if isinstance(param, ir.IOptional):
type_ = f"{type_} | None"

Check warning on line 57 in src/styx/backend/python/utils.py

View check run for this annotation

Codecov / codecov/patch

src/styx/backend/python/utils.py#L57

Added line #L57 was not covered by tests

return type_


Expand Down
2 changes: 2 additions & 0 deletions src/styx/frontend/boutiques/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,7 @@ def _arg_elem_from_bt_elem(
default_value=d.get("default-value", ir.IOptional.SetToNone)
if input_type.is_optional
else d.get("default-value"),
choices=choices,
)

case InputTypePrimitive.Integer:
Expand All @@ -209,6 +210,7 @@ def _arg_elem_from_bt_elem(
else d.get("default-value"),
min_value=constraints.value_min,
max_value=constraints.value_max,
choices=choices,
)

case InputTypePrimitive.Float:
Expand Down

0 comments on commit 6839478

Please sign in to comment.