# Path: ronin/contexts.py
# def current_context(immutable=True):
#     """
#     Returns the current context if there is one, otherwise raises :class:`NoContextException`.
#     
#     By default, the context will be treated as immutable.
#     
#     :param immutable: set to False in order to allow changes to the context
#     :type immutable: bool
#     :returns: current context
#     :rtype: :class:`Context`
#     """
# 
#     ctx = Context._peek_thread_local()
#     if ctx is None:
#         raise NoContextException()
#     return Context(ctx, True) if immutable else ctx
# 
# Path: ronin/utils/types.py
# def verify_type(value, the_type):
#     """
#     Raises :class:`TypeError` if the value is not an instance of the type.
# 
#     :param value: value
#     :param the_type: type or type name
#     :type the_type: type|str
#     :raises TypeError: if ``value`` is not an instance of ``the_type``
#     :raises ~exceptions.ValueError: if ``the_type`` is invalid
#     :raises ImportError: if could not import the module
#     :raises AttributeError: if could not find the symbol in the module
#     """
#     
#     if isinstance(the_type, string):
#         the_type = import_symbol(the_type)
#         if not isclass(the_type):
#             raise ValueError('{} is not a type'.format(the_type))
#     
#     if not isinstance(value, the_type):
#         raise TypeError('not an instance of {}: {}'.format(type_name(the_type),
#                                                            type_name(type(value)))) 
# 
# Path: ronin/utils/collections.py
# class StrictList(list):
#     """
#     A list that raises :class:`~exceptions.TypeError` exceptions when objects of the wrong type are
#     inserted.
#     
#     :param items: initial list
#     :type items: list
#     :param value_type: type(s) required for list values
#     :type value_type: :obj:`type` or :obj:`str` or (:obj:`type` or :obj:`str`)
#     :param wrapper_function: calls this optional function on all values before added to the list
#     :type wrapper_function: ~types.FunctionType
#     :param unwrapper_function: calls this optional function on all values when retrieved from the
#      list
#     :type unwrapper_function: ~types.FunctionType
#     """
# 
#     def __init__(self, items=None, value_type=None, wrapper_function=None, unwrapper_function=None):
#         super(StrictList, self).__init__()
#         if isinstance(items, StrictList):
#             self.value_type = items.value_type
#             self.wrapper_function = items.wrapper_function
#             self.unwrapper_function = items.unwrapper_function
#         self.value_type = _convert_type(value_type)
#         self.wrapper_function = wrapper_function
#         self.unwrapper_function = unwrapper_function
#         if items:
#             for item in items:
#                 self.append(item)
# 
#     def _wrap(self, value):
#         if (self.value_type is not None) and (not isinstance(value, self.value_type)):
#             raise TypeError('value must be a "{}": {!r}'.format(type_name(self.value_type), value))
#         if self.wrapper_function is not None:
#             value = self.wrapper_function(value)
#         return value
# 
#     def _unwrap(self, value):
#         if self.unwrapper_function is not None:
#             value = self.unwrapper_function(value)
#         return value
# 
#     def __getitem__(self, index):
#         value = super(StrictList, self).__getitem__(index)
#         value = self._unwrap(value)
#         return value
# 
#     def __setitem__(self, index, value):
#         value = self._wrap(value)
#         return super(StrictList, self).__setitem__(index, value)
# 
#     def __iadd__(self, values):
#         values = [self._wrap(v) for v in values]
#         return super(StrictList, self).__iadd__(values)
# 
#     def append(self, value):
#         value = self._wrap(value)
#         return super(StrictList, self).append(value)
# 
#     def extend(self, values):
#         values = [self._wrap(v) for v in values]
#         return super(StrictList, self).extend(values)
# 
#     def insert(self, index, value):
#         value = self._wrap(value)
#         return super(StrictList, self).insert(index, value)
# 
# Path: ronin/utils/strings.py
# def stringify(value):
#     """
#     Casts the value to a Unicode string. If the value is a function, calls it using
#     :func:`ronin.contexts.current_context` as its only argument, and recurses until a
#     non-FunctionType value is returned.
#     
#     None values are preserved, whether None is directly sent to this function or is the return
#     value of function argument.
#     
#     This function is the heart of Rōnin's deferred value capability, as it allows lambdas to be
#     passed around instead of strings.
#     
#     :param value: value or None
#     :type value: str|FunctionType
#     :returns: stringified value or None
#     :rtype: str
#     """
#     
#     if value is None:
#         return None
#     elif hasattr(value, '__call__'):
#         with current_context() as ctx:
#             value = value(ctx)
#         return stringify(value)
#     else:
#         try:
#             return to_str(value)
#         except UnicodeDecodeError:
#             return str(value).decode(_ENCODING)


from .contexts import current_context
from .utils.types import verify_type
from .utils.collections import StrictList
from .utils.strings import stringify
from types import FunctionType
# Copyright 2016-2018 Tal Liron
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from __future__ import unicode_literals


class Extension(object):
    """
    Base class for extensions.
    
    Extensions can nest child extensions (and so can they).
    
    :ivar extensions: child extensions
    :vartype command: [:class:`Extension`]
    """
    
    def __init__(self):

