diff --git a/docs/web3.pm.rst b/docs/web3.pm.rst
index 7cf836313c..ec25e0d8e8 100644
--- a/docs/web3.pm.rst
+++ b/docs/web3.pm.rst
@@ -8,15 +8,30 @@ To learn more about the EthPM spec, visit the `documentation `__.
-Attaching
----------
- To use ``web3.pm``, attach it to your ``web3`` instance.
-
- .. code-block:: python
-
- from web3.pm import PM
- PM.attach(web3, 'pm')
-
+.. WARNING::
+
+ The ``web3.pm`` API is still under development and likely to change quickly.
+
+ Now is a great time to get familiar with the API, and test out writing
+ code that uses some of the great upcoming features.
+
+ By default, access to this module has been turned off in the stable version of Web3.py:
+
+ .. code-block:: python
+
+ >>> from web3.auto import w3
+ >>> w3.pm
+ ...
+ AttributeError: The Package Management feature is disabled by default ...
+
+ In order to access these features, you can turn it on with...
+
+ .. code-block:: python
+
+ >>> web3.enable_unstable_package_management_api()
+ >>> w3.pm
+
+
Methods
-------
@@ -25,8 +40,6 @@ The following methods are available on the ``web3.pm`` namespace.
.. autoclass:: web3.pm.PM
:members:
-.. note:: If you want to implement your own registry and use it with ``web3.pm``, you must create a subclass that inherits from ``ERCRegistry``, implements all the methods defined in ``ERCRegistry``, and manually set it as the ```registry`` attribute on ``web3.pm``.
-
.. autoclass:: web3.pm.ERCRegistry
:members: __init__, _release, _get_package_name, _get_all_package_ids, _get_release_id, _get_all_release_ids, _get_release_data, _generate_release_id, _num_package_ids, _num_release_ids
@@ -36,3 +49,16 @@ The following methods are available on the ``web3.pm`` namespace.
.. autoclass:: web3.pm.SolidityReferenceRegistry
:members:
+
+Creating your own Registry class
+--------------------------------
+If you want to implement your own registry and use it with ``web3.pm``, you must create a subclass that inherits from ``ERCRegistry``, and implements all the `ERC 1319 standard methods `_ prefixed with an underscore in ``ERCRegistry``. Then, you have to manually set it as the ``registry`` attribute on ``web3.pm``.
+
+.. code-block:: python
+
+ custom_registry = CustomRegistryClass(address, w3)
+ w3.pm.registry = custom_registry
+
+One reason a user might want to create their own Registry class is if they build a custom Package Registry smart contract that has features beyond those specified in `ERC 1319 `_. For example, the ability to delete a release or some micropayment feature. Rather than accessing those functions directly on the contract instance, they can create a custom ``ERCRegistry`` subclass to easily call both the standard & custom methods.
+
+The ``VyperReferenceRegistry`` class is an example of this, as it contains all of the ``ERC 1319`` defined functions (prefixed with an underscore, eg ``_get_package_name``) but also contains functions that are unique to the Vyper Registry reference implementation (eg ``transfer_owner``).
diff --git a/tests/core/pm-module/conftest.py b/tests/core/pm-module/conftest.py
index b65412c6ab..4e4cf52be4 100644
--- a/tests/core/pm-module/conftest.py
+++ b/tests/core/pm-module/conftest.py
@@ -1,7 +1,5 @@
import json
-import logging
import pytest
-import sys
from eth_tester import (
EthereumTester,
@@ -9,6 +7,7 @@
)
from eth_utils import (
function_abi_to_4byte_selector,
+ to_bytes,
to_canonical_address,
)
from ethpm import (
@@ -27,28 +26,24 @@
from web3 import Web3
from web3.pm import (
- PM,
SolidityReferenceRegistry,
VyperReferenceRegistry,
)
-VY_PACKAGE_ID_1 = b'\xd0Y\xe8\xa6\xeaZ\x8b\xbf\x8d\xd0\x97\xa7\xb8\x92#\x16\xdc\xb7\xf0$\xe8"\x0bV\xd3\xc9\xe7\x18\x8ajv@' # noqa: E501
-VY_PACKAGE_ID_2 = b"m\xf7\t\xa8V\x98\xad\x92\x14b\xb8\x97\x95G\xe3\xa8s\xe2.\x1cs\xb1\xcbi\x1f\x93v\x84\x7f\xb2\xd4\x02" # noqa: E501
-VY_PACKAGE_ID_3 = b"\x80\xe4\x1aB\xe3\xb8\xc3\xaf\x0e\xa5\x1c?\xd5\rH\x1e\xef\x13g\xdd\x9d7\x97\xba\x93\xd3]\xcf`f\x08\x82" # noqa: E501
-VY_RELEASE_ID_1 = b"Y^&\xf1\xb2${\xac\xc5~2\x80\x7f\x80Y\xe0\xb0\x83}\xd9\xc4~iF\x99A\x96\xbd)\xc9\xca\x97" # noqa: E501
-VY_RELEASE_ID_2 = b"\x04Y,\xb9\xce\xd5A>\x1b\t\xe8{\x08\x9b\xf6\x96\xa0^\xfbv\xee\x87\xc8\xc4\x12Yc_\xacm\x93\x8a" # noqa: E501
-VY_RELEASE_ID_3 = b'\xa0m\xbcQ\xf8\x89\x18\x94w\x8c\xe0=\xc2=pm"\x8c\x99x\x95\x95u\x8b\xd3\xdc\xac:\x93\xf4\x7f\n' # noqa: E501
-VY_RELEASE_ID_4 = b"\x9co\x87\xdd\xa6C[%\x06\xe8\x12\x06\xb3\x9e\xd7\x82\xa4K\x92\xd8&\xc2J\xb0+\xbd\xed2\x1b\x86\xe2\xad" # noqa: E501
-SOL_PACKAGE_ID_1 = b"`\xc5\x11+a\x15\x9ekB\xd5M\x94Px9N\x9d_\xc9\xc6\xff\x0f=\xf7\x89w\x00o\x8b\xbc\x06\xd4" # noqa: E501
-SOL_PACKAGE_ID_2 = b"\xdb\xcf\xb0\xbdq\x15\xbfe\x93P\xd7{\xb2+\xb8\x89\xca\x82\x94\xf6\x1b\x0c\xa4\x80\xf8\xa4{\xb8\xfc\x90L\xc9" # noqa: E501
-SOL_PACKAGE_ID_3 = b"\xf3\xe4\x00,H\xa7\xf8\xf3H]b\x98\x83\x17\x84\x9c\x17S@\xb6e\x17\xc3\xb2\x99?rVC\xeb\xa8K" # noqa: E501
-SOL_RELEASE_ID_1 = b"s\x83Vh\xf7\x1cz\xe8\\\xbd\xcd\xbbZ\x99\x05\xfaB\x0f\xfe\x85\xa8G\xd2\x83\xfa\x9b\xee\xfc\xd5l\xac\xc4" # noqa: E501
-SOL_RELEASE_ID_2 = b"\xe5\xef\x02\x92\xa3\xb3kj\xc2\xbe\x07\xee\x92\xdfa\xbe\x15\xe0\xb9\xf1\x02\xdf2\xcb\xe3\xf0\xc0\x12\xefi\xd4b" # noqa: E501
-SOL_RELEASE_ID_3 = b"\x12\x80\x14\x8e\n\xf5\xc4~\x95\xb4\x1d\xf1W4\xd0rls \xfcL\xf2\x1e\xfe9#\xfb\x04{S\x89\x9d" # noqa: E501
-SOL_RELEASE_ID_4 = b"p\x82\xe9T\xe4\xfdj\xdf\x8a%\xc6\xce\xfe!\x8f2\xecf\xd8\xa1\x97\x19\x7f\x1d\x05\xaag\xa6\\\xafQ\x11" # noqa: E501
-
-
-logging.basicConfig(stream=sys.stdout, level=logging.INFO, format="%(message)s")
+VY_PACKAGE_ID_1 = to_bytes(hexstr='0xd059e8a6ea5a8bbf8dd097a7b8922316dcb7f024e8220b56d3c9e7188a6a7640') # noqa: E501
+VY_PACKAGE_ID_2 = to_bytes(hexstr='0x6df709a85698ad921462b8979547e3a873e22e1c73b1cb691f9376847fb2d402') # noqa: E501
+VY_PACKAGE_ID_3 = to_bytes(hexstr='0x80e41a42e3b8c3af0ea51c3fd50d481eef1367dd9d3797ba93d35dcf60660882') # noqa: E501
+VY_RELEASE_ID_1 = to_bytes(hexstr='0x595e26f1b2247bacc57e32807f8059e0b0837dd9c47e6946994196bd29c9ca97') # noqa: E501
+VY_RELEASE_ID_2 = to_bytes(hexstr='0x04592cb9ced5413e1b09e87b089bf696a05efb76ee87c8c41259635fac6d938a') # noqa: E501
+VY_RELEASE_ID_3 = to_bytes(hexstr='0xa06dbc51f8891894778ce03dc23d706d228c99789595758bd3dcac3a93f47f0a') # noqa: E501
+VY_RELEASE_ID_4 = to_bytes(hexstr='0x9c6f87dda6435b2506e81206b39ed782a44b92d826c24ab02bbded321b86e2ad') # noqa: E501
+SOL_PACKAGE_ID_1 = to_bytes(hexstr='0x60c5112b61159e6b42d54d945078394e9d5fc9c6ff0f3df78977006f8bbc06d4') # noqa: E501
+SOL_PACKAGE_ID_2 = to_bytes(hexstr='0xdbcfb0bd7115bf659350d77bb22bb889ca8294f61b0ca480f8a47bb8fc904cc9') # noqa: E501
+SOL_PACKAGE_ID_3 = to_bytes(hexstr='0xf3e4002c48a7f8f3485d62988317849c175340b66517c3b2993f725643eba84b') # noqa: E501
+SOL_RELEASE_ID_1 = to_bytes(hexstr='0x73835668f71c7ae85cbdcdbb5a9905fa420ffe85a847d283fa9beefcd56cacc4') # noqa: E501
+SOL_RELEASE_ID_2 = to_bytes(hexstr='0xe5ef0292a3b36b6ac2be07ee92df61be15e0b9f102df32cbe3f0c012ef69d462') # noqa: E501
+SOL_RELEASE_ID_3 = to_bytes(hexstr='0x1280148e0af5c47e95b41df15734d0726c7320fc4cf21efe3923fb047b53899d') # noqa: E501
+SOL_RELEASE_ID_4 = to_bytes(hexstr='0x7082e954e4fd6adf8a25c6cefe218f32ec66d8a197197f1d05aa67a65caf5111') # noqa: E501
def setup_w3():
@@ -61,7 +56,7 @@ def setup_w3():
w3 = Web3(Web3.EthereumTesterProvider(ethereum_tester=t))
w3.eth.defaultAccount = w3.eth.accounts[0]
w3.eth.defaultContractFactory = LinkableContract
- PM.attach(w3, 'pm')
+ w3.enable_unstable_package_management_api()
return w3
diff --git a/tests/core/pm-module/test_ens_integration.py b/tests/core/pm-module/test_ens_integration.py
index 30d7e96ab6..239171f413 100644
--- a/tests/core/pm-module/test_ens_integration.py
+++ b/tests/core/pm-module/test_ens_integration.py
@@ -13,7 +13,6 @@
InvalidAddress,
)
from web3.pm import (
- PM,
VyperReferenceRegistry,
)
@@ -119,19 +118,18 @@ def ens_setup(deployer):
def ens(ens_setup, mocker):
mocker.patch('web3.middleware.stalecheck._isfresh', return_value=True)
ens_setup.web3.eth.defaultAccount = ens_setup.web3.eth.coinbase
+ ens_setup.web3.enable_unstable_package_management_api()
return ens_setup
def test_ens_must_be_set_before_ens_methods_can_be_used(ens):
w3 = ens.web3
- PM.attach(w3, 'pm')
with pytest.raises(InvalidAddress):
w3.pm.set_registry("tester.eth")
def test_web3_ens(ens):
w3 = ens.web3
- PM.attach(w3, 'pm')
ns = ENS.fromWeb3(w3, ens.ens.address)
w3.ens = ns
registry = VyperReferenceRegistry.deploy_new_instance(w3)
diff --git a/tests/core/pm-module/test_registry_integration.py b/tests/core/pm-module/test_registry_integration.py
index cf7ced9114..20d9ff8903 100644
--- a/tests/core/pm-module/test_registry_integration.py
+++ b/tests/core/pm-module/test_registry_integration.py
@@ -16,7 +16,6 @@
PMError,
)
from web3.pm import (
- PM,
ERCRegistry,
VyperReferenceRegistry,
get_vyper_registry_manifest,
@@ -28,7 +27,7 @@ def fresh_w3():
w3 = Web3(Web3.EthereumTesterProvider())
w3.eth.defaultAccount = w3.eth.accounts[0]
w3.eth.defaultContractFactory = LinkableContract
- PM.attach(w3, "pm")
+ w3.enable_unstable_package_management_api()
return w3
diff --git a/web3/main.py b/web3/main.py
index 4c3290053e..8bc95d9e94 100644
--- a/web3/main.py
+++ b/web3/main.py
@@ -206,3 +206,18 @@ def ens(self):
@ens.setter
def ens(self, new_ens):
self._ens = new_ens
+
+ @property
+ def pm(self):
+ if self._pm is not None:
+ return self._pm
+ else:
+ raise AttributeError(
+ "The Package Management feature is disabled by default until "
+ "its API stabilizes. To use these features, please enable them by running "
+ "`w3.enable_unstable_package_management_api()` and try again."
+ )
+
+ def enable_unstable_package_management_api(self):
+ from web3.pm import PM
+ PM.attach(self, '_pm')