Skip to content

Commit

Permalink
refactor: use raw import statements over import_module for lazy imp…
Browse files Browse the repository at this point in the history
…orts (#2354)
  • Loading branch information
antazoey authored Oct 30, 2024
1 parent eda5355 commit 84928c5
Show file tree
Hide file tree
Showing 12 changed files with 65 additions and 60 deletions.
12 changes: 6 additions & 6 deletions src/ape/__init__.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
import signal
import threading
from typing import Any

if threading.current_thread() is threading.main_thread():
# If we are in the main thread, we can safely set the signal handler
signal.signal(signal.SIGINT, lambda s, f: _sys.exit(130))

import sys as _sys
from importlib import import_module

__all__ = [
"accounts",
Expand All @@ -23,16 +21,18 @@
]


def __getattr__(name: str) -> Any:
def __getattr__(name: str):
if name not in __all__:
raise AttributeError(name)

elif name == "reverts":
contextmanagers = import_module("ape.pytest.contextmanagers")
return contextmanagers.RevertsContextManager
from ape.pytest.contextmanagers import RevertsContextManager

return RevertsContextManager

else:
access = import_module("ape.managers.project").ManagerAccessMixin
from ape.utils.basemodel import ManagerAccessMixin as access

if name == "Contract":
return access.chain_manager.contracts.instance_at

Expand Down
6 changes: 2 additions & 4 deletions src/ape/_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
from collections.abc import Iterable
from functools import cached_property
from gettext import gettext
from importlib import import_module
from importlib.metadata import entry_points
from pathlib import Path
from typing import TYPE_CHECKING, Any, Optional
Expand Down Expand Up @@ -65,6 +64,7 @@ def parse_args(self, ctx: "Context", args: list[str]) -> list[str]:
return super().parse_args(ctx, args)

def format_commands(self, ctx, formatter) -> None:
from ape.plugins._utils import PluginMetadataList
from ape.utils.basemodel import ManagerAccessMixin as access

commands = []
Expand All @@ -86,10 +86,8 @@ def format_commands(self, ctx, formatter) -> None:
"Plugin": [],
"3rd-Party Plugin": [],
}
plugin_utils = import_module("ape.plugins._utils")
metadata_cls = plugin_utils.PluginMetadataList
plugin_manager = access.plugin_manager
pl_metadata = metadata_cls.load(plugin_manager, include_available=False)
pl_metadata = PluginMetadataList.load(plugin_manager, include_available=False)
for cli_name, cmd in commands:
help = cmd.get_short_help_str(limit)
plugin = pl_metadata.get_plugin(cli_name, check_available=False)
Expand Down
18 changes: 12 additions & 6 deletions src/ape/cli/choices.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,9 @@ def __init__(self, key: _ACCOUNT_TYPE_FILTER = None):

@cached_property
def choices(self) -> Sequence: # type: ignore[override]
module = import_module("ape.types.basic")
return module._LazySequence(self._choices_iterator)
from ape.types.basic import _LazySequence

return _LazySequence(self._choices_iterator)

