hiero-ledger / hiero-ledger/hiero-sdk-python
feat: Add arithmetic operators to Hbar (+, -, abs)
- Dominant language
- Python
- Stars
- 63
- Forks
- 298
- Avg merge
- 3d 18h
- Merged PRs (30d)
- 38
Description
### π§βπ Beginner Issue
This issue adds arithmetic operators (`+`, `-`, `abs`) to the `Hbar` class, bringing it in line with Python conventions and making it easier to work with HBAR amounts in user code.
It involves editing one file (`hbar.py`), adding three short methods, and writing unit tests. No network calls, no protobuf, no breaking changes β a great first contribution to get familiar with the codebase.
### π Problem Description
The `Hbar` class in `src/hiero_sdk_python/hbar.py` supports comparison operators
(`<`, `>`, `<=`, `>=`, `==`) but has no arithmetic operators. This means developers
cannot add, subtract, or get the absolute value of two `Hbar` values using Python's
native syntax.
Current behaviour:
```python
a = Hbar(10)
b = Hbar(5)
a + b # TypeError: unsupported operand type(s) for +: 'Hbar' and 'Hbar'
a - b # TypeError
abs(a) # TypeError
### π‘ Expected Solution
****Proposed** Change**
Add the following dunder methods to hbar.py:
- __add__(self, other: Hbar) -> Hbar
- __sub__(self, other: Hbar) -> Hbar
- __abs__(self) -> Hbar
All three should operate on the internal _amount_in_tinybar value and return a new Hbar instance via Hbar.from_tinybars(...). Non-Hbar operands should return NotImplemented.
Unit tests should be added to hbar_test.py .
### π Research Pointers
- Main file to edit:
hbar.py
- Existing tests to understand the class:
hbar_test.py
- The class already has __lt__, __le__, __gt__, __ge__ β follow the same pattern for the new methods
- The existing negated() method and from_tinybars() classmethod show how to construct a new Hbar from a tinybar value β you'll use the same approach
- Python docs on arithmetic dunder methods: https://docs.python.org/3/reference/datamodel.html#emulating-numeric-types
- For reference, the Hiero JS SDK exposes .plus() and .minus() on its Hbar type
### π οΈ Implementation Notes
- All three methods should operate on the internal _amount_in_tinybar integer value
- Return a new Hbar instance using Hbar.from_tinybars(result)
- If the operand is not an Hbar instance, return NotImplemented (same pattern as the existing comparison operators)
- __abs__ takes no second argument β it just returns Hbar.from_tinybars(abs(self._amount_in_tinybar))
- The existing negated() method should remain unchanged for backwards compatibility
### π§ Beginner Contributors β Prerequisites & Expectations
- You should be comfortable reading and writing Python classes
- You should understand what dunder (magic) methods are in Python
- You should have the repo set up locally and be able to run the unit tests (uv run pytest tests/unit/hbar_test.py)
- Please comment "I'd like to work on this" before starting β one contributor will be assigned at a time
### π§ͺ Testing Requirements
Add tests to hbar_test.py covering:
- Hbar(10) + Hbar(5) equals Hbar(15)
- Hbar(10) - Hbar(5) equals Hbar(5)
- abs(Hbar(-3)) equals Hbar(3) and abs(Hbar(3)) equals Hbar(3)
- Adding a non-Hbar type raises TypeError (e.g. Hbar(1) + 5)
- Subtracting a non-Hbar type raises TypeError
- Edge cases: adding Hbar.ZERO, subtracting to get a negative result
Run tests with:
```python
uv run pytest tests/unit/hbar_test.py -v
```
### π‘οΈ Quality & Review Standards
- Follow the existing code style in hbar.py (type hints, docstrings, return types)
- No new dependencies
- No breaking changes to existing behaviour
- Ruff linting must pass: uv run ruff check src/hiero_sdk_python/hbar.py
### β PR Quality Checklist
- [ ] __add__, __sub__, and __abs__ are implemented in hbar.py
- [ ] All new methods have type hints and docstrings
- [ ] Unit tests added and passing
- [ ] uv run ruff check passes with no errors
- [ ] PR title follows conventional commits format: feat: add arithmetic operators to Hbar
- [ ] Commits are GPG and DCO signed
### π Workflow quick reference
You have done this before β here are the links if you need them:
| Step | Guide |
|------|-------|
| Claim this issue | Comment `/assign` below |
| Sync with main | [Rebasing guide](https://github.com/hiero-ledger/sdk-collaboration-hub/blob/main/guides/issue-progression/for-developers/rebasing.md) |
| Open a PR and link this issue | [PR guide](https://github.com/hiero-ledger/sdk-collaboration-hub/blob/main/guides/issue-progression/for-developers/contributor-workflow.md) |
| Resolve merge conflicts | [Merge conflicts guide](https://github.com/hiero-ledger/sdk-collaboration-hub/blob/main/guides/issue-progression/for-developers/merge_conflicts.md) |
### π Resources & Support
**π Stuck?**
> [!TIP]
> **Comment on this issue:** and describe what you have tried. A maintainer will respond.
**Python SDK References:**
- [Windows Setup Guide](https://github.com/hiero-ledger/hiero-sdk-python/blob/main/docs/sdk_developers/setup_windows.md) β platform-specific installation steps
- [Pylance guide](https://github.com/hiero-ledger/hiero-sdk-python/blob/main/docs/sdk_developers/pylance.md) β inline type checking during development
- [Running examples](https://github.com/hiero-ledger/hiero-sdk-python/blob/main/docs/sdk_developers/examples.md)
- [Browse closed beginner PRs](https://github.com/hiero-ledger/hiero-sdk-python/pulls?q=is%3Apr+is%3Amerged+label%3A%22skill%3A+beginner%22) β see how others did it
**References:**
- [Hedera Protobufs](https://github.com/hashgraph/hedera-protobufs)
- [Community Calls](https://zoom-lfx.platform.linuxfoundation.org/meetings/hiero?view=week)
- [Discord](https://github.com/hiero-ledger/sdk-collaboration-hub/blob/main/guides/issue-progression/for-developers/discord.md)
Contributor guide
Assessment
This issue has not been assessed yet.