Skip to content

Commit

Permalink
Force the use of kw-args for all optional arguments in __init__ methods
Browse files Browse the repository at this point in the history
  • Loading branch information
emilk committed Sep 28, 2023
1 parent 6ac92c3 commit d49574b
Show file tree
Hide file tree
Showing 28 changed files with 69 additions and 38 deletions.
62 changes: 40 additions & 22 deletions crates/re_types_builder/src/codegen/python.rs
Original file line number Diff line number Diff line change
Expand Up @@ -409,8 +409,8 @@ impl PythonCodeGenerator {
}

// rerun/{datatypes|components|archetypes}/__init__.py
write_init(&kind_path, &mods, files_to_write);
write_init(&test_kind_path, &test_mods, files_to_write);
write_init_file(&kind_path, &mods, files_to_write);
write_init_file(&test_kind_path, &test_mods, files_to_write);
}

fn write_files(&self, files_to_write: &BTreeMap<Utf8PathBuf, String>) {
Expand Down Expand Up @@ -458,7 +458,7 @@ impl PythonCodeGenerator {
}
}

fn write_init(
fn write_init_file(
kind_path: &Utf8PathBuf,
mods: &HashMap<String, Vec<String>>,
files_to_write: &mut BTreeMap<Utf8PathBuf, String>,
Expand Down Expand Up @@ -603,11 +603,7 @@ fn code_for_struct(
2,
4,
);
} else if !obj.is_delegating_component() {
// In absence of a an extension class __init__ method, we don't *need* an __init__ method here.
// But if we don't generate one, LSP will show the class's doc string instead of parameter documentation.
code.push_text(quote_init_method(obj, ext_class, objects), 2, 4);
} else {
} else if obj.is_delegating_component() {
code.push_text(
format!(
"# You can define your own __init__ function as a member of {} in {}",
Expand All @@ -616,6 +612,10 @@ fn code_for_struct(
2,
4,
);
} else {
// In absence of a an extension class __init__ method, we don't *need* an __init__ method here.
// But if we don't generate one, LSP will show the class's doc string instead of parameter documentation.
code.push_text(quote_init_method(obj, ext_class, objects), 2, 4);
}

if obj.is_delegating_component() {
Expand Down Expand Up @@ -1510,7 +1510,7 @@ fn quote_arrow_support_from_obj(
}
}

fn quote_argument_type_alias(
fn quote_parameter_type_alias(
arg_type_fqname: &str,
class_fqname: &str,
objects: &Objects,
Expand All @@ -1535,13 +1535,13 @@ fn quote_argument_type_alias(
}
}

fn quote_init_argument_from_field(
fn quote_init_parameter_from_field(
field: &ObjectField,
objects: &Objects,
current_obj_fqname: &str,
) -> String {
let type_annotation = if let Some(fqname) = field.typ.fqname() {
quote_argument_type_alias(fqname, current_obj_fqname, objects, field.typ.is_plural())
quote_parameter_type_alias(fqname, current_obj_fqname, objects, field.typ.is_plural())
} else {
let type_annotation = quote_field_type_from_field(objects, field, false).0;
// Relax type annotation for numpy arrays.
Expand All @@ -1563,29 +1563,47 @@ fn quote_init_method(obj: &Object, ext_class: &ExtensionClass, objects: &Objects
// If the type is fully transparent (single non-nullable field and not an archetype),
// we have to use the "{obj.name}Like" type directly since the type of the field itself might be too narrow.
// -> Whatever type aliases there are for this type, we need to pick them up.
let arguments: Vec<_> =
let parameters: Vec<_> =
if obj.kind != ObjectKind::Archetype && obj.fields.len() == 1 && !obj.fields[0].is_nullable
{
vec![format!(
"{}: {}",
obj.fields[0].name,
quote_argument_type_alias(&obj.fqname, &obj.fqname, objects, false)
quote_parameter_type_alias(&obj.fqname, &obj.fqname, objects, false)
)]
} else if obj.is_union() {
vec![format!(
"inner: {} | None = None",
quote_argument_type_alias(&obj.fqname, &obj.fqname, objects, false)
quote_parameter_type_alias(&obj.fqname, &obj.fqname, objects, false)
)]
} else {
obj.fields
let required = obj
.fields
.iter()
.sorted_by_key(|field| field.is_nullable)
.map(|field| quote_init_argument_from_field(field, objects, &obj.fqname))
.collect()
.filter(|field| !field.is_nullable)
.map(|field| quote_init_parameter_from_field(field, objects, &obj.fqname))
.collect_vec();

let optional = obj
.fields
.iter()
.filter(|field| field.is_nullable)
.map(|field| quote_init_parameter_from_field(field, objects, &obj.fqname))
.collect_vec();

if optional.is_empty() {
required
} else {
required
.into_iter()
.chain(std::iter::once("*".to_owned())) // Force kw-args for all optional arguments
.chain(optional)
.collect()
}
};
let head = format!("def __init__(self: Any, {}):", arguments.join(", "));
let head = format!("def __init__(self: Any, {}):", parameters.join(", "));

let argument_docs = if obj.is_union() {
let parameter_docs = if obj.is_union() {
Vec::new()
} else {
obj.fields
Expand Down Expand Up @@ -1614,11 +1632,11 @@ fn quote_init_method(obj: &Object, ext_class: &ExtensionClass, objects: &Objects
r#"""""#.to_owned(),
format!("Create a new instance of the {} {doc_typedesc}.", obj.name),
];
if !argument_docs.is_empty() {
if !parameter_docs.is_empty() {
doc_string_lines.push("\n".to_owned());
doc_string_lines.push("Parameters".to_owned());
doc_string_lines.push("----------".to_owned());
for doc in argument_docs {
for doc in parameter_docs {
doc_string_lines.push(doc);
}
};
Expand Down
1 change: 1 addition & 0 deletions rerun_py/rerun_sdk/rerun/archetypes/asset3d.py

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions rerun_py/rerun_sdk/rerun/archetypes/depth_image.py

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion rerun_py/rerun_sdk/rerun/archetypes/image.py

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions rerun_py/rerun_sdk/rerun/archetypes/line_strips2d.py

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions rerun_py/rerun_sdk/rerun/archetypes/line_strips3d.py

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions rerun_py/rerun_sdk/rerun/archetypes/points2d.py

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions rerun_py/rerun_sdk/rerun/archetypes/points3d.py

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion rerun_py/rerun_sdk/rerun/archetypes/segmentation_image.py

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion rerun_py/rerun_sdk/rerun/archetypes/text_document.py

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions rerun_py/rerun_sdk/rerun/archetypes/text_log.py

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions rerun_py/rerun_sdk/rerun/archetypes/time_series_scalar.py

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion rerun_py/rerun_sdk/rerun/datatypes/annotation_info.py

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion rerun_py/rerun_sdk/rerun/datatypes/material.py

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion rerun_py/rerun_sdk/rerun/datatypes/mesh_properties.py

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion rerun_py/rerun_sdk/rerun/datatypes/tensor_dimension.py

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions rerun_py/tests/test_types/archetypes/affix_fuzzer3.py

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions rerun_py/tests/test_types/archetypes/affix_fuzzer4.py

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion rerun_py/tests/test_types/components/affix_fuzzer10.py

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion rerun_py/tests/test_types/components/affix_fuzzer11.py

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion rerun_py/tests/test_types/components/affix_fuzzer13.py

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion rerun_py/tests/test_types/components/affix_fuzzer17.py

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion rerun_py/tests/test_types/components/affix_fuzzer18.py

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion rerun_py/tests/test_types/components/affix_fuzzer7.py

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion rerun_py/tests/test_types/components/affix_fuzzer8.py

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions rerun_py/tests/test_types/datatypes/affix_fuzzer1.py

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion rerun_py/tests/test_types/datatypes/affix_fuzzer2.py

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion rerun_py/tests/test_types/datatypes/affix_fuzzer5.py

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit d49574b

Please sign in to comment.