Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Deprecate geth.personal namespace methods #3364

Merged
merged 1 commit into from
Apr 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions docs/web3.geth.rst
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,10 @@ GethPersonal API

The following methods are available on the ``web3.geth.personal`` namespace.

.. warning:: Deprecated: Geth has deprecated the ``personal`` namespace and
has transitioned to using ``clef`` for account management. The ``personal``
namespace will be removed in *web3.py* ``v7``.

.. py:method:: ec_recover(message, signature)

* Delegates to ``personal_ecRecover`` RPC Method
Expand Down
1 change: 1 addition & 0 deletions newsfragments/3364.deprecation.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Deprecate the ``geth.personal`` namespace methods. These will be removed in *web3.py* ``v7``.
29 changes: 22 additions & 7 deletions web3/_utils/decorators.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,22 +35,37 @@ def wrapped(*args: Any) -> Any:
return wrapped


def deprecated_for(replace_message: str) -> Callable[..., Any]:
def deprecate_method(
replacement_method: str = None, deprecation_msg: str = None
) -> Callable[..., Any]:
"""
Decorate a deprecated function, with info about what to use instead, like:
Decorate a deprecated function with info on its replacement method OR a clarifying
reason for the deprecation.

@deprecated_for("to_bytes()")
def toAscii(arg):
@deprecate_method("to_bytes()")
def to_ascii(arg):
...

@deprecate_method(deprecation_msg=(
"This method is no longer supported and will be removed in the next release."
))
def some_method(arg):
...
"""
if replacement_method is None and deprecation_msg is None:
raise ValueError(
"Must provide either `replacement_method` or `deprecation_msg`"
)

def decorator(to_wrap: TFunc) -> TFunc:
@functools.wraps(to_wrap)
def wrapper(*args: Any, **kwargs: Any) -> Callable[..., Any]:
warnings.warn(
f"{to_wrap.__name__} is deprecated in favor of {replace_message}",
category=DeprecationWarning,
msg = (
f"{to_wrap.__name__} is deprecated in favor of {replacement_method}"
if replacement_method is not None
else deprecation_msg
)
warnings.warn(msg, category=DeprecationWarning)
return to_wrap(*args, **kwargs)

return cast(TFunc, wrapper)
Expand Down
20 changes: 8 additions & 12 deletions web3/_utils/miner.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,26 +28,22 @@
mungers=[default_root_munger],
)

make_dag = DeprecatedMethod(
_make_dag, "make_dag", msg="All mining methods have been deprecated"
)
make_dag = DeprecatedMethod(_make_dag, msg="All mining methods have been deprecated")

_set_extra: Method[Callable[[str], bool]] = Method(
RPC.miner_setExtra,
mungers=[default_root_munger],
)

set_extra = DeprecatedMethod(
_set_extra, "set_extra", msg="All mining methods have been deprecated"
)
set_extra = DeprecatedMethod(_set_extra, msg="All mining methods have been deprecated")

_set_etherbase: Method[Callable[[ChecksumAddress], bool]] = Method(
RPC.miner_setEtherbase,
mungers=[default_root_munger],
)

set_etherbase = DeprecatedMethod(
_set_etherbase, "set_etherbase", msg="All mining methods have been deprecated"
_set_etherbase, msg="All mining methods have been deprecated"
)

_set_gas_price: Method[Callable[[Wei], bool]] = Method(
Expand All @@ -56,30 +52,30 @@
)

set_gas_price = DeprecatedMethod(
_set_gas_price, "set_gas_price", msg="All mining methods have been deprecated"
_set_gas_price, msg="All mining methods have been deprecated"
)

_start: Method[Callable[[int], bool]] = Method(
RPC.miner_start,
mungers=[default_root_munger],
)

start = DeprecatedMethod(_start, "start", msg="All mining methods have been deprecated")
start = DeprecatedMethod(_start, msg="All mining methods have been deprecated")

_stop: Method[Callable[[], bool]] = Method(
RPC.miner_stop,
is_property=True,
)

stop = DeprecatedMethod(_stop, "stop", msg="All mining methods have been deprecated")
stop = DeprecatedMethod(_stop, msg="All mining methods have been deprecated")

_start_auto_dag: Method[Callable[[], bool]] = Method(
RPC.miner_startAutoDag,
is_property=True,
)

start_auto_dag = DeprecatedMethod(
_start_auto_dag, "start_auto_dag", msg="All mining methods have been deprecated"
_start_auto_dag, msg="All mining methods have been deprecated"
)

_stop_auto_dag: Method[Callable[[], bool]] = Method(
Expand All @@ -88,5 +84,5 @@
)

