Repository: ethereum/web3.py (language: python)

Issue:
Remove dependence on eth-utils `ValidationError` for `Web3ValidationError`
All *web3.py* exceptions extend from `Web3Exception`. This will suffice for fine-tuning all exceptions raised within *web3.py*. 

The current approach to the tooling libraries is to internalize all exceptions as internal exception classes to each library, e.g. `Web3Exception`, `ENSException`, `PyGethException`, etc...

One day, if all libraries are caught up, perhaps it will make sense to inherit all of them from *eth-utils* base exception classes for better control over exception handling. For now, let's remove any ambiguity about how they should behave by removing this inheritance from `Web3ValidationError`.

### Tasks

- [ ] Remove ``ValidationError`` from ``Web3ValidationError`` inherited classes [here](https://github.com/ethereum/web3.py/blob/main/web3/exceptions.py#L188).
- [ ] Update the migration guide to reflect this breaking change.


Discussion / hints:

Fix patch:
diff --git a/ens/exceptions.py b/ens/exceptions.py
index ae471845b7..d49801a62f 100644
--- a/ens/exceptions.py
+++ b/ens/exceptions.py
@@ -1,6 +1,3 @@
-from eth_utils import (
-    ValidationError,
-)
 import idna
 
 
@@ -104,8 +101,7 @@ class UnderfundedBid(ENSException):
     """
 
 
-# type ignored because subclassing ValidationError which has type Any
-class ENSValidationError(ENSException, ValidationError):  # type: ignore[misc]
+class ENSValidationError(ENSException):
     """
     Raised if there is a validation error
     """
diff --git a/newsfragments/3443.breaking.rst b/newsfragments/3443.breaking.rst
new file mode 100644
index 0000000000..2ae5595531
--- /dev/null
+++ b/newsfragments/3443.breaking.rst
@@ -0,0 +1,1 @@
+Remove ``Web3ValidationError`` dependence / inheritance from `eth-utils` ``ValidationError``.
diff --git a/web3/exceptions.py b/web3/exceptions.py
index 6b62b7fd2a..653bada2ef 100644
--- a/web3/exceptions.py
+++ b/web3/exceptions.py
@@ -8,10 +8,6 @@
     Union,
 )
 
-from eth_utils import (
-    ValidationError,
-)
-
 from web3.types import (
     BlockData,
     RPCResponse,
@@ -184,8 +180,7 @@ class FallbackNotFound(Web3Exception):
     """
 
 
-# type ignored because subclassing ValidationError which has type Any
-class Web3ValidationError(Web3Exception, ValidationError):  # type: ignore[misc]
+class Web3ValidationError(Web3Exception):
     """
     Raised when a supplied value is invalid.
     """


Test patch:
diff --git a/tests/core/method-class/test_method.py b/tests/core/method-class/test_method.py
index 07c82fd6fb..99530c4a9e 100644
--- a/tests/core/method-class/test_method.py
+++ b/tests/core/method-class/test_method.py
@@ -3,9 +3,6 @@
 )
 import pytest
 
-from eth_utils import (
-    ValidationError,
-)
 from eth_utils.toolz import (
     compose,
 )
@@ -15,6 +12,7 @@
     Web3,
 )
 from web3.exceptions import (
+    Web3ValidationError,
     Web3ValueError,
 )
 from web3.method import (
@@ -160,13 +158,13 @@ def test_empty_mungers_for_property_with_no_input_parameters(empty):
     assert method.input_munger(object(), [], {}) == ()
 
 
-def test_default_munger_for_property_with_input_parameters_raises_ValidationError():
+def test_default_munger_for_property_with_input_params_raises_validation_error():
     method = Method(
         is_property=True,
         json_rpc_method="eth_method",
     )
     with pytest.raises(
-        ValidationError, match="Parameters cannot be passed to a property"
+        Web3ValidationError, match="Parameters cannot be passed to a property"
     ):
         method.input_munger(object(), [1], {})
 
@@ -174,20 +172,22 @@ def test_default_munger_for_property_with_input_parameters_raises_ValidationErro
 @pytest.mark.parametrize(
     "empty", ([], (), None), ids=["empty-list", "empty-tuple", "None"]
 )
-def test_empty_mungers_for_property_with_input_parameters_raises_ValidationError(empty):
+def test_empty_mungers_for_property_with_input_params_raises_validation_error(empty):
     method = Method(
         is_property=True,
         mungers=empty,
         json_rpc_method="eth_method",
     )
     with pytest.raises(
-        ValidationError, match="Parameters cannot be passed to a property"
+        Web3ValidationError, match="Parameters cannot be passed to a property"
     ):
         method.input_munger(object(), [1], {})
 
 
-def test_property_with_mungers_raises_ValidationError():
-    with pytest.raises(ValidationError, match="Mungers cannot be used with a property"):
+def test_property_with_mungers_raises_validation_error():
+    with pytest.raises(
+        Web3ValidationError, match="Mungers cannot be used with a property"
+    ):
         Method(
             is_property=True,
             mungers=[lambda m, z, y: "success"],