[livecoding] r146 committed - Extending the supported functionality....

3 views
Skip to first unread message

livec...@googlecode.com

unread,
Sep 6, 2010, 8:08:17 AM9/6/10
to py-livecod...@googlegroups.com
Revision: 146
Author: richard.m.tew
Date: Mon Sep 6 05:07:54 2010
Log: Extending the supported functionality.
- Properties are not updated in place correctly. That is not copied as a
whole, but rather their components are reconstructed as a new property on
the original class instance.
- A warning is logged if there are any instances of the throwaway new
class, as this can lead to these leaked instances causing errors (not being
updated when later updates to their file happen, hitting the 2.x class
function class verification check).
http://code.google.com/p/livecoding/source/detail?r=146

Modified:
/trunk/reloader.py

=======================================
--- /trunk/reloader.py Fri Mar 19 00:43:01 2010
+++ /trunk/reloader.py Mon Sep 6 05:07:54 2010
@@ -6,6 +6,7 @@
import types
import weakref
import time
+import gc

logger = logging.getLogger("reloader")
# logger.setLevel(logging.DEBUG)
@@ -312,6 +313,8 @@
elif isinstance(newValue, types.UnboundMethodType) or
isinstance(newValue, types.MethodType):
logger.debug("Rebound method '%s' to function", attrName)
newValue = RebindFunction(newValue.im_func, globals_)
+ else:
+ logger.debug("Updated changed attribute '%s'", attrName)

# Build up the retained original globals with contributions.
globals_[attrName] = newValue
@@ -325,6 +328,10 @@
def UpdateClass(self, scriptFile, value, newValue, globals_):
logger.debug("Updating class %s:%s from %s:%s", value,
hex(id(value)), newValue, hex(id(newValue)))

+ instances = self.FindClassInstances(newValue)
+ if len(instances):
+ logger.warn("Found %d instances of the %s class that will be
in the wild" % (len(instances), newValue.__name__))
+
if value is None or value is NonExistentValue:
authoritativeValue = newValue
else:
@@ -335,6 +342,15 @@
attrValue = RebindFunction(attrValue, globals_)
elif isinstance(attrValue, types.UnboundMethodType) or
isinstance(attrValue, types.MethodType):
attrValue = RebindFunction(attrValue.im_func, globals_)
+ elif isinstance(attrValue, property):
+ fget, fset, fdel = attrValue.fget, attrValue.fset,
attrValue.fdel
+ if fget:
+ fget = RebindFunction(fget, globals_)
+ if fset:
+ fset = RebindFunction(fset, globals_)
+ if fdel:
+ fdel = RebindFunction(fdel, globals_)
+ attrValue = property(fget, fset, fdel, attrValue.__doc__)
else:
# __doc__: On new-style classes, this cannot be
overwritten.
# __dict__: This makes no sense to overwrite.
@@ -364,6 +380,13 @@
except Exception:
logger.exception("Error broadcasting class update")

+ def FindClassInstances(self, class_):
+ instances = []
+ for referrer in gc.get_referrers(class_):
+ if type(referrer) is types.InstanceType or type(referrer) is
class_:
+ instances.append(referrer)
+ return instances
+
#
------------------------------------------------------------------------
# Leaked attribute support

Reply all
Reply to author
Forward
0 new messages