Skip to content

Commit

Permalink
Refactor json decorator (#1482)
Browse files Browse the repository at this point in the history
* refactor json decorator

* is

* is not

* lints

* hopefully fix recursion 🤞

* try again

* 😤

* disable stupid lint

* fix merge

* use thoralf's version
  • Loading branch information
DaughterOfMars authored Oct 25, 2023
1 parent f7252f6 commit ef0e0e6
Show file tree
Hide file tree
Showing 6 changed files with 66 additions and 74 deletions.
11 changes: 5 additions & 6 deletions bindings/python/iota_sdk/types/address.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,15 +74,14 @@ class ImplicitAccountCreationAddress:
type: int = field(default_factory=lambda: int(
AddressType.IMPLICIT_ACCOUNT_CREATION), init=False)

@staticmethod
def _to_dict_custom(addr_dict: dict) -> dict:
def to_dict(self) -> dict:
"""
Converts an implicit account creation address to the dictionary representation.
"""
if 'address' in addr_dict:
address = addr_dict.pop('address')
addr_dict['pubKeyHash'] = address.pop('pubKeyHash')
return addr_dict
return {
"type": self.type,
"pubKeyHash": self.address.pub_key_hash
}

@staticmethod
def from_dict(addr_dict: dict):
Expand Down
9 changes: 1 addition & 8 deletions bindings/python/iota_sdk/types/burn.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# SPDX-License-Identifier: Apache-2.0

from __future__ import annotations # Allow reference to Burn in Burn class
from typing import List, Optional, Dict, Any
from typing import List, Optional
from dataclasses import dataclass
from iota_sdk.types.native_token import NativeToken
from iota_sdk.types.common import HexStr, json
Expand Down Expand Up @@ -57,10 +57,3 @@ def add_native_token(self, native_token: NativeToken) -> Burn:
else:
self.native_tokens.append(native_token)
return self

@staticmethod
def _to_dict_custom(config) -> Dict[str, Any]:
if "nativeTokens" in config:
config["nativeTokens"] = {nativeToken.to_dict()["id"]: nativeToken.to_dict()[
"amount"] for nativeToken in config["nativeTokens"]}
return config
56 changes: 33 additions & 23 deletions bindings/python/iota_sdk/types/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,21 +12,26 @@


def json(cls):
"""Decorator to add custom to_dict and to_json methods to a dataclass."""
# Apply the dataclass_json decorator first to get the default behavior
"""Decorator to add to_dict and to_json methods to a dataclass."""

# Get potential override method
to_dict = getattr(cls, "to_dict", None)

# Apply the dataclass_json decorator to get the default behavior
cls = dataclass_json(
letter_case=LetterCase.CAMEL,
undefined=Undefined.RAISE)(cls)

# Store original methods
original_to_dict = cls.to_dict
# If no custom one is defined, set the default from dataclass_json
if to_dict is None:
to_dict = cls.to_dict

# Override methods
# Override to_dict to remove None values
def custom_to_dict(self, *args, **kwargs):
original_dict = original_to_dict(self, *args, **kwargs)
# pylint: disable=protected-access
original_dict = to_dict(self, *args, **kwargs)

result = {k: v for k, v in original_dict.items() if v is not None}
if hasattr(cls, "_to_dict_custom"):
result = getattr(cls, "_to_dict_custom")(result)
return result

def custom_to_json(self, *args, **kwargs):
Expand Down Expand Up @@ -74,21 +79,26 @@ class Node():
password: Optional[str] = None
disabled: Optional[bool] = None

@staticmethod
def _to_dict_custom(encoded):

if 'jwt' in encoded or 'username' in encoded or 'password' in encoded:
encoded['auth'] = {}
if 'jwt' in encoded:
encoded['auth']['jwt'] = encoded.pop('jwt')
if 'username' in encoded or 'password' in encoded:
basic_auth = encoded['auth']['basicAuthNamePwd'] = []
if 'username' in encoded:
basic_auth.append(encoded.pop('username'))
if 'password' in encoded:
basic_auth.append(encoded.pop('password'))

return encoded
def to_dict(self):
"""Custom dict conversion.
"""

res = {
'url': self.url,
'disabled': self.disabled
}
if self.jwt is not None or self.username is not None or self.password is not None:
auth = res['auth'] = {}
if self.jwt is not None:
auth['jwt'] = self.jwt
if self.username is not None or self.password is not None:
basic_auth = auth['basicAuthNamePwd'] = []
if self.username is not None:
basic_auth.append(self.username)
if self.password is not None:
basic_auth.append(self.password)

return res


def opt_int_encoder(value):
Expand Down
17 changes: 7 additions & 10 deletions bindings/python/iota_sdk/types/send_params.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

from __future__ import annotations
from dataclasses import dataclass, field
from typing import Optional, List, Dict
from typing import Optional, List
from dataclasses_json import config
from iota_sdk.types.common import HexStr, json
from iota_sdk.types.native_token import NativeToken
Expand Down Expand Up @@ -71,18 +71,15 @@ class CreateNativeTokenParams():
foundry_metadata: The foundry metadata of the native token.
account_id: The ID of the corresponding account.
"""
circulating_supply: int
maximum_supply: int
circulating_supply: int = field(metadata=config(
encoder=str
))
maximum_supply: int = field(metadata=config(
encoder=str
))
foundry_metadata: Optional[str] = None
account_id: Optional[str] = None

@staticmethod
def _to_dict_custom(cfg: Dict[str, any]) -> Dict[str, any]:
cfg['circulatingSupply'] = hex(cfg['circulatingSupply'])
cfg['maximumSupply'] = hex(cfg['maximumSupply'])

return cfg


@json
@dataclass
Expand Down
15 changes: 0 additions & 15 deletions bindings/python/iota_sdk/types/token_scheme.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,20 +22,5 @@ class SimpleTokenScheme:
maximum_supply: HexStr
type: int = field(default_factory=lambda: 0, init=False)

@staticmethod
def _to_dict_custom(config):
"""
The function converts integer values in the config to hexadecimal strings.
"""

if isinstance(config['mintedTokens'], int):
config['mintedTokens'] = str(hex(config['mintedTokens']))
if isinstance(config['meltedTokens'], int):
config['meltedTokens'] = str(hex(config['meltedTokens']))
if isinstance(config['maximumSupply'], int):
config['maximumSupply'] = str(hex(config['maximumSupply']))

return config


TokenScheme: TypeAlias = SimpleTokenScheme
32 changes: 20 additions & 12 deletions bindings/python/iota_sdk/types/transaction_options.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# SPDX-License-Identifier: Apache-2.0

from enum import Enum
from typing import Optional, List, Dict, Union
from typing import Optional, List, Union
from dataclasses import dataclass
from iota_sdk.types.burn import Burn
from iota_sdk.types.common import json
Expand All @@ -27,9 +27,19 @@ class RemainderValueStrategyCustomAddress:
internal: bool
used: bool

@staticmethod
def _to_dict_custom(config: Dict[str, any]) -> Dict[str, any]:
return dict({"strategy": "CustomAddress", "value": config})
def to_dict(self) -> dict:
"""Custom dict conversion.
"""

return {
'strategy': 'CustomAddress',
'value': {
'address': self.address,
'keyIndex': self.key_index,
'internal': self.internal,
'used': self.used
}
}


class RemainderValueStrategy(Enum):
Expand All @@ -42,16 +52,14 @@ class RemainderValueStrategy(Enum):
ChangeAddress = None
ReuseAddress = None

def _to_dict_custom(self):
def to_dict(self):
"""Custom dict conversion.
"""
The function `_to_dict_custom` returns a dictionary with the strategy name and its corresponding value.

Returns:
a dictionary with two key-value pairs. The "strategy" key is assigned the value of self.name,
and the "value" key is assigned the first element of self.value.
"""
return dict({"strategy": self.name, "value": self.value[0]})
return {
'strategy': self.name,
'value': self.value[0]
}


@json
Expand Down

0 comments on commit ef0e0e6

Please sign in to comment.