diff --git a/eth_utils/__init__.py b/eth_utils/__init__.py index f6ed0f37..8cde245d 100644 --- a/eth_utils/__init__.py +++ b/eth_utils/__init__.py @@ -1,139 +1,147 @@ +from importlib import ( + import_module, +) from importlib.metadata import ( version as __version, ) - -from .abi import ( - abi_to_signature, - collapse_if_tuple, - event_abi_to_log_topic, - event_signature_to_log_topic, - filter_abi_by_name, - filter_abi_by_type, - function_abi_to_4byte_selector, - function_signature_to_4byte_selector, - get_abi_input_names, - get_abi_input_types, - get_abi_output_names, - get_abi_output_types, - get_aligned_abi_inputs, - get_all_event_abis, - get_all_function_abis, - get_normalized_abi_inputs, -) -from .address import ( - is_address, - is_binary_address, - is_canonical_address, - is_checksum_address, - is_checksum_formatted_address, - is_hex_address, - is_normalized_address, - is_same_address, - to_canonical_address, - to_checksum_address, - to_normalized_address, -) -from .applicators import ( - apply_formatter_at_index, - apply_formatter_if, - apply_formatter_to_array, - apply_formatters_to_dict, - apply_formatters_to_sequence, - apply_key_map, - apply_one_of_formatters, - combine_argument_formatters, -) -from .conversions import ( - hexstr_if_str, - text_if_str, - to_bytes, - to_hex, - to_int, - to_text, -) -from .crypto import ( - keccak, -) -from .currency import ( - denoms, - from_wei, - to_wei, -) -from .decorators import ( - combomethod, - replace_exceptions, -) -from .encoding import ( - big_endian_to_int, - int_to_big_endian, -) -from .exceptions import ( - ValidationError, -) -from .functional import ( - apply_to_return_value, - flatten_return, - reversed_return, - sort_return, - to_dict, - to_list, - to_ordered_dict, - to_set, - to_tuple, -) -from .hexadecimal import ( - add_0x_prefix, - decode_hex, - encode_hex, - is_0x_prefixed, - is_hex, - is_hexstr, - remove_0x_prefix, -) -from .humanize import ( - humanize_bytes, - humanize_hash, - humanize_hexstr, - humanize_integer_sequence, - humanize_ipfs_uri, - humanize_seconds, - humanize_wei, -) -from .logging import ( - DEBUG2_LEVEL_NUM, - ExtendedDebugLogger, - HasExtendedDebugLogger, - HasExtendedDebugLoggerMeta, - HasLogger, - HasLoggerMeta, - get_extended_debug_logger, - get_logger, - setup_DEBUG2_logging, -) -from .module_loading import ( - import_string, -) -from .network import ( - Network, - name_from_chain_id, - network_from_chain_id, - short_name_from_chain_id, -) -from .numeric import ( - clamp, -) -from .types import ( - is_boolean, - is_bytes, - is_dict, - is_integer, - is_list, - is_list_like, - is_null, - is_number, - is_string, - is_text, - is_tuple, +from typing import ( + Any, + List, ) __version__ = __version("eth-utils") + +_lazy_imports = { + # abi + "abi_to_signature": "abi", + "collapse_if_tuple": "abi", + "event_abi_to_log_topic": "abi", + "event_signature_to_log_topic": "abi", + "filter_abi_by_name": "abi", + "filter_abi_by_type": "abi", + "function_abi_to_4byte_selector": "abi", + "function_signature_to_4byte_selector": "abi", + "get_abi_input_names": "abi", + "get_abi_input_types": "abi", + "get_abi_output_names": "abi", + "get_abi_output_types": "abi", + "get_aligned_abi_inputs": "abi", + "get_all_event_abis": "abi", + "get_all_function_abis": "abi", + "get_normalized_abi_inputs": "abi", + # address + "is_address": "address", + "is_binary_address": "address", + "is_canonical_address": "address", + "is_checksum_address": "address", + "is_checksum_formatted_address": "address", + "is_hex_address": "address", + "is_normalized_address": "address", + "is_same_address": "address", + "to_canonical_address": "address", + "to_checksum_address": "address", + "to_normalized_address": "address", + # applicators + "apply_formatter_at_index": "applicators", + "apply_formatter_if": "applicators", + "apply_formatter_to_array": "applicators", + "apply_formatters_to_dict": "applicators", + "apply_formatters_to_sequence": "applicators", + "apply_key_map": "applicators", + "apply_one_of_formatters": "applicators", + "combine_argument_formatters": "applicators", + # conversions + "hexstr_if_str": "conversions", + "text_if_str": "conversions", + "to_bytes": "conversions", + "to_hex": "conversions", + "to_int": "conversions", + "to_text": "conversions", + # crypto + "keccak": "crypto", + # currency + "denoms": "currency", + "from_wei": "currency", + "to_wei": "currency", + # decorators + "combomethod": "decorators", + "replace_exceptions": "decorators", + # encoding + "big_endian_to_int": "encoding", + "int_to_big_endian": "encoding", + # exceptions + "ValidationError": "exceptions", + # functional + "apply_to_return_value": "functional", + "flatten_return": "functional", + "reversed_return": "functional", + "sort_return": "functional", + "to_dict": "functional", + "to_list": "functional", + "to_ordered_dict": "functional", + "to_set": "functional", + "to_tuple": "functional", + # hexadecimal + "add_0x_prefix": "hexadecimal", + "decode_hex": "hexadecimal", + "encode_hex": "hexadecimal", + "is_0x_prefixed": "hexadecimal", + "is_hex": "hexadecimal", + "is_hexstr": "hexadecimal", + "remove_0x_prefix": "hexadecimal", + # humanize + "humanize_bytes": "humanize", + "humanize_hash": "humanize", + "humanize_hexstr": "humanize", + "humanize_integer_sequence": "humanize", + "humanize_ipfs_uri": "humanize", + "humanize_seconds": "humanize", + "humanize_wei": "humanize", + # logging + "DEBUG2_LEVEL_NUM": "logging", + "ExtendedDebugLogger": "logging", + "HasExtendedDebugLogger": "logging", + "HasExtendedDebugLoggerMeta": "logging", + "HasLogger": "logging", + "HasLoggerMeta": "logging", + "get_extended_debug_logger": "logging", + "get_logger": "logging", + "setup_DEBUG2_logging": "logging", + # module_loading + "import_string": "module_loading", + # network + "Network": "network", + "name_from_chain_id": "network", + "network_from_chain_id": "network", + "short_name_from_chain_id": "network", + # numeric + "clamp": "numeric", + # types + "is_boolean": "types", + "is_bytes": "types", + "is_dict": "types", + "is_integer": "types", + "is_list": "types", + "is_list_like": "types", + "is_null": "types", + "is_number": "types", + "is_string": "types", + "is_text": "types", + "is_tuple": "types", +} + + +def __getattr__(name: str) -> Any: + if name in _lazy_imports: + module_name = _lazy_imports[name] + module = import_module(f".{module_name}", package=__name__) + value = getattr(module, name) + globals()[name] = value # Cache the imported function in globals + return value + elif name in globals(): + return globals()[name] + raise AttributeError(f"module {__name__} has no attribute {name}") + + +def __dir__() -> List[str]: + return list(_lazy_imports.keys()) + list(globals().keys()) diff --git a/newsfragments/293.performance.rst b/newsfragments/293.performance.rst new file mode 100644 index 00000000..99200da8 --- /dev/null +++ b/newsfragments/293.performance.rst @@ -0,0 +1 @@ +Convert to lazy-loading modules to improve import times