mirror of https://github.com/nucypher/nucypher.git
Additional annotations and comments.
parent
4169dbb004
commit
f1b130afa1
|
@ -1,7 +1,12 @@
|
||||||
import eth_utils
|
import eth_utils
|
||||||
import functools
|
import functools
|
||||||
import inspect
|
import inspect
|
||||||
from constant_sorrow.constants import (CONTRACT_ATTRIBUTE, CONTRACT_CALL, TRANSACTION, UNKNOWN_CONTRACT_INTERFACE)
|
from constant_sorrow.constants import (
|
||||||
|
CONTRACT_ATTRIBUTE,
|
||||||
|
CONTRACT_CALL,
|
||||||
|
TRANSACTION,
|
||||||
|
UNKNOWN_CONTRACT_INTERFACE
|
||||||
|
)
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from twisted.logger import Logger
|
from twisted.logger import Logger
|
||||||
from typing import Callable, Optional, Union
|
from typing import Callable, Optional, Union
|
||||||
|
@ -82,7 +87,7 @@ def validate_checksum_address(func: Callable) -> Callable:
|
||||||
return wrapped
|
return wrapped
|
||||||
|
|
||||||
|
|
||||||
def only_me(func: Callable):
|
def only_me(func: Callable) -> Callable:
|
||||||
"""Decorator to enforce invocation of permissioned actor methods"""
|
"""Decorator to enforce invocation of permissioned actor methods"""
|
||||||
@functools.wraps(func)
|
@functools.wraps(func)
|
||||||
def wrapped(actor=None, *args, **kwargs):
|
def wrapped(actor=None, *args, **kwargs):
|
||||||
|
@ -92,10 +97,10 @@ def only_me(func: Callable):
|
||||||
return wrapped
|
return wrapped
|
||||||
|
|
||||||
|
|
||||||
def save_receipt(actor_method):
|
def save_receipt(actor_method) -> Callable:
|
||||||
"""Decorator to save the receipts of transmitted transactions from actor methods"""
|
"""Decorator to save the receipts of transmitted transactions from actor methods"""
|
||||||
@functools.wraps(actor_method)
|
@functools.wraps(actor_method)
|
||||||
def wrapped(self, *args, **kwargs):
|
def wrapped(self, *args, **kwargs) -> dict:
|
||||||
receipt = actor_method(self, *args, **kwargs)
|
receipt = actor_method(self, *args, **kwargs)
|
||||||
self._saved_receipts.append((datetime.utcnow(), receipt))
|
self._saved_receipts.append((datetime.utcnow(), receipt))
|
||||||
return receipt
|
return receipt
|
||||||
|
@ -107,7 +112,7 @@ def save_receipt(actor_method):
|
||||||
#
|
#
|
||||||
|
|
||||||
|
|
||||||
# TODO: Disable collection in prod (detect test package?)
|
# TODO: Auto disable collection in prod (detect test package?)
|
||||||
COLLECT_CONTRACT_API = True
|
COLLECT_CONTRACT_API = True
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -6,9 +6,8 @@ from typing import Callable, Generator, Iterable, List, Type, Union
|
||||||
from unittest.mock import Mock
|
from unittest.mock import Mock
|
||||||
|
|
||||||
from nucypher.blockchain.eth import agents
|
from nucypher.blockchain.eth import agents
|
||||||
from nucypher.blockchain.eth.agents import ContractAgency, EthereumContractAgent
|
from nucypher.blockchain.eth.agents import Agent, ContractAgency, EthereumContractAgent
|
||||||
from nucypher.blockchain.eth.constants import NULL_ADDRESS
|
from nucypher.blockchain.eth.constants import NULL_ADDRESS
|
||||||
from nucypher.blockchain.eth.decorators import ContractInterfaces
|
|
||||||
from nucypher.blockchain.eth.interfaces import BlockchainInterfaceFactory
|
from nucypher.blockchain.eth.interfaces import BlockchainInterfaceFactory
|
||||||
from tests.constants import MOCK_PROVIDER_URI
|
from tests.constants import MOCK_PROVIDER_URI
|
||||||
|
|
||||||
|
@ -54,16 +53,18 @@ class MockContractAgent:
|
||||||
return r
|
return r
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def __setup_mock(cls, agent_class: Type[EthereumContractAgent]) -> None:
|
def __setup_mock(cls, agent_class: Type[Agent]) -> None:
|
||||||
|
|
||||||
api_methods = list(cls.__collect_contract_api(agent_class=agent_class))
|
api_methods: Iterable[Callable] = list(cls.__collect_contract_api(agent_class=agent_class))
|
||||||
mock_methods, mock_properties = list(), dict()
|
mock_methods, mock_properties = list(), dict()
|
||||||
|
|
||||||
for agent_interface in api_methods:
|
for agent_interface in api_methods:
|
||||||
|
|
||||||
# Handle
|
# Handle
|
||||||
try:
|
try:
|
||||||
real_method = agent_interface.fget # Handle properties
|
# TODO: #2022: This might be a method also decorated @property
|
||||||
|
# Get the inner function of the property
|
||||||
|
real_method: Callable = agent_interface.fget # Handle properties
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
real_method = agent_interface
|
real_method = agent_interface
|
||||||
|
|
||||||
|
@ -71,7 +72,7 @@ class MockContractAgent:
|
||||||
interface = getattr(real_method, cls.__COLLECTION_MARKER)
|
interface = getattr(real_method, cls.__COLLECTION_MARKER)
|
||||||
default_return = cls.__DEFAULTS.get(interface)
|
default_return = cls.__DEFAULTS.get(interface)
|
||||||
|
|
||||||
# TODO: Special handling of PropertyMocks?
|
# TODO: #2022 Special handling of PropertyMocks?
|
||||||
# # Setup
|
# # Setup
|
||||||
# if interface == CONTRACT_ATTRIBUTE:
|
# if interface == CONTRACT_ATTRIBUTE:
|
||||||
# mock = PropertyMock()
|
# mock = PropertyMock()
|
||||||
|
@ -96,7 +97,7 @@ class MockContractAgent:
|
||||||
return interface_calls
|
return interface_calls
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def __is_contract_method(cls, agent_class: Type['EthereumContractAgent'], method_name: str) -> bool:
|
def __is_contract_method(cls, agent_class: Type[Agent], method_name: str) -> bool:
|
||||||
method_or_property = getattr(agent_class, method_name)
|
method_or_property = getattr(agent_class, method_name)
|
||||||
try:
|
try:
|
||||||
real_method: Callable = method_or_property.fget # Property (getter)
|
real_method: Callable = method_or_property.fget # Property (getter)
|
||||||
|
@ -106,7 +107,7 @@ class MockContractAgent:
|
||||||
return contract_api
|
return contract_api
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def __collect_contract_api(cls, agent_class: Type[EthereumContractAgent]) -> Generator[Callable, None, None]:
|
def __collect_contract_api(cls, agent_class: Type[Agent]) -> Generator[Callable, None, None]:
|
||||||
agent_attrs = dir(agent_class)
|
agent_attrs = dir(agent_class)
|
||||||
predicate = cls.__is_contract_method
|
predicate = cls.__is_contract_method
|
||||||
methods = (getattr(agent_class, name) for name in agent_attrs if predicate(agent_class, name))
|
methods = (getattr(agent_class, name) for name in agent_attrs if predicate(agent_class, name))
|
||||||
|
@ -156,7 +157,7 @@ class MockContractAgency(ContractAgency):
|
||||||
__agents = dict()
|
__agents = dict()
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_agent(cls, agent_class: Type[EthereumContractAgent], *args, **kwargs) -> MockContractAgent:
|
def get_agent(cls, agent_class: Type[Agent], *args, **kwargs) -> Type[MockContractAgent]:
|
||||||
try:
|
try:
|
||||||
mock_agent = cls.__agents[agent_class]
|
mock_agent = cls.__agents[agent_class]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
|
@ -165,7 +166,7 @@ class MockContractAgency(ContractAgency):
|
||||||
return mock_agent
|
return mock_agent
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_agent_by_contract_name(cls, contract_name: str, *args, **kwargs) -> MockContractAgent:
|
def get_agent_by_contract_name(cls, contract_name: str, *args, **kwargs) -> Type[MockContractAgent]:
|
||||||
agent_name = super()._contract_name_to_agent_name(name=contract_name)
|
agent_name = super()._contract_name_to_agent_name(name=contract_name)
|
||||||
agent_class = getattr(agents, agent_name)
|
agent_class = getattr(agents, agent_name)
|
||||||
mock_agent = cls.get_agent(agent_class=agent_class)
|
mock_agent = cls.get_agent(agent_class=agent_class)
|
||||||
|
|
Loading…
Reference in New Issue