/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
5387.2.7 by John Arbash Meinel
Merge bzr.dev 5444 to resolve some small text conflicts.
1
# Copyright (C) 2006-2010 Canonical Ltd
1996.1.1 by John Arbash Meinel
Adding a ScopeReplacer class, which can replace itself on demand
2
#
3
# This program is free software; you can redistribute it and/or modify
4
# it under the terms of the GNU General Public License as published by
5
# the Free Software Foundation; either version 2 of the License, or
6
# (at your option) any later version.
7
#
8
# This program is distributed in the hope that it will be useful,
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
# GNU General Public License for more details.
12
#
13
# You should have received a copy of the GNU General Public License
14
# along with this program; if not, write to the Free Software
4183.7.1 by Sabin Iacob
update FSF mailing address
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
1996.1.1 by John Arbash Meinel
Adding a ScopeReplacer class, which can replace itself on demand
16
17
"""Functionality to create lazy evaluation objects.
18
19
This includes waiting to import a module until it is actually used.
1996.1.26 by John Arbash Meinel
Update HACKING and docstrings
20
21
Most commonly, the 'lazy_import' function is used to import other modules
5891.1.2 by Andrew Bennetts
Fix a bunch of docstring formatting nits, making pydoctor a bit happier.
22
in an on-demand fashion. Typically use looks like::
23
6624 by Jelmer Vernooij
Merge Python3 porting work ('py3 pokes')
24
    from .lazy_import import lazy_import
1996.1.26 by John Arbash Meinel
Update HACKING and docstrings
25
    lazy_import(globals(), '''
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
26
    from breezy import (
1996.1.26 by John Arbash Meinel
Update HACKING and docstrings
27
        errors,
28
        osutils,
29
        branch,
30
        )
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
31
    import breezy.branch
1996.1.26 by John Arbash Meinel
Update HACKING and docstrings
32
    ''')
33
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
34
Then 'errors, osutils, branch' and 'breezy' will exist as lazy-loaded
5891.1.2 by Andrew Bennetts
Fix a bunch of docstring formatting nits, making pydoctor a bit happier.
35
objects which will be replaced with a real object on first use.
1996.1.26 by John Arbash Meinel
Update HACKING and docstrings
36
5891.1.2 by Andrew Bennetts
Fix a bunch of docstring formatting nits, making pydoctor a bit happier.
37
In general, it is best to only load modules in this way. This is because
38
it isn't safe to pass these variables to other functions before they
39
have been replaced. This is especially true for constants, sometimes
40
true for classes or functions (when used as a factory, or you want
41
to inherit from them).
1996.1.1 by John Arbash Meinel
Adding a ScopeReplacer class, which can replace itself on demand
42
"""
43
6379.6.7 by Jelmer Vernooij
Move importing from future until after doc string, otherwise the doc string will disappear.
44
from __future__ import absolute_import
45
1996.1.1 by John Arbash Meinel
Adding a ScopeReplacer class, which can replace itself on demand
46
47
class ScopeReplacer(object):
48
    """A lazy object that will replace itself in the appropriate scope.
49
50
    This object sits, ready to create the real object the first time it is
51
    needed.
52
    """
53
2399.1.8 by John Arbash Meinel
Change lazy_import to allow proxying when necessary.
54
    __slots__ = ('_scope', '_factory', '_name', '_real_obj')
2413.4.1 by John Arbash Meinel
Cherrypick just the epydoc builder changes.
55
6111.3.2 by Martin von Gagern
Allow subclasses to override _should_proxy.
56
    # If you to do x = y, setting this to False will disallow access to
57
    # members from the second variable (i.e. x). This should normally
58
    # be enabled for reasons of thread safety and documentation, but
59
    # will be disabled during the selftest command to check for abuse.
6111.3.1 by Martin von Gagern
Make lazy imports (at least more) thread-safe.
60
    _should_proxy = True
2399.1.11 by John Arbash Meinel
Update lazy_import with tests for the new '_should_proxy' variable.
61
1996.1.1 by John Arbash Meinel
Adding a ScopeReplacer class, which can replace itself on demand
62
    def __init__(self, scope, factory, name):
63
        """Create a temporary object in the specified scope.
64
        Once used, a real object will be placed in the scope.
65
66
        :param scope: The scope the object should appear in
67
        :param factory: A callable that will create the real object.
68
            It will be passed (self, scope, name)
69
        :param name: The variable name in the given scope.
70
        """
