Jonathan Eunice avatar Jonathan Eunice committed 670ffad

tested under Python3 with tox & py.test; docs extended for Py3

Comments (0)

Files changed (6)

 syntax: glob
 *.swp.{py,txt,html,css,js}
+*.swp
 *.pyc
+.tox
 .DS_Store
 build/*
 dist/*
     t2 = Thing("one")
     assert t1 is t2
     
+Python 3
+========
+
+``mementos`` works in Python 3 just as in Python 2, but with different
+syntax. Instead of the
+double-underscore class attribute assignment, Python 3 uses a keyword argument
+at class creation time::
+
+    class Thing3(object, metaclass=MementoMetaclass):
+        ...
+       
+Unfortunately, Python 2 and Python 3 don't recognize each other's syntax
+for metaclass specification, so straightforwad code designed
+for one won't even compile for
+the other. You can get around this by using the
+``with_metaclass()`` function from the
+``six`` cross-version compatibility module. It's very short, so you can
+drop it into any program thus::
+    
+    def with_metaclass(meta, base=object):
+        """Create a base class with a metaclass."""
+        return meta("NewBase", (base,), {})
+    
+    class Thing23(with_metaclass(MementoMetaclass, object)):
+        ...
+
+alternatively you can import it from the ``six`` module::
+
+    from six import with_metaclass
+    ...
+    
+(You can even inline what ``with_metaclass()`` does directly, but it's
+ugly and not recommended.)
 
 Notes
 =====
 
- *  Derived from `an ActiveState recipe
+ *  Mementos was derived from `an ActiveState recipe
     <http://code.activestate.com/recipes/286132-memento-design-pattern-in-python/>`_ by Valentino Volonghi.
+    Thank you, Valentino!
     
  *  It is safe to memoize multiple classes at the same time. They will all be stored in the same cache, but
     their class is a part of the cache key, so the values are distinct.
         assert ot1 is ot2
         assert ot1.color == ot2.color == 'blue'
         assert ot1.weight == ot2.weight == 'light'
+        
+ *  Automated multi-version testing with 
+    `pytest <http://pypi.python.org/pypi/pytest>`_
+    and `tox <http://pypi.python.org/pypi/tox>`_ modules has commenced. ``mementos`` is now
+    successfully packaged for, and tested against, all late-model verions of
+    Python (2.6, 2.7, 3.2, and 3.3) and one (2.5) that isn't so very recent.
 
 Installation
 ============
+[pytest]
+python_files = test/*.py
 #! /usr/bin/env python
 
 from setuptools import setup
-from decimal import Decimal
-import re
+import sys
 
 def linelist(text):
     """
     Dangerous, self-modifying, and also, helps keep version numbers
     ascending without human intervention.
     """
+    from decimal import Decimal
+    import re 
+
     d = Decimal(s)
     increment = Decimal('0.001')
     d = d.quantize(increment) + increment
     open('setup.py', 'w').write(setup)
     return dstr
 
+def linelist(text):
+    """
+    Returns each non-blank line in text enclosed in a list.
+    """
+    return [ l.strip() for l in text.strip().splitlines() if l.split() ]
+    
+    # The double-mention of l.strip() is yet another fine example of why
+    # Python needs en passant aliasing.
+
 setup(
     name='mementos',
-    version=verno("0.108"),
+    version=verno("0.404"),
     author='Jonathan Eunice',
     author_email='jonathan.eunice@gmail.com',
     description='Memoizing metaclass. Drop-dead simple way to create cached objects',
     url='https://bitbucket.org/jeunice/mementos',
     py_modules=['mementos'],
     install_requires=[],
+    tests_require = ['tox', 'pytest'],
+    zip_safe = True,
     classifiers=linelist("""
         Development Status :: 4 - Beta
         Operating System :: OS Independent
         License :: OSI Approved :: BSD License
         Intended Audience :: Developers
         Programming Language :: Python
+        Programming Language :: Python :: 2.5
+        Programming Language :: Python :: 2.6
+        Programming Language :: Python :: 2.7
+        Programming Language :: Python :: 3.2
+        Programming Language :: Python :: 3.3
         Topic :: Software Development :: Libraries :: Python Modules
     """)
 )
-
-
 from mementos import *
 
-if __name__ == '__main__':
-    
-    class Thing(object):
-        
-        __metaclass__ = MementoMetaclass
-        
+def with_metaclass(meta, base=object):
+    """Create a base class with a metaclass."""
+    return meta("NewBase", (base,), {})
+
+def test_one():    
+    class Thing(with_metaclass(MementoMetaclass, object)):
+                
         def __init__(self, name):
             self.name = name
         
     o2 = Thing(name="lovely")
     assert o1 is not o2   # because the call signature is different
     
-    class OtherThing(object):
-            
-        __metaclass__ = MementoMetaclass
+    class OtherThing(with_metaclass(MementoMetaclass, object)):
         
         def __init__(self, name):
             self.name = name
     assert ot1 is ot2
     assert ot1.color == ot2.color == 'blue'
     assert ot1.weight == ot2.weight == 'light'
+    
+def test_inline_with_metaclass():
+    
+    # Make sure you can do the metaclass specification directly.
+    
+    class Thing23(MementoMetaclass("NewBase", (object,), {})):
+                
+        def __init__(self, name):
+            self.name = name
+        
 
-    print "working as designed!"
-    
+    t1 = Thing23("one")
+    t2 = Thing23("one")
+    assert t1 is t2
+    
+    o1 = Thing23("lovely")
+    o2 = Thing23(name="lovely")
+    assert o1 is not o2   # because the call signature is different
+    
+    
+# need to extend for Py3
+# http://mikewatkins.ca/2008/11/29/python-2-and-3-metaclasses/
+[tox]
+envlist = py25, py26, py27, py32, py33
+
+[testenv]
+changedir=test
+deps=
+    pytest       # install pytest in the venvs
+    six
+commands=py.test {posargs}
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.