google / google/ml_collections

Feature request: Expose `_apply_op` as a public method

Open
#5 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
Python
Stars
1k
Forks
49
PR merge metrics
No merged PRs in 30d

Description

Hi,

I have found the private function `_apply_op` to be quite useful for custom lazy computation. For example:

```python
import ml_collections

structures = ml_collections.FieldReference(
[
"parotid_right",
"parotid_left",
"brainstem",
"spinal_cord",
],
field_type=list,
)

################################################
number_of_structures = structures._apply_op(len)
number_of_structures._field_type = int
################################################

edge_length = ml_collections.FieldReference(512, field_type=int)

cfg = ml_collections.ConfigDict(
{
"structures": structures,
"edge_length": edge_length,
"mask_shape": (edge_length, edge_length, number_of_structures),
}
)

assert cfg.mask_shape == (512, 512, 4) # Passes

cfg.structures = ["brainstem", "spinal_cord"]
cfg.edge_length = 64
assert cfg.mask_shape == (64, 64, 2) # Passes
```

Might it be possible that this method be exposed as a first class method named `apply_op` (or more simply `apply`)? I'd be happy to make a PR including the above as a test if there is interest in making this design adjustment.

Here is an example implementation:

```python
def apply(parent: ml_collections.FieldReference, fn, field_type=None):
child = parent._apply_op(fn) # pylint: disable = protected-access

if field_type is not None:
child._field_type = field_type # pylint: disable = protected-access

a_child_value = child.get()
if not isinstance(
a_child_value, child._field_type # pylint: disable = protected-access
):
raise TypeError(
f"Expected operation result to be of type {field_type}. "
f"Instead however it was {type(a_child_value)}. "
"Adjust the `field_type` parameter accordingly."
)

return child
```

and a corresponding test:

```python
def test_config_apply():
fr = ml_collections.FieldReference("a,b,c", field_type=str)

def fn(string):
return string.split(",")

with pytest.raises(TypeError):
apply(fr, fn)

new_fr = apply(fr, fn, field_type=list)
assert new_fr.get() == ["a", "b", "c"]
```

Cheers,
Simon

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.