<commit_before>#!/usr/bin/python
# (c) 2017 <NAME>. MIT licensed, see https://opensource.org/licenses/MIT
# Part of Blender Driver, see https://github.com/sjjhsjjh/blender-driver
"""RESTful interfaces module.

Cannot be run as a program, sorry."""
# Exit if run other than as a module.
if __name__ == '__main__':
    print(__doc__)
    raise SystemExit(1)


#
# Module for enum type.
# https://docs.python.org/3.5/library/enum.html
from enum import Enum


# Import some classes from the Blender mathutils module, so that values of these
# types can be detected by GET. They need to be converted into list()s so that
# they can be JSON dumped.
# from mathutils import Vector, Matrix, Quaternion

class RestMethod(Enum):
    DELETE = 1
    GET    = 2
    PATCH  = 3
    POST   = 4
    PUT    = 5

class RestInterface(object):
    
    def verbosely(self, origin__name__, *args):
        """Print, if verbose. Always pass __name__ as the first argument."""
        if not self.verbose:
            return False
        print(origin__name__, *args)
        return True

    def rest_traverse1(self, path, creating=False):
        """Get one item."""
        pass
    
    def rest_traverse(self, path, creating=False):
        """Descend the structure."""
        pass


    def rest_PATCH(self, valueDict):
        for key, value in valueDict:
            if hasattr(self.restPrincipal, key):
                setattr(self.restPrincipal, key, value)
            else:
                # If key is numeric
                # If my dictionary has it
                pass
        pass

    @property
    def principal(self):
        return self._principal
    @principal.setter
    def principal(self, principal):
        self._principal = principal
    
    @staticmethod
    def str_quote(str_, quote):
        if isinstance(str_, str):
            return str_.join((quote, quote))
        else:
            return str(str_)
    
    @staticmethod
    def pathify(path, quote='"'):
        if path is not None:
            if isinstance(path, str):
                yield path, RestInterface.str_quote(path, quote)
            else:
                try:
                    for item in path:
                        yield item, RestInterface.str_quote(item, quote)
                except TypeError:
                    # Not a string, also not iterable. Probably a number.
                    yield path, str(path)
    
    class PointType(Enum):
        LIST = 1
        DICTIONARY = 2
        ATTR = 3
    
    @staticmethod
    def get_point(parent, specifier):
        if specifier is None:
            raise TypeError("Specifier must be string or numeric, but is None.")
        numeric = not isinstance(specifier, str)
        type = None
        if numeric:
            type = RestInterface.PointType.LIST
            try:
                point = parent[specifier]
            except IndexError:
                point = None
            except TypeError:
                type = None
                point = None
            except KeyError:
                type = None
                point = None
        else:
            type = RestInterface.PointType.DICTIONARY
            try:
                in_ = specifier in parent
            except TypeError:
                type = None
                in_ = False
            if in_:
                point = parent[specifier]
            elif hasattr(parent, specifier):
                point = getattr(parent, specifier)
                type = RestInterface.PointType.ATTR
            else:
                point = None
                
        return point, numeric, type
    
    @staticmethod
    def get_path(parent, path):
        for leg, legStr in RestInterface.pathify(path):
            point, numeric, type = RestInterface.get_point(parent, leg)
            if type is None:
                raise TypeError(" ".join((
                    "Couldn't get point for ", legStr, "in", str(parent))))
            if point is None:
                error = " ".join((
                    "No point for", legStr, "in", str(parent)))
                raise IndexError(error) if numeric else KeyError(error)
            parent = point
        
        return parent
    
    def make_point(self, path, index, point=None):
        """
        Default make_point, which can be overridden.
        """
        specifier = path[index]
        if isinstance(specifier, str):
            try:
                if specifier not in point:
                    point[specifier] = None
                return point
            except TypeError:
                # None, or not a dictionary, so create a dictionary.
                return {specifier: None}
        else:
            # It would be super-neat to do this be try:ing the len() and then
            # except TypeError: to set length zero. The problem is that all
            # iterables are OK for len(), so string and dictionary values don't
            # generate the exception.
            length = 0
            if isinstance(point, tuple) or isinstance(point, list):
                length = len(point)
                if length > specifier:
                    return point
            extension = (None,) * ((specifier - length) + 1)
            if isinstance(point, tuple):
                return point + extension
            try:
                point.extend(extension)
                return point
            except AttributeError:
                # None or not a list, so create a list.
                return list(extension)
    
    def _set_path(self, parent, path, value, enumerator):
        self.verbosely(__name__, '_set_path()', parent, path, value)

        try:
            index, (leg, legStr) = next(enumerator)
        except StopIteration:
            return value
        
        wasTuple = isinstance(parent, tuple)

        point, numeric, type = RestInterface.get_point(parent, leg)
        if numeric and isinstance(parent, str):
            # Sorry, have to force descent into a string to fail.
            point = None
        
        self.verbosely(__name__,
            "{:2d} {}\n  {}\n  {}\n  {} {}".format(
                index, legStr, parent, point, str(numeric), str(type)))

        if type is None or point is None:
            parent = self.make_point(path, index, parent)
            self.verbosely(__name__, '_set_path made point', parent)
            point, numeric, type = RestInterface.get_point(parent, leg)

        if type is None:
            raise AssertionError("".join((<commit_msg>Commit before renaming.<commit_after>#!/usr/bin/python
# (c) 2017 <NAME>. MIT licensed, see https://opensource.org/licenses/MIT
# Part of Blender Driver, see https://github.com/sjjhsjjh/blender-driver
"""RESTful interfaces module.

Cannot be run as a program, sorry."""
# Exit if run other than as a module.
if __name__ == '__main__':
    print(__doc__)
    raise SystemExit(1)


#
# Module for enum type.
# https://docs.python.org/3.5/library/enum.html
from enum import Enum


# Import some classes from the Blender mathutils module, so that values of these
# types can be detected by GET. They need to be converted into list()s so that
# they can be JSON dumped.
# from mathutils import Vector, Matrix, Quaternion

class RestMethod(Enum):
    DELETE = 1
    GET    = 2
    PATCH  = 3
    POST   = 4
    PUT    = 5

class RestInterface(object):
    
    def verbosely(self, origin__name__, *args):
        """Print, if verbose. Always pass __name__ as the first argument."""
        if not self.verbose:
            return False
        print(origin__name__, *args)
        return True

    def rest_traverse1(self, path, creating=False):
        """Get one item."""
        pass
    
    def rest_traverse(self, path, creating=False):
        """Descend the structure."""
        pass


    def rest_PATCH(self, valueDict):
        for key, value in valueDict:
            if hasattr(self.restPrincipal, key):
                setattr(self.restPrincipal, key, value)
            else:
                # If key is numeric
                # If my dictionary has it
                pass
        pass

    @property
    def principal(self):
        return self._principal
    @principal.setter
    def principal(self, principal):
        self._principal = principal
    
    @staticmethod
    def str_quote(str_, quote):
        if isinstance(str_, str):
            return str_.join((quote, quote))
        else:
            return str(str_)
    
    @staticmethod
    def pathify(path, quote='"'):
        if path is not None:
            if isinstance(path, str):
                yield path, RestInterface.str_quote(path, quote)
            else:
                try:
                    for item in path:
                        yield item, RestInterface.str_quote(item, quote)
                except TypeError:
                    # Not a string, also not iterable. Probably a number.
                    yield path, str(path)
    
    class PointType(Enum):
        LIST = 1
        DICTIONARY = 2
        ATTR = 3
    
    @staticmethod
    def get_point(parent, specifier):
        if specifier is None:
            raise TypeError("Specifier must be string or numeric, but is None.")
        numeric = not isinstance(specifier, str)
        type = None
        if numeric:
            type = RestInterface.PointType.LIST
            try:
                point = parent[specifier]
            except IndexError:
                point = None
            except TypeError:
                type = None
                point = None
            except KeyError:
                type = None
                point = None
        else:
            type = RestInterface.PointType.DICTIONARY
            try:
                in_ = specifier in parent
            except TypeError:
                type = None
                in_ = False
            if in_:
                point = parent[specifier]
            elif hasattr(parent, specifier):
                point = getattr(parent, specifier)
                type = RestInterface.PointType.ATTR
            else:
                point = None
                
        return point, numeric, type
    
    @staticmethod
    def get_path(parent, path):
        for leg, legStr in RestInterface.pathify(path):
            point, numeric, type = RestInterface.get_point(parent, leg)
            if type is None:
                raise TypeError(" ".join((
                    "Couldn't get point for ", legStr, "in", str(parent))))
            if point is None:
                error = " ".join((
                    "No point for", legStr, "in", str(parent)))
                raise IndexError(error) if numeric else KeyError(error)
            parent = point
        
        return parent
    
    def make_point(self, path, index, point=None):
        """
        Default make_point, which can be overridden.
        """
        specifier = path[index]
        if isinstance(specifier, str):
            try:
                if specifier not in point:
                    point[specifier] = None
                return point
            except TypeError:
                # None, or not a dictionary, so create a dictionary.
                return {specifier: None}
        else:
            # It would be super-neat to do this by try:ing the len() and then
            # except TypeError: to set length zero. The problem is that all
            # iterables are OK for len(), so string and dictionary values don't
            # generate the exception.
            length = 0
            if isinstance(point, (tuple, list)):
                length = len(point)
                if length > specifier:
                    return point
            extension = (None,) * ((specifier - length) + 1)
            if isinstance(point, tuple):
                return point + extension
            try:
                point.extend(extension)
                return point
            except AttributeError:
                # None or not a list, so create a list.
                return list(extension)
    
    def _set_path(self, parent, path, value, enumerator):
        self.verbosely(__name__, '_set_path()', parent, path, value)

        try:
            index, (leg, legStr) = next(enumerator)
        except StopIteration:
            return value
        
        wasTuple = isinstance(parent, tuple)

        point, numeric, type = RestInterface.get_point(parent, leg)
        if numeric and isinstance(parent, str):
            # Sorry, hack to force descent into a string to fail if setting.
            point = None
        
        self.verbosely(__name__,
            "{:2d} {}\n  {}\n  {}\n  {} {}".format(
                index, legStr, parent, point, str(numeric), str(type)))

        if type is None or point is None:
            parent = self.make_point(path, index, parent)
            self.verbosely(__name__, '_set_path made point', parent)
            point, numeric, type = RestInterface.get_point(parent, leg)

        if type is None:
            raise AssertionError("".join((
{'fraction_non_alphanumeric': 0.08316755929609794, 'fraction_numerical': 0.002907421576128539, 'mean_word_length': 1.5913957176843774, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 7, 'https://': 6, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4280707', 'n_tokens_mistral': 3494, 'n_tokens_neox': 3302, 'n_words': 1151}