fix: preserve Wei and Gwei types in arithmetic#3849
Conversation
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 6055bad9c2
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| Gwei = NewType("Gwei", int) | ||
| class _IntegerType(int): | ||
| def __add__(self, other: int) -> Self: | ||
| return self.__class__(int(self) + other) |
There was a problem hiding this comment.
Preserve non-integer arithmetic results or raise TypeError
The overridden arithmetic methods coerce every result back through self.__class__(...), which silently truncates non-integer numeric results instead of preserving Python’s normal semantics. For example, Wei(1) + 0.9 now becomes Wei(1) (via int(1.9)), and Wei(1) + Decimal('1.9') similarly drops the fractional part. This is a runtime correctness regression introduced by the new _IntegerType implementation and can corrupt values whenever callers mix Wei/Gwei with non-int numeric types.
Useful? React with 👍 / 👎.
What was wrong?
WeiandGweiwereNewTypealiases overint. Static type checkers treat arithmetic on aNewTypeas returning the baseint, so common accumulation patterns lose their unit type and augmented assignment is rejected.For example:
How was it fixed?
This changes
WeiandGweito lightweightintsubclasses backed by a shared internal_IntegerTypehelper. The helper preserves the concrete subclass for common integer arithmetic operations such as addition, subtraction, multiplication, floor division, modulo, divmod, and unary operations.Because the classes still subclass
int, existing runtime behavior remains compatible with code that expects integers.Verification
python3 -m py_compile web3/types.py tests/core/types/test_currency_types.pymypy web3/types.py tests/core/types/test_currency_types.pypytest tests/core/types/test_currency_types.py -qCloses #3833