Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ This changelog is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.


### Added
- Added `__str__` and `__repr__` methods to `AccountInfo` class for improved logging and debugging experience (#1098)
- Added Good First Issue (GFI) management and frequency documentation to clarify maintainer expectations and SDK-level GFI governance.
- Added SDK-level Good First Issue (GFI) guidelines for maintainers to clarify what qualifies as a good first issue.
- Codecov workflow
Expand Down
12 changes: 3 additions & 9 deletions examples/account/account_info.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,19 +53,13 @@ def build_mock_account_info() -> AccountInfo:

def print_account_info(info: AccountInfo) -> None:
"""Pretty-print key AccountInfo fields."""
print("📜 AccountInfo Example (Mock Data)")
print(f"Account ID: {info.account_id}")
print(f"Key: {info.key}")
print(f"Balance: {info.balance}")
print(f"Expiration Time: {info.expiration_time}")
print(f"Auto Renew Period: {info.auto_renew_period}")
print(f"Token Relationships: {info.token_relationships}")
print(f"Memo: {info.account_memo}")
print("📜 AccountInfo String Representation:")
print(info)

def main():
"""Run the AccountInfo example."""
info = build_mock_account_info()
print_account_info(info)

if __name__ == "__main__":
main()
main()
53 changes: 53 additions & 0 deletions src/hiero_sdk_python/account/account_info.py
Original file line number Diff line number Diff line change
Expand Up @@ -153,3 +153,56 @@ def _to_proto(self) -> CryptoGetInfoResponse.AccountInfo:
decline_reward=self.decline_staking_reward
),
)

def __str__(self) -> str:
"""Returns a user-friendly string representation of the AccountInfo."""
# Define simple fields to print if they exist
# Format: (value_to_check, label)
simple_fields = [
(self.account_id, "Account ID"),
(self.contract_account_id, "Contract Account ID"),
(self.balance, "Balance"),
(self.key, "Key"),
(self.account_memo, "Memo"),
(self.owned_nfts, "Owned NFTs"),
(self.max_automatic_token_associations, "Max Automatic Token Associations"),
(self.staked_account_id, "Staked Account ID"),
(self.staked_node_id, "Staked Node ID"),
(self.proxy_received, "Proxy Received"),
(self.expiration_time, "Expiration Time"),
(self.auto_renew_period, "Auto Renew Period"),
]

# Use a list comprehension to process simple fields (reduces complexity score)
lines = [f"{label}: {val}" for val, label in simple_fields if val is not None]

# 2. Handle booleans and special cases explicitly
if self.is_deleted is not None:
lines.append(f"Deleted: {self.is_deleted}")

if self.receiver_signature_required is not None:
lines.append(f"Receiver Signature Required: {self.receiver_signature_required}")

if self.decline_staking_reward is not None:
lines.append(f"Decline Staking Reward: {self.decline_staking_reward}")

if self.token_relationships:
lines.append(f"Token Relationships: {len(self.token_relationships)}")

return "\n".join(lines)

def __repr__(self) -> str:
"""Returns a string representation of the AccountInfo object for debugging."""
return (
f"AccountInfo("
f"account_id={self.account_id!r}, "
f"contract_account_id={self.contract_account_id!r}, "
f"is_deleted={self.is_deleted!r}, "
f"balance={self.balance!r}, "
f"receiver_signature_required={self.receiver_signature_required!r}, "
f"owned_nfts={self.owned_nfts!r}, "
f"account_memo={self.account_memo!r}, "
f"staked_node_id={self.staked_node_id!r}, "
f"staked_account_id={self.staked_account_id!r}"
f")"
)
17 changes: 17 additions & 0 deletions tests/unit/account_info_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -169,3 +169,20 @@ def test_proto_conversion(account_info):
assert converted_account_info.token_relationships == account_info.token_relationships
assert converted_account_info.account_memo == account_info.account_memo
assert converted_account_info.owned_nfts == account_info.owned_nfts

def test_str_and_repr(account_info):
"""Test the __str__ and __repr__ methods"""
info_str = str(account_info)
info_repr = repr(account_info)

# __str__ checks (User-friendly output)
assert "Account ID: 0.0.100" in info_str
assert "Contract Account ID: 0.0.100" in info_str
assert "Balance: 0.05000000 ℏ" in info_str
assert "Memo: Test account memo" in info_str

# __repr__ checks (Debug output)
assert info_repr.startswith("AccountInfo(")
assert "account_id=AccountId(shard=0, realm=0, num=100" in info_repr
assert "contract_account_id='0.0.100'" in info_repr
assert "account_memo='Test account memo'" in info_repr