stop_auto_dag = DeprecatedMethod(
_stop_auto_dag, "stop_auto_dag", msg="All mining methods have been deprecated"
_stop_auto_dag, msg="All mining methods have been deprecated"
)
111 changes: 67 additions & 44 deletions web3/_utils/module_testing/go_ethereum_personal_module.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,17 +55,20 @@

class GoEthereumPersonalModuleTest:
def test_personal_import_raw_key(self, w3: "Web3") -> None:
actual = w3.geth.personal.import_raw_key(PRIVATE_KEY_HEX, PASSWORD)
with pytest.warns(DeprecationWarning):
actual = w3.geth.personal.import_raw_key(PRIVATE_KEY_HEX, PASSWORD)
assert actual == ADDRESS

def test_personal_list_accounts(self, w3: "Web3") -> None:
accounts = w3.geth.personal.list_accounts()
with pytest.warns(DeprecationWarning):
accounts = w3.geth.personal.list_accounts()
assert is_list_like(accounts)
assert len(accounts) > 0
assert all((is_checksum_address(item) for item in accounts))

def test_personal_list_wallets(self, w3: "Web3") -> None:
wallets = w3.geth.personal.list_wallets()
with pytest.warns(DeprecationWarning):
wallets = w3.geth.personal.list_wallets()
assert is_list_like(wallets)
assert len(wallets) > 0
assert is_checksum_address(wallets[0]["accounts"][0]["address"])
Expand All @@ -76,18 +79,19 @@ def test_personal_list_wallets(self, w3: "Web3") -> None:
def test_personal_lock_account(
self, w3: "Web3", unlockable_account_dual_type: ChecksumAddress
) -> None:
# TODO: how do we test this better?
w3.geth.personal.lock_account(unlockable_account_dual_type)
with pytest.warns(DeprecationWarning):
w3.geth.personal.lock_account(unlockable_account_dual_type)

def test_personal_unlock_account_success(
self,
w3: "Web3",
unlockable_account_dual_type: ChecksumAddress,
unlockable_account_pw: str,
) -> None:
result = w3.geth.personal.unlock_account(
unlockable_account_dual_type, unlockable_account_pw
)
with pytest.warns(DeprecationWarning):
result = w3.geth.personal.unlock_account(
unlockable_account_dual_type, unlockable_account_pw
)
assert result is True

