Commits

Jonathan Eunice committed ed475c7

about to clone

Comments (0)

Files changed (4)

 The net is that you can provide just about any kind of callable.
 But the meta-programming of the magic interpretation API could use a little work.
 
-
 Subclassing
 ===========
 
 
     options = Superclass.options.add(
         func   = None,
-        prefix = Prohibited,
-        suffix = Prohibited,
+        prefix = Prohibited,  # was available in superclass, but not here
+        suffix = Prohibited,  # ditto
     )
 
-  * AlernativelyBy copying or restating the superclass's options. In this case, the subclass
-    is "starting fresh" with its options, which have no connection to the 
+An alternative is to copy (or restart) the superclass's options. That suits cases
+where changes to the superclass's options should not effect the subclass's options.
+With ``add()``, they remain linked in the same way as instances and classes are.
 
 Flat Arguments
 ==============
         
 to consume optional ``prefix`` and ``suffix`` flat arguments.
 
+Next Steps
+==========
+ 
+  * add property like setters
+  * extend setters to multiple options
+  * clean up quoteroptions as a result
+
 Notes
 =====
 
         for key in self.keys():
             self[key] = oc[key] 
     
-    def push(self, kwargs):
+    def push(self, *args):
         """
         Create the next layer down. Intended for instances to call during
-        ``__init__()``
+        ``__init__()``. If just one arg is given, it's the kwargs. If 3,
+        it's args, keys, kwargs.
+        
         """
-        return OptionsChain(self, kwargs)
-    
+        if len(args) == 1:
+            return OptionsChain(self, args[0])
+        elif len(args) == 3:
+            return OptionsChain(self, args[2])._addflat(args[0], args[1])
+        else:
+            raise ValueError('either 1 args or 3')
+
+  
     def add(self, **kwargs):
         """
         Create the next layer down. Like ``push()``, but accepts full kwargs
         guts = attrs(self, first=list(grandpa.keys()), underscores=True)
         return "{}({} layers: {})".format(self.__class__.__name__, n_layers, guts)
     
-    def push(self, kwargs):
+    def push(self, *args):
         """
         Create the next layer down. Intended for instances to call during
-        ``__init__()``
+        ``__init__()``. If just one arg is given, it's the kwargs. If 3,
+        it's args, keys, kwargs.
+        
         """
-        return OptionsChain(self, kwargs)
+        if len(args) == 1:
+            return OptionsChain(self, args[0])
+        elif len(args) == 3:
+            return OptionsChain(self, args[2])._addflat(args[0], args[1])
+        else:
+            raise ValueError('either 1 args or 3')
 
     def add(self, **kwargs):
         """
 
     #  TBD Handle the unsetting of magic in subclasses
 
-    def addflat(self, args, keys):
+    def _addflat(self, args, keys):
         """
         Sometimes kwargs aren't the most elegant way to provide options. In those
         cases, this routine helps map flat args to kwargs. Provide the actual args,
             raise ValueError('More args than keys not allowed')
         additional = dict(zip(keys, args))
         self.update(additional)
+        return self
   
     #def __setattr__(self, name, value):
     #    print "OptionsChain.__setattr__() name:", name, "value:", value
     
     # Would it make sense to support magicalized class setting -- for subclasses?
     # even if it would, how to accomplish neatly? probably would require a
-    # property like object that lets you assign the magic along with the initial value
+    # property like object that lets you assign the magic along with the initial value
+    
+    # next step: integrate setter from testprop.py
+    # consider adding _for key pointing to object that options are for
+    # also providing access to whole dict for arguments like chars
+    # and clean up HTMLQuoter using the improved functions & access
+    
+    # quoter might provide the usecase for a getter, too - in that suffix is == prefix
+    # if suffix itself not given
+    
+    # instead of Magic() or Setter() maybe Property() or Prop()
 
 setup(
     name='options',
-    version=verno("0.024"),
+    version=verno("0.027"),
     author='Jonathan Eunice',
     author_email='jonathan.eunice@gmail.com',
     description='Container for flexible class, instance, and function call options',
     # nb must set property in __class__ (here, E) not in instance (e)
     
 class Setter(object):
-    def __init__(self, initial, updater):
+    def __init__(self, initial, setter=None, getter=None):
         self.initial = initial
-        self.updater = updater
+        self.setter = setter
+        self.getter = getter
     
 class Stuffer(object):
     def __init__(self, **kwargs):
         for k,v in kwargs.items():
             if isinstance(v, Setter):
                 self.s[k] = v.initial
-                self.magic[k] = v.updater
+                self.magic[k] = v.setter
             else:
                 self.s[k] = v
 
         if key in self.__dict__:
             return self.__dict__[key]
         # handle special attributes
+        elif key in self.magic:
+            getter = self.magic[key]
+            return getter(self.s[key]) if getter else self.s[key]   
         else:
             return self.s[key]
     
         for k,v in kwargs.items():
             if isinstance(v, Setter):
                 self[k] = v.initial
-                self._magic[k] = v.updater
+                self._magic[k] = v
             else:
                 self[k] = v
+                
+    def __getattr__(self, key):
+        # handle normal object attributes
+        if key == '_magic' or key in self.__dict__:
+            return self.__dict__[key]  # BREAKS HERE
+        # handle special attributes
+        elif key in self._magic:
+            getter = self._magic[key].getter
+            return getter(self[key]) if getter else self[key]   
+        else:
+            return self[key]
     
     def __setattr__(self, key, value):
         # handle normal object attributes
         if key == '_magic' or key in self.__dict__:
             stuf.__setattr__(self, key, value)
         elif key in self._magic:
-            value = self._magic[key](value)
+            value = self._magic[key].setter(value)
             self[key] = value
         else:
             self[key] = value