1551.18.22 by Aaron Bentley
Fix exception when ScopeReplacer is assigned to before retrieving any members
71
        object.__setattr__(self, '_scope', scope)
72
        object.__setattr__(self, '_factory', factory)
73
        object.__setattr__(self, '_name', name)
74
        object.__setattr__(self, '_real_obj', None)
1996.1.1 by John Arbash Meinel
Adding a ScopeReplacer class, which can replace itself on demand
75
        scope[name] = self
76
6111.3.1 by Martin von Gagern
Make lazy imports (at least more) thread-safe.
77
    def _resolve(self):
78
        """Return the real object for which this is a placeholder"""
6111.3.8 by Martin Packman
Fold ScopeReplacer._duplicate_replacement back into object replacing method
79
        name = object.__getattribute__(self, '_name')
6111.3.1 by Martin von Gagern
Make lazy imports (at least more) thread-safe.
80
        real_obj = object.__getattribute__(self, '_real_obj')
6111.3.8 by Martin Packman
Fold ScopeReplacer._duplicate_replacement back into object replacing method
81
        if real_obj is None:
82
            # No obj generated previously, so generate from factory and scope.
83
            factory = object.__getattribute__(self, '_factory')
84
            scope = object.__getattribute__(self, '_scope')
85
            obj = factory(self, scope, name)
86
            if obj is self:
87
                raise errors.IllegalUseOfScopeReplacer(name, msg="Object tried"
88
                    " to replace itself, check it's not using its own scope.")
89
90
            # Check if another thread has jumped in while obj was generated.
91
            real_obj = object.__getattribute__(self, '_real_obj')
92
            if real_obj is None:
93
                # Still no prexisting obj, so go ahead and assign to scope and
94
                # return. There is still a small window here where races will
95
                # not be detected, but safest to avoid additional locking.
96
                object.__setattr__(self, '_real_obj', obj)
97
                scope[name] = obj
98
                return obj
99
100
        # Raise if proxying is disabled as obj has already been generated.
101
        if not ScopeReplacer._should_proxy:
102
            raise errors.IllegalUseOfScopeReplacer(
103
                name, msg="Object already replaced, did you assign it"
104
                          " to another variable?")
105
        return real_obj
1996.1.1 by John Arbash Meinel
Adding a ScopeReplacer class, which can replace itself on demand
106
107
    def __getattribute__(self, attr):
6111.3.1 by Martin von Gagern
Make lazy imports (at least more) thread-safe.
108
        obj = object.__getattribute__(self, '_resolve')()
1996.1.1 by John Arbash Meinel
Adding a ScopeReplacer class, which can replace itself on demand
109
        return getattr(obj, attr)
110
1551.18.22 by Aaron Bentley
Fix exception when ScopeReplacer is assigned to before retrieving any members
111
    def __setattr__(self, attr, value):
6111.3.1 by Martin von Gagern
Make lazy imports (at least more) thread-safe.
112
        obj = object.__getattribute__(self, '_resolve')()
1551.18.22 by Aaron Bentley
Fix exception when ScopeReplacer is assigned to before retrieving any members
113
        return setattr(obj, attr, value)
114
1996.1.1 by John Arbash Meinel
Adding a ScopeReplacer class, which can replace itself on demand
115
    def __call__(self, *args, **kwargs):
6111.3.1 by Martin von Gagern
Make lazy imports (at least more) thread-safe.
116
        obj = object.__getattribute__(self, '_resolve')()
1996.1.1 by John Arbash Meinel
Adding a ScopeReplacer class, which can replace itself on demand
117
        return obj(*args, **kwargs)
118
6111.3.1 by Martin von Gagern
Make lazy imports (at least more) thread-safe.
119
120
def disallow_proxying():
121
    """Disallow lazily imported modules to be used as proxies.
122
123
    Calling this function might cause problems with concurrent imports
124
    in multithreaded environments, but will help detecting wasteful
125
    indirection, so it should be called when executing unit tests.
126
6111.3.5 by Martin Packman
Remove _last_duplicate_replacement complication from lazy imports
127
    Only lazy imports that happen after this call are affected.
128
    """
6111.3.1 by Martin von Gagern
Make lazy imports (at least more) thread-safe.
129
    ScopeReplacer._should_proxy = False
