Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: new wait for idle #1219

Closed
wants to merge 8 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions .github/workflows/test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,9 @@ jobs:
- "3.4/stable"
- "3.5/stable"
- "3.6/stable"
new_wait_for_idle:
- "True"
- "False"
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
Expand Down Expand Up @@ -116,7 +119,9 @@ jobs:
# # set model defaults
# juju model-defaults apt-http-proxy=$PROXY apt-https-proxy=$PROXY juju-http-proxy=$PROXY juju-https-proxy=$PROXY snap-http-proxy=$PROXY snap-https-proxy=$PROXY
# juju model-defaults
- run: uvx -p ${{ matrix.python }} tox -e integration
- run: uvx -p ${{ matrix.python }} tox -s -e integration
env:
JUJU_NEW_WAIT_FOR_IDLE: ${{ matrix.new_wait_for_idle }}

integration-quarantine:
name: Quarantined Integration Tests
Expand Down Expand Up @@ -144,4 +149,4 @@ jobs:
with:
provider: lxd
juju-channel: ${{ matrix.juju }}
- run: uvx -p ${{ matrix.python }} tox -e integration-quarantine
- run: uvx -p ${{ matrix.python }} tox -s -e integration-quarantine
72 changes: 45 additions & 27 deletions juju/client/facade.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
from collections import defaultdict
from glob import glob
from pathlib import Path
from typing import Any, Mapping, Sequence
from typing import Any, Mapping, Sequence, TypeVar, overload

import packaging.version
import typing_inspect
Expand Down Expand Up @@ -183,7 +183,7 @@ def ref_type(self, obj):
return self.get_ref_type(obj["$ref"])


CLASSES = {}
CLASSES: dict[str, type[Type]] = {}
factories = codegen.Capture()


Expand Down Expand Up @@ -479,37 +479,52 @@ def ReturnMapping(cls): # noqa: N802
def decorator(f):
@functools.wraps(f)
async def wrapper(*args, **kwargs):
nonlocal cls
reply = await f(*args, **kwargs)
if cls is None:
return reply
if "error" in reply:
cls = CLASSES["Error"]
if typing_inspect.is_generic_type(cls) and issubclass(
typing_inspect.get_origin(cls), Sequence
):
parameters = typing_inspect.get_parameters(cls)
result = []
item_cls = parameters[0]
for item in reply:
result.append(item_cls.from_json(item))
"""
if 'error' in item:
cls = CLASSES['Error']
else:
cls = item_cls
result.append(cls.from_json(item))
"""
else:
result = cls.from_json(reply["response"])

return result
return _convert_response(reply, cls=cls)

return wrapper

return decorator


@overload
def _convert_response(response: dict[str, Any], *, cls: type[SomeType]) -> SomeType: ...


@overload
def _convert_response(response: dict[str, Any], *, cls: None) -> dict[str, Any]: ...


def _convert_response(response: dict[str, Any], *, cls: type[Type] | None) -> Any:
dimaqq marked this conversation as resolved.
Show resolved Hide resolved
if cls is None:
return response
if "error" in response:
# TODO: I don't think this ever happens,
# errors are handled by Connection.rpc(),
# though, admittedly the shape is different.
cls = CLASSES["Error"]
if typing_inspect.is_generic_type(cls) and issubclass(
typing_inspect.get_origin(cls), Sequence
):
# TODO: I'm not sure this ever happens either.
parameters = typing_inspect.get_parameters(cls)
result = []
item_cls = parameters[0]
for item in response:
result.append(item_cls.from_json(item))
"""
if 'error' in item:
cls = CLASSES['Error']
else:
cls = item_cls
result.append(cls.from_json(item))
"""
else:
result = cls.from_json(response["response"])

return result


def make_func(cls, name, description, params, result, _async=True):
indent = " "
args = Args(cls.schema, params)
Expand Down Expand Up @@ -663,7 +678,7 @@ async def rpc(self, msg: dict[str, _RichJson]) -> _Json:
return result

@classmethod
def from_json(cls, data):
def from_json(cls, data: Type | str | dict[str, Any] | list[Any]) -> Type | None:
def _parse_nested_list_entry(expr, result_dict):
if isinstance(expr, str):
if ">" in expr or ">=" in expr:
Expand Down Expand Up @@ -742,6 +757,9 @@ def get(self, key, default=None):
return getattr(self, attr, default)


SomeType = TypeVar("SomeType", bound=Type)


class Schema(dict):
def __init__(self, schema):
self.name = schema["Name"]
Expand Down
Loading
Loading