Skip to content

Commit

Permalink
chore: refactor jrpc response type coercion for testing
Browse files Browse the repository at this point in the history
  • Loading branch information
dimaqq committed Oct 2, 2024
1 parent 0e2513b commit 2269934
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 22 deletions.
59 changes: 37 additions & 22 deletions juju/client/facade.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# Copyright 2023 Canonical Ltd.
# Licensed under the Apache V2, see LICENCE file for details.
from __future__ import annotations

import argparse
import builtins
Expand All @@ -13,7 +14,7 @@
from collections import defaultdict
from glob import glob
from pathlib import Path
from typing import Any, Mapping, Sequence, TypeVar
from typing import overload, Any, Dict, Mapping, Optional, Sequence, TypeVar, Type as TypingType

import typing_inspect

Expand Down Expand Up @@ -482,31 +483,42 @@ def ReturnMapping(cls):
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:
return _convert_response(reply, cls=cls)
return wrapper
return decorator


@overload
def _convert_response(response: Dict, *, cls: TypingType[SomeType]) -> SomeType: ...


@overload
def _convert_response(response: Dict, *, cls: None) -> Dict: ...


def _convert_response(response: dict, *, cls: Optional[TypingType[Type]]):
if cls is None:
return response
if 'error' in response:
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 response:
result.append(item_cls.from_json(item))
"""
if 'error' in item:
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'])
cls = item_cls
result.append(cls.from_json(item))
"""
else:
result = cls.from_json(response['response'])

return result
return wrapper
return decorator
return result


def makeFunc(cls, name, description, params, result, _async=True):
Expand Down Expand Up @@ -737,6 +749,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
9 changes: 9 additions & 0 deletions juju/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -2849,6 +2849,15 @@ async def _get_source_api(self, url):
await controller.connect(controller_name=controller_name)
return controller

# FIXME scraped from charm collection
# apps
# - most common: [explicit, list, of, apps]
# - rare: implicit None
# status
# - common implicit None
# - common "active"
# - rare "blocked"
# - very rare "unknown"
async def wait_for_idle(self,
apps: Optional[List[str]] = None,
raise_on_error=True,
Expand Down

0 comments on commit 2269934

Please sign in to comment.