130
1996.1.1 by John Arbash Meinel
Adding a ScopeReplacer class, which can replace itself on demand
131
7011.1.1 by Martin
Make replacement for lazy import tests less dodgy
132
_builtin_import = __import__
133
134
1996.1.2 by John Arbash Meinel
start working on some lazy importing code
135
class ImportReplacer(ScopeReplacer):
136
    """This is designed to replace only a portion of an import list.
137
138
    It will replace itself with a module, and then make children
139
    entries also ImportReplacer objects.
140
141
    At present, this only supports 'import foo.bar.baz' syntax.
142
    """
143
1996.1.23 by John Arbash Meinel
Clean up comment as suggested by Robert
144
    # '_import_replacer_children' is intentionally a long semi-unique name
145
    # that won't likely exist elsewhere. This allows us to detect an
146
    # ImportReplacer object by using
147
    #       object.__getattribute__(obj, '_import_replacer_children')
148
    # We can't just use 'isinstance(obj, ImportReplacer)', because that
149
    # accesses .__class__, which goes through __getattribute__, and triggers
150
    # the replacement.
1996.1.2 by John Arbash Meinel
start working on some lazy importing code
151
    __slots__ = ('_import_replacer_children', '_member', '_module_path')
152
1996.1.15 by John Arbash Meinel
Everything is now hooked up
153
    def __init__(self, scope, name, module_path, member=None, children={}):
1996.1.2 by John Arbash Meinel
start working on some lazy importing code
154
        """Upon request import 'module_path' as the name 'module_name'.
155
        When imported, prepare children to also be imported.
156
157
        :param scope: The scope that objects should be imported into.
158
            Typically this is globals()
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
159
        :param name: The variable name. Often this is the same as the
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
160
            module_path. 'breezy'
1996.1.4 by John Arbash Meinel
Change how parameters are passed to support 'import root1.mod1 as mod1'
161
        :param module_path: A list for the fully specified module path
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
162
            ['breezy', 'foo', 'bar']
1996.1.2 by John Arbash Meinel
start working on some lazy importing code
163
        :param member: The member inside the module to import, often this is
164
            None, indicating the module is being imported.
165
        :param children: Children entries to be imported later.
1996.1.15 by John Arbash Meinel
Everything is now hooked up
166
            This should be a map of children specifications.
5891.1.2 by Andrew Bennetts
Fix a bunch of docstring formatting nits, making pydoctor a bit happier.
167
            ::
168
            
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
169
                {'foo':(['breezy', 'foo'], None,
170
                    {'bar':(['breezy', 'foo', 'bar'], None {})})
5891.1.2 by Andrew Bennetts
Fix a bunch of docstring formatting nits, making pydoctor a bit happier.
171
                }
172
173
        Examples::
174
1996.1.2 by John Arbash Meinel
start working on some lazy importing code
175
            import foo => name='foo' module_path='foo',
1996.1.15 by John Arbash Meinel
Everything is now hooked up
176
                          member=None, children={}
1996.1.2 by John Arbash Meinel
start working on some lazy importing code
177
            import foo.bar => name='foo' module_path='foo', member=None,
1996.1.15 by John Arbash Meinel
Everything is now hooked up
178
                              children={'bar':(['foo', 'bar'], None, {}}
1996.1.2 by John Arbash Meinel
start working on some lazy importing code
179
            from foo import bar => name='bar' module_path='foo', member='bar'
1996.1.15 by John Arbash Meinel
Everything is now hooked up
180
                                   children={}
1996.1.2 by John Arbash Meinel
start working on some lazy importing code
181
            from foo import bar, baz would get translated into 2 import
182
            requests. On for 'name=bar' and one for 'name=baz'
183
        """
3376.2.4 by Martin Pool
Remove every assert statement from bzrlib!
184
        if (member is not None) and children:
185
            raise ValueError('Cannot supply both a member and children')
1996.1.2 by John Arbash Meinel
start working on some lazy importing code
186
1551.18.22 by Aaron Bentley
Fix exception when ScopeReplacer is assigned to before retrieving any members
187
        object.__setattr__(self, '_import_replacer_children', children)
188
        object.__setattr__(self, '_member', member)
189
        object.__setattr__(self, '_module_path', module_path)
1996.1.3 by John Arbash Meinel
Basic single-level imports work
190
191
        # Indirecting through __class__ so that children can
192
        # override _import (especially our instrumented version)
193
        cls = object.__getattribute__(self, '__class__')
1996.1.2 by John Arbash Meinel
start working on some lazy importing code
194
        ScopeReplacer.__init__(self, scope=scope, name=name,
1996.1.3 by John Arbash Meinel
Basic single-level imports work
195
                               factory=cls._import)
