Exemplo n.º 1
0
 def get_doc(obj, indent=False):
     doc = inspect.getdoc(obj)
     if doc:
         doc = ('r"""\n%s\n"""\n' % doc)
         if indent:
             doc = parsing.indent_block(doc)
         return doc
     return ''
Exemplo n.º 2
0
 def get_doc(obj, indent=False):
     doc = inspect.getdoc(obj)
     if doc:
         doc = ('r"""\n%s\n"""\n' % doc)
         if indent:
             doc = parsing.indent_block(doc)
         return doc
     return ''
Exemplo n.º 3
0
    def _generate_code(self, scope, mixin_funcs, depth=0):
        """
        Generate a string, which uses python syntax as an input to the
        PyFuzzyParser.
        """
        def get_doc(obj, indent=False):
            doc = inspect.getdoc(obj)
            if doc:
                doc = ('r"""\n%s\n"""\n' % doc)
                if indent:
                    doc = parsing.indent_block(doc)
                return doc
            return ''

        def is_in_base_classes(cls, name, comparison):
            """ Base classes may contain the exact same object """
            if name in mixin_funcs:
                return False
            try:
                mro = cls.mro()
            except TypeError:
                # this happens, if cls == type
                return False
            for base in mro[1:]:
                try:
                    attr = getattr(base, name)
                except AttributeError:
                    continue
                if attr == comparison:
                    return True
            return False

        def get_scope_objects(names):
            """
            Looks for the names defined with dir() in an objects and divides
            them into different object types.
            """
            classes = {}
            funcs = {}
            stmts = {}
            members = {}
            for n in names:
                if '__' in n and n not in mixin_funcs:
                    continue
                try:
                    # this has a builtin_function_or_method
                    exe = getattr(scope, n)
                except AttributeError:
                    # happens e.g. in properties of
                    # PyQt4.QtGui.QStyleOptionComboBox.currentText
                    # -> just set it to None
                    members[n] = None
                else:
                    if inspect.isclass(scope):
                        if is_in_base_classes(scope, n, exe):
                            continue
                    if inspect.isbuiltin(exe) or inspect.ismethod(exe) \
                                or inspect.ismethoddescriptor(exe):
                        funcs[n] = exe
                    elif inspect.isclass(exe):
                        classes[n] = exe
                    elif inspect.ismemberdescriptor(exe):
                        members[n] = exe
                    else:
                        stmts[n] = exe
            return classes, funcs, stmts, members

        code = ''
        if inspect.ismodule(scope):  # generate comment where the code's from.
            try:
                path = scope.__file__
            except AttributeError:
                path = '?'
            code += '# Generated module %s from %s\n' % (scope.__name__, path)

        code += get_doc(scope)

        names = set(dir(scope)) - set(['__file__', '__name__', '__doc__',
                                                '__path__', '__package__'])

        classes, funcs, stmts, members = get_scope_objects(names)

        # classes
        for name, cl in classes.items():
            bases = (c.__name__ for c in cl.__bases__)
            code += 'class %s(%s):\n' % (name, ','.join(bases))
            if depth == 0:
                try:
                    mixin = mixin_funcs[name]
                except KeyError:
                    mixin = {}
                cl_code = self._generate_code(cl, mixin, depth + 1)
                code += parsing.indent_block(cl_code)
            code += '\n'

        # functions
        for name, func in funcs.items():
            params, ret = parse_function_doc(func)
            if depth > 0:
                params = 'self, ' + params
            doc_str = get_doc(func, indent=True)
            try:
                mixin = mixin_funcs[name]
            except KeyError:
                # normal code generation
                code += 'def %s(%s):\n' % (name, params)
                code += doc_str
                code += parsing.indent_block('%s\n\n' % ret)
            else:
                # generation of code with mixins
                # the parser only supports basic functions with a newline after
                # the double dots
                # find doc_str place
                pos = re.search(r'\):\s*\n', mixin).end()
                if pos is None:
                    raise Exception("Builtin function not parsed correctly")
                code += mixin[:pos] + doc_str + mixin[pos:]

        # class members (functions) properties?
        for name, func in members.items():
            # recursion problem in properties TODO remove
            if name in ['fget', 'fset', 'fdel']:
                continue
            ret = 'pass'
            code += '@property\ndef %s(self):\n' % (name)
            code += parsing.indent_block(get_doc(func) + '%s\n\n' % ret)

        # variables
        for name, value in stmts.items():
            if is_py3k:
                file_type = io.TextIOWrapper
            else:
                file_type = types.FileType
            if type(value) == file_type:
                value = 'open()'
            elif name == 'None':
                value = ''
            elif type(value).__name__ in ['int', 'bool', 'float',
                                          'dict', 'list', 'tuple']:
                value = repr(value)
            else:
                # get the type, if the type is not simple.
                mod = type(value).__module__
                value = type(value).__name__ + '()'
                if mod != '__builtin__':
                    value = '%s.%s' % (mod, value)
            code += '%s = %s\n' % (name, value)

        if depth == 0:
            #with open('writeout.py', 'w') as f:
            #    f.write(code)
            #import sys
            #sys.stdout.write(code)
            #exit()
            pass
        return code
