Skip to content

Value objects use dataclasses#225

Merged
seddonym merged 5 commits intopython-grimp:masterfrom
Peter554:value-objectgs
Jun 19, 2025
Merged

Value objects use dataclasses#225
seddonym merged 5 commits intopython-grimp:masterfrom
Peter554:value-objectgs

Conversation

@Peter554
Copy link
Collaborator

@Peter554 Peter554 commented Jun 16, 2025

Some tidying to adapt valueobjects.py to use python @dataclasses. IMO this keeps the code a bit more uniform/standard - I don't think we really need a custom value object implementation.

Comment on lines 89 to 77
def __init__(self, *module_tails: str, independent: bool = True) -> None:
object.__setattr__(self, "module_tails", set(module_tails))
object.__setattr__(self, "independent", independent)
Copy link
Collaborator Author

@Peter554 Peter554 Jun 16, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧀 This custom __init__ needed since module_tails is a variadic argument.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧀 object.__setattr__ needed since the dataclass is frozen.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might be worth adding these pull request comments as code comments?

@codspeed-hq
Copy link

codspeed-hq bot commented Jun 16, 2025

CodSpeed Instrumentation Performance Report

Merging #225 will not alter performance

Comparing Peter554:value-objectgs (81dc0bf) with master (8a413e4)

Summary

✅ 22 untouched benchmarks

@Peter554 Peter554 force-pushed the value-objectgs branch 2 times, most recently from d610d7f to eee7761 Compare June 16, 2025 19:37
Copy link
Collaborator

@seddonym seddonym left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for looking at this - I agree it is better.

I feel if we're going to do it, we should completely remove ValueObject, what do you think?

Would you mind double checking Import Linter's tests pass on this version?

A Python module.
"""

__slots__ = ("name",)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should do slots=True on the dataclass decorator, right?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe slots was only added in 3.10 to the dataclass decorator, and we support 3.9.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh fair enough. Ok to leave this line in then, with a comment to switch once we drop 3.9? (I'm assuming it will work with dataclasses.)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm seeing this error when leaving the __slots__ = ("name",) line in

joblib.externals.loky.process_executor.BrokenProcessPool: A task has failed to un-serialize. Please ensure that the arguments of the function are all picklable.

So it seems like it doesn't work...

I suppose since the benchmarks are still passing then the performance change to use slots=True can't be so big.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's strange, oh well - soon joblib will be gone I hope.

I seem to remember slots making a noticeable difference to some early profiling I did, but as you say, this is what benchmarks are for! So let's drop it for now.

@Peter554
Copy link
Collaborator Author

@seddonym I've updated the PR now.

Would you mind double checking Import Linter's tests pass on this version?

I've run the import-linter tests locally (Python 3.12) and they are passing 🤞

@Peter554 Peter554 requested a review from seddonym June 18, 2025 17:30
@Peter554 Peter554 mentioned this pull request Jun 18, 2025
Copy link
Collaborator

@seddonym seddonym left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is nearly there. I would prefer not to drop the slots optimization though.

A Python module.
"""

__slots__ = ("name",)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh fair enough. Ok to leave this line in then, with a comment to switch once we drop 3.9? (I'm assuming it will work with dataclasses.)

name: The fully qualified name of a Python module, e.g. 'package.foo.bar'.
"""
self.name = name
"""The fully qualified name of a Python module, e.g. 'package.foo.bar'."""
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be a line comment i.e. # ....

Comment on lines 89 to 77
def __init__(self, *module_tails: str, independent: bool = True) -> None:
object.__setattr__(self, "module_tails", set(module_tails))
object.__setattr__(self, "independent", independent)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might be worth adding these pull request comments as code comments?



class TestDirectImport:
def test_repr(self):
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we've lost coverage for the str method, instead of removing this mind tweaking it so we test that instead?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

True - I've changed this to test the __str__ method now.

Peter554 added 4 commits June 19, 2025 12:10
This is a change of behaviour - see the removed test.

However it is consistent with how value objects work
in dataclasses / attrs
These tests feel a bit unneceessary now that we're
using the dataclasses implementation.
@Peter554 Peter554 requested a review from seddonym June 19, 2025 10:15
Copy link
Collaborator

@seddonym seddonym left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good stuff, thanks!

@seddonym seddonym merged commit 0941b8f into python-grimp:master Jun 19, 2025
18 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants