Skip to content

Commit

Permalink
chore: add compatibility with the next ops release (#178)
Browse files Browse the repository at this point in the history
The next release of ops has some backwards-incompatible changes to
private methods. This PR does the minimum to keep Scenario working with
the current version of ops and the next release.

I'll open a ticket for doing a nicer version of this where the new
`_JujuContext` class is used (which would presumably mean requiring the
new version of ops). But this will let people continue upgrading their
ops as long as they're using the latest 6.x of Scenario.

The relevant ops PR is: canonical/operator#1313
  • Loading branch information
tonyandrewmeyer authored Aug 26, 2024
1 parent 602f9b9 commit 91fef2a
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 4 deletions.
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ build-backend = "setuptools.build_meta"
[project]
name = "ops-scenario"

version = "6.1.5"
version = "6.1.6"

authors = [
{ name = "Pietro Pasotti", email = "[email protected]" }
Expand Down
37 changes: 34 additions & 3 deletions scenario/ops_main_mock.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
# See LICENSE file for licensing details.
import inspect
import os
import pathlib
import sys
from typing import TYPE_CHECKING, Any, Optional, Sequence, cast

Expand All @@ -15,7 +16,7 @@
from ops.log import setup_root_logging

# use logger from ops.main so that juju_log will be triggered
from ops.main import CHARM_STATE_FILE, _Dispatcher, _get_charm_dir, _get_event_args
from ops.main import CHARM_STATE_FILE, _Dispatcher, _get_event_args
from ops.main import logger as ops_logger

if TYPE_CHECKING: # pragma: no cover
Expand All @@ -33,6 +34,17 @@ class BadOwnerPath(RuntimeError):
"""Error raised when the owner path does not lead to a valid ObjectEvents instance."""


# TODO: Use ops.jujucontext's _JujuContext.charm_dir.
def _get_charm_dir():
charm_dir = os.environ.get("JUJU_CHARM_DIR")
if charm_dir is None:
# Assume $JUJU_CHARM_DIR/lib/op/main.py structure.
charm_dir = pathlib.Path(f"{__file__}/../../..").resolve()
else:
charm_dir = pathlib.Path(charm_dir).resolve()
return charm_dir


def _get_owner(root: Any, path: Sequence[str]) -> ops.ObjectEvents:
"""Walk path on root to an ObjectEvents instance."""
obj = root
Expand Down Expand Up @@ -75,7 +87,17 @@ def _emit_charm_event(
f"Use Context.run_custom instead.",
)

args, kwargs = _get_event_args(charm, event_to_emit)
try:
args, kwargs = _get_event_args(charm, event_to_emit)
except TypeError:
# ops 2.16+
import ops.jujucontext # type: ignore

args, kwargs = _get_event_args(
charm,
event_to_emit,
ops.jujucontext._JujuContext.from_dict(os.environ), # type: ignore
)
ops_logger.debug("Emitting Juju event %s.", event_name)
event_to_emit.emit(*args, **kwargs)

Expand Down Expand Up @@ -159,7 +181,16 @@ def setup(state: "State", event: "Event", context: "Context", charm_spec: "_Char
charm_class = charm_spec.charm_type
charm_dir = _get_charm_dir()

dispatcher = _Dispatcher(charm_dir)
try:
dispatcher = _Dispatcher(charm_dir)
except TypeError:
# ops 2.16+
import ops.jujucontext # type: ignore

dispatcher = _Dispatcher(
charm_dir,
ops.jujucontext._JujuContext.from_dict(os.environ), # type: ignore
)
dispatcher.run_any_legacy_hook()

framework = setup_framework(charm_dir, state, event, context, charm_spec)
Expand Down

0 comments on commit 91fef2a

Please sign in to comment.