# Path: ronin/contexts.py
# def current_context(immutable=True):
#     """
#     Returns the current context if there is one, otherwise raises :class:`NoContextException`.
#     
#     By default, the context will be treated as immutable.
#     
#     :param immutable: set to False in order to allow changes to the context
#     :type immutable: bool
#     :returns: current context
#     :rtype: :class:`Context`
#     """
# 
#     ctx = Context._peek_thread_local()
#     if ctx is None:
#         raise NoContextException()
#     return Context(ctx, True) if immutable else ctx
# 
# Path: ronin/utils/types.py
# def verify_type(value, the_type):
#     """
#     Raises :class:`TypeError` if the value is not an instance of the type.
# 
#     :param value: value
#     :param the_type: type or type name
#     :type the_type: type|str
#     :raises TypeError: if ``value`` is not an instance of ``the_type``
#     :raises ~exceptions.ValueError: if ``the_type`` is invalid
#     :raises ImportError: if could not import the module
#     :raises AttributeError: if could not find the symbol in the module
#     """
#     
#     if isinstance(the_type, string):
#         the_type = import_symbol(the_type)
#         if not isclass(the_type):
#             raise ValueError('{} is not a type'.format(the_type))
#     
#     if not isinstance(value, the_type):
#         raise TypeError('not an instance of {}: {}'.format(type_name(the_type),
#                                                            type_name(type(value)))) 
# 
# Path: ronin/utils/collections.py
# class StrictList(list):
#     """
#     A list that raises :class:`~exceptions.TypeError` exceptions when objects of the wrong type are
#     inserted.
#     
#     :param items: initial list
#     :type items: list
#     :param value_type: type(s) required for list values
#     :type value_type: :obj:`type` or :obj:`str` or (:obj:`type` or :obj:`str`)
#     :param wrapper_function: calls this optional function on all values before added to the list
#     :type wrapper_function: ~types.FunctionType
#     :param unwrapper_function: calls this optional function on all values when retrieved from the
#      list
#     :type unwrapper_function: ~types.FunctionType
#     """
# 
#     def __init__(self, items=None, value_type=None, wrapper_function=None, unwrapper_function=None):
#         super(StrictList, self).__init__()
#         if isinstance(items, StrictList):
#             self.value_type = items.value_type
#             self.wrapper_function = items.wrapper_function
#             self.unwrapper_function = items.unwrapper_function
#         self.value_type = _convert_type(value_type)
#         self.wrapper_function = wrapper_function
#         self.unwrapper_function = unwrapper_function
#         if items:
#             for item in items:
#                 self.append(item)
# 
#     def _wrap(self, value):
#         if (self.value_type is not None) and (not isinstance(value, self.value_type)):
#             raise TypeError('value must be a "{}": {!r}'.format(type_name(self.value_type), value))
#         if self.wrapper_function is not None:
#             value = self.wrapper_function(value)
#         return value
# 
#     def _unwrap(self, value):
#         if self.unwrapper_function is not None:
#             value = self.unwrapper_function(value)
#         return value
# 
#     def __getitem__(self, index):
#         value = super(StrictList, self).__getitem__(index)
#         value = self._unwrap(value)
#         return value
# 
#     def __setitem__(self, index, value):
#         value = self._wrap(value)
#         return super(StrictList, self).__setitem__(index, value)
# 
#     def __iadd__(self, values):
#         values = [self._wrap(v) for v in values]
#         return super(StrictList, self).__iadd__(values)
# 
#     def append(self, value):
#         value = self._wrap(value)
#         return super(StrictList, self).append(value)
# 
#     def extend(self, values):
#         values = [self._wrap(v) for v in values]
#         return super(StrictList, self).extend(values)
# 
#     def insert(self, index, value):
#         value = self._wrap(value)
#         return super(StrictList, self).insert(index, value)
# 
# Path: ronin/utils/strings.py
# def stringify(value):
#     """
#     Casts the value to a Unicode string. If the value is a function, calls it using
#     :func:`ronin.contexts.current_context` as its only argument, and recurses until a
#     non-FunctionType value is returned.
#     
#     None values are preserved, whether None is directly sent to this function or is the return
#     value of function argument.
#     
#     This function is the heart of Rōnin's deferred value capability, as it allows lambdas to be
#     passed around instead of strings.
#     
#     :param value: value or None
#     :type value: str|FunctionType
#     :returns: stringified value or None
#     :rtype: str
#     """
#     
#     if value is None:
#         return None
#     elif hasattr(value, '__call__'):
#         with current_context() as ctx:
#             value = value(ctx)
#         return stringify(value)
#     else:
#         try:
#             return to_str(value)
#         except UnicodeDecodeError:
#             return str(value).decode(_ENCODING)


# Path: ronin/extensions.py
from .contexts import current_context
from .utils.types import verify_type
from .utils.collections import StrictList
from .utils.strings import stringify
from types import FunctionType

# Copyright 2016-2018 Tal Liron
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from __future__ import unicode_literals


class Extension(object):
    """
    Base class for extensions.
    
    Extensions can nest child extensions (and so can they).
    
    :ivar extensions: child extensions
    :vartype command: [:class:`Extension`]
    """
    
    def __init__(self):

        self.extensions = StrictList(value_type=Extension)