def test_personal_unlock_account_failure(
Expand All @@ -99,7 +103,8 @@ def test_personal_unlock_account_failure(
)

def test_personal_new_account(self, w3: "Web3") -> None:
new_account = w3.geth.personal.new_account(PASSWORD)
with pytest.warns(DeprecationWarning):
new_account = w3.geth.personal.new_account(PASSWORD)
assert is_checksum_address(new_account)

def test_personal_send_transaction(
Expand All @@ -118,7 +123,10 @@ def test_personal_send_transaction(
"value": Wei(1),
"gasPrice": w3.to_wei(1, "gwei"),
}
txn_hash = w3.geth.personal.send_transaction(txn_params, unlockable_account_pw)
with pytest.warns(DeprecationWarning):
txn_hash = w3.geth.personal.send_transaction(
txn_params, unlockable_account_pw
)
assert txn_hash
transaction = w3.eth.get_transaction(txn_hash)

Expand All @@ -139,10 +147,13 @@ def test_personal_sign_and_ecrecover(
unlockable_account_pw: str,
) -> None:
message = "test-web3-geth-personal-sign"
signature = w3.geth.personal.sign(
message, unlockable_account_dual_type, unlockable_account_pw
)
signer = w3.geth.personal.ec_recover(message, signature)
with pytest.warns(DeprecationWarning):
signature = w3.geth.personal.sign(
message, unlockable_account_dual_type, unlockable_account_pw
)

with pytest.warns(DeprecationWarning):
signer = w3.geth.personal.ec_recover(message, signature)
assert is_same_address(signer, unlockable_account_dual_type)

@pytest.mark.xfail(
Expand Down Expand Up @@ -193,13 +204,14 @@ def test_personal_sign_typed_data(
}
}
"""
signature = HexBytes(
w3.geth.personal.sign_typed_data(
json.loads(typed_message),
unlockable_account_dual_type,
unlockable_account_pw,
with pytest.warns(DeprecationWarning):
signature = HexBytes(
w3.geth.personal.sign_typed_data(
json.loads(typed_message),
unlockable_account_dual_type,
unlockable_account_pw,
)
)
)

expected_signature = HexBytes(
"0xc8b56aaeefd10ab4005c2455daf28d9082af661ac347cd"
Expand All @@ -219,33 +231,38 @@ async def test_async_sign_and_ec_recover(
unlockable_account_pw: str,
) -> None:
message = "This is a test"
signature = await async_w3.geth.personal.sign(
message, async_unlockable_account_dual_type, unlockable_account_pw
)
with pytest.warns(DeprecationWarning):
signature = await async_w3.geth.personal.sign(
message, async_unlockable_account_dual_type, unlockable_account_pw
)
address = await async_w3.geth.personal.ec_recover(message, signature)
assert is_same_address(async_unlockable_account_dual_type, address)

@pytest.mark.asyncio
async def test_async_import_key(self, async_w3: "AsyncWeb3") -> None:
address = await async_w3.geth.personal.import_raw_key(
THIRD_PRIVATE_KEY_HEX, "Testing"
)
with pytest.warns(DeprecationWarning):
address = await async_w3.geth.personal.import_raw_key(
THIRD_PRIVATE_KEY_HEX, "Testing"
)
assert address is not None

@pytest.mark.asyncio
async def test_async_list_accounts(self, async_w3: "AsyncWeb3") -> None:
accounts = await async_w3.geth.personal.list_accounts()
with pytest.warns(DeprecationWarning):
accounts = await async_w3.geth.personal.list_accounts()
assert len(accounts) > 0

@pytest.mark.asyncio
async def test_async_list_wallets(self, async_w3: "AsyncWeb3") -> None:
wallets = await async_w3.geth.personal.list_wallets()
with pytest.warns(DeprecationWarning):
wallets = await async_w3.geth.personal.list_wallets()
assert isinstance(wallets[0], AttributeDict)

@pytest.mark.asyncio
async def test_async_new_account(self, async_w3: "AsyncWeb3") -> None:
passphrase = "Create New Account"
account = await async_w3.geth.personal.new_account(passphrase)
with pytest.warns(DeprecationWarning):
account = await async_w3.geth.personal.new_account(passphrase)
assert is_checksum_address(account)

@pytest.mark.asyncio
Expand All @@ -255,13 +272,16 @@ async def test_async_unlock_lock_account(
async_unlockable_account_dual_type: ChecksumAddress,
unlockable_account_pw: str,
) -> None:
unlocked = await async_w3.geth.personal.unlock_account(
async_unlockable_account_dual_type, unlockable_account_pw
)
with pytest.warns(DeprecationWarning):
unlocked = await async_w3.geth.personal.unlock_account(
async_unlockable_account_dual_type, unlockable_account_pw
)
assert unlocked is True
locked = await async_w3.geth.personal.lock_account(
async_unlockable_account_dual_type
)

with pytest.warns(DeprecationWarning):
locked = await async_w3.geth.personal.lock_account(
async_unlockable_account_dual_type
)
assert locked is True

@pytest.mark.asyncio
Expand All @@ -275,9 +295,10 @@ async def test_async_send_transaction(
tx_params["to"] = async_unlockable_account_dual_type
tx_params["from"] = async_unlockable_account_dual_type
tx_params["value"] = Wei(123)
response = await async_w3.geth.personal.send_transaction(
tx_params, unlockable_account_pw
)
with pytest.warns(DeprecationWarning):
response = await async_w3.geth.personal.send_transaction(
tx_params, unlockable_account_pw
)
assert response is not None

@pytest.mark.xfail(
Expand All @@ -291,10 +312,12 @@ async def test_async_sign_typed_data(
unlockable_account_pw: str,
) -> None:
message = {"message": "This is a test"}
signature = await async_w3.geth.personal.sign_typed_data(
message, async_unlockable_account_dual_type, unlockable_account_pw
)
address = await async_w3.geth.personal.ec_recover(
json.dumps(message), signature
)
with pytest.warns(DeprecationWarning):
signature = await async_w3.geth.personal.sign_typed_data(
message, async_unlockable_account_dual_type, unlockable_account_pw
)
with pytest.warns(DeprecationWarning):
address = await async_w3.geth.personal.ec_recover(
json.dumps(message), signature
)
assert is_same_address(async_unlockable_account_dual_type, address)
4 changes: 2 additions & 2 deletions web3/contract/base_contract.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@
PropertyCheckingFactory,
)
from web3._utils.decorators import (
deprecated_for,
deprecate_method,
)
from web3._utils.empty import (
empty,
Expand Down Expand Up @@ -727,7 +727,7 @@ class BaseContract:
# Public API
#
@combomethod
@deprecated_for("encode_abi()")
@deprecate_method("encode_abi()")
def encodeABI(
cls,
fn_name: str,
Expand Down
Loading