/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to bzrlib/lazy_import.py

First attempt to merge .dev and resolve the conflicts (but tests are 
failing)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2006 by Canonical Ltd
 
1
# Copyright (C) 2006 Canonical Ltd
2
2
#
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
40
40
    to inherit from them).
41
41
"""
42
42
 
43
 
import re
44
 
import sys
45
 
 
46
 
from bzrlib import (
47
 
    errors,
48
 
    )
49
 
 
50
43
 
51
44
class ScopeReplacer(object):
52
45
    """A lazy object that will replace itself in the appropriate scope.
55
48
    needed.
56
49
    """
57
50
 
58
 
    __slots__ = ('_scope', '_factory', '_name')
 
51
    __slots__ = ('_scope', '_factory', '_name', '_real_obj')
 
52
 
 
53
    # Setting this to True will allow you to do x = y, and still access members
 
54
    # from both variables. This should not normally be enabled, but is useful
 
55
    # when building documentation.
 
56
    _should_proxy = False
59
57
 
60
58
    def __init__(self, scope, factory, name):
61
59
        """Create a temporary object in the specified scope.
66
64
            It will be passed (self, scope, name)
67
65
        :param name: The variable name in the given scope.
68
66
        """
69
 
        self._scope = scope
70
 
        self._factory = factory
71
 
        self._name = name
 
67
        object.__setattr__(self, '_scope', scope)
 
68
        object.__setattr__(self, '_factory', factory)
 
69
        object.__setattr__(self, '_name', name)
 
70
        object.__setattr__(self, '_real_obj', None)
72
71
        scope[name] = self
73
72
 
74
73
    def _replace(self):
88
87
                          " to another variable?",
89
88
                extra=e)
90
89
        obj = factory(self, scope, name)
 
90
        if ScopeReplacer._should_proxy:
 
91
            object.__setattr__(self, '_real_obj', obj)
91
92
        scope[name] = obj
92
93
        return obj
93
94
 
99
100
        # del self._name
100
101
 
101
102
    def __getattribute__(self, attr):
102
 
        _replace = object.__getattribute__(self, '_replace')
103
 
        obj = _replace()
104
 
        _cleanup = object.__getattribute__(self, '_cleanup')
105
 
        _cleanup()
 
103
        obj = object.__getattribute__(self, '_real_obj')
 
104
        if obj is None:
 
105
            _replace = object.__getattribute__(self, '_replace')
 
106
            obj = _replace()
 
107
            _cleanup = object.__getattribute__(self, '_cleanup')
 
108
            _cleanup()
106
109
        return getattr(obj, attr)
107
110
 
 
111
    def __setattr__(self, attr, value):
 
112
        obj = object.__getattribute__(self, '_real_obj')
 
113
        if obj is None:
 
114
            _replace = object.__getattribute__(self, '_replace')
 
115
            obj = _replace()
 
116
            _cleanup = object.__getattribute__(self, '_cleanup')
 
117
            _cleanup()
 
118
        return setattr(obj, attr, value)
 
119
 
108
120
    def __call__(self, *args, **kwargs):
109
121
        _replace = object.__getattribute__(self, '_replace')
110
122
        obj = _replace()
158
170
            from foo import bar, baz would get translated into 2 import
159
171
            requests. On for 'name=bar' and one for 'name=baz'
160
172
        """
161
 
        if member is not None:
162
 
            assert not children, \
163
 
                'Cannot supply both a member and children'
 
173
        if (member is not None) and children:
 
174
            raise ValueError('Cannot supply both a member and children')
164
175
 
165
 
        self._import_replacer_children = children
166
 
        self._member = member
167
 
        self._module_path = module_path
 
176
        object.__setattr__(self, '_import_replacer_children', children)
 
177
        object.__setattr__(self, '_member', member)
 
178
        object.__setattr__(self, '_module_path', module_path)
168
179
 
169
180
        # Indirecting through __class__ so that children can
170
181
        # override _import (especially our instrumented version)
248
259
 
249
260
        :param import_str: The import string to process
250
261
        """
251
 
        assert import_str.startswith('import ')
 
262
        if not import_str.startswith('import '):
 
263
            raise ValueError('bad import string %r' % (import_str,))
252
264
        import_str = import_str[len('import '):]
253
265
 
254
266
        for path in import_str.split(','):
293
305
 
294
306
        :param from_str: The import string to process
295
307
        """
296
 
        assert from_str.startswith('from ')
 
308
        if not from_str.startswith('from '):
 
309
            raise ValueError('bad from/import %r' % from_str)
297
310
        from_str = from_str[len('from '):]
298
311
 
299
312
        from_module, import_list = from_str.split(' import ')
377
390
    # This is just a helper around ImportProcessor.lazy_import
378
391
    proc = ImportProcessor(lazy_import_class=lazy_import_class)
379
392
    return proc.lazy_import(scope, text)
 
393
 
 
394
 
 
395
# The only module that this module depends on is 'bzrlib.errors'. But it
 
396
# can actually be imported lazily, since we only need it if there is a
 
397
# problem.
 
398
 
 
399
lazy_import(globals(), """
 
400
from bzrlib import errors
 
401
""")