1996.1.2 by John Arbash Meinel
start working on some lazy importing code
196
197
    def _import(self, scope, name):
198
        children = object.__getattribute__(self, '_import_replacer_children')
199
        member = object.__getattribute__(self, '_member')
200
        module_path = object.__getattribute__(self, '_module_path')
7011.1.1 by Martin
Make replacement for lazy import tests less dodgy
201
        name = '.'.join(module_path)
1996.1.2 by John Arbash Meinel
start working on some lazy importing code
202
        if member is not None:
7011.1.1 by Martin
Make replacement for lazy import tests less dodgy
203
            module = _builtin_import(name, scope, scope, [member], level=0)
1996.1.2 by John Arbash Meinel
start working on some lazy importing code
204
            return getattr(module, member)
205
        else:
7011.1.1 by Martin
Make replacement for lazy import tests less dodgy
206
            module = _builtin_import(name, scope, scope, [], level=0)
1996.1.4 by John Arbash Meinel
Change how parameters are passed to support 'import root1.mod1 as mod1'
207
            for path in module_path[1:]:
208
                module = getattr(module, path)
1996.1.2 by John Arbash Meinel
start working on some lazy importing code
209
210
        # Prepare the children to be imported
1996.1.15 by John Arbash Meinel
Everything is now hooked up
211
        for child_name, (child_path, child_member, grandchildren) in \
6621.2.26 by Martin
Misc set of changes to get started with selftest on Python 3
212
                children.items():
1996.1.5 by John Arbash Meinel
Test that we can lazy import a module, and its children
213
            # Using self.__class__, so that children get children classes
214
            # instantiated. (This helps with instrumented tests)
215
            cls = object.__getattribute__(self, '__class__')
216
            cls(module.__dict__, name=child_name,
1996.1.15 by John Arbash Meinel
Everything is now hooked up
217
                module_path=child_path, member=child_member,
1996.1.5 by John Arbash Meinel
Test that we can lazy import a module, and its children
218
                children=grandchildren)
1996.1.3 by John Arbash Meinel
Basic single-level imports work
219
        return module
1996.1.9 by John Arbash Meinel
Create a method for handling 'import *' syntax.
220
221
1996.1.12 by John Arbash Meinel
Switch from individual functions to a class
222
class ImportProcessor(object):
1996.1.15 by John Arbash Meinel
Everything is now hooked up
223
    """Convert text that users input into lazy import requests"""
224
1996.1.18 by John Arbash Meinel
Add more structured error handling
225
    # TODO: jam 20060912 This class is probably not strict enough about
226
    #       what type of text it allows. For example, you can do:
227
    #       import (foo, bar), which is not allowed by python.
228
    #       For now, it should be supporting a superset of python import
229
    #       syntax which is all we really care about.
230
1996.1.15 by John Arbash Meinel
Everything is now hooked up
231
    __slots__ = ['imports', '_lazy_import_class']
232
233
    def __init__(self, lazy_import_class=None):
1996.1.12 by John Arbash Meinel
Switch from individual functions to a class
234
        self.imports = {}
1996.1.15 by John Arbash Meinel
Everything is now hooked up
235
        if lazy_import_class is None:
236
            self._lazy_import_class = ImportReplacer
237
        else:
238
            self._lazy_import_class = lazy_import_class
239
1996.1.19 by John Arbash Meinel
Write a simple wrapper function to make lazy imports easy.
240
    def lazy_import(self, scope, text):
1996.1.15 by John Arbash Meinel
Everything is now hooked up
241
        """Convert the given text into a bunch of lazy import objects.
242
243
        This takes a text string, which should be similar to normal python
244
        import markup.
245
        """
246
        self._build_map(text)
247
        self._convert_imports(scope)
248
249
    def _convert_imports(self, scope):
250
        # Now convert the map into a set of imports
6621.2.26 by Martin
Misc set of changes to get started with selftest on Python 3
251
        for name, info in self.imports.items():
1996.1.15 by John Arbash Meinel
Everything is now hooked up
252
            self._lazy_import_class(scope, name=name, module_path=info[0],
253
                                    member=info[1], children=info[2])
1996.1.12 by John Arbash Meinel
Switch from individual functions to a class
254
1996.1.14 by John Arbash Meinel
Add tests for converting from a string to the final map
255
    def _build_map(self, text):
256
        """Take a string describing imports, and build up the internal map"""
