1. Jonathan Eunice
  2. options

Commits

Jonathan Eunice  committed 784ec81

Added check for bad option names.

  • Participants
  • Parent commits 1d35b73
  • Branches default

Comments (0)

Files changed (8)

File CHANGES.rst

View file
  • Ignore whitespace
 Change Log
 ==========
 
+
+1.0.4 (October 24, 2013)
+'''''''''''''''''''''''''
+
+  * When bad option names are defined ("bad" here meaning "conflicts with
+    names already chosen for pre-existing methods"), a ``BadOptionName``
+    exception will be raised.
+
 1.0.3 (September 23, 2013)
 ''''''''''''''''''''''''''
 

File docs/CHANGES.rst

View file
  • Ignore whitespace
 Change Log
 ==========
 
+
+1.0.4 (October 24, 2013)
+'''''''''''''''''''''''''
+
+  * When bad option names are defined ("bad" here meaning "conflicts with
+    names already chosen for pre-existing methods"), a ``BadOptionName``
+    exception will be raised.
+
 1.0.3 (September 23, 2013)
 ''''''''''''''''''''''''''
 

File docs/conf.py

View file
  • Ignore whitespace
 # The short X.Y version.
 version = '1.0'
 # The full version, including alpha/beta/rc tags.
-release = '1.0.3'
+release = '1.0.4'
 
 # The language for content autogenerated by Sphinx. Refer to documentation
 # for a list of supported languages.

File docs/index.rst

View file
  • Ignore whitespace
             if 'suffix' not in used:
                 self.options.suffix = self.options.prefix
 
+Choosing Option Names
+=====================
+
+You can choose pretty much any option name that is a legitimate Python
+keyword argument. The exceptions: Names that are already defined by
+methods of ``Options`` or ``OptionsChain``. These are mapping-style
+objects, so many of the method names of ``dict`` such as ``items``,
+``values``, ``get``, and ``setdefault`` are off-limits. If you try
+to define options with verboten names, a ``BadOptionName`` exception
+will be raised. This will save you grief down the road.
+
 Related Work
 ============
 

File options/__init__.py

View file
  • Ignore whitespace
 __all__ = """
     Unset Prohibited Transient attrs
     Options OptionsChain OptionsContext
+    BadOptionName
     __version__
 """.split()

File options/core.py

View file
  • Ignore whitespace
 Prohibited = NullType('Prohibited')
 Transient  = NullType('Transient')
 
+class BadOptionName(AttributeError):
+    """
+    Raised when an Options object is given an option name that conflicts
+    with an existing method.
+    """
+    pass
 
 def attrs(m, first=[], underscores=False):
     """
     def __init__(self, *args, **kwargs):
         orderedstuf.__init__(self, *args)
         for k, v in kwargs.items():
-            self[k] = v
+            if hasattr(self, k):
+                raise BadOptionName("Options already defines an attribute {0!r}".format(k))
+            else:
+                self[k] = v
         self._magic = {}
 
         # The explicit for loop setting values from kwargs should not be necessary.
         # still exists in PyPy 2.1 with stuf 0.9.12 in Sept 2013. Patch
         # retained.)
 
+
     def set(self, **kwargs):
         # To set values at the base options level, create a temporary next level,
         # which will have the magical option interpretation. Then copy the resulting
         """
         child = OptionsChain(self, {})
         for key, value in kwargs.items():
-            child[key] = value
+            if hasattr(OptionsChain, key):
+                raise BadOptionName("OptionsChain already defines an attribute {0!r}".format(key))
+            else:
+                child[key] = value
         return child
 
     def magic(self, **kwargs):
         """
         child = OptionsChain(self, {})
         for key, value in kwargs.items():
-            child[key] = value
+            if hasattr(OptionsChain, key):
+                raise BadOptionName("OptionsChain already defines an attribute {0!r}".format(key))
+            else:
+                child[key] = value
         return child
 
     def set(self, **kwargs):

File options/version.py

View file
  • Ignore whitespace
-__version__ = '1.0.3'
+__version__ = '1.0.4'

File test/test.py

View file
  • Ignore whitespace
 
     assert not is_tall(one)
 
+def test_no_aliases():
+    # o works just fine
+    o = Options(color='red', shape='box')
+    assert o.color == 'red'
+    assert o.shape == 'box'
+
+    # but not if you try to add a bad option to it
+    with raises(BadOptionName):
+        o.add(items=55)
+        assert False
+
+    # cant create it initially wiht bad option name, either
+    with raises(BadOptionName):
+        o = Options(color='red', shape='box', items=False)
+        assert False
+
+    # o and oo are fine, but cant add bad option to it either
+    o = Options(color='red', shape='box')
+    oo = o.push({})
+    with raises(BadOptionName):
+        ooo = oo.add(values=44)
+        assert False
+
+
 #def test_child():
 #    options = Options(
 #            this=1,