This file is indexed.

/usr/share/pyshared/jedi/docstrings.py is in python-jedi 0.7.0-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
"""
Docstrings are another source of information for functions and classes.
:mod:`dynamic` tries to find all executions of functions, while the docstring
parsing is much easier. There are two different types of docstrings that |jedi|
understands:

- `Sphinx <http://sphinx-doc.org/markup/desc.html#info-field-lists>`_
- `Epydoc <http://epydoc.sourceforge.net/manual-fields.html>`_

For example, the sphinx annotation ``:type foo: str`` clearly states that the
type of ``foo`` is ``str``.

As an addition to parameter searching, this module also provides return
annotations.
"""

import re

from jedi import cache
from jedi import parsing
import evaluate
import evaluate_representation as er

DOCSTRING_PARAM_PATTERNS = [
    r'\s*:type\s+%s:\s*([^\n]+)',  # Sphinx
    r'\s*@type\s+%s:\s*([^\n]+)',  # Epydoc
]

DOCSTRING_RETURN_PATTERNS = [
    re.compile(r'\s*:rtype:\s*([^\n]+)', re.M),  # Sphinx
    re.compile(r'\s*@rtype:\s*([^\n]+)', re.M),  # Epydoc
]

REST_ROLE_PATTERN = re.compile(r':[^`]+:`([^`]+)`')


@cache.memoize_default()
def follow_param(param):
    func = param.parent_function
    # print func, param, param.parent_function
    param_str = _search_param_in_docstr(func.docstr, str(param.get_name()))
    user_position = (1, 0)

    if param_str is not None:

        # Try to import module part in dotted name.
        # (e.g., 'threading' in 'threading.Thread').
        if '.' in param_str:
            param_str = 'import %s\n%s' % (
                param_str.rsplit('.', 1)[0],
                param_str)
            user_position = (2, 0)

        p = parsing.Parser(param_str, None, user_position,
                           no_docstr=True)
        if p.user_stmt is None:
            return []
        return evaluate.follow_statement(p.user_stmt)
    return []


def _search_param_in_docstr(docstr, param_str):
    """
    Search `docstr` for a type of `param_str`.

    >>> _search_param_in_docstr(':type param: int', 'param')
    'int'
    >>> _search_param_in_docstr('@type param: int', 'param')
    'int'
    >>> _search_param_in_docstr(
    ...   ':type param: :class:`threading.Thread`', 'param')
    'threading.Thread'
    >>> _search_param_in_docstr('no document', 'param') is None
    True

    """
    # look at #40 to see definitions of those params
    patterns = [re.compile(p % re.escape(param_str))
                for p in DOCSTRING_PARAM_PATTERNS]
    for pattern in patterns:
        match = pattern.search(docstr)
        if match:
            return _strip_rest_role(match.group(1))

    return None


def _strip_rest_role(type_str):
    """
    Strip off the part looks like a ReST role in `type_str`.

    >>> _strip_rest_role(':class:`ClassName`')  # strip off :class:
    'ClassName'
    >>> _strip_rest_role(':py:obj:`module.Object`')  # works with domain
    'module.Object'
    >>> _strip_rest_role('ClassName')  # do nothing when not ReST role
    'ClassName'

    See also:
    http://sphinx-doc.org/domains.html#cross-referencing-python-objects

    """
    match = REST_ROLE_PATTERN.match(type_str)
    if match:
        return match.group(1)
    else:
        return type_str


def find_return_types(func):
    def search_return_in_docstr(code):
        for p in DOCSTRING_RETURN_PATTERNS:
            match = p.search(code)
            if match:
                return match.group(1)

    if isinstance(func, er.InstanceElement):
        func = func.var

    if isinstance(func, er.Function):
        func = func.base_func

    type_str = search_return_in_docstr(func.docstr)
    if not type_str:
        return []

    p = parsing.Parser(type_str, None, (1, 0), no_docstr=True)
    if p.user_stmt is None:
        return []
    p.user_stmt.parent = func
    return list(evaluate.follow_statement(p.user_stmt))