Welcome to mirror list, hosted at ThFree Co, Russian Federation.

complete_import.py « autocomplete « bl_console_utils « modules « scripts « release - git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 2f321fee0b280f38d2fb1b6c608fa0b36b70085e (plain)
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
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
# SPDX-License-Identifier: GPL-2.0-or-later

# Copyright (c) 2009 Fernando Perez, www.stani.be

# Original copyright (see docstring):
# ****************************************************************************
#       Copyright (C) 2001-2006 Fernando Perez <fperez@colorado.edu>
#
#  Distributed under the terms of the BSD License.  The full license is in
#  the file COPYING, distributed as part of this software.
# ****************************************************************************

"""Completer for import statements

Original code was from IPython/Extensions/ipy_completers.py. The following
changes have been made:
- ported to python3
- pep8 polishing
- limit list of modules to prefix in case of "from w"
- sorted modules
- added sphinx documentation
- complete() returns a blank list of the module isn't found
"""


import os
import sys

TIMEOUT_STORAGE = 3  # Time in secs after which the root-modules will be stored
TIMEOUT_GIVEUP = 20  # Time in secs after which we give up

ROOT_MODULES = None


def get_root_modules():
    """
    Returns a list containing the names of all the modules available in the
    folders of the python-path.

    :returns: modules
    :rtype: list
    """
    global ROOT_MODULES
    modules = []
    if not(ROOT_MODULES is None):
        return ROOT_MODULES
    from time import time
    t = time()
    store = False
    for path in sys.path:
        modules += module_list(path)
        if time() - t >= TIMEOUT_STORAGE and not store:
            # Caching the list of root modules, please wait!
            store = True
        if time() - t > TIMEOUT_GIVEUP:
            # This is taking too long, we give up.
            ROOT_MODULES = []
            return []

    modules += sys.builtin_module_names

    # needed for modules defined in C
    modules += sys.modules.keys()

    modules = list(set(modules))
    if '__init__' in modules:
        modules.remove('__init__')
    modules = sorted(modules)
    if store:
        ROOT_MODULES = modules
    return modules


def module_list(path):
    """
    Return the list containing the names of the modules available in
    the given folder.

    :param path: folder path
    :type path: str
    :returns: modules
    :rtype: list
    """

    if os.path.isdir(path):
        folder_list = os.listdir(path)
    elif path.endswith('.egg'):
        from zipimport import zipimporter
        try:
            folder_list = [f for f in zipimporter(path)._files]
        except:
            folder_list = []
    else:
        folder_list = []
    #folder_list = glob.glob(os.path.join(path,'*'))
    folder_list = [
        p for p in folder_list
        if (os.path.exists(os.path.join(path, p, '__init__.py')) or
            p[-3:] in {'.py', '.so'} or
            p[-4:] in {'.pyc', '.pyo', '.pyd'})]

    folder_list = [os.path.basename(p).split('.')[0] for p in folder_list]
    return folder_list


def complete(line):
    """
    Returns a list containing the completion possibilities for an import line.

    :param line:

        incomplete line which contains an import statement::

            import xml.d
            from xml.dom import

    :type line: str
    :returns: list of completion possibilities
    :rtype: list

    >>> complete('import weak')
    ['weakref']
    >>> complete('from weakref import C')
    ['CallableProxyType']
    """
    import inspect

    def try_import(mod, *, only_modules=False):

        def is_importable(module, attr):
            if only_modules:
                return inspect.ismodule(getattr(module, attr))
            else:
                return not(attr[:2] == '__' and attr[-2:] == '__')

        try:
            m = __import__(mod)
        except:
            return []
        mods = mod.split('.')
        for module in mods[1:]:
            m = getattr(m, module)
        if (not hasattr(m, '__file__')) or (not only_modules) or\
           (hasattr(m, '__file__') and '__init__' in m.__file__):
            completion_list = [attr for attr in dir(m)
                               if is_importable(m, attr)]
        else:
            completion_list = []
        completion_list.extend(getattr(m, '__all__', []))
        if hasattr(m, '__file__') and '__init__' in m.__file__:
            completion_list.extend(module_list(os.path.dirname(m.__file__)))
        completion_list = list(set(completion_list))
        if '__init__' in completion_list:
            completion_list.remove('__init__')
        return completion_list

    def filter_prefix(names, prefix):
        return [name for name in names if name.startswith(prefix)]

    words = line.split(' ')
    if len(words) == 3 and words[0] == 'from':
        return ['import ']
    if len(words) < 3 and (words[0] in {'import', 'from'}):
        if len(words) == 1:
            return get_root_modules()
        mod = words[1].split('.')
        if len(mod) < 2:
            return filter_prefix(get_root_modules(), words[-1])
        completion_list = try_import('.'.join(mod[:-1]), only_modules=True)
        completion_list = ['.'.join(mod[:-1] + [el]) for el in completion_list]
        return filter_prefix(completion_list, words[-1])
    if len(words) >= 3 and words[0] == 'from':
        mod = words[1]
        return filter_prefix(try_import(mod), words[-1])

    # get here if the import is not found
    # import invalidmodule
    #                      ^, in this case return nothing
    return []