diff --git a/CHANGELOG.md b/CHANGELOG.md index acb14d596..75c4e9871 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ This changelog is based on [Keep a Changelog](https://keepachangelog.com/en/1.1. - Added TokenUnpauseTransaction class - Added expiration_time, auto_renew_period, auto_renew_account, fee_schedule_key, kyc_key in `TokenCreateTransaction`, `TokenUpdateTransaction` classes - Added comprehensive Google-style docstrings to the `CustomFee` class and its methods in `custom_fee.py`. +- Added repr method to `src/hiero_sdk_python/tokens/custom_fixed_fee.py`, made `examples/custom_fee_fixed.` modular, and updated `tests/unit/test_custom_fee.py` correspondingly. ### Changed - chore: validate that token airdrop transactions require an available token service on the channel (#632) diff --git a/examples/custom_fee_fixed.py b/examples/custom_fee_fixed.py index 7fd244b23..c914b3e95 100644 --- a/examples/custom_fee_fixed.py +++ b/examples/custom_fee_fixed.py @@ -1,5 +1,12 @@ """ -Run with: +Example for creating and displaying a CustomFixedFee object. + +This example demonstrates: +1. How to instantiate CustomFixedFee. +2. The output of the new __repr__ method for clear debugging. +3. How to convert the fee object to its protobuf representation. + +Run with: uv run examples/custom_fixed_fee.py python examples/custom_fixed_fee.py """ @@ -7,23 +14,28 @@ from hiero_sdk_python.account.account_id import AccountId from hiero_sdk_python.tokens.token_id import TokenId -def custom_fixed_fee(): +def demonstrate_custom_fixed_fee(): + """Creates and displays a CustomFixedFee.""" + + # 1. Create the CustomFixedFee object fixed_fee = CustomFixedFee( amount=100, denominating_token_id=TokenId(0, 0, 123), fee_collector_account_id=AccountId(0, 0, 456), all_collectors_are_exempt=False, ) - print("CustomFixedFee:") - print(f"Amount: {fixed_fee.amount}") - print(f"Denominating Token ID: {fixed_fee.denominating_token_id}") - print(f"Fee Collector Account ID: {fixed_fee.fee_collector_account_id}") - print(f"All Collectors Exempt: {fixed_fee.all_collectors_are_exempt}") - # Convert to protobuf + + # 2. Print the object directly to see the __repr__ output + print("--- CustomFixedFee (using __repr__) ---") + print(fixed_fee) + + # 3. Convert to protobuf fixed_fee_proto = fixed_fee._to_proto() - print("Fixed Fee Protobuf:", fixed_fee_proto) + print("\n--- Fixed Fee Protobuf ---") + print(fixed_fee_proto) if __name__ == "__main__": - custom_fixed_fee() \ No newline at end of file + # Call the main function when the script is executed + demonstrate_custom_fixed_fee() \ No newline at end of file diff --git a/src/hiero_sdk_python/tokens/custom_fixed_fee.py b/src/hiero_sdk_python/tokens/custom_fixed_fee.py index 100cc0bdd..48daf5a30 100644 --- a/src/hiero_sdk_python/tokens/custom_fixed_fee.py +++ b/src/hiero_sdk_python/tokens/custom_fixed_fee.py @@ -36,6 +36,8 @@ class CustomFixedFee(CustomFee): custom fee is attached to. """ + __slots__ = ("amount", "denominating_token_id") + def __init__( self, amount: int = 0, @@ -181,7 +183,7 @@ def _to_topic_fee_proto(self) -> "custom_fees_pb2.FixedCustomFee": Raises: ValueError: If the fee amount is negative or potentially if IDs are invalid. - (Note: Current implementation doesn't explicitly check amount >= 0). + (Note: Current implementation doesn't explicitly check amount >= 0). """ from hiero_sdk_python.hapi.services import custom_fees_pb2 @@ -261,4 +263,21 @@ def __eq__(self, other: "CustomFixedFee") -> bool: Returns: bool: True if the objects are considered equal, False otherwise. """ - return super().__eq__(other) and self.amount == other.amount and self.denominating_token_id == other.denominating_token_id \ No newline at end of file + if not isinstance(other, CustomFixedFee): + return False + + return ( + super().__eq__(other) and + self.amount == other.amount and + self.denominating_token_id == other.denominating_token_id + ) + + def __repr__(self) -> str: + """Generates a developer-friendly string representation of the object.""" + return ( + f"{self.__class__.__name__}(" + f"amount={self.amount}, " + f"denominating_token_id={self.denominating_token_id!r}, " + f"fee_collector_account_id={self.fee_collector_account_id!r}, " + f"all_collectors_are_exempt={self.all_collectors_are_exempt})" + ) \ No newline at end of file diff --git a/tests/unit/test_custom_fee.py b/tests/unit/test_custom_fee.py index 78fd1b263..7b20d2caf 100644 --- a/tests/unit/test_custom_fee.py +++ b/tests/unit/test_custom_fee.py @@ -17,14 +17,20 @@ def test_custom_fixed_fee(): all_collectors_are_exempt=True, ) - proto = fee._to_proto() # Changed from _to_protobuf - new_fee = CustomFixedFee._from_proto(proto) # Changed from CustomFee._from_protobuf - + proto = fee._to_proto() + new_fee = CustomFixedFee._from_proto(proto) assert isinstance(new_fee, CustomFixedFee) assert new_fee.amount == 100 assert new_fee.denominating_token_id == TokenId(0, 0, 123) assert new_fee.fee_collector_account_id == AccountId(0, 0, 456) assert new_fee.all_collectors_are_exempt is True + assert fee == new_fee + fee_repr = repr(fee) + assert "CustomFixedFee" in fee_repr + assert "amount=100" in fee_repr + assert "denominating_token_id=TokenId(shard_num=0, realm_num=0, num=123)" in fee_repr + assert "fee_collector_account_id=AccountId(shard_num=0, realm_num=0, num=456)" in fee_repr + assert "all_collectors_are_exempt=True" in fee_repr def test_custom_fractional_fee(): fee = CustomFractionalFee( @@ -37,8 +43,8 @@ def test_custom_fractional_fee(): all_collectors_are_exempt=False, ) - proto = fee._to_proto() # Changed from _to_protobuf - new_fee = CustomFractionalFee._from_proto(proto) # Changed from CustomFee._from_protobuf + proto = fee._to_proto() + new_fee = CustomFractionalFee._from_proto(proto) assert isinstance(new_fee, CustomFractionalFee) assert new_fee.numerator == 1 @@ -48,6 +54,7 @@ def test_custom_fractional_fee(): assert new_fee.assessment_method == FeeAssessmentMethod.EXCLUSIVE assert new_fee.fee_collector_account_id == AccountId(0, 0, 456) assert new_fee.all_collectors_are_exempt is False + assert fee == new_fee def test_custom_royalty_fee(): fallback_fee = CustomFixedFee( @@ -62,8 +69,8 @@ def test_custom_royalty_fee(): all_collectors_are_exempt=True, ) - proto = fee._to_proto() # Changed from _to_protobuf - new_fee = CustomRoyaltyFee._from_proto(proto) # Changed from CustomFee._from_protobuf + proto = fee._to_proto() + new_fee = CustomRoyaltyFee._from_proto(proto) assert isinstance(new_fee, CustomRoyaltyFee) assert new_fee.numerator == 5 @@ -72,4 +79,5 @@ def test_custom_royalty_fee(): assert new_fee.all_collectors_are_exempt is True assert isinstance(new_fee.fallback_fee, CustomFixedFee) assert new_fee.fallback_fee.amount == 50 - assert new_fee.fallback_fee.denominating_token_id == TokenId(0, 0, 789) \ No newline at end of file + assert new_fee.fallback_fee.denominating_token_id == TokenId(0, 0, 789) + assert fee == new_fee \ No newline at end of file