Skip to content
Draft
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
71 changes: 46 additions & 25 deletions eth_abi/grammar.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import functools
import re
from typing import Optional

import parsimonious
from parsimonious import (
Expand Down Expand Up @@ -224,7 +225,7 @@ class TupleType(ABIType):
Represents the result of parsing a tuple type string e.g. "(int,bool)".
"""

__slots__ = ("components",)
__slots__ = ("components", "_type_str")

def __init__(self, components, arrlist=None, *, node=None):
super().__init__(arrlist, node)
Expand All @@ -235,15 +236,26 @@ def __init__(self, components, arrlist=None, *, node=None):
tuple type's components.
"""

def to_type_str(self):
arrlist = self.arrlist

if isinstance(arrlist, tuple):
arrlist = "".join(repr(list(a)) for a in arrlist)
else:
arrlist = ""
self._type_str: Optional[str] = None
"""
The string representation of an ABI type. Once populated,
this will be equal to the type string from which it was created.
"""

return f"({','.join(c.to_type_str() for c in self.components)}){arrlist}"
def to_type_str(self) -> str:
type_str = self._type_str
if type_str is None:
arrlist = self.arrlist

if isinstance(arrlist, tuple):
arrlist = "".join(repr(list(a)) for a in arrlist)
else:
arrlist = ""

type_str = self._type_str = (
f"({','.join(c.to_type_str() for c in self.components)}){arrlist}"
)
return type_str

@property
def item_type(self):
Expand Down Expand Up @@ -276,7 +288,7 @@ class BasicType(ABIType):
"ufixed128x19[][2]".
"""

__slots__ = ("base", "sub")
__slots__ = ("base", "sub", "_type_str")

def __init__(self, base, sub=None, arrlist=None, *, node=None):
super().__init__(arrlist, node)
Expand All @@ -291,22 +303,31 @@ def __init__(self, base, sub=None, arrlist=None, *, node=None):
type.
"""

def to_type_str(self):
sub, arrlist = self.sub, self.arrlist

if isinstance(sub, int):
sub = str(sub)
elif isinstance(sub, tuple):
sub = "x".join(str(s) for s in sub)
else:
sub = ""

if isinstance(arrlist, tuple):
arrlist = "".join(repr(list(a)) for a in arrlist)
else:
arrlist = ""
self._type_str: Optional[str] = None
"""
The string representation of an ABI type. Once populated,
this will be equal to the type string from which it was created.
"""

return self.base + sub + arrlist
def to_type_str(self):
type_str = self._type_str
if type_str is None:
sub, arrlist = self.sub, self.arrlist

if isinstance(sub, int):
sub = str(sub)
elif isinstance(sub, tuple):
sub = "x".join(str(s) for s in sub)
else:
sub = ""

if isinstance(arrlist, tuple):
arrlist = "".join(repr(list(a)) for a in arrlist)
else:
arrlist = ""

type_str = self._type_str = self.base + sub + arrlist
return type_str

@property
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is there a reason we don't use cached_property here?

Copy link
Author

@BobTheBuidler BobTheBuidler May 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It won't let me comment in the correct place, so I'll ask here.

secondly, is there a reason we don't use cached_property on is_dynamic (or set it during init)?

def item_type(self):
Expand Down