Repository: ethereum/web3.py
Pull request #1954 (2021-04-23 21:57:13)

Parity setMode to snake
### What was wrong?
Add set_mode, deprecate setMode.

Related to Issue #1429 

### Todo:
- [x] Add entry to the [release notes](https://github.com/ethereum/web3.py/blob/master/newsfragments/README.md)

#### Cute Animal Picture

![image](https://user-images.githubusercontent.com/6540608/115933604-6f7f1000-a44c-11eb-8112-3711bb5b7f3c.png)




Patch:
diff --git a/newsfragments/1954.feature.rst b/newsfragments/1954.feature.rst
new file mode 100644
index 00000000..e728f931
--- /dev/null
+++ b/newsfragments/1954.feature.rst
@@ -0,0 +1,1 @@
+Add ``parity.set_mode``, deprecate ``parity.setMode``
diff --git a/newsfragments/1964.misc.rst b/newsfragments/1964.misc.rst
new file mode 100644
index 00000000..3ee6cac9
--- /dev/null
+++ b/newsfragments/1964.misc.rst
@@ -0,0 +1,1 @@
+Rename ModuleV2 to Module, since Module was removed in #1805
diff --git a/web3/_utils/admin.py b/web3/_utils/admin.py
index 7c3eba87..2505451d 100644
--- a/web3/_utils/admin.py
+++ b/web3/_utils/admin.py
@@ -16,7 +16,7 @@ from web3.method import (
     default_root_munger,
 )
 from web3.module import (
-    ModuleV2,
+    Module,
 )
 from web3.types import (
     EnodeURI,
@@ -26,7 +26,7 @@ from web3.types import (
 
 
 def admin_start_params_munger(
-    module: ModuleV2, host: str = 'localhost', port: int = 8546, cors: str = '',
+    module: Module, host: str = 'localhost', port: int = 8546, cors: str = '',
     apis: str = 'eth,net,web3'
 ) -> Tuple[str, int, str, str]:
     return (host, port, cors, apis)
diff --git a/web3/_utils/method_formatters.py b/web3/_utils/method_formatters.py
index 396790f5..1562d780 100644
--- a/web3/_utils/method_formatters.py
+++ b/web3/_utils/method_formatters.py
@@ -97,7 +97,7 @@ from web3.types import (
 
 if TYPE_CHECKING:
     from web3 import Web3  # noqa: F401
-    from web3.module import ModuleV2  # noqa: F401
+    from web3.module import Module  # noqa: F401
     from web3.eth import Eth  # noqa: F401
 
 
@@ -656,7 +656,7 @@ FILTER_RESULT_FORMATTERS: Dict[RPCEndpoint, Callable[..., Any]] = {
 @to_tuple
 def apply_module_to_formatters(
         formatters: Tuple[Callable[..., TReturn]],
-        module: "ModuleV2",
+        module: "Module",
         method_name: Union[RPCEndpoint, Callable[..., RPCEndpoint]],
 ) -> Iterable[Callable[..., TReturn]]:
     for f in formatters:
@@ -665,7 +665,7 @@ def apply_module_to_formatters(
 
 def get_result_formatters(
     method_name: Union[RPCEndpoint, Callable[..., RPCEndpoint]],
-    module: "ModuleV2",
+    module: "Module",
 ) -> Dict[str, Callable[..., Any]]:
     formatters = combine_formatters(
         (PYTHONIC_RESULT_FORMATTERS,),
diff --git a/web3/_utils/module.py b/web3/_utils/module.py
index 56ae71a9..afc0e46e 100644
--- a/web3/_utils/module.py
+++ b/web3/_utils/module.py
@@ -13,13 +13,13 @@ from web3.exceptions import (
 
 if TYPE_CHECKING:
     from web3 import Web3  # noqa: F401
-    from web3.module import ModuleV2  # noqa: F401
+    from web3.module import Module  # noqa: F401
 
 
 def attach_modules(
-    parent_module: Union["Web3", "ModuleV2"],
+    parent_module: Union["Web3", "Module"],
     module_definitions: Dict[str, Sequence[Any]],
-    w3: Optional[Union["Web3", "ModuleV2"]] = None
+    w3: Optional[Union["Web3", "Module"]] = None
 ) -> None:
     for module_name, module_info in module_definitions.items():
         module_class = module_info[0]
diff --git a/web3/beacon/main.py b/web3/beacon/main.py
index 348ee1a8..62d616a9 100644
--- a/web3/beacon/main.py
+++ b/web3/beacon/main.py
@@ -6,11 +6,11 @@ from typing import (
 import requests
 
 from web3.module import (
-    ModuleV2,
+    Module,
 )
 
 
-class Beacon(ModuleV2):
+class Beacon(Module):
     def __init__(
         self,
         base_url: str,
diff --git a/web3/eth.py b/web3/eth.py
index 1593da5e..af857e18 100644
--- a/web3/eth.py
+++ b/web3/eth.py
@@ -81,7 +81,7 @@ from web3.method import (
     default_root_munger,
 )
 from web3.module import (
-    ModuleV2,
+    Module,
 )
 from web3.types import (
     ENS,
@@ -104,7 +104,7 @@ from web3.types import (
 )
 
 
-class Eth(ModuleV2):
+class Eth(Module):
     account = Account()
     _default_account: Union[ChecksumAddress, Empty] = empty
     _default_block: BlockIdentifier = "latest"
diff --git a/web3/exceptions.py b/web3/exceptions.py
index 86c1b2be..806d8f19 100644
--- a/web3/exceptions.py
+++ b/web3/exceptions.py
@@ -213,6 +213,6 @@ class ContractLogicError(SolidityError, ValueError):
 class InvalidParityMode(TypeError, ValueError):
     # Inherits from TypeError for backwards compatibility
     """
-    Raised when web3.parity.setMode() is called with no or invalid args
+    Raised when web3.parity.set_mode() is called with no or invalid args
     """
     pass
diff --git a/web3/geth.py b/web3/geth.py
index 32cb054c..db479acc 100644
--- a/web3/geth.py
+++ b/web3/geth.py
@@ -56,11 +56,11 @@ from web3._utils.txpool import (
     status,
 )
 from web3.module import (
-    ModuleV2,
+    Module,
 )
 
 
-class GethPersonal(ModuleV2):
+class GethPersonal(Module):
     """
     https://github.com/ethereum/go-ethereum/wiki/management-apis#personal
     """
@@ -85,7 +85,7 @@ class GethPersonal(ModuleV2):
     unlockAccount = unlockAccount
 
 
-class GethTxPool(ModuleV2):
+class GethTxPool(Module):
     """
     https://github.com/ethereum/go-ethereum/wiki/Management-APIs#txpool
     """
@@ -94,7 +94,7 @@ class GethTxPool(ModuleV2):
     status = status
 
 
-class GethAdmin(ModuleV2):
+class GethAdmin(Module):
     """
     https://github.com/ethereum/go-ethereum/wiki/Management-APIs#admin
     """
@@ -115,7 +115,7 @@ class GethAdmin(ModuleV2):
     stopWS = stopWS
 
 
-class GethMiner(ModuleV2):
+class GethMiner(Module):
     """
     https://github.com/ethereum/go-ethereum/wiki/Management-APIs#miner
     """
@@ -136,6 +136,6 @@ class GethMiner(ModuleV2):
     stopAutoDag = stopAutoDag
 
 
-class Geth(ModuleV2):
+class Geth(Module):
     personal: GethPersonal
     admin: GethAdmin
diff --git a/web3/method.py b/web3/method.py
index 1eae06fd..087902e9 100644
--- a/web3/method.py
+++ b/web3/method.py
@@ -37,7 +37,7 @@ from web3.types import (
 
 if TYPE_CHECKING:
     from web3 import Web3  # noqa: F401
-    from web3.module import ModuleV2  # noqa: F401
+    from web3.module import Module  # noqa: F401
 
 Munger = Callable[..., Any]
 
@@ -59,14 +59,14 @@ def _munger_star_apply(fn: Callable[..., TReturn]) -> Callable[..., TReturn]:
     return inner
 
 
-def default_munger(module: "ModuleV2", *args: Any, **kwargs: Any) -> Tuple[()]:
+def default_munger(module: "Module", *args: Any, **kwargs: Any) -> Tuple[()]:
     if not args and not kwargs:
         return ()
     else:
         raise TypeError("Parameters passed to method without parameter mungers defined.")
 
 
-def default_root_munger(module: "ModuleV2", *args: Any) -> List[Any]:
+def default_root_munger(module: "Module", *args: Any) -> List[Any]:
     return [*args]
 
 
@@ -129,8 +129,8 @@ class Method(Generic[TFunc]):
         self.error_formatters = get_error_formatters
         self.method_choice_depends_on_args = method_choice_depends_on_args
 
-    def __get__(self, obj: Optional["ModuleV2"] = None,
-                obj_type: Optional[Type["ModuleV2"]] = None) -> TFunc:
+    def __get__(self, obj: Optional["Module"] = None,
+                obj_type: Optional[Type["Module"]] = None) -> TFunc:
         if obj is None:
             raise TypeError(
                 "Direct calls to methods are not supported. "
@@ -149,7 +149,7 @@ class Method(Generic[TFunc]):
         raise ValueError("``json_rpc_method`` config invalid.  May be a string or function")
 
     def input_munger(
-        self, module: "ModuleV2", args: Any, kwargs: Any
+        self, module: "Module", args: Any, kwargs: Any
     ) -> List[Any]:
         # This function takes the "root_munger" - the first munger in
         # the list of mungers) and then pipes the return value of the
@@ -168,7 +168,7 @@ class Method(Generic[TFunc]):
         return munged_inputs
 
     def process_params(
-        self, module: "ModuleV2", *args: Any, **kwargs: Any
+        self, module: "Module", *args: Any, **kwargs: Any
     ) -> Tuple[Tuple[Union[RPCEndpoint, Callable[..., Any]], Any], Tuple[Any, Any]]:
         params = self.input_munger(module, args, kwargs)
 
@@ -202,8 +202,8 @@ class DeprecatedMethod():
         self.old_name = old_name
         self.new_name = new_name
 
-    def __get__(self, obj: Optional["ModuleV2"] = None,
-                obj_type: Optional[Type["ModuleV2"]] = None) -> Any:
+    def __get__(self, obj: Optional["Module"] = None,
+                obj_type: Optional[Type["Module"]] = None) -> Any:
         warnings.warn(
             f"{self.old_name} is deprecated in favor of {self.new_name}",
             category=DeprecationWarning,
diff --git a/web3/module.py b/web3/module.py
index 22c835cc..1d3f6de4 100644
--- a/web3/module.py
+++ b/web3/module.py
@@ -46,7 +46,7 @@ TReturn = TypeVar('TReturn')
 
 @curry
 def retrieve_blocking_method_call_fn(
-    w3: "Web3", module: "ModuleV2", method: Method[Callable[..., TReturn]]
+    w3: "Web3", module: "Module", method: Method[Callable[..., TReturn]]
 ) -> Callable[..., Union[TReturn, LogFilter]]:
     def caller(*args: Any, **kwargs: Any) -> Union[TReturn, LogFilter]:
         try:
@@ -61,7 +61,7 @@ def retrieve_blocking_method_call_fn(
 
 @curry
 def retrieve_async_method_call_fn(
-    w3: "Web3", module: "ModuleV2", method: Method[Callable[..., Any]]
+    w3: "Web3", module: "Module", method: Method[Callable[..., Any]]
 ) -> Callable[..., Coroutine[Any, Any, RPCResponse]]:
     async def caller(*args: Any, **kwargs: Any) -> RPCResponse:
         (method_str, params), response_formatters = method.process_params(module, *args, **kwargs)
@@ -75,7 +75,7 @@ def retrieve_async_method_call_fn(
 #  Only the calling functions need access to the request methods.
 #  Any "re-entrant" shinanigans can go in the middlewares, which do
 #  have web3 access.
-class ModuleV2:
+class Module:
     is_async = False
 
     def __init__(self, web3: "Web3") -> None:
diff --git a/web3/net.py b/web3/net.py
index ce5a43e8..68e0193d 100644
--- a/web3/net.py
+++ b/web3/net.py
@@ -9,11 +9,11 @@ from web3._utils.net import (
     version,
 )
 from web3.module import (
-    ModuleV2,
+    Module,
 )
 
 
-class Net(ModuleV2):
+class Net(Module):
     """
         https://github.com/ethereum/wiki/wiki/JSON-RPC
     """
diff --git a/web3/parity.py b/web3/parity.py
index aa34bcb2..d88954e9 100644
--- a/web3/parity.py
+++ b/web3/parity.py
@@ -46,7 +46,7 @@ from web3.method import (
     default_root_munger,
 )
 from web3.module import (
-    ModuleV2,
+    Module,
 )
 from web3.types import (
     ENS,
@@ -63,7 +63,7 @@ from web3.types import (
 )
 
 
-class ParityPersonal(ModuleV2):
+class ParityPersonal(Module):
     """
     https://wiki.parity.io/JSONRPC-personal-module
     """
@@ -85,7 +85,7 @@ class ParityPersonal(ModuleV2):
     unlockAccount = unlockAccount
 
 
-class Parity(ModuleV2):
+class Parity(Module):
     """
     https://paritytech.github.io/wiki/JSONRPC-parity-module
     """
@@ -210,7 +210,7 @@ class Parity(ModuleV2):
         mungers=[trace_transactions_munger],
     )
 
-    setMode: Method[Callable[[ParityMode], bool]] = Method(
+    set_mode: Method[Callable[[ParityMode], bool]] = Method(
         RPC.parity_setMode,
         mungers=[default_root_munger],
     )
@@ -226,6 +226,7 @@ class Parity(ModuleV2):
     traceReplayTransaction = DeprecatedMethod(trace_replay_transaction, 'traceReplayTransaction',
                                               'trace_replay_transaction')
     netPeers = DeprecatedMethod(net_peers, 'netPeers', 'net_peers')
+    setMode = DeprecatedMethod(set_mode, 'setMode', 'set_mode')
     traceBlock = DeprecatedMethod(trace_block, 'traceBlock', 'trace_block')
     traceFilter = DeprecatedMethod(trace_filter, 'traceFilter', 'trace_filter')
     traceReplayBlockTransactions = DeprecatedMethod(trace_replay_block_transactions,
diff --git a/web3/pm.py b/web3/pm.py
index 75caa5ea..5257db22 100644
--- a/web3/pm.py
+++ b/web3/pm.py
@@ -60,7 +60,7 @@ from web3.exceptions import (
     PMError,
 )
 from web3.module import (
-    ModuleV2,
+    Module,
 )
 from web3.types import (
     ENS,
@@ -312,7 +312,7 @@ class SimpleRegistry(ERC1319Registry):
         return cls(tx_receipt["contractAddress"], w3)
 
 
-class PM(ModuleV2):
+class PM(Module):
     """
     The PM module will work with any subclass of ``ERC1319Registry``, tailored to a particular
     implementation of `ERC1319  <https://github.com/ethereum/EIPs/issues/1319>`__, set as
diff --git a/web3/version.py b/web3/version.py
index 61898bc4..9b591c1f 100644
--- a/web3/version.py
+++ b/web3/version.py
@@ -10,11 +10,11 @@ from web3.method import (
     Method,
 )
 from web3.module import (
-    ModuleV2,
+    Module,
 )
 
 
-class BaseVersion(ModuleV2):
+class BaseVersion(Module):
     retrieve_caller_fn = None
 
     _get_node_version: Method[Callable[[], str]] = Method(RPC.web3_clientVersion)
@@ -49,7 +49,7 @@ class BlockingVersion(BaseVersion):
         return self._get_protocol_version()
 
 
-class Version(ModuleV2):
+class Version(Module):
     @property
     def api(self) -> NoReturn:
         raise DeprecationWarning(


Test patch:
diff --git a/tests/core/method-class/test_method.py b/tests/core/method-class/test_method.py
index 6b78980c..594eaa65 100644
--- a/tests/core/method-class/test_method.py
+++ b/tests/core/method-class/test_method.py
@@ -17,7 +17,7 @@ from web3.method import (
     default_root_munger,
 )
 from web3.module import (
-    ModuleV2,
+    Module,
     apply_result_formatters,
 )
 
@@ -254,7 +254,7 @@ def return_exception_raising_formatter(method):
     return compose(formatter)
 
 
-class FakeModule(ModuleV2):
+class FakeModule(Module):
     method = Method(
         'eth_method',
         mungers=[keywords],
diff --git a/tests/core/method-class/test_result_formatters.py b/tests/core/method-class/test_result_formatters.py
index 97312589..88880c02 100644
--- a/tests/core/method-class/test_result_formatters.py
+++ b/tests/core/method-class/test_result_formatters.py
@@ -12,7 +12,7 @@ from web3.middleware.fixture import (
     construct_result_generator_middleware,
 )
 from web3.module import (
-    ModuleV2,
+    Module,
 )
 from web3.providers import (
     BaseProvider,
@@ -35,7 +35,7 @@ result_middleware = construct_result_generator_middleware({
 })
 
 
-class ModuleForTest(ModuleV2):
+class ModuleForTest(Module):
     method = Method(
         'method_for_test',
         result_formatters=result_formatter)
diff --git a/tests/core/utilities/test_attach_modules.py b/tests/core/utilities/test_attach_modules.py
index 11343b26..c38eb403 100644
--- a/tests/core/utilities/test_attach_modules.py
+++ b/tests/core/utilities/test_attach_modules.py
@@ -8,28 +8,28 @@ from web3.exceptions import (
     ValidationError,
 )
 from web3.module import (
-    ModuleV2,
+    Module,
 )
 from web3.providers.eth_tester import (
     EthereumTesterProvider,
 )
 
 
-class MockEth(ModuleV2):
+class MockEth(Module):
     def block_number(self):
         return 42
 
 
-class MockGeth(ModuleV2):
+class MockGeth(Module):
     pass
 
 
-class MockGethAdmin(ModuleV2):
+class MockGethAdmin(Module):
     def start_ws(self):
         return True
 
 
-class MockGethPersonal(ModuleV2):
+class MockGethPersonal(Module):
     def unlock_account(self):
         return True
 
diff --git a/web3/_utils/module_testing/parity_module.py b/web3/_utils/module_testing/parity_module.py
index f8012a36..923564c0 100644
--- a/web3/_utils/module_testing/parity_module.py
+++ b/web3/_utils/module_testing/parity_module.py
@@ -216,12 +216,16 @@ class ParitySetModuleTest:
         ]
     )
     def test_set_mode(self, web3: "Web3", mode: ParityMode) -> None:
-        assert web3.parity.setMode(mode) is True
+        assert web3.parity.set_mode(mode) is True
+
+    def test_set_mode_deprecated(self, web3: "Web3", mode: ParityMode) -> None:
+        with pytest.warns(DeprecationWarning, match="setMode is deprecated in favor of set_mode"):
+            assert web3.parity.setMode(mode) is True
 
     def test_set_mode_with_bad_string(self, web3: "Web3") -> None:
         with pytest.raises(InvalidParityMode, match="Couldn't parse parameters: mode"):
             # type ignored b/c it's an invalid literal ParityMode
-            web3.parity.setMode('not a mode')  # type: ignore
+            web3.parity.set_mode('not a mode')  # type: ignore
 
     def test_set_mode_with_no_argument(self, web3: "Web3") -> None:
         with pytest.raises(
@@ -229,4 +233,4 @@ class ParitySetModuleTest:
             match='Invalid params: invalid length 0, expected a tuple of size 1.'
         ):
             # type ignored b/c setMode expects arguments
-            web3.parity.setMode()  # type: ignore
+            web3.parity.set_mode()  # type: ignore
diff --git a/web3/testing.py b/web3/testing.py
index 788a85f5..4537df8c 100644
--- a/web3/testing.py
+++ b/web3/testing.py
@@ -6,11 +6,11 @@ from web3._utils.rpc_abi import (
     RPC,
 )
 from web3.module import (
-    ModuleV2,
+    Module,
 )
 
 
-class Testing(ModuleV2):
+class Testing(Module):
     def timeTravel(self, timestamp: int) -> None:
         return self.web3.manager.request_blocking(RPC.testing_timeTravel, [timestamp])