Skip to content

Commit

Permalink
refactor: separate CORE_PLUGINS from setup.py
Browse files Browse the repository at this point in the history
  • Loading branch information
antazoey committed Apr 24, 2024
1 parent 2cd6f78 commit 1ae53e2
Show file tree
Hide file tree
Showing 9 changed files with 60 additions and 67 deletions.
21 changes: 11 additions & 10 deletions setup.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
#!/usr/bin/env python
import re
from pathlib import Path
from typing import Dict

from setuptools import find_packages, setup

here = Path(__file__).parent.absolute()
packages_data: Dict = {}
with open(here / "src" / "ape" / "__modules__.py", encoding="utf8") as modules_file:
exec(modules_file.read(), packages_data)
_HERE = Path(__file__).parent.absolute()
_CORE_PLUGIN_PATTERN = re.compile(r"\bape_\w+(?!\S)")
_PACKAGES = find_packages("src")
_MODULES = {p for p in _PACKAGES if re.match(_CORE_PLUGIN_PATTERN, p)}
_MODULES.add("ape")

extras_require = {
"test": [ # `test` GitHub Action jobs uses this
Expand Down Expand Up @@ -52,15 +53,15 @@
],
"dev": [
# commitizen: Manage commits and publishing releases
(here / "cz-requirement.txt").read_text().strip(),
(_HERE / "cz-requirement.txt").read_text().strip(),
"pre-commit", # Ensure that linters are run prior to committing
"pytest-watch", # `ptw` test watcher/runner
"ipdb", # Debugger (Must use `export PYTHONBREAKPOINT=ipdb.set_trace`)
],
# NOTE: These are extras that someone can install to get up and running quickly w/ ape
# They should be kept up to date with what works and what doesn't out of the box
# Usage example: `pipx install eth-ape[recommended-plugins]`
"recommended-plugins": (here / "recommended-plugins.txt").read_text().splitlines(),
"recommended-plugins": (_HERE / "recommended-plugins.txt").read_text().splitlines(),
}

