예제 #1
0
    measured,
    measured_total,
    measure_total,
    DEFAULT_CONTEXT_TOTAL as context_total,
)

DELIMITER = '___'
SPECIAL_NAME = 'special_name'
GROWTH_NODE_NAME = 'growth_node'

figures_values_contract = new_contract('figures_values',
                                       'dict(str: dict(str: float))')

number_pattern = re.compile(r'-?[ ]?\d+\.?\d*')

empty_dict = types.MappingProxyType({})


@contract(base_name='str', object_name='str', returns='str')
def compose_full_name(base_name: str, object_name: str) -> str:
    return f'{base_name}{DELIMITER}{object_name}'


@contract(full_name='str', returns='list[2](str)')
def split_full_name(full_name: str) -> (str, str):
    return full_name.split(DELIMITER, maxsplit=2)


@contract(flatten_dict='dict(str: float)', returns='figures_values')
def roll_up_values_dict(flatten_dict: dict) -> dict:
    """Make hierarchical dictionary from flatten.
예제 #2
0
 def extensions(self):
     """Mapping[:class:`str`, :class:`py:types.ModuleType`]: A read-only mapping of extension name to extension."""
     return types.MappingProxyType(self.__extensions)
예제 #3
0
 def pubsub_patterns(self):
     if self._pubsub_conn and not self._pubsub_conn.closed:
         return self._pubsub_conn.pubsub_patterns
     return types.MappingProxyType({})
예제 #4
0
def singledispatch(func):
    """Single-dispatch generic function decorator.

    Transforms a function into a generic function, which can have different
    behaviours depending upon the type of its first argument. The decorated
    function acts as the default implementation, and additional
    implementations can be registered using the register() attribute of the
    generic function.
    """
    # There are many programs that use functools without singledispatch, so we
    # trade-off making singledispatch marginally slower for the benefit of
    # making start-up of such applications slightly faster.
    import types, weakref

    registry = {}
    dispatch_cache = weakref.WeakKeyDictionary()
    cache_token = None

    def dispatch(cls):
        """generic_func.dispatch(cls) -> <function implementation>

        Runs the dispatch algorithm to return the best available implementation
        for the given *cls* registered on *generic_func*.

        """
        nonlocal cache_token
        if cache_token is not None:
            current_token = get_cache_token()
            if cache_token != current_token:
                dispatch_cache.clear()
                cache_token = current_token
        try:
            impl = dispatch_cache[cls]
        except KeyError:
            try:
                impl = registry[cls]
            except KeyError:
                impl = _find_impl(cls, registry)
            dispatch_cache[cls] = impl
        return impl

    def register(cls, func=None):
        """generic_func.register(cls, func) -> func

        Registers a new implementation for the given *cls* on a *generic_func*.

        """
        nonlocal cache_token
        if func is None:
            if isinstance(cls, type):
                return lambda f: register(cls, f)
            ann = getattr(cls, '__annotations__', {})
            if not ann:
                raise TypeError(
                    f"Invalid first argument to `register()`: {cls!r}. "
                    f"Use either `@register(some_class)` or plain `@register` "
                    f"on an annotated function."
                )
            func = cls

            # only import typing if annotation parsing is necessary
            from typing import get_type_hints
            argname, cls = next(iter(get_type_hints(func).items()))
            assert isinstance(cls, type), (
                f"Invalid annotation for {argname!r}. {cls!r} is not a class."
            )
        registry[cls] = func
        if cache_token is None and hasattr(cls, '__abstractmethods__'):
            cache_token = get_cache_token()
        dispatch_cache.clear()
        return func

    def wrapper(*args, **kw):
        if not args:
            raise TypeError(f'{funcname} requires at least '
                            '1 positional argument')

        return dispatch(args[0].__class__)(*args, **kw)

    funcname = getattr(func, '__name__', 'singledispatch function')
    registry[object] = func
    wrapper.register = register
    wrapper.dispatch = dispatch
    wrapper.registry = types.MappingProxyType(registry)
    wrapper._clear_cache = dispatch_cache.clear
    update_wrapper(wrapper, func)
    return wrapper
예제 #5
0

_HAS_DEFAULT_FACTORY = _HAS_DEFAULT_FACTORY_CLASS()


# A sentinel object to detect if a parameter is supplied or not.  Use
#  a class to give it a better repr.
class _MISSING_TYPE:
    pass


MISSING = _MISSING_TYPE()

# Since most per-field metadata will be unused, create an empty
#  read-only proxy that can be shared among all fields.
_EMPTY_METADATA = types.MappingProxyType({})

# Markers for the various kinds of fields and pseudo-fields.
_FIELD = object()  # An actual field.
_FIELD_CLASSVAR = object()  # Not a field, but a ClassVar.
_FIELD_INITVAR = object()  # Not a field, but an InitVar.

# The name of an attribute on the class where we store the Field
#  objects. Also used to check if a class is a Data Class.
_FIELDS = '__dataclass_fields__'

# The name of an attribute on the class that stores the parameters to
# @dataclass.
_PARAMS = '__dataclass_params__'

# The name of the function, that if it exists, is called at the end of
예제 #6
0
 def unpacking_object_hook(self, obj):
     if type(obj) is dict:
         return types.MappingProxyType(obj)
예제 #7
0
 def field(self):
     return types.MappingProxyType(self.__field)
예제 #8
0
IGNORED_VIOLATIONS = (
    'WPS201',  # it is a module level violation
    'WPS202',  # since our test case is complex, that's fine
    'WPS203',  # it is a module level violation
    'WPS204',  # our tests have a lot of overused expressions
    'WPS226',  # we have a lot of ugly strings inside
    'WPS400',  # it is a module level violation
    'WPS402',  # we obviously use a lot of `noqa` comments
)

#: Number and count of violations that would be raised.
VERSION_SPECIFIC = types.MappingProxyType({
    'WPS216': 1,
    'WPS224': 1,
    'WPS307': 1,
    'WPS332': 0,  # TODO: pyflakes fails at `:=` at the moment
    'WPS416': int(not PY38),  # only works for `< python3.8`
    'WPS451': int(PY38),  # only works for `>= python3.8`
    'WPS452': int(PY38),  # only works for `>= python3.8`
    'WPS602': 2,
})

#: Number and count of violations that would be raised.
SHOULD_BE_RAISED = types.MappingProxyType({
    'WPS000': 0,  # logically unacceptable.
    'WPS100': 0,  # logically unacceptable.
    'WPS101': 0,  # logically unacceptable.
    'WPS102': 0,  # logically unacceptable.
    'WPS110': 4,
    'WPS111': 1,
    'WPS112': 1,
    'WPS113': 1,
예제 #9
0
    return bool(value)


def as_is(value):
    return value


__typecast_map = {
    bool: to_bool,
    float: float,
    int: int,
    str: str,
}

TYPECAST_MAP = types.MappingProxyType(__typecast_map)


class TypeCastByAnnotation:
    # Чет выглядит ваще как техномагия
    def items(self):
        res = []
        for var_name in self:
            res.append((var_name, getattr(self, var_name)))
        return res

    def __setattr__(self, key: str, value):
        if key in self.__annotations__:
            _type = self.__annotations__[key]
            _type = TYPECAST_MAP.get(_type, as_is)
        else:
예제 #10
0
    def _event_ctx(self, etype, data):
        """
        Handle event. Check validity and conditions.

        Timed states look for 'duration' key in the data. If it is
        present, the value overrides the default timer duration.

        Return value:
            True = transition accepted, either executed or scheduled
                   for execution
            False = transition rejected
        """
        if isinstance(data, cabc.MutableMapping):
            # make read-only to prevent any ugly hacks
            rodata = types.MappingProxyType(data)
        else:
            rodata = data
        fsm_event_data.set(rodata)

        if isinstance(etype, Goto):
            newstate = etype.state
            self._check_state(newstate)
        else:
            if etype not in self._ct_events:
                raise EdzedUnknownEvent(
                    f"{self}: Unknown event type {etype!r}")
            try:
                newstate = self._ct_transition[(etype, self.state)]
            except KeyError:
                newstate = self._ct_transition.get((etype, None), None)
            if newstate is None:
                self.log_debug(
                    "No transition defined for event %s in state %s", etype,
                    self._state)
                for event in self._on_notrans:
                    event.send(self,
                               trigger='notrans',
                               event=etype,
                               state=self._state)
                return False
            if self.is_initialized() and not all(self._run_cb('cond', etype)):
                self.log_debug(
                    "not executing event %s (%s -> %s), condition not satisfied",
                    etype, self.state, newstate)
                return False

        if self._fsm_event_active:
            # recursive call:
            #   - event ->  enter_STATE -> new event, or
            #   - timed event with zero duration -> next event
            if self._next_event is not None:
                raise EdzedCircuitError(
                    "Forbidden event multiplication; "
                    f"Two events ({self._next_event[0]} and {etype}) were generated "
                    "while handling a single event")
            self._next_event = (etype, data, newstate)
            return True

        self._fsm_event_active = True
        try:
            if self.is_initialized():
                self._run_cb('exit', self._state)
                self._send_events('on_exit')
                self._stop_timer()
            assert self._next_event is None
            for _ in range(self._ct_chainlimit):
                if self._next_event:
                    # intermediate state: skip generated events and exit the state immediately
                    self._run_cb('exit', self._state)
                    etype, data, newstate = self._next_event
                    self._next_event = None
                self.log_debug("state: %s -> %s (event: %s)", self._state,
                               newstate, etype)
                self._state = newstate
                with self._enable_event:
                    self._run_cb('enter', self._state)
                if self._next_event:
                    continue
                try:
                    timed_event = self._ct_timed_event[newstate]
                except KeyError:
                    pass  # new state is not a timed state
                else:
                    with self._enable_event:
                        self._start_timer(data.get('duration'), timed_event)
                    if self._next_event:
                        continue
                break
            else:
                raise EdzedCircuitError(
                    'Chained state transition limit reached (infinite loop?)')
            output = self.calc_output()
            if output is not block.UNDEF:
                self.set_output(output)
            self._send_events('on_enter')
            return True
        finally:
            self._fsm_event_active = False
예제 #11
0
파일: enums.py 프로젝트: Reliku/hikari
    def __new__(
        mcs: typing.Type[_T],
        name: str,
        bases: typing.Tuple[typing.Type[typing.Any], ...],
        namespace: typing.Union[typing.Dict[str, typing.Any], _EnumNamespace],
    ) -> _T:
        global _Flag

        if _Flag is NotImplemented:
            # noinspection PyRedundantParentheses
            return (_Flag := super().__new__(mcs, name, bases, namespace))

        assert isinstance(namespace, _EnumNamespace)
        new_namespace = {
            "__objtype__": int,
            "__enumtype__": _Flag,
            "_name_to_member_map_": (name_to_member := {}),
            "_value_to_member_map_": (value_to_member := {}),
            "_powers_of_2_to_member_map_": (powers_of_2_map := {}),
            # We cant weakref, as we inherit from int. Turns out that is significantly
            # slower anyway, so it isn't important for now. We just manually limit
            # the cache size.
            # This also randomly ends up with a 0 value in it at the start
            # during the next for loop. I cannot work out for the life of me
            # why this happens.
            "_temp_members_": {},
            "_member_names_": (member_names := []),
            # Required to be immutable by enum API itself.
            "__members__": types.MappingProxyType(namespace.names_to_values),
            **namespace,
            # This copies over all methods, including operator overloads. This
            # has the effect of making pdoc aware of any methods or properties
            # we defined on Flag.
            **{
                name: value
                for name, value in Flag.__dict__.items() if name not in ("__class__", "__module__", "__doc__")
            },
        }

        cls = super().__new__(mcs, name, (int, *bases), new_namespace)

        for name, value in namespace.names_to_values.items():
            # Patching the member init call is around 100ns faster per call than
            # using the default type.__call__ which would make us do the lookup
            # in cls.__new__. Reason for this is that python will also always
            # invoke cls.__init__ if we do this, so we end up with two function
            # calls.
            member = cls.__new__(cls, value)
            member._name_ = name
            member._value_ = value
            name_to_member[name] = member
            value_to_member[value] = member
            member_names.append(name)
            setattr(cls, name, member)

            if not (value & value - 1):
                powers_of_2_map[value] = member

        all_bits = functools.reduce(operator.or_, value_to_member.keys())
        all_bits_member = cls.__new__(cls, all_bits)
        all_bits_member._name_ = None
        all_bits_member._value_ = all_bits
        setattr(cls, "__everything__", all_bits_member)

        return cls
예제 #12
0
"""Pythonization some names and fields."""
import types

FIELDS = types.MappingProxyType({
    'global': 'global_field',
    'type': 'type_field',
})

METHODS = types.MappingProxyType({
    'return': 'return_method',
})
예제 #13
0
파일: usage.py 프로젝트: ruioavieira/qiime2
 def records(self) -> types.MappingProxyType:
     """
     A read-only view of ``ScopeRecords`` in the current scope.
     """
     return types.MappingProxyType(self._records)
예제 #14
0
def mappingproxytype_okay(value=MappingProxyType({}),
                          value2=types.MappingProxyType({})):
    pass
예제 #15
0
 def parameters(self):
     try:
         return types.MappingProxyType(self._parameters)
     except AttributeError:
         return OrderedDict(self._parameters.items())
예제 #16
0
import types
a_dict = {'a': 1, 'b': 3}
proxy_dict = types.MappingProxyType(a_dict)  # a view on the dict.


class OneClass:
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

    def default(self):
        pass


def OneFunction(param1):
    print('In the function one. ' + param1.__class__.__name__)


OneClassInst = OneClass()
OneClassInst.default = types.MethodType(OneFunction, OneClassInst)
OneClassInst.default()

expected_ns = {}


class AMeta(type):
    def __new__(*args, **kwargs):
        return type.__new__(*args, **kwargs)

    def __prepare__(*args):
        return expected_ns
예제 #17
0
def _asmappingproxy(mapping):
    if isinstance(mapping, types.MappingProxyType):
        return mapping
    else:
        return types.MappingProxyType(mapping)
예제 #18
0
 def __members__(cls) -> Mapping[str, Any]:
     return types.MappingProxyType(cls._enum_member_map_)
예제 #19
0
 def metadata_proxy(d):
     return types.MappingProxyType(dict(d))
예제 #20
0
파일: cpi.py 프로젝트: hraffiest/poptimizer
from poptimizer import config
from poptimizer.data.adapters.gateways import gateways
from poptimizer.shared import adapters, col

# Параметры загрузки валидации данных
START_URL = "https://rosstat.gov.ru/price"
URL_CORE = "https://rosstat.gov.ru/"
CPI_PATTERN = re.compile("storage/mediabank/[a-zA-Z0-9]+/Индексы потребительских цен.*html?")
FILE_PATTERN = re.compile("https://rosstat.gov.ru/storage/mediabank/[a-zA-Z0-9]+/i_ipc.*xlsx")
END_OF_JAN = 31
PARSING_PARAMETERS = types.MappingProxyType(
    {
        "sheet_name": "ИПЦ",
        "header": 3,
        "skiprows": [4],
        "skipfooter": 3,
        "index_col": 0,
        "engine": "openpyxl",
    },
)
NUM_OF_MONTH = 12
FIRST_YEAR = 1991
FIRST_MONTH = "январь"


class CPIGatewayError(config.POptimizerError):
    """Ошибки, связанные с загрузкой данных по инфляции."""


async def _get_cpi_url(session: aiohttp.ClientSession) -> str:
    """Получить url на страницу с потребительской инфляцией."""
예제 #21
0
 def __init__(self, raw_meta: dict):
     self._metas = types.MappingProxyType(raw_meta)
예제 #22
0
 def __init__(self, app: traits.GatewayBotAware) -> None:
     self._app = app
     self._connections = {}
     self.connections = types.MappingProxyType(self._connections)
     self._is_alive = False
     self._is_closing = False
예제 #23
0
파일: enums.py 프로젝트: silverkip/solidbot
 def __members__(cls):
     return types.MappingProxyType(cls._enum_member_map_)
예제 #24
0
class DdsRegion:
    def __init__(self):
        pass

    AF_SOUTH_1 = Region(id="af-south-1",
                        endpoint="https://dds.af-south-1.myhuaweicloud.com")

    CN_NORTH_4 = Region(id="cn-north-4",
                        endpoint="https://dds.cn-north-4.myhuaweicloud.com")

    CN_NORTH_1 = Region(id="cn-north-1",
                        endpoint="https://dds.cn-north-1.myhuaweicloud.com")

    CN_EAST_2 = Region(id="cn-east-2",
                       endpoint="https://dds.cn-east-2.myhuaweicloud.com")

    CN_EAST_3 = Region(id="cn-east-3",
                       endpoint="https://dds.cn-east-3.myhuaweicloud.com")

    CN_SOUTH_1 = Region(id="cn-south-1",
                        endpoint="https://dds.cn-south-1.myhuaweicloud.com")

    CN_SOUTHWEST_2 = Region(
        id="cn-southwest-2",
        endpoint="https://dds.cn-southwest-2.myhuaweicloud.com")

    AP_SOUTHEAST_2 = Region(
        id="ap-southeast-2",
        endpoint="https://dds.ap-southeast-2.myhuaweicloud.com")

    AP_SOUTHEAST_1 = Region(
        id="ap-southeast-1",
        endpoint="https://dds.ap-southeast-1.myhuaweicloud.com")

    AP_SOUTHEAST_3 = Region(
        id="ap-southeast-3",
        endpoint="https://dds.ap-southeast-3.myhuaweicloud.com")

    RU_NORTHWEST_2 = Region(
        id="ru-northwest-2",
        endpoint="https://dds.ru-northwest-2.myhuaweicloud.com")

    CN_SOUTH_2 = Region(id="cn-south-2",
                        endpoint="https://dds.cn-south-2.myhuaweicloud.com")

    CN_NORTH_2 = Region(id="cn-north-2",
                        endpoint="https://dds.cn-north-2.myhuaweicloud.com")

    static_fields = types.MappingProxyType({
        "af-south-1": AF_SOUTH_1,
        "cn-north-4": CN_NORTH_4,
        "cn-north-1": CN_NORTH_1,
        "cn-east-2": CN_EAST_2,
        "cn-east-3": CN_EAST_3,
        "cn-south-1": CN_SOUTH_1,
        "cn-southwest-2": CN_SOUTHWEST_2,
        "ap-southeast-2": AP_SOUTHEAST_2,
        "ap-southeast-1": AP_SOUTHEAST_1,
        "ap-southeast-3": AP_SOUTHEAST_3,
        "ru-northwest-2": RU_NORTHWEST_2,
        "cn-south-2": CN_SOUTH_2,
        "cn-north-2": CN_NORTH_2,
    })

    @staticmethod
    def value_of(region_id, static_fields=static_fields):
        if region_id is None or len(region_id) == 0:
            raise KeyError("Unexpected empty parameter: region_id.")
        if not static_fields.get(region_id):
            raise KeyError("Unexpected region_id: " + region_id)
        return static_fields.get(region_id)
예제 #25
0
 def cogs(self):
     """Mapping[:class:`str`, :class:`Cog`]: A read-only mapping of cog name to cog."""
     return types.MappingProxyType(self.__cogs)
예제 #26
0
파일: pose.py 프로젝트: OLaprevote/pyrolyse
def _get_energies_scores(self):
    """Modified by pyrolyse at pyrolyse.core.pose"""
    import types

    return types.MappingProxyType(self.pose.energies.active_total_energies())
예제 #27
0
SHOULD_BE_RAISED = types.MappingProxyType({
    'WPS100': 0,
    'WPS101': 0,
    'WPS102': 0,
    'WPS110': 3,
    'WPS111': 1,
    'WPS112': 1,
    'WPS113': 1,
    'WPS114': 1,
    'WPS115': 1,
    'WPS116': 1,
    'WPS117': 1,
    'WPS118': 1,
    'WPS119': 1,
    'WPS120': 1,
    'WPS121': 1,
    'WPS122': 1,
    'WPS123': 1,

    'WPS200': 0,
    'WPS201': 0,
    'WPS202': 0,
    'WPS203': 0,
    'WPS204': 0,

    'WPS210': 1,
    'WPS211': 1,
    'WPS212': 1,
    'WPS213': 1,
    'WPS214': 0,
    'WPS215': 1,
    'WPS216': 0,
    'WPS217': 1,
    'WPS218': 1,
    'WPS219': 1,
    'WPS220': 1,
    'WPS221': 2,
    'WPS222': 1,
    'WPS223': 1,
    'WPS224': 1,
    'WPS225': 1,
    'WPS226': 0,
    'WPS227': 1,
    'WPS228': 1,
    'WPS229': 1,
    'WPS230': 1,

    'WPS300': 1,
    'WPS301': 1,
    'WPS302': 1,
    'WPS303': 1,
    'WPS304': 1,
    'WPS305': 1,
    'WPS306': 2,
    'WPS307': 1,
    'WPS308': 1,
    'WPS309': 1,
    'WPS310': 4,
    'WPS311': 1,
    'WPS312': 1,
    'WPS313': 1,
    'WPS314': 1,
    'WPS315': 1,
    'WPS316': 0,
    'WPS317': 1,
    'WPS318': 3,
    'WPS319': 2,
    'WPS320': 2,
    'WPS321': 1,
    'WPS322': 1,
    'WPS323': 0,
    'WPS324': 1,
    'WPS325': 1,
    'WPS326': 1,
    'WPS327': 1,
    'WPS328': 2,
    'WPS329': 1,
    'WPS330': 1,
    'WPS331': 1,
    'WPS332': 1,
    'WPS333': 1,
    'WPS334': 1,
    'WPS335': 1,
    'WPS336': 1,
    'WPS337': 1,
    'WPS338': 1,
    'WPS339': 1,
    'WPS340': 1,
    'WPS341': 1,
    'WPS342': 1,
    'WPS343': 1,
    'WPS344': 1,
    'WPS345': 1,
    'WPS346': 1,
    'WPS347': 3,
    'WPS348': 1,

    'WPS400': 0,
    'WPS401': 0,
    'WPS402': 0,
    'WPS403': 0,
    'WPS404': 1,
    'WPS405': 1,
    'WPS406': 1,
    'WPS407': 1,
    'WPS408': 1,
    'WPS409': 1,
    'WPS410': 1,
    'WPS411': 0,
    'WPS412': 0,
    'WPS413': 1,
    'WPS414': 1,
    'WPS415': 1,
    'WPS416': 1,
    'WPS417': 1,
    'WPS418': 1,
    'WPS419': 1,
    'WPS420': 2,
    'WPS421': 1,
    'WPS422': 1,
    'WPS423': 1,
    'WPS424': 1,
    'WPS425': 1,
    'WPS426': 1,
    'WPS427': 1,
    'WPS428': 2,
    'WPS429': 1,
    'WPS430': 1,
    'WPS431': 2,
    'WPS432': 2,
    'WPS433': 1,
    'WPS434': 1,
    'WPS435': 1,
    'WPS436': 1,
    'WPS437': 1,
    'WPS438': 4,
    'WPS439': 1,
    'WPS440': 1,
    'WPS441': 1,
    'WPS442': 2,
    'WPS443': 1,
    'WPS444': 1,
    'WPS445': 1,
    'WPS446': 1,
    'WPS447': 1,
    'WPS448': 1,

    'WPS500': 1,
    'WPS501': 1,
    'WPS502': 2,
    'WPS503': 1,
    'WPS504': 1,
    'WPS505': 1,
    'WPS506': 1,
    'WPS507': 1,
    'WPS508': 1,
    'WPS509': 1,
    'WPS510': 1,
    'WPS511': 1,
    'WPS512': 1,
    'WPS513': 1,
    'WPS514': 1,
    'WPS515': 1,
    'WPS516': 1,
    'WPS517': 2,
    'WPS518': 1,
    'WPS519': 1,
    'WPS520': 1,
    'WPS521': 1,

    'WPS600': 1,
    'WPS601': 1,
    'WPS602': 2,
    'WPS603': 1,
    'WPS604': 2,
    'WPS605': 1,
    'WPS606': 1,
    'WPS607': 1,
    'WPS608': 1,
    'WPS609': 1,
    'WPS610': 1,
    'WPS611': 1,
    'WPS612': 1,

    'WPS701': 2,
    'WPS702': 2,
})
예제 #28
0
def load_settings():
    """ Fetch the middleware settings.

    :return dict: settings
    """
    # Get the user-provided settings
    user_settings = dict(getattr(django_settings, _settings_key, {}))
    user_settings_keys = set(user_settings.keys())

    # Check for required but missing settings
    missing = _required_settings_keys - user_settings_keys
    if missing:
        raise AuthzConfigurationError('Missing required {} config: {}'.format(
            _settings_key, missing))

    # Check for unknown settings
    unknown = user_settings_keys - _available_settings_keys
    if unknown:
        raise AuthzConfigurationError('Unknown {} config params: {}'.format(
            _settings_key, unknown))

    # Merge defaults with provided settings
    defaults = _available_settings_keys - user_settings_keys
    user_settings.update({key: _available_settings[key] for key in defaults})

    if not user_settings.get('JWKS') and not user_settings.get('JWKS_URL'):
        raise AuthzConfigurationError(
            'Either JWKS or JWKS_URL must be set, or both')

    if type(user_settings['MIN_SCOPE']) == str:
        user_settings['MIN_SCOPE'] = (user_settings['MIN_SCOPE'], )

    if not type(
            user_settings['FORCED_ANONYMOUS_ROUTES']) in {list, tuple, set}:
        raise AuthzConfigurationError(
            'FORCED_ANONYMOUS_ROUTES must be a list, tuple or set')

    if not type(user_settings['PROTECTED']) in {list, tuple, set}:
        raise AuthzConfigurationError('PROTECTED must be a list, tuple or set')

    for resource in user_settings['PROTECTED']:
        if not type(resource) == tuple or not len(resource) == 3:
            raise ProtectedRecourceSyntaxError(
                'Resource in PROTECTED must be a tuple of length 3')
        (route, methods, scopes) = resource
        if not type(route) is str:
            raise AuthzConfigurationError(
                'Route in PROTECTED resource must be a string')
        for aroute in user_settings['FORCED_ANONYMOUS_ROUTES']:
            if route.startswith(aroute):
                raise ProtectedRouteConflictError(
                    f'{route} is configured in PROTECTED, but this would be '
                    f'overruled by {aroute} in FORCED_ANONYMOUS_ROUTES')
        if not type(methods) is list:
            raise AuthzConfigurationError(
                'Methods in PROTECTED resource must be a list')
        for method in methods:
            if not method in _methods_valid_options:
                str_methods = ', '.join(_methods_valid_options)
                raise AuthzConfigurationError(
                    f'Invalid value for methods: {method}. Must be one of {str_methods}.'
                )
        if not type(scopes) is list:
            raise AuthzConfigurationError(
                'Scopes in PROTECTED resource must be a list')
        if not len(scopes) > 0:
            raise NoRequiredScopesError(
                f'You must require at least one scope for protected route {route}'
            )

    return types.MappingProxyType(user_settings)
    def exec(self):
        ###################################################################
        #
        # 基本コンテナオブジェクトと読み取り専用オブジェクト
        #
        # Python の基本コンテナとして
        #   * リスト (list)
        #   * ディクショナリ (dict)
        #   * セット (set)
        # が存在するが、それぞれ読み取り専用として扱えるオブジェクトが
        # 対で存在する。対応としては以下のようになる。
        #
        # リスト
        #    tuple に変更すると読み取り専用のリストとして使える
        # ディクショナリ
        #    types.MappingProxyType オブジェクトが読み取り専用として使える
        # セット
        #    frozenset が読み取り専用として使える
        #
        ##################################################################
        #
        # listとtuple
        #
        a_list = list(range(10))
        pr('list', a_list)

        a_list.append(100)
        a_list.insert(0, 101)
        del a_list[1]

        pr('list is mutable', a_list)

        a_tuple = tuple(a_list)
        pr('tuple', a_tuple)

        try:
            # noinspection PyUnresolvedReferences
            a_tuple.append(102)
        except AttributeError as attr_ex:
            pr('tuple is immutable', attr_ex)

        try:
            # noinspection PyUnresolvedReferences
            del a_tuple[0]
        except TypeError as type_ex:
            pr('tuple is immutable2', type_ex)

        # tupleは生成時に元データをコピーして生成されるので
        # 元のデータに変更があっても影響はない
        a_list.clear()
        a_list.append(999)
        pr('tuple', a_tuple)

        hr()

        #
        # dictとtypes.MappingProxyType
        #
        a_dict = dict(hello=1, world=2)
        pr('dict', a_dict)

        a_dict['spam'] = 100
        del a_dict['world']

        pr('dict is mutable', a_dict)

        a_proxy = types.MappingProxyType(a_dict)
        try:
            # noinspection PyUnresolvedReferences
            a_proxy['hello'] = 200
        except TypeError as type_ex:
            pr('MappingProxyType is immutable', type_ex)

        try:
            # noinspection PyUnresolvedReferences
            del a_proxy['hello']
        except TypeError as type_ex:
            pr('MappingProxyType is immutable2', type_ex)

        # MappingProxyTypeのみの特殊動作。
        # このオブジェクト自体が動的ビューなので
        # 元オブジェクトの変更は即座に反映される。
        # (tupleやfrozensetの場合は元の値がコピーされているため元データ
        #  変更しても影響はない。)
        a_dict['world'] = 999
        pr('proxy', a_proxy['world'])

        hr()

        #
        # setとfrozenset
        #
        a_set = set(a_tuple)
        pr('set', a_set)

        a_set.add(10)
        a_set.add(3)
        a_set.remove(2)

        pr('set is mutable', a_set)

        a_frozenset = frozenset(a_set)

        try:
            # noinspection PyUnresolvedReferences
            a_frozenset.add(4)
        except AttributeError as attr_ex:
            pr('frozenset is immutable', attr_ex)

        try:
            # noinspection PyUnresolvedReferences
            a_frozenset.remove(10)
        except AttributeError as attr_ex:
            pr('frozenset is immutable2', attr_ex)

        # frozensetは生成時に元データをコピーして生成されるので
        # 元のデータに変更があっても影響はない
        a_set.clear()
        a_set.add(999)
        pr('frozenset', a_frozenset)

        hr()
예제 #30
0
 def components(self) -> typing.Mapping[typing.Type, Component]:
     return types.MappingProxyType(self._components)