X-Git-Url: https://osm.etsi.org/gitweb/?p=osm%2FN2VC.git;a=blobdiff_plain;f=modules%2Flibjuju%2Fjuju%2Fclient%2Ffacade.py;h=9e2aabf62c31437fe86e70abe2034a36334468ce;hp=c959e01649964a9a5eb955e2fc0829ebabfcc90f;hb=29ad6453fb8cdece73b8c2f623cf81d5d730982d;hpb=68858c1915122c2dbc8999a5cd3229694abf5f3a diff --git a/modules/libjuju/juju/client/facade.py b/modules/libjuju/juju/client/facade.py index c959e01..9e2aabf 100644 --- a/modules/libjuju/juju/client/facade.py +++ b/modules/libjuju/juju/client/facade.py @@ -1,16 +1,16 @@ import argparse import builtins -from collections import defaultdict import functools -from glob import glob import json import keyword -from pathlib import Path import pprint import re import textwrap -from typing import Sequence, Mapping, TypeVar, Any, Union import typing +from collections import defaultdict +from glob import glob +from pathlib import Path +from typing import Any, Mapping, Sequence, TypeVar, Union from . import codegen @@ -44,19 +44,19 @@ HEADER = """\ # Classes and helper functions that we'll write to _client.py LOOKUP_FACADE = ''' def lookup_facade(name, version): - """ - Given a facade name and version, attempt to pull that facade out - of the correct client.py file. + """ + Given a facade name and version, attempt to pull that facade out + of the correct client.py file. - """ - try: - facade = getattr(CLIENTS[str(version)], name) - except KeyError: - raise ImportError("No facades found for version {}".format(version)) - except AttributeError: - raise ImportError( - "No facade with name '{}' in version {}".format(name, version)) - return facade + """ + try: + facade = getattr(CLIENTS[str(version)], name) + except KeyError: + raise ImportError("No facades found for version {}".format(version)) + except AttributeError: + raise ImportError( + "No facade with name '{}' in version {}".format(name, version)) + return facade ''' @@ -127,6 +127,7 @@ class TypeRegistry(dict): return self[refname] + _types = TypeRegistry() _registry = KindRegistry() CLASSES = {} @@ -170,13 +171,13 @@ def name_to_py(name): def strcast(kind, keep_builtins=False): - if issubclass(kind, typing.GenericMeta): - return str(kind)[1:] - if str(kind).startswith('~'): - return str(kind)[1:] if (kind in basic_types or type(kind) in basic_types) and keep_builtins is False: return kind.__name__ + if str(kind).startswith('~'): + return str(kind)[1:] + if issubclass(kind, typing.GenericMeta): + return str(kind)[1:] return kind @@ -257,7 +258,7 @@ def buildTypes(schema, capture): for kind in sorted((k for k in _types if not isinstance(k, str)), key=lambda x: str(x)): name = _types[kind] - if name in capture and not name in NAUGHTY_CLASSES: + if name in capture and name not in NAUGHTY_CLASSES: continue args = Args(kind) # Write Factory class for _client.py @@ -277,9 +278,7 @@ class {}(Type): pprint.pformat(args.SchemaToPyMapping(), width=999), ", " if args else "", args.as_kwargs(), - textwrap.indent(args.get_doc(), INDENT * 2)) - ] - assignments = args._get_arg_str(False, False) + textwrap.indent(args.get_doc(), INDENT * 2))] if not args: source.append("{}pass".format(INDENT * 2)) @@ -289,7 +288,16 @@ class {}(Type): arg_type = arg[1] arg_type_name = strcast(arg_type) if arg_type in basic_types: - source.append("{}self.{} = {}".format(INDENT * 2, arg_name, arg_name)) + source.append("{}self.{} = {}".format(INDENT * 2, + arg_name, + arg_name)) + elif type(arg_type) is typing.TypeVar: + source.append("{}self.{} = {}.from_json({}) " + "if {} else None".format(INDENT * 2, + arg_name, + arg_type_name, + arg_name, + arg_name)) elif issubclass(arg_type, typing.Sequence): value_type = ( arg_type_name.__parameters__[0] @@ -297,10 +305,16 @@ class {}(Type): else None ) if type(value_type) is typing.TypeVar: - source.append("{}self.{} = [{}.from_json(o) for o in {} or []]".format( - INDENT * 2, arg_name, strcast(value_type), arg_name)) + source.append( + "{}self.{} = [{}.from_json(o) " + "for o in {} or []]".format(INDENT * 2, + arg_name, + strcast(value_type), + arg_name)) else: - source.append("{}self.{} = {}".format(INDENT * 2, arg_name, arg_name)) + source.append("{}self.{} = {}".format(INDENT * 2, + arg_name, + arg_name)) elif issubclass(arg_type, typing.Mapping): value_type = ( arg_type_name.__parameters__[1] @@ -308,15 +322,21 @@ class {}(Type): else None ) if type(value_type) is typing.TypeVar: - source.append("{}self.{} = {{k: {}.from_json(v) for k, v in ({} or dict()).items()}}".format( - INDENT * 2, arg_name, strcast(value_type), arg_name)) + source.append( + "{}self.{} = {{k: {}.from_json(v) " + "for k, v in ({} or dict()).items()}}".format( + INDENT * 2, + arg_name, + strcast(value_type), + arg_name)) else: - source.append("{}self.{} = {}".format(INDENT * 2, arg_name, arg_name)) - elif type(arg_type) is typing.TypeVar: - source.append("{}self.{} = {}.from_json({}) if {} else None".format( - INDENT * 2, arg_name, arg_type_name, arg_name, arg_name)) + source.append("{}self.{} = {}".format(INDENT * 2, + arg_name, + arg_name)) else: - source.append("{}self.{} = {}".format(INDENT * 2, arg_name, arg_name)) + source.append("{}self.{} = {}".format(INDENT * 2, + arg_name, + arg_name)) source = "\n".join(source) capture.clear(name) @@ -414,7 +434,7 @@ def ReturnMapping(cls): return decorator -def makeFunc(cls, name, params, result, async=True): +def makeFunc(cls, name, params, result, _async=True): INDENT = " " args = Args(params) assignments = [] @@ -428,21 +448,24 @@ def makeFunc(cls, name, params, result, async=True): source = """ @ReturnMapping({rettype}) -{async}def {name}(self{argsep}{args}): +{_async}def {name}(self{argsep}{args}): ''' {docstring} Returns -> {res} ''' # map input types to rpc msg _params = dict() - msg = dict(type='{cls.name}', request='{name}', version={cls.version}, params=_params) + msg = dict(type='{cls.name}', + request='{name}', + version={cls.version}, + params=_params) {assignments} - reply = {await}self.rpc(msg) + reply = {_await}self.rpc(msg) return reply """ - fsource = source.format(async="async " if async else "", + fsource = source.format(_async="async " if _async else "", name=name, argsep=", " if args else "", args=args, @@ -451,7 +474,7 @@ def makeFunc(cls, name, params, result, async=True): docstring=textwrap.indent(args.get_doc(), INDENT), cls=cls, assignments=assignments, - await="await " if async else "") + _await="await " if _async else "") ns = _getns() exec(fsource, ns) func = ns[name] @@ -539,7 +562,7 @@ class Type: return d def to_json(self): - return json.dumps(self.serialize()) + return json.dumps(self.serialize(), cls=TypeEncoder, sort_keys=True) class Schema(dict): @@ -576,7 +599,7 @@ class Schema(dict): if not defs: return for d, data in defs.items(): - if d in _registry and not d in NAUGHTY_CLASSES: + if d in _registry and d not in NAUGHTY_CLASSES: continue node = self.deref(data, d) kind = node.get("type") @@ -762,6 +785,7 @@ def generate_facades(options): return captures + def setup(): parser = argparse.ArgumentParser() parser.add_argument("-s", "--schema", default="juju/client/schemas*") @@ -769,6 +793,7 @@ def setup(): options = parser.parse_args() return options + def main(): options = setup() @@ -780,5 +805,6 @@ def main(): write_definitions(captures, options, last_version) write_client(captures, options) + if __name__ == '__main__': main()