# NOTE: `pip install -e .[dev]` to install package
Expand Down Expand Up @@ -149,13 +150,13 @@
},
python_requires=">=3.9,<4",
extras_require=extras_require,
py_modules=packages_data["__modules__"],
py_modules=list(_MODULES),
license="Apache-2.0",
zip_safe=False,
keywords="ethereum",
packages=find_packages("src"),
packages=_PACKAGES,
package_dir={"": "src"},
package_data={p: ["py.typed"] for p in packages_data["__modules__"]},
package_data={p: ["py.typed"] for p in _MODULES},
classifiers=[
"Development Status :: 5 - Production/Stable",
"Intended Audience :: Developers",
Expand Down
15 changes: 0 additions & 15 deletions src/ape/__modules__.py

This file was deleted.

23 changes: 23 additions & 0 deletions src/ape/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -643,6 +643,29 @@ def __init__(
super().__init__(provider, *args, **kwargs)


class PluginInstallError(ApeException):
"""
An error to use when installing a plugin fails.
"""


class PluginVersionError(PluginInstallError):
"""
An error related to specified plugin version.
"""

def __init__(
self, operation: str, reason: Optional[str] = None, resolution: Optional[str] = None
):
message = f"Unable to {operation} plugin."
if reason:
message = f"{message}\nReason: {reason}"
if resolution:
message = f"{message}\nTo resolve: {resolution}"

super().__init__(message)


def handle_ape_exception(err: ApeException, base_paths: list[Path]) -> bool:
"""
Handle a transaction error by showing relevant stack frames,
Expand Down
20 changes: 10 additions & 10 deletions src/ape/managers/plugins.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,9 @@
from importlib.metadata import distributions
from typing import Any, Generator, Iterator, List, Optional, Set, Tuple

from ape.__modules__ import __modules__
from ape.exceptions import ApeAttributeError
from ape.logging import logger
from ape.plugins._utils import clean_plugin_name
from ape.plugins._utils import CORE_PLUGINS, clean_plugin_name
from ape.plugins.pluggy_patch import plugin_manager as pluggy_manager
from ape.utils.basemodel import _assert_not_ipython_check
from ape.utils.misc import log_instead_of_fail
Expand Down Expand Up @@ -82,20 +81,21 @@ def _register_plugins(self):
if self.__registered:
return

plugins = [
x.name.replace("-", "_")
for x in distributions()
if getattr(x, "name", "").startswith("ape-")
]
locals = [p for p in __modules__ if p != "ape"]
plugin_modules = tuple([*plugins, *locals])
plugins: list[str] = []
for dist in distributions():
if not (name := getattr(dist, "name", "")):
continue
elif name.startswith("ape-"):
plugins.append(name.replace("-", "_"))

plugin_modules = tuple([*plugins, *CORE_PLUGINS])

for module_name in plugin_modules:
try:
module = importlib.import_module(module_name)
pluggy_manager.register(module)
except Exception as err:
if module_name in __modules__:
if module_name in CORE_PLUGINS:
# Always raise core plugin registration errors.
raise

Expand Down
15 changes: 12 additions & 3 deletions src/ape/plugins/_utils.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import re
import sys
from enum import Enum
from functools import cached_property
from pathlib import Path
from shutil import which
from typing import Any, Dict, Iterable, Iterator, List, Optional, Sequence, Tuple

Expand All @@ -9,19 +11,26 @@
from packaging.version import Version
from pydantic import field_validator, model_validator

from ape.__modules__ import __modules__
from ape.exceptions import PluginVersionError
from ape.logging import logger
from ape.utils import BaseInterfaceModel, get_package_version, log_instead_of_fail
from ape.utils._github import github_client
from ape.utils.basemodel import BaseModel
from ape.utils.misc import _get_distributions
from ape.version import version as ape_version_str
from ape_plugins.exceptions import PluginVersionError

# Plugins maintained OSS by ApeWorX (and trusted)
CORE_PLUGINS = {p for p in __modules__ if p != "ape"}
# Use `uv pip` if installed, otherwise `python -m pip`
PIP_COMMAND = ["uv", "pip"] if which("uv") else [sys.executable, "-m", "pip"]
PLUGIN_PATTERN = re.compile(r"\bape_\w+(?!\S)")
CORE_PLUGINS = [
"ape",
*[
f.name
for f in Path(__file__).parent.parent.parent.iterdir()
if f.name.startswith("ape_") and f.is_dir() and re.match(PLUGIN_PATTERN, f.name)
],
]


def clean_plugin_name(name: str) -> str:
Expand Down
26 changes: 0 additions & 26 deletions src/ape_plugins/exceptions.py

This file was deleted.

2 changes: 1 addition & 1 deletion tests/functional/test_plugins.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

import pytest

from ape.exceptions import PluginVersionError
from ape.logging import LogLevel
from ape.plugins._utils import (
ApePluginsRepr,
Expand All @@ -13,7 +14,6 @@
PluginType,
ape_version,
)
from ape_plugins.exceptions import PluginVersionError

CORE_PLUGINS = ("run",)
AVAILABLE_PLUGINS = ("available", "installed")
Expand Down
3 changes: 2 additions & 1 deletion tests/functional/test_trace.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,8 @@ def test_get_gas_report_transfer(gas_tracker, sender, receiver):


def test_transaction_trace_create(vyper_contract_instance):
trace = TransactionTrace(transaction_hash=vyper_contract_instance.creation_metadata.txn_hash)
tx_hash = vyper_contract_instance.creation_metadata.txn_hash
trace = TransactionTrace(transaction_hash=tx_hash)
actual = f"{trace}"
expected = r"VyperContract\.__new__\(num=0\) \[\d+ gas\]"
assert re.match(expected, actual)
Expand Down
2 changes: 1 addition & 1 deletion tests/integration/cli/test_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -386,7 +386,7 @@ def test_fails():
pytester.makepyfile(test)
stdin = "print(foo)\nexit\n"
monkeypatch.setattr("sys.stdin", io.StringIO(stdin))
result = pytester.runpytest_subprocess("--interactive", "-s")
result = pytester.runpytest("--interactive", "-s")
result.assert_outcomes(failed=1)
actual = str(result.stdout)
assert secret in actual
Expand Down

0 comments on commit 1ae53e2

Please sign in to comment.