Rev 2976: Ensure that setting attributes on ScopeReplacer objects works in file:///home/pqm/archives/thelove/bzr/%2Btrunk/
Canonical.com Patch Queue Manager
pqm at pqm.ubuntu.com
Fri Nov 9 03:13:20 GMT 2007
At file:///home/pqm/archives/thelove/bzr/%2Btrunk/
------------------------------------------------------------
revno: 2976
revision-id: pqm at pqm.ubuntu.com-20071109031316-n814a39wmtxvybyw
parent: pqm at pqm.ubuntu.com-20071107140948-l3p8njdhgwstdkri
parent: aaron.bentley at utoronto.ca-20071109022444-7pnank284u5prg5h
committer: Canonical.com Patch Queue Manager <pqm at pqm.ubuntu.com>
branch nick: +trunk
timestamp: Fri 2007-11-09 03:13:16 +0000
message:
Ensure that setting attributes on ScopeReplacer objects works
modified:
NEWS NEWS-20050323055033-4e00b5db738777ff
bzrlib/lazy_import.py lazy_import.py-20060910203832-f77c54gf3n232za0-1
bzrlib/tests/test_lazy_import.py test_lazy_import.py-20060910203832-f77c54gf3n232za0-2
------------------------------------------------------------
revno: 1551.2.49.1.40.1.22.1.42.1.31.1.39.1.17.1.77.1.3.1.23
merged: aaron.bentley at utoronto.ca-20071109022444-7pnank284u5prg5h
parent: aaron.bentley at utoronto.ca-20071109015537-q83rlmzstfggjebb
committer: Aaron Bentley <aaron.bentley at utoronto.ca>
branch nick: Aaron's mergeable stuff
timestamp: Thu 2007-11-08 21:24:44 -0500
message:
Ensure that the attribute is actually set
------------------------------------------------------------
revno: 1551.2.49.1.40.1.22.1.42.1.31.1.39.1.17.1.77.1.3.1.22
merged: aaron.bentley at utoronto.ca-20071109015537-q83rlmzstfggjebb
parent: aaron.bentley at utoronto.ca-20071109011256-g85ljjfbvpf9cc2j
committer: Aaron Bentley <aaron.bentley at utoronto.ca>
branch nick: Aaron's mergeable stuff
timestamp: Thu 2007-11-08 20:55:37 -0500
message:
Fix exception when ScopeReplacer is assigned to before retrieving any members
------------------------------------------------------------
revno: 1551.2.49.1.40.1.22.1.42.1.31.1.39.1.17.1.77.1.3.1.21
merged: aaron.bentley at utoronto.ca-20071109011256-g85ljjfbvpf9cc2j
parent: abentley at panoramicfeedback.com-20071019135148-7567ag3iu82is1xk
parent: pqm at pqm.ubuntu.com-20071107140948-l3p8njdhgwstdkri
committer: Aaron Bentley <aaron.bentley at utoronto.ca>
branch nick: Aaron's mergeable stuff
timestamp: Thu 2007-11-08 20:12:56 -0500
message:
Merge bzr.dev
=== modified file 'NEWS'
--- a/NEWS 2007-11-07 13:14:09 +0000
+++ b/NEWS 2007-11-09 01:55:37 +0000
@@ -67,6 +67,9 @@
* Wrap medusa ftp test server as an FTPServer feature.
(Vincent Ladeuil, #157752)
+ * Fix exception when ScopeReplacer is assigned to before any members have
+ been retrieved. (Aaron Bentley)
+
API BREAKS:
* ``osutils.backup_file`` is deprecated. Actually it's not used in bzrlib
=== modified file 'bzrlib/lazy_import.py'
--- a/bzrlib/lazy_import.py 2007-04-12 21:33:07 +0000
+++ b/bzrlib/lazy_import.py 2007-11-09 01:55:37 +0000
@@ -64,10 +64,10 @@
It will be passed (self, scope, name)
:param name: The variable name in the given scope.
"""
- self._scope = scope
- self._factory = factory
- self._name = name
- self._real_obj = None
+ object.__setattr__(self, '_scope', scope)
+ object.__setattr__(self, '_factory', factory)
+ object.__setattr__(self, '_name', name)
+ object.__setattr__(self, '_real_obj', None)
scope[name] = self
def _replace(self):
@@ -88,7 +88,7 @@
extra=e)
obj = factory(self, scope, name)
if ScopeReplacer._should_proxy:
- self._real_obj = obj
+ object.__setattr__(self, '_real_obj', obj)
scope[name] = obj
return obj
@@ -108,6 +108,15 @@
_cleanup()
return getattr(obj, attr)
+ def __setattr__(self, attr, value):
+ obj = object.__getattribute__(self, '_real_obj')
+ if obj is None:
+ _replace = object.__getattribute__(self, '_replace')
+ obj = _replace()
+ _cleanup = object.__getattribute__(self, '_cleanup')
+ _cleanup()
+ return setattr(obj, attr, value)
+
def __call__(self, *args, **kwargs):
_replace = object.__getattribute__(self, '_replace')
obj = _replace()
@@ -165,9 +174,9 @@
assert not children, \
'Cannot supply both a member and children'
- self._import_replacer_children = children
- self._member = member
- self._module_path = module_path
+ object.__setattr__(self, '_import_replacer_children', children)
+ object.__setattr__(self, '_member', member)
+ object.__setattr__(self, '_module_path', module_path)
# Indirecting through __class__ so that children can
# override _import (especially our instrumented version)
=== modified file 'bzrlib/tests/test_lazy_import.py'
--- a/bzrlib/tests/test_lazy_import.py 2007-04-12 21:33:07 +0000
+++ b/bzrlib/tests/test_lazy_import.py 2007-11-09 02:24:44 +0000
@@ -150,6 +150,39 @@
('foo', 2),
], actions)
+ def test_setattr_replaces(self):
+ """ScopeReplacer can create an instance in local scope.
+
+ An object should appear in globals() by constructing a ScopeReplacer,
+ and it will be replaced with the real object upon the first request.
+ """
+ def factory(replacer, scope, name):
+ return TestClass()
+ try:
+ test_obj6
+ except NameError:
+ # test_obj6 shouldn't exist yet
+ pass
+ else:
+ self.fail('test_obj6 was not supposed to exist yet')
+
+ orig_globals = set(globals().keys())
+
+ lazy_import.ScopeReplacer(scope=globals(), name='test_obj6',
+ factory=factory)
+
+ new_globals = set(globals().keys())
+
+ # We can't use isinstance() because that uses test_obj6.__class__
+ # and that goes through __getattribute__ which would activate
+ # the replacement
+ self.assertEqual(lazy_import.ScopeReplacer,
+ object.__getattribute__(test_obj6, '__class__'))
+ test_obj6.bar = 'test'
+ self.assertNotEqual(lazy_import.ScopeReplacer,
+ object.__getattribute__(test_obj6, '__class__'))
+ self.assertEqual('test', test_obj6.bar)
+
def test_replace_side_effects(self):
"""Creating a new object should only create one entry in globals.
More information about the bazaar-commits
mailing list