@property
def _choices_iterator(self) -> Iterator[str]:
Expand Down Expand Up @@ -172,8 +173,9 @@ def select_account(
Returns:
:class:`~ape.api.accounts.AccountAPI`
"""
account_module = import_module("ape.api.accounts")
if key and isinstance(key, type) and not issubclass(key, account_module.AccountAPI):
from ape.api.accounts import AccountAPI

if key and isinstance(key, type) and not issubclass(key, AccountAPI):
raise AccountsError(f"Cannot return accounts with type '{key}'.")

prompt = AccountAliasPromptChoice(prompt_message=prompt_message, key=key)
Expand All @@ -196,8 +198,12 @@ def __init__(
self._key_filter = key
self._prompt_message = prompt_message or "Select an account"
self.name = name
module = import_module("ape.types.basic")
self.choices = module._LazySequence(self._choices_iterator)

@cached_property
def choices(self) -> Sequence[str]: # type: ignore[override]
from ape.types.basic import _LazySequence

return _LazySequence(self._choices_iterator)

def convert(
self, value: Any, param: Optional[Parameter], ctx: Optional[Context]
Expand Down
10 changes: 5 additions & 5 deletions src/ape/cli/commands.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import inspect
from importlib import import_module
from typing import TYPE_CHECKING, Any, Optional

import click
Expand All @@ -26,6 +25,7 @@ def get_param_from_ctx(ctx: "Context", param: str) -> Optional[Any]:


def parse_network(ctx: "Context") -> Optional["ProviderContextManager"]:
from ape.api.providers import ProviderAPI
from ape.utils.basemodel import ManagerAccessMixin as access

interactive = get_param_from_ctx(ctx, "interactive")
Expand All @@ -36,8 +36,7 @@ def parse_network(ctx: "Context") -> Optional["ProviderContextManager"]:
return provider.network.use_provider(provider, disconnect_on_exit=not interactive)

provider = get_param_from_ctx(ctx, "network")
provider_module = import_module("ape.api.providers")
if provider is not None and isinstance(provider, provider_module.ProviderAPI):
if provider is not None and isinstance(provider, ProviderAPI):
return provider.network.use_provider(provider, disconnect_on_exit=not interactive)

elif provider not in (None, _NONE_NETWORK) and isinstance(provider, str):
Expand Down Expand Up @@ -72,9 +71,10 @@ def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)

def parse_args(self, ctx: "Context", args: list[str]) -> list[str]:
from ape.api.providers import ProviderAPI

arguments = args # Renamed for better pdb support.
provider_module = import_module("ape.api.providers")
base_type = provider_module.ProviderAPI if self._use_cls_types else str
base_type = ProviderAPI if self._use_cls_types else str
if existing_option := next(
iter(
x
Expand Down
4 changes: 1 addition & 3 deletions src/ape/cli/options.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import inspect
from collections.abc import Callable
from functools import partial
from importlib import import_module
from pathlib import Path
from typing import TYPE_CHECKING, Any, NoReturn, Optional, Union

Expand Down Expand Up @@ -347,11 +346,10 @@ def _update_context_with_network(ctx, provider, requested_network_objects):


def _get_provider(value, default, keep_as_choice_str):
from ape.api.providers import ProviderAPI
from ape.utils.basemodel import ManagerAccessMixin

use_default = value is None and default == "auto"
provider_module = import_module("ape.api.providers")
ProviderAPI = provider_module.ProviderAPI

if not keep_as_choice_str and use_default:
default_ecosystem = ManagerAccessMixin.network_manager.default_ecosystem
Expand Down
4 changes: 2 additions & 2 deletions src/ape/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
import traceback
from collections.abc import Collection, Iterable
from functools import cached_property
from importlib import import_module
from inspect import getframeinfo, stack
from pathlib import Path
from types import CodeType, TracebackType
Expand Down Expand Up @@ -922,7 +921,8 @@ def _get_custom_python_traceback(
# https://github.com/pallets/jinja/blob/main/src/jinja2/debug.py#L142

if project is None:
access = import_module("ape.utils.basemodel").ManagerAccessMixin
from ape.utils.basemodel import ManagerAccessMixin as access

project = access.local_project

if not (base_path := getattr(project, "path", None)):
Expand Down
51 changes: 28 additions & 23 deletions src/ape/managers/__init__.py
Original file line number Diff line number Diff line change
@@ -1,43 +1,48 @@
from importlib import import_module
from typing import Any


def __getattr__(name: str) -> Any:
def __getattr__(name: str):
if name == "AccountManager":
module = import_module("ape.managers.accounts")
return module.AccountManager
from ape.managers.accounts import AccountManager

return AccountManager

elif name == "ChainManager":
module = import_module("ape.managers.chain")
return module.ChainManager
from ape.managers.chain import ChainManager

return ChainManager

elif name == "CompilerManager":
module = import_module("ape.managers.compilers")
return module.CompilerManager
from ape.managers.compilers import CompilerManager

return CompilerManager

elif name == "ConfigManager":
module = import_module("ape.managers.config")
return module.ConfigManager
from ape.managers.config import ConfigManager

return ConfigManager

elif name == "ConversionManager":
module = import_module("ape.managers.converters")
return module.ConversionManager
from ape.managers.converters import ConversionManager

return ConversionManager

elif name == "NetworkManager":
module = import_module("ape.managers.networks")
return module.NetworkManager
from ape.managers.networks import NetworkManager

return NetworkManager

elif name == "PluginManager":
module = import_module("ape.managers.plugins")
return module.PluginManager
from ape.managers.plugins import PluginManager

return PluginManager

elif name == "ProjectManager":
module = import_module("ape.managers.project")
return module.ProjectManager
from ape.managers.project import ProjectManager

return ProjectManager

elif name == "QueryManager":
module = import_module("ape.managers.query")
return module.QueryManager
from ape.managers.query import QueryManager

return QueryManager

else:
raise AttributeError(name)
3 changes: 1 addition & 2 deletions src/ape/types/basic.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
from collections.abc import Callable, Iterator, Sequence
from importlib import import_module
from typing import Annotated, TypeVar, Union, overload

from pydantic import BeforeValidator
Expand All @@ -11,7 +10,7 @@ def _hex_int_validator(value, info):
return value

# NOTE: Allows this module to load lazier.
access = import_module("ape.utils.basemodel").ManagerAccessMixin
from ape.utils.basemodel import ManagerAccessMixin as access

convert = access.conversion_manager.convert
return convert(value, int)
Expand Down
3 changes: 1 addition & 2 deletions src/ape_accounts/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
from importlib import import_module
from typing import Any

from ape.plugins import AccountPlugin, register

Expand All @@ -11,7 +10,7 @@ def account_types():
return AccountContainer, KeyfileAccount


def __getattr__(name: str) -> Any:
def __getattr__(name: str):
return getattr(import_module("ape_accounts.accounts"), name)


Expand Down
5 changes: 3 additions & 2 deletions src/ape_cache/_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,9 @@


def get_engine() -> "CacheQueryProvider":
basemodel = import_module("ape.utils.basemodel")
return basemodel.ManagerAccessMixin.query_manager.engines["cache"]
from ape.utils.basemodel import ManagerAccessMixin

return ManagerAccessMixin.query_manager.engines["cache"]


@click.group(short_help="Query from caching database")
Expand Down
3 changes: 1 addition & 2 deletions src/ape_networks/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
from importlib import import_module
from typing import Any

from ape.plugins import Config, register

Expand All @@ -11,7 +10,7 @@ def config_class():
return NetworksConfig


def __getattr__(name: str) -> Any:
def __getattr__(name: str):
if name in ("NetworksConfig", "CustomNetwork"):
return getattr(import_module("ape_networks.config"), name)

Expand Down
6 changes: 3 additions & 3 deletions src/ape_networks/_cli.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import json
from collections.abc import Callable, Sequence
from importlib import import_module
from typing import TYPE_CHECKING

import click
Expand Down Expand Up @@ -118,10 +117,11 @@ def run(cli_ctx, provider):
Start a subprocess node as if running independently
and stream stdout and stderr.
"""
from ape.api.providers import SubprocessProvider

# Ignore extra loggers, such as web3 loggers.
cli_ctx.logger._extra_loggers = {}
providers_module = import_module("ape.api.providers")
if not isinstance(provider, providers_module.SubprocessProvider):
if not isinstance(provider, SubprocessProvider):
cli_ctx.abort(
f"`ape networks run` requires a provider that manages a process, not '{provider.name}'."
)
Expand Down

0 comments on commit 84928c5

Please sign in to comment.