mm-web3 0.5.1__tar.gz → 0.5.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- mm_web3-0.5.3/.claude/settings.local.json +10 -0
- mm_web3-0.5.3/PKG-INFO +9 -0
- {mm_web3-0.5.1 → mm_web3-0.5.3}/justfile +2 -2
- {mm_web3-0.5.1 → mm_web3-0.5.3}/pyproject.toml +16 -16
- {mm_web3-0.5.1 → mm_web3-0.5.3}/src/mm_web3/retry.py +2 -2
- {mm_web3-0.5.1 → mm_web3-0.5.3}/tests/test_account.py +7 -5
- {mm_web3-0.5.1 → mm_web3-0.5.3}/tests/test_calcs.py +3 -3
- {mm_web3-0.5.1 → mm_web3-0.5.3}/tests/test_config.py +1 -2
- {mm_web3-0.5.1 → mm_web3-0.5.3}/tests/test_validators.py +1 -2
- mm_web3-0.5.3/uv.lock +1689 -0
- mm_web3-0.5.1/PKG-INFO +0 -9
- mm_web3-0.5.1/dict.dic +0 -0
- mm_web3-0.5.1/uv.lock +0 -1414
- {mm_web3-0.5.1 → mm_web3-0.5.3}/.gitignore +0 -0
- {mm_web3-0.5.1 → mm_web3-0.5.3}/.pre-commit-config.yaml +0 -0
- {mm_web3-0.5.1 → mm_web3-0.5.3}/README.md +0 -0
- {mm_web3-0.5.1 → mm_web3-0.5.3}/src/mm_web3/__init__.py +0 -0
- {mm_web3-0.5.1 → mm_web3-0.5.3}/src/mm_web3/account.py +0 -0
- {mm_web3-0.5.1 → mm_web3-0.5.3}/src/mm_web3/calcs.py +0 -0
- {mm_web3-0.5.1 → mm_web3-0.5.3}/src/mm_web3/config.py +0 -0
- {mm_web3-0.5.1 → mm_web3-0.5.3}/src/mm_web3/log.py +0 -0
- {mm_web3-0.5.1 → mm_web3-0.5.3}/src/mm_web3/network.py +0 -0
- {mm_web3-0.5.1 → mm_web3-0.5.3}/src/mm_web3/node.py +0 -0
- {mm_web3-0.5.1 → mm_web3-0.5.3}/src/mm_web3/proxy.py +0 -0
- {mm_web3-0.5.1 → mm_web3-0.5.3}/src/mm_web3/py.typed +0 -0
- {mm_web3-0.5.1 → mm_web3-0.5.3}/src/mm_web3/utils.py +0 -0
- {mm_web3-0.5.1 → mm_web3-0.5.3}/src/mm_web3/validators.py +0 -0
- {mm_web3-0.5.1 → mm_web3-0.5.3}/tests/__init__.py +0 -0
- {mm_web3-0.5.1 → mm_web3-0.5.3}/tests/common.py +0 -0
- {mm_web3-0.5.1 → mm_web3-0.5.3}/tests/test_network.py +0 -0
- {mm_web3-0.5.1 → mm_web3-0.5.3}/tests/test_node.py +0 -0
- {mm_web3-0.5.1 → mm_web3-0.5.3}/tests/test_proxy.py +0 -0
- {mm_web3-0.5.1 → mm_web3-0.5.3}/tests/test_retry.py +0 -0
- {mm_web3-0.5.1 → mm_web3-0.5.3}/tests/test_utils.py +0 -0
mm_web3-0.5.3/PKG-INFO
ADDED
|
@@ -1,33 +1,33 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "mm-web3"
|
|
3
|
-
version = "0.5.
|
|
3
|
+
version = "0.5.3"
|
|
4
4
|
description = ""
|
|
5
5
|
requires-python = ">=3.13"
|
|
6
6
|
dependencies = [
|
|
7
|
-
"mm-std~=0.5.
|
|
8
|
-
"mm-http~=0.1
|
|
9
|
-
"mm-print~=0.
|
|
7
|
+
"mm-std~=0.5.4",
|
|
8
|
+
"mm-http~=0.2.1",
|
|
9
|
+
"mm-print~=0.2.0",
|
|
10
10
|
"loguru>=0.7.3",
|
|
11
|
-
"pydantic
|
|
11
|
+
"pydantic~=2.12.3",
|
|
12
12
|
]
|
|
13
13
|
|
|
14
14
|
[build-system]
|
|
15
15
|
requires = ["hatchling"]
|
|
16
16
|
build-backend = "hatchling.build"
|
|
17
17
|
|
|
18
|
-
[
|
|
19
|
-
dev
|
|
20
|
-
"pytest~=8.4.
|
|
21
|
-
"pytest-asyncio~=1.
|
|
22
|
-
"pytest-xdist~=3.
|
|
18
|
+
[dependency-groups]
|
|
19
|
+
dev = [
|
|
20
|
+
"pytest~=8.4.1",
|
|
21
|
+
"pytest-asyncio~=1.2.0",
|
|
22
|
+
"pytest-xdist~=3.8.0",
|
|
23
23
|
"pytest-httpserver~=1.1.3",
|
|
24
|
-
"ruff~=0.
|
|
25
|
-
"mypy~=1.
|
|
24
|
+
"ruff~=0.14.2",
|
|
25
|
+
"mypy~=1.18.2",
|
|
26
26
|
"pip-audit~=2.9.0",
|
|
27
|
-
"bandit~=1.8.
|
|
28
|
-
"pre-commit~=4.
|
|
29
|
-
"python-dotenv~=1.1
|
|
30
|
-
"eth-account
|
|
27
|
+
"bandit~=1.8.6",
|
|
28
|
+
"pre-commit~=4.3.0",
|
|
29
|
+
"python-dotenv~=1.2.1",
|
|
30
|
+
"eth-account~=0.13.7",
|
|
31
31
|
]
|
|
32
32
|
|
|
33
33
|
[tool.mypy]
|
|
@@ -15,7 +15,7 @@ FuncWithNodeAndProxy = Callable[[str, str | None], Awaitable[Result[T]]]
|
|
|
15
15
|
FuncWithProxy = Callable[[str | None], Awaitable[Result[T]]]
|
|
16
16
|
|
|
17
17
|
|
|
18
|
-
async def retry_with_node_and_proxy(retries: int, nodes: Nodes, proxies: Proxies, func: FuncWithNodeAndProxy[T]) -> Result[T]:
|
|
18
|
+
async def retry_with_node_and_proxy[T](retries: int, nodes: Nodes, proxies: Proxies, func: FuncWithNodeAndProxy[T]) -> Result[T]:
|
|
19
19
|
"""
|
|
20
20
|
Retry the given function multiple times with random node and proxy on each attempt.
|
|
21
21
|
|
|
@@ -42,7 +42,7 @@ async def retry_with_node_and_proxy(retries: int, nodes: Nodes, proxies: Proxies
|
|
|
42
42
|
return Result.err(res.unwrap_err(), {"retry_logs": logs})
|
|
43
43
|
|
|
44
44
|
|
|
45
|
-
async def retry_with_proxy(retries: int, proxies: Proxies, func: FuncWithProxy[T]) -> Result[T]:
|
|
45
|
+
async def retry_with_proxy[T](retries: int, proxies: Proxies, func: FuncWithProxy[T]) -> Result[T]:
|
|
46
46
|
"""
|
|
47
47
|
Retry the given function multiple times using a random proxy on each attempt.
|
|
48
48
|
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
from pathlib import Path
|
|
2
|
+
from typing import cast
|
|
2
3
|
|
|
3
4
|
import pytest
|
|
5
|
+
from pydantic import ValidationInfo
|
|
4
6
|
|
|
5
7
|
from mm_web3.account import PrivateKeyMap
|
|
6
8
|
|
|
@@ -40,13 +42,13 @@ class TestPrivateKeyMapValidation:
|
|
|
40
42
|
def test_validate_existing_privatekeymap(self) -> None:
|
|
41
43
|
"""Test that existing PrivateKeyMap passes validation."""
|
|
42
44
|
original = PrivateKeyMap(TEST_ETH_PRIVATE_KEYS)
|
|
43
|
-
validated = PrivateKeyMap.validate(original, None)
|
|
45
|
+
validated = PrivateKeyMap.validate(original, cast(ValidationInfo, None))
|
|
44
46
|
assert validated is original
|
|
45
47
|
|
|
46
48
|
def test_validate_dict_with_strings(self) -> None:
|
|
47
49
|
"""Test validation of dict with string keys and values."""
|
|
48
50
|
test_dict = {"addr1": "key1", "addr2": "key2"}
|
|
49
|
-
result = PrivateKeyMap.validate(test_dict, None)
|
|
51
|
+
result = PrivateKeyMap.validate(test_dict, cast(ValidationInfo, None))
|
|
50
52
|
assert isinstance(result, PrivateKeyMap)
|
|
51
53
|
assert result == test_dict
|
|
52
54
|
|
|
@@ -54,18 +56,18 @@ class TestPrivateKeyMapValidation:
|
|
|
54
56
|
"""Test validation fails with non-string keys."""
|
|
55
57
|
test_dict = {123: "key1", "addr2": "key2"}
|
|
56
58
|
with pytest.raises(TypeError, match="All keys in PrivateKeyMap must be strings"):
|
|
57
|
-
PrivateKeyMap.validate(test_dict, None)
|
|
59
|
+
PrivateKeyMap.validate(test_dict, cast(ValidationInfo, None))
|
|
58
60
|
|
|
59
61
|
def test_validate_dict_with_non_string_values(self) -> None:
|
|
60
62
|
"""Test validation fails with non-string values."""
|
|
61
63
|
test_dict = {"addr1": 123, "addr2": "key2"}
|
|
62
64
|
with pytest.raises(TypeError, match="All values in PrivateKeyMap must be strings"):
|
|
63
|
-
PrivateKeyMap.validate(test_dict, None)
|
|
65
|
+
PrivateKeyMap.validate(test_dict, cast(ValidationInfo, None))
|
|
64
66
|
|
|
65
67
|
def test_validate_invalid_type(self) -> None:
|
|
66
68
|
"""Test validation fails with invalid type."""
|
|
67
69
|
with pytest.raises(TypeError, match="Invalid type for PrivateKeyMap"):
|
|
68
|
-
PrivateKeyMap.validate("invalid", None)
|
|
70
|
+
PrivateKeyMap.validate("invalid", cast(ValidationInfo, None))
|
|
69
71
|
|
|
70
72
|
|
|
71
73
|
class TestPrivateKeyMapFromList:
|
|
@@ -17,7 +17,7 @@ class TestCalcDecimalExpression:
|
|
|
17
17
|
def test_plain_numbers(self) -> None:
|
|
18
18
|
assert calc_decimal_expression("123.45") == Decimal("123.45")
|
|
19
19
|
assert calc_decimal_expression("-0.5") == Decimal("-0.5")
|
|
20
|
-
assert calc_decimal_expression("0") == Decimal(
|
|
20
|
+
assert calc_decimal_expression("0") == Decimal(0)
|
|
21
21
|
assert calc_decimal_expression(" 100.0 ") == Decimal("100.0")
|
|
22
22
|
|
|
23
23
|
@patch("mm_web3.calcs.random_decimal")
|
|
@@ -32,7 +32,7 @@ class TestCalcDecimalExpression:
|
|
|
32
32
|
mock_random.return_value = Decimal("2.5")
|
|
33
33
|
result = calc_decimal_expression("RANDOM(1, 5)")
|
|
34
34
|
assert result == Decimal("2.5")
|
|
35
|
-
mock_random.assert_called_once_with(Decimal(
|
|
35
|
+
mock_random.assert_called_once_with(Decimal(1), Decimal(5))
|
|
36
36
|
|
|
37
37
|
def test_random_function_invalid_args(self) -> None:
|
|
38
38
|
with pytest.raises(ValueError, match="wrong expression, random part"):
|
|
@@ -250,5 +250,5 @@ class TestSplitOnPlusMinusTokens:
|
|
|
250
250
|
with pytest.raises(ValueError, match="ends with -"):
|
|
251
251
|
_split_on_plus_minus_tokens("100-")
|
|
252
252
|
|
|
253
|
-
with pytest.raises(ValueError, match="ends with
|
|
253
|
+
with pytest.raises(ValueError, match=r"ends with \+"):
|
|
254
254
|
_split_on_plus_minus_tokens("100+")
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import asyncio
|
|
1
2
|
import tempfile
|
|
2
3
|
import zipfile
|
|
3
4
|
from pathlib import Path
|
|
@@ -154,8 +155,6 @@ url = "https://example.com"
|
|
|
154
155
|
result = await AsyncValidatorConfig.read_toml_config_async(missing_file)
|
|
155
156
|
assert result.is_err()
|
|
156
157
|
|
|
157
|
-
import asyncio
|
|
158
|
-
|
|
159
158
|
asyncio.run(test_async_methods())
|
|
160
159
|
|
|
161
160
|
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
from pathlib import Path
|
|
2
|
+
from unittest.mock import patch
|
|
2
3
|
|
|
3
4
|
import pytest
|
|
4
5
|
|
|
@@ -189,8 +190,6 @@ class TestConfigValidatorsLogFile:
|
|
|
189
190
|
|
|
190
191
|
def test_log_file_tilde_expansion(self, tmp_path: Path) -> None:
|
|
191
192
|
"""Test log file validator expands tilde in path."""
|
|
192
|
-
from unittest.mock import patch
|
|
193
|
-
|
|
194
193
|
validator = ConfigValidators.log_file()
|
|
195
194
|
|
|
196
195
|
test_path = tmp_path / "test.log"
|