Skip to content

Commit

Permalink
fix: dataclassy regression (#55)
Browse files Browse the repository at this point in the history
* chore: upgrade dataclassy to v0.10.1

* refactor: normalize abstract dataclass usage

* fix: forgot to implement abstractmethod (now visible with previous)

* fix: remove unused Web3 subclassing

NOTE: Fixes issue with MRO introduced in dataclassy v0.10.1

* fix: remove unnecessary abstractmethod (visible because of abc fix)

* fix: incorrect `__contains__` use for `AccountContainerAPI`

* feat: add `remove`/`__delitem__` to `AccountContainerAPI`
  • Loading branch information
fubuloubu authored May 27, 2021
1 parent 1131c11 commit 489babe
Show file tree
Hide file tree
Showing 10 changed files with 63 additions and 30 deletions.
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@
install_requires=[
"backports.cached_property ; python_version<'3.8'",
"click>=8.0.0",
"dataclassy==0.10.0", # see https://github.com/biqqles/dataclassy/issues/46
"dataclassy>=0.10.1,<1.0",
"eth-account>=0.5.2,<0.6.0",
"pluggy>=0.13.1,<1.0",
"PyGithub>=1.54,<2.0",
Expand Down
32 changes: 23 additions & 9 deletions src/ape/api/accounts.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
from abc import ABCMeta, abstractmethod
from pathlib import Path
from typing import TYPE_CHECKING, Iterator, Optional, Type

from dataclassy import dataclass
from eth_account.datastructures import SignedMessage # type: ignore
from eth_account.datastructures import SignedTransaction
from eth_account.messages import SignableMessage # type: ignore

from .base import abstractdataclass, abstractmethod

if TYPE_CHECKING:
from ape.managers.networks import NetworkManager


@dataclass
class AddressAPI(metaclass=ABCMeta):
@abstractdataclass
class AddressAPI:
network_manager: Optional["NetworkManager"] = None

@property
Expand Down Expand Up @@ -78,8 +78,8 @@ def sign_transaction(self, txn: dict) -> Optional[SignedTransaction]:
...


@dataclass
class AccountContainerAPI(metaclass=ABCMeta):
@abstractdataclass
class AccountContainerAPI:
data_folder: Path
account_type: Type[AccountAPI]

Expand Down Expand Up @@ -107,17 +107,31 @@ def append(self, account: AccountAPI):
if not isinstance(account, self.account_type):
raise # Not the right type for this container

if account in self:
if account.address in self:
raise # Account already in container

if account.alias and account.alias in self.aliases:
raise # Alias already in use

self.__setitem__(account.address, account)

@abstractmethod
def __setitem__(self, address: str, account: AccountAPI):
raise NotImplementedError("Must define this method to use `container.append(...)`")
raise NotImplementedError("Must define this method to use `container.append(acct)`")

def remove(self, account: AccountAPI):
if not isinstance(account, self.account_type):
raise # Not the right type for this container

if account.address not in self:
raise # Account not in container

if account.alias and account.alias in self.aliases:
raise # Alias already in use

self.__delitem__(account.address)

def __delitem__(self, address: str):
raise NotImplementedError("Must define this method to use `container.remove(acct)`")

def __contains__(self, address: str) -> bool:
try:
Expand Down
19 changes: 19 additions & 0 deletions src/ape/api/base.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
from abc import ABCMeta, abstractmethod
from functools import partial

from dataclassy import dataclass
from dataclassy.dataclass import DataClassMeta


class AbstractDataClassMeta(DataClassMeta, ABCMeta):
pass


abstractdataclass = partial(dataclass, meta=AbstractDataClassMeta)

__all__ = [
"abstractdataclass",
"abstractmethod",
"AbstractDataClassMeta",
"dataclass",
]
6 changes: 4 additions & 2 deletions src/ape/api/compiler.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
from abc import ABC, abstractmethod
from pathlib import Path
from typing import List, Set

from ape.types import ContractType

from .base import abstractdataclass, abstractmethod

class CompilerAPI(ABC):

@abstractdataclass
class CompilerAPI:
@property
@abstractmethod
def name(self) -> str:
Expand Down
2 changes: 1 addition & 1 deletion src/ape/api/config.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from enum import Enum
from typing import Dict, Union

from dataclassy import dataclass
from .base import dataclass


class ConfigEnum(str, Enum):
Expand Down
9 changes: 3 additions & 6 deletions src/ape/api/explorers.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
from abc import ABCMeta, abstractmethod

from dataclassy import dataclass

from . import networks
from .base import abstractdataclass, abstractmethod


@dataclass
class ExplorerAPI(metaclass=ABCMeta):
@abstractdataclass
class ExplorerAPI:
"""
An Explorer must work with a particular Network in a particular Ecosystem
"""
Expand Down
8 changes: 4 additions & 4 deletions src/ape/api/networks.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
from abc import ABCMeta, abstractmethod
from functools import partial
from pathlib import Path
from typing import TYPE_CHECKING, Dict, Iterator, List, Optional, Type

from dataclassy import dataclass
from pluggy import PluginManager # type: ignore

from ape.utils import cached_property

from .base import abstractdataclass, abstractmethod, dataclass

if TYPE_CHECKING:
from ape.managers.networks import NetworkManager

Expand Down Expand Up @@ -127,8 +127,8 @@ def __exit__(self, *args, **kwargs):
self.network_manager.active_provider = self._connected_providers[-1]


@dataclass
class NetworkAPI(metaclass=ABCMeta):
@abstractdataclass
class NetworkAPI:
"""
A Network is a wrapper around a Provider for a specific Ecosystem
"""
Expand Down
8 changes: 3 additions & 5 deletions src/ape/api/providers.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
from abc import ABCMeta, abstractmethod
from pathlib import Path

from dataclassy import dataclass

from . import networks
from .base import abstractdataclass, abstractmethod


@dataclass
class ProviderAPI(metaclass=ABCMeta):
@abstractdataclass
class ProviderAPI:
"""
A Provider must work with a particular Network in a particular Ecosystem
"""
Expand Down
2 changes: 1 addition & 1 deletion src/ape_infura/providers.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from ape.api import ProviderAPI


class Infura(Web3, ProviderAPI):
class Infura(ProviderAPI):
_web3: Web3 = None # type: ignore

def __post_init__(self):
Expand Down
5 changes: 4 additions & 1 deletion src/ape_test/providers.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from ape.api import ProviderAPI


class LocalNetwork(Web3, ProviderAPI):
class LocalNetwork(ProviderAPI):
_web3: Web3 = None # type: ignore

def connect(self):
Expand All @@ -12,6 +12,9 @@ def connect(self):
def disconnect(self):
pass

def update_settings(self, new_settings: dict):
pass

def __post_init__(self):
self._web3 = Web3(EthereumTesterProvider())

Expand Down

0 comments on commit 489babe

Please sign in to comment.