Commits

Luke Plant committed 82b7e1d

Initial import

  • Participants

Comments (0)

Files changed (4)

+# The copy on call attempt - all features, but the output is:
+
+#   Howdy; ['x']; 1
+#   Howdy; ['x', 'x']; 1
+#   Howdy; ['x', 'x', 'x']; 1
+#   Howdy; ['x', 'x', 'x', 'x']; 1
+
+import threading
+import copy
+
+class View(object):
+
+    def __call__(self, request, *args, **kwargs):
+        self = copy.copy(self)
+        return self.dispatch(request, *args, **kwargs)
+
+class MyView(View):
+
+    def __init__(self, greeting="Hello"):
+        self.foo = []
+        self.bar = 0
+        self.greeting = greeting
+
+    def dispatch(self, request, *args, **kwargs):
+        self.bar += 1
+        self.foo.append('x')
+        return "%s; %r; %d" % (self.greeting, self.foo, self.bar)
+
+def mydec(func):
+    def _wrapper(*args, **kwargs):
+        return func(*args, **kwargs)
+    return _wrapper
+
+view = mydec(MyView(greeting="Howdy"))
+
+responses = []
+
+def runview():
+    global responses
+    request = object()
+    responses.append(view(request))
+
+# Concurrent threads:
+t1 = threading.Thread(target=runview)
+t2 = threading.Thread(target=runview)
+
+t1.start()
+t2.start()
+t1.join()
+t2.join()
+
+# Serial threads:
+runview()
+runview()
+
+for r in responses:
+    print r
+# Gets the right output. Getting a response back from calling a class violates
+# expectations, and you have to subclass to configure.
+
+import threading
+
+class View(object):
+
+    def __new__(cls, request, *args, **kwargs):
+        self = object.__new__(cls)
+        self.__init__()
+        return self.dispatch(request, *args, **kwargs)
+
+class MyView(View):
+    greeting = "Hello"
+
+    def __init__(self):
+        self.foo = []
+        self.bar = 0
+
+    def dispatch(self, request, *args, **kwargs):
+        self.bar += 1
+        self.foo.append('x')
+        return "%s; %r; %d" % (self.greeting, self.foo, self.bar)
+
+class MyConfiguredView(MyView):
+    greeting = "Howdy"
+
+def mydec(func):
+    def _wrapper(*args, **kwargs):
+        return func(*args, **kwargs)
+    return _wrapper
+
+view = mydec(MyConfiguredView)
+
+responses = []
+
+def runview():
+    global responses
+    request = object()
+    responses.append(view(request))
+
+# Concurrent threads:
+t1 = threading.Thread(target=runview)
+t2 = threading.Thread(target=runview)
+
+t1.start()
+t2.start()
+t1.join()
+t2.join()
+
+# Serial threads:
+runview()
+runview()
+
+for r in responses:
+    print r

magicnew_with_configure.py

+# Gets the right output. Getting a response back from calling a class violates
+# expectations.
+
+import threading
+
+class View(object):
+
+    def __new__(cls, request, *args, **kwargs):
+        self = object.__new__(cls)
+        self.__init__()
+        return self.dispatch(request, *args, **kwargs)
+
+    @classmethod
+    def configure(cls, **kwargs):
+        class SubClass(cls):
+            pass
+        for key, val in kwargs.items():
+            setattr(cls, key, val)
+        return SubClass
+
+class MyView(View):
+    greeting = "Hello"
+
+    def __init__(self):
+        self.foo = []
+        self.bar = 0
+
+    def dispatch(self, request, *args, **kwargs):
+        self.bar += 1
+        self.foo.append('x')
+        return "%s; %r; %d" % (self.greeting, self.foo, self.bar)
+
+def mydec(func):
+    def _wrapper(*args, **kwargs):
+        return func(*args, **kwargs)
+    return _wrapper
+
+view = mydec(MyView.configure(greeting="Howdy"))
+
+responses = []
+
+def runview():
+    global responses
+    request = object()
+    responses.append(view(request))
+
+# Concurrent threads:
+t1 = threading.Thread(target=runview)
+t2 = threading.Thread(target=runview)
+
+t1.start()
+t2.start()
+t1.join()
+t2.join()
+
+# Serial threads:
+runview()
+runview()
+
+for r in responses:
+    print r
+# The aim is:
+#  * get all the features here
+#  * program naively
+#  * and yet end up with the output:
+#     Howdy; ['x'] 1
+#     Howdy; ['x'] 1
+#     Howdy; ['x'] 1
+#     Howdy; ['x'] 1
+
+# The naive attempt - all features, but the output is:
+
+#   Howdy; foo: ['x']; bar 1
+#   Howdy; foo: ['x', 'x']; bar 2
+#   Howdy; foo: ['x', 'x', 'x']; bar 3
+#   Howdy; foo: ['x', 'x', 'x', 'x']; bar 4
+
+import threading
+
+class View(object):
+
+    def __call__(self, request, *args, **kwargs):
+        return self.dispatch(request, *args, **kwargs)
+
+class MyView(View):
+
+    def __init__(self, greeting="Hello"):
+        self.foo = []
+        self.bar = 0
+        self.greeting = greeting
+
+    def dispatch(self, request, *args, **kwargs):
+        self.bar += 1
+        self.foo.append('x')
+        return "%s; %r; %d" % (self.greeting, self.foo, self.bar)
+
+def mydec(func):
+    def _wrapper(*args, **kwargs):
+        return func(*args, **kwargs)
+    return _wrapper
+
+view = mydec(MyView(greeting="Howdy"))
+
+responses = []
+
+def runview():
+    global responses
+    request = object()
+    responses.append(view(request))
+
+# Concurrent threads:
+t1 = threading.Thread(target=runview)
+t2 = threading.Thread(target=runview)
+
+t1.start()
+t2.start()
+t1.join()
+t2.join()
+
+# Serial threads:
+runview()
+runview()
+
+for r in responses:
+    print r