This file is indexed.

/usr/share/pyshared/spyderlib/rope_patch.py is in python-spyderlib 2.1.9-1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
# -*- coding: utf-8 -*-
#
# Copyright © 2011 Pierre Raybaut
# Licensed under the terms of the MIT License
# (see spyderlib/__init__.py for details)

"""
Patching rope:

[1] For compatibility with Spyder's standalone version, build with py2exe or
    cx_Freeze

[2] For better performances, see this thread:
http://groups.google.com/group/rope-dev/browse_thread/thread/57de5731f202537a

[3] To avoid considering folders without __init__.py as Python packages, thus
avoiding side effects as non-working introspection features on a Python module
or package when a folder in current directory has the same name.
See this thread:
http://groups.google.com/group/rope-dev/browse_thread/thread/924c4b5a6268e618

[4] To avoid rope adding a 2 spaces indent to every docstring it gets, because
it breaks the work of Sphinx on the Object Inspector.
"""

def apply():
    """Monkey patching rope
    
    See [1], [2] and [3] in module docstring."""
    import rope
    if rope.VERSION not in ('0.9.3', '0.9.2'):
        raise ImportError, "rope %s can't be patched" % rope.VERSION

    # [1] Patching project.Project for compatibility with py2exe/cx_Freeze
    #     distributions
    from spyderlib.baseconfig import is_py2exe_or_cx_Freeze
    if is_py2exe_or_cx_Freeze():
        from rope.base import project
        class PatchedProject(project.Project):
            def _default_config(self):
                # py2exe/cx_Freeze distribution
                from spyderlib.baseconfig import get_module_source_path
                fname = get_module_source_path('spyderlib',
                                               'default_config.py')
                return open(fname, 'rb').read()
        project.Project = PatchedProject
    
    # Patching pycore.PyCore...
    from rope.base import pycore
    class PatchedPyCore(pycore.PyCore):
        # [2] ...so that forced builtin modules (i.e. modules that were 
        # declared as 'extension_modules' in rope preferences) will be indeed
        # recognized as builtins by rope, as expected
        def get_module(self, name, folder=None):
            """Returns a `PyObject` if the module was found."""
            # check if this is a builtin module
            pymod = self._builtin_module(name)
            if pymod is not None:
                return pymod
            module = self.find_module(name, folder)
            if module is None:
                raise pycore.ModuleNotFoundError(
                                            'Module %s not found' % name)
            return self.resource_to_pyobject(module)
        # [3] ...to avoid considering folders without __init__.py as Python
        # packages
        def _find_module_in_folder(self, folder, modname):
            module = folder
            packages = modname.split('.')
            for pkg in packages[:-1]:
                if  module.is_folder() and module.has_child(pkg):
                    module = module.get_child(pkg)
                else:
                    return None
            if module.is_folder():
                if module.has_child(packages[-1]) and \
                   module.get_child(packages[-1]).is_folder() and \
                   module.get_child(packages[-1]).has_child('__init__.py'):
                    return module.get_child(packages[-1])
                elif module.has_child(packages[-1] + '.py') and \
                     not module.get_child(packages[-1] + '.py').is_folder():
                    return module.get_child(packages[-1] + '.py')
    pycore.PyCore = PatchedPyCore
    
    # [2] Patching BuiltinFunction for the calltip/doc functions to be 
    # able to retrieve the function signatures with forced builtins
    from rope.base import builtins, pyobjects
    from spyderlib.utils.dochelpers import getargs
    class PatchedBuiltinFunction(builtins.BuiltinFunction):
        def __init__(self, returned=None, function=None, builtin=None,
                     argnames=[], parent=None):
            builtins._BuiltinElement.__init__(self, builtin, parent)
            pyobjects.AbstractFunction.__init__(self)
            self.argnames = argnames
            if not argnames and builtin:
                self.argnames = getargs(self.builtin)
            if self.argnames is None:
                self.argnames = []
            self.returned = returned
            self.function = function
    builtins.BuiltinFunction = PatchedBuiltinFunction

    # [2] Patching BuiltinName for the go to definition feature to simply work 
    # with forced builtins
    from rope.base import libutils
    import inspect
    class PatchedBuiltinName(builtins.BuiltinName):
        def _pycore(self):
            p = self.pyobject
            while p.parent is not None:
                p = p.parent
            if isinstance(p, builtins.BuiltinModule) and p.pycore is not None:
                return p.pycore
        def get_definition_location(self):
            if not inspect.isbuiltin(self.pyobject):
                _lines, lineno = inspect.getsourcelines(self.pyobject.builtin)
                path = inspect.getfile(self.pyobject.builtin)
                pycore = self._pycore()
                if pycore and pycore.project:
                    resource = libutils.path_to_resource(pycore.project, path)
                    module = pyobjects.PyModule(pycore, None, resource)
                    return (module, lineno)
            return (None, None)
    builtins.BuiltinName = PatchedBuiltinName
    
    # [4] Patching PyDocExtractor so that _get_class_docstring and
    # _get_single_function_docstring don't add a 2 spaces indent to
    # every docstring. The only value that we are modifying is the indent
    # keyword, from 2 to 0.
    from rope.contrib import codeassist
    class PatchedPyDocExtractor(codeassist.PyDocExtractor):
        def _get_class_docstring(self, pyclass):
            contents = self._trim_docstring(pyclass.get_doc(), indents=0)
            supers = [super.get_name() for super in pyclass.get_superclasses()]
            doc = 'class %s(%s):\n\n' % (pyclass.get_name(), ', '.join(supers)) + contents

            if '__init__' in pyclass:
                init = pyclass['__init__'].get_object()
                if isinstance(init, pyobjects.AbstractFunction):
                    doc += '\n\n' + self._get_single_function_docstring(init)
            return doc
            
        def _get_single_function_docstring(self, pyfunction):
            signature = self._get_function_signature(pyfunction)
            docs = pyfunction.get_doc()
            docs = self._trim_docstring(pyfunction.get_doc(), indents=0)
            return docs
            return signature + ':\n\n' + docs
    codeassist.PyDocExtractor = PatchedPyDocExtractor