Exemplo n.º 4
0
def _generate_code(scope, mixin_funcs={}, depth=0):
    """
    Generate a string, which uses python syntax as an input to the
    PyFuzzyParser.
    """
    def get_doc(obj, indent=False):
        doc = inspect.getdoc(obj)
        if doc:
            doc = ('r"""\n%s\n"""\n' % doc)
            if indent:
                doc = parsing.indent_block(doc)
            return doc
        return ''

    def is_in_base_classes(cls, name, comparison):
        """ Base classes may contain the exact same object """
        if name in mixin_funcs:
            return False
        try:
            mro = cls.mro()
        except TypeError:
            # this happens, if cls == type
            return False
        for base in mro[1:]:
            try:
                attr = getattr(base, name)
            except AttributeError:
                continue
            if attr == comparison:
                return True
        return False

    def get_scope_objects(names):
        """
        Looks for the names defined with dir() in an objects and divides
        them into different object types.
        """
        classes = {}
        funcs = {}
        stmts = {}
        members = {}
        for n in names:
            try:
                # this has a builtin_function_or_method
                exe = getattr(scope, n)
            except AttributeError:
                # happens e.g. in properties of
                # PyQt4.QtGui.QStyleOptionComboBox.currentText
                # -> just set it to None
                members[n] = None
            else:
                if inspect.isclass(scope):
                    if is_in_base_classes(scope, n, exe):
                        continue
                if inspect.isbuiltin(exe) or inspect.ismethod(exe) \
                            or inspect.ismethoddescriptor(exe):
                    funcs[n] = exe
                elif inspect.isclass(exe):
                    classes[n] = exe
                elif inspect.ismemberdescriptor(exe):
                    members[n] = exe
                else:
                    stmts[n] = exe
        return classes, funcs, stmts, members

    code = ''
    if inspect.ismodule(scope):  # generate comment where the code's from.
        try:
            path = scope.__file__
        except AttributeError:
            path = '?'
        code += '# Generated module %s from %s\n' % (scope.__name__, path)

    code += get_doc(scope)

    names = set(dir(scope)) - set(['__file__', '__name__', '__doc__',
                                            '__path__', '__package__']) \
                            | set(['mro'])

    classes, funcs, stmts, members = get_scope_objects(names)

    # classes
    for name, cl in classes.items():
        bases = (c.__name__ for c in cl.__bases__)
        code += 'class %s(%s):\n' % (name, ','.join(bases))
        if depth == 0:
            try:
                mixin = mixin_funcs[name]
            except KeyError:
                mixin = {}
            if not isinstance(mixin, dict):
                mixin = {}
            cl_code = _generate_code(cl, mixin, depth + 1)
            code += parsing.indent_block(cl_code)
        code += '\n'

    # functions
    for name, func in funcs.items():
        params, ret = parse_function_doc(func)
        if depth > 0:
            params = 'self, ' + params
        doc_str = get_doc(func, indent=True)
        try:
            mixin = mixin_funcs[name]
            # In pypy reversed is builtin
            if isinstance(mixin, dict):
                raise KeyError()
        except KeyError:
            # normal code generation
            code += 'def %s(%s):\n' % (name, params)
            code += doc_str
            code += parsing.indent_block('%s\n\n' % ret)
        else:
            # generation of code with mixins
            # the parser only supports basic functions with a newline after
            # the double dots
            # find doc_str place
            pos = re.search(r'\):\s*\n', mixin).end()
            if pos is None:
                raise Exception("Builtin function not parsed correctly")
            code += mixin[:pos] + doc_str + mixin[pos:]

    # class members (functions) properties?
    for name, func in members.items():
        # recursion problem in properties TODO remove
        if name in ['fget', 'fset', 'fdel']:
            continue
        ret = 'pass'
        code += '@property\ndef %s(self):\n' % (name)
        code += parsing.indent_block(get_doc(func) + '%s\n\n' % ret)

    # variables
    for name, value in stmts.items():
        if is_py3k:
            file_type = io.TextIOWrapper
        else:
            file_type = types.FileType
        if type(value) == file_type:
            value = 'open()'
        elif name == 'None':
            value = ''
        elif type(value).__name__ in [
                'int', 'bool', 'float', 'dict', 'list', 'tuple'
        ]:
            value = repr(value)
        else:
            # get the type, if the type is not simple.
            mod = type(value).__module__
            value = type(value).__name__ + '()'
            if mod != '__builtin__':
                value = '%s.%s' % (mod, value)
        code += '%s = %s\n' % (name, value)

    if depth == 0:
        #with open('writeout.py', 'w') as f:
        #    f.write(code)
        #import sys
        #sys.stdout.write(code)
        #exit()
        pass
    return code