Merge branch 'master' into python3
authorFredrik Tolf <fredrik@dolda2000.com>
Wed, 27 Jun 2012 04:48:08 +0000 (06:48 +0200)
committerFredrik Tolf <fredrik@dolda2000.com>
Wed, 27 Jun 2012 04:59:05 +0000 (06:59 +0200)
wrw/proto.py
wrw/util.py

index 7df66ff..881f4e4 100644 (file)
@@ -1,8 +1,12 @@
 statusinfo = {
-    400: ("Bad Request", "Your issued HTTP request is invalid."),
-    403: ("Forbidden", "You are not authorized to view the requested resource."),
+    400: ("Bad Request", "Invalid HTTP request."),
+    401: ("Unauthorized", "Authentication must be provided for the requested resource."),
+    403: ("Forbidden", "You are not authorized to request the requested resource."),
     404: ("Not Found", "The requested resource was not found."),
-    500: ("Server Error", "An internal error occurred.")
+    405: ("Method Not Allowed", "The request method is not recognized or permitted by the requested resource."),
+    500: ("Server Error", "An internal error occurred."),
+    501: ("Not Implemented", "The requested functionality has not been implemented."),
+    503: ("Service Unavailable", "Service is being denied at this time."),
     }
 
 def httpdate(ts):
index c8b7b2c..a7f1e4c 100644 (file)
@@ -98,3 +98,91 @@ class manudirty(object):
 
     def dirty(self):
         self.__dirty = True
+
+class specslot(object):
+    __slots__ = ["nm", "idx", "dirty"]
+    unbound = object()
+    
+    def __init__(self, nm, idx, dirty):
+        self.nm = nm
+        self.idx = idx
+        self.dirty = dirty
+
+    @staticmethod
+    def slist(ins):
+        # Avoid calling __getattribute__
+        return specdirty.__sslots__.__get__(ins, type(ins))
+
+    def __get__(self, ins, cls):
+        val = self.slist(ins)[self.idx]
+        if val is specslot.unbound:
+            raise AttributeError("specslot %r is unbound" % self.nm)
+        return val
+
+    def __set__(self, ins, val):
+        self.slist(ins)[self.idx] = val
+        if self.dirty:
+            ins.dirty()
+
+    def __delete__(self, ins):
+        self.slist(ins)[self.idx] = specslot.unbound
+        ins.dirty()
+
+class specclass(type):
+    def __init__(self, name, bases, tdict):
+        super().__init__(name, bases, tdict)
+        sslots = set()
+        dslots = set()
+        for cls in self.__mro__:
+            css = cls.__dict__.get("__saveslots__", ())
+            sslots.update(css)
+            dslots.update(cls.__dict__.get("__dirtyslots__", css))
+        self.__sslots_l__ = list(sslots)
+        self.__sslots_a__ = list(sslots | dslots)
+        for i, slot in enumerate(self.__sslots_a__):
+            setattr(self, slot, specslot(slot, i, slot in dslots))
+
+class specdirty(sessiondata, metaclass=specclass):
+    __slots__ = ["session", "__sslots__", "_is_dirty"]
+    
+    def __specinit__(self):
+        pass
+
+    @staticmethod
+    def __new__(cls, req, sess):
+        self = super().__new__(cls)
+        self.session = sess
+        self.__sslots__ = [specslot.unbound] * len(cls.__sslots_a__)
+        self.__specinit__()
+        self._is_dirty = False
+        return self
+
+    def __getnewargs__(self):
+        return (None, self.session)
+
+    def dirty(self):
+        self._is_dirty = True
+
+    def sessfrozen(self):
+        self._is_dirty = False
+
+    def sessdirty(self):
+        return self._is_dirty
+
+    def __getstate__(self):
+        ret = {}
+        for nm, val in zip(type(self).__sslots_a__, specslot.slist(self)):
+            if val is specslot.unbound:
+                ret[nm] = False, None
+            else:
+                ret[nm] = True, val
+        return ret
+
+    def __setstate__(self, st):
+        ss = specslot.slist(self)
+        for i, nm in enumerate(type(self).__sslots_a__):
+            bound, val = st.pop(nm, (False, None))
+            if not bound:
+                ss[i] = specslot.unbound
+            else:
+                ss[i] = val