257
        for line in self._canonicalize_import_text(text):
1996.1.18 by John Arbash Meinel
Add more structured error handling
258
            if line.startswith('import '):
1996.1.14 by John Arbash Meinel
Add tests for converting from a string to the final map
259
                self._convert_import_str(line)
1996.1.18 by John Arbash Meinel
Add more structured error handling
260
            elif line.startswith('from '):
1996.1.14 by John Arbash Meinel
Add tests for converting from a string to the final map
261
                self._convert_from_str(line)
1996.1.18 by John Arbash Meinel
Add more structured error handling
262
            else:
263
                raise errors.InvalidImportLine(line,
264
                    "doesn't start with 'import ' or 'from '")
1996.1.14 by John Arbash Meinel
Add tests for converting from a string to the final map
265
1996.1.12 by John Arbash Meinel
Switch from individual functions to a class
266
    def _convert_import_str(self, import_str):
267
        """This converts a import string into an import map.
268
269
        This only understands 'import foo, foo.bar, foo.bar.baz as bing'
270
271
        :param import_str: The import string to process
272
        """
3376.2.4 by Martin Pool
Remove every assert statement from bzrlib!
273
        if not import_str.startswith('import '):
3376.2.8 by Martin Pool
Some review cleanups for assertion removal
274
            raise ValueError('bad import string %r' % (import_str,))
1996.1.12 by John Arbash Meinel
Switch from individual functions to a class
275
        import_str = import_str[len('import '):]
276
277
        for path in import_str.split(','):
278
            path = path.strip()
1996.1.14 by John Arbash Meinel
Add tests for converting from a string to the final map
279
            if not path:
280
                continue
1996.1.12 by John Arbash Meinel
Switch from individual functions to a class
281
            as_hunks = path.split(' as ')
282
            if len(as_hunks) == 2:
283
                # We have 'as' so this is a different style of import
284
                # 'import foo.bar.baz as bing' creates a local variable
285
                # named 'bing' which points to 'foo.bar.baz'
286
                name = as_hunks[1].strip()
287
                module_path = as_hunks[0].strip().split('.')
1996.1.18 by John Arbash Meinel
Add more structured error handling
288
                if name in self.imports:
289
                    raise errors.ImportNameCollision(name)
6621.26.1 by Martin
Prevent lazy imports misunderstanding relative import syntax
290
                if not module_path[0]:
291
                    raise ImportError(path)
1996.1.12 by John Arbash Meinel
Switch from individual functions to a class
292
                # No children available in 'import foo as bar'
293
                self.imports[name] = (module_path, None, {})
294
            else:
295
                # Now we need to handle
296
                module_path = path.split('.')
297
                name = module_path[0]
6621.26.1 by Martin
Prevent lazy imports misunderstanding relative import syntax
298
                if not name:
299
                    raise ImportError(path)
1996.1.12 by John Arbash Meinel
Switch from individual functions to a class
300
                if name not in self.imports:
301
                    # This is a new import that we haven't seen before
302
                    module_def = ([name], None, {})
303
                    self.imports[name] = module_def
304
                else:
305
                    module_def = self.imports[name]
306
307
                cur_path = [name]
308
                cur = module_def[2]
309
                for child in module_path[1:]:
310
                    cur_path.append(child)
311
                    if child in cur:
1996.1.15 by John Arbash Meinel
Everything is now hooked up
312
                        cur = cur[child][2]
1996.1.12 by John Arbash Meinel
Switch from individual functions to a class
313
                    else:
314
                        next = (cur_path[:], None, {})
315
                        cur[child] = next
316
                        cur = next[2]
317
318
    def _convert_from_str(self, from_str):
319
        """This converts a 'from foo import bar' string into an import map.
320
321
        :param from_str: The import string to process
322
        """
3376.2.4 by Martin Pool
Remove every assert statement from bzrlib!
323
        if not from_str.startswith('from '):
324
            raise ValueError('bad from/import %r' % from_str)
1996.1.12 by John Arbash Meinel
Switch from individual functions to a class
325
        from_str = from_str[len('from '):]
326
327
        from_module, import_list = from_str.split(' import ')
328
329
        from_module_path = from_module.split('.')
330
6621.26.1 by Martin
Prevent lazy imports misunderstanding relative import syntax
331
        if not from_module_path[0]:
332
            raise ImportError(from_module)
333
1996.1.12 by John Arbash Meinel
Switch from individual functions to a class
334
        for path in import_list.split(','):
