Skip to content

Commit

Permalink
feat: allow provider plugins to define NAME at class-level (#2428)
Browse files Browse the repository at this point in the history
  • Loading branch information
antazoey authored Dec 20, 2024
1 parent 2f9d83f commit cb43786
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 2 deletions.
1 change: 1 addition & 0 deletions src/ape/api/networks.py
Original file line number Diff line number Diff line change
Expand Up @@ -1154,6 +1154,7 @@ def providers(self): # -> dict[str, Partial[ProviderAPI]]
)
):
# NOTE: Lazily load provider config
provider_name = provider_class.NAME or provider_name
providers[provider_name] = partial(
provider_class,
name=provider_name,
Expand Down
8 changes: 6 additions & 2 deletions src/ape/api/providers.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
from pathlib import Path
from signal import SIGINT, SIGTERM, signal
from subprocess import DEVNULL, PIPE, Popen
from typing import TYPE_CHECKING, Any, Optional, Union, cast
from typing import TYPE_CHECKING, Any, ClassVar, Optional, Union, cast

from eth_utils import to_hex
from pydantic import Field, computed_field, field_serializer, model_validator
Expand Down Expand Up @@ -188,8 +188,12 @@ class ProviderAPI(BaseInterfaceModel):
plugin or the `ape-hardhat <https://github.com/ApeWorX/ape-hardhat>`__ plugin.
"""

# TODO: In 0.9, make not optional.
NAME: ClassVar[Optional[str]] = None

# TODO: Remove in 0.9 and have NAME be defined at the class-level (in plugins).
name: str
"""The name of the provider (should be the plugin name)."""
"""(deprecated: use NAME). The name of the provider (should be the plugin name)."""

network: NetworkAPI
"""A reference to the network this provider provides."""
Expand Down
1 change: 1 addition & 0 deletions src/ape_node/provider.py
Original file line number Diff line number Diff line change
Expand Up @@ -379,6 +379,7 @@ def __init__(self):


# NOTE: Using EthereumNodeProvider because of it's geth-derived default behavior.
# TODO: In 0.9, change NAME to be `gethdev`, so for local networks it is more obvious.
class GethDev(EthereumNodeProvider, TestProviderAPI, SubprocessProvider):
_process: Optional[GethDevProcess] = None
name: str = "node"
Expand Down
26 changes: 26 additions & 0 deletions tests/functional/test_network_api.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import copy
from pathlib import Path
from typing import ClassVar
from unittest import mock

import pytest
Expand Down Expand Up @@ -206,6 +207,31 @@ def test_providers(ethereum):
assert "node" in providers


def test_providers_NAME_defined(mocker):
"""
Show that when a provider plugin used the NAME ClassVar,
the provider's name is that instead of the plugin's name.
"""
ecosystem_name = "my-ecosystem"
network_name = "my-network"
provider_name = "my-provider"

class MyProvider(ProviderAPI):
NAME: ClassVar[str] = provider_name

class MyNetwork(NetworkAPI):
def _get_plugin_providers(self):
yield "my-provider-plugin", (ecosystem_name, network_name, MyProvider)

class MyEcosystem(Ethereum):
pass

ecosystem = MyEcosystem(name=ecosystem_name)
network = MyNetwork(name=network_name, ecosystem=ecosystem)
actual = list(network.providers)
assert actual == [provider_name] # And not "my-provider-plugin"


def test_providers_custom_network(project, custom_networks_config_dict, ethereum):
with project.temp_config(**custom_networks_config_dict):
network = ethereum.apenet
Expand Down

0 comments on commit cb43786

Please sign in to comment.