335
            path = path.strip()
1996.1.14 by John Arbash Meinel
Add tests for converting from a string to the final map
336
            if not path:
337
                continue
1996.1.12 by John Arbash Meinel
Switch from individual functions to a class
338
            as_hunks = path.split(' as ')
339
            if len(as_hunks) == 2:
340
                # We have 'as' so this is a different style of import
341
                # 'import foo.bar.baz as bing' creates a local variable
342
                # named 'bing' which points to 'foo.bar.baz'
343
                name = as_hunks[1].strip()
344
                module = as_hunks[0].strip()
345
            else:
346
                name = module = path
1996.1.18 by John Arbash Meinel
Add more structured error handling
347
            if name in self.imports:
348
                raise errors.ImportNameCollision(name)
1996.1.12 by John Arbash Meinel
Switch from individual functions to a class
349
            self.imports[name] = (from_module_path, module, {})
350
1996.1.14 by John Arbash Meinel
Add tests for converting from a string to the final map
351
    def _canonicalize_import_text(self, text):
1996.1.12 by John Arbash Meinel
Switch from individual functions to a class
352
        """Take a list of imports, and split it into regularized form.
353
354
        This is meant to take regular import text, and convert it to
355
        the forms that the rest of the converters prefer.
356
        """
357
        out = []
358
        cur = None
359
        continuing = False
360
361
        for line in text.split('\n'):
362
            line = line.strip()
363
            loc = line.find('#')
364
            if loc != -1:
365
                line = line[:loc].strip()
366
367
            if not line:
368
                continue
369
            if cur is not None:
370
                if line.endswith(')'):
371
                    out.append(cur + ' ' + line[:-1])
372
                    cur = None
373
                else:
374
                    cur += ' ' + line
375
            else:
376
                if '(' in line and ')' not in line:
377
                    cur = line.replace('(', '')
378
                else:
379
                    out.append(line.replace('(', '').replace(')', ''))
1996.1.18 by John Arbash Meinel
Add more structured error handling
380
        if cur is not None:
381
            raise errors.InvalidImportLine(cur, 'Unmatched parenthesis')
1996.1.12 by John Arbash Meinel
Switch from individual functions to a class
382
        return out
1996.1.19 by John Arbash Meinel
Write a simple wrapper function to make lazy imports easy.
383
384
385
def lazy_import(scope, text, lazy_import_class=None):
386
    """Create lazy imports for all of the imports in text.
387
5891.1.2 by Andrew Bennetts
Fix a bunch of docstring formatting nits, making pydoctor a bit happier.
388
    This is typically used as something like::
389
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
390
        from breezy.lazy_import import lazy_import
5891.1.2 by Andrew Bennetts
Fix a bunch of docstring formatting nits, making pydoctor a bit happier.
391
        lazy_import(globals(), '''
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
392
        from breezy import (
5891.1.2 by Andrew Bennetts
Fix a bunch of docstring formatting nits, making pydoctor a bit happier.
393
            foo,
394
            bar,
395
            baz,
396
            )
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
397
        import breezy.branch
398
        import breezy.transport
5891.1.2 by Andrew Bennetts
Fix a bunch of docstring formatting nits, making pydoctor a bit happier.
399
        ''')
1996.1.19 by John Arbash Meinel
Write a simple wrapper function to make lazy imports easy.
400
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
401
    Then 'foo, bar, baz' and 'breezy' will exist as lazy-loaded
1996.1.19 by John Arbash Meinel
Write a simple wrapper function to make lazy imports easy.
402
    objects which will be replaced with a real object on first use.
403
404
    In general, it is best to only load modules in this way. This is
405
    because other objects (functions/classes/variables) are frequently
406
    used without accessing a member, which means we cannot tell they
407
    have been used.
408
    """
409
    # This is just a helper around ImportProcessor.lazy_import
410
    proc = ImportProcessor(lazy_import_class=lazy_import_class)
411
    return proc.lazy_import(scope, text)
1996.3.19 by John Arbash Meinel
make lazy_import lazily import errors
412
413
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
414
# The only module that this module depends on is 'breezy.errors'. But it
1996.3.19 by John Arbash Meinel
make lazy_import lazily import errors
415
# can actually be imported lazily, since we only need it if there is a
416
# problem.
417
418
lazy_import(globals(), """
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
419
from breezy import errors
1996.3.19 by John Arbash Meinel
make lazy_import lazily import errors
420
""")