Commits

Daniel Holth committed 5c3985d

version 0.4 - cache markers; markerlib.compile()

  • Participants
  • Parent commits 6936828

Comments (0)

Files changed (6)

+0.4
+===
+- Cache compiled marker functions with weakref.WeakValueDictionary
+- Rename markerlib.as_function to markerlib.compile
+
 0.3
 ===
 - Might work on Python 2.5 (includes needed parts of the ast module from
 Usage::
 
     >>> import markerlib
-    >>> marker = markerlib.as_function("os.name == 'posix'")
+    >>> marker = markerlib.compile("os.name == 'posix'")
     >>> marker(environment=markerlib.default_environment(),
                override={'os.name':'posix'})
     True

File markerlib/__init__.py

-from markerlib.markers import default_environment, as_function, interpret
+from markerlib.markers import default_environment, compile, interpret, as_function

File markerlib/markers.py

     a free string, like '2.4', or 'win32'
 """
 
-__all__ = ['default_environment', 'as_function', 'interpret']
+__all__ = ['default_environment', 'compile', 'interpret']
 
 # Would import from ast but for Python 2.5
 from _ast import Compare, BoolOp, Attribute, Name, Load, Str, cmpop, boolop
 import os
 import platform
 import sys
+import weakref
+
+_builtin_compile = compile
 
 from platform import python_implementation
 
     return new_tree
 
 def compile_marker(parsed_marker):
-    return compile(parsed_marker, '<environment marker>', 'eval',
+    return _builtin_compile(parsed_marker, '<environment marker>', 'eval',
                    dont_inherit=True)
 
-def as_function(marker):
+_cache = weakref.WeakValueDictionary()
+
+def compile(marker):
     """Return compiled marker as a function accepting an environment dict."""
+    try:
+        return _cache[marker]
+    except KeyError:
+        pass
     if not marker.strip():
-        def dummy_marker(environment=None, override=None):
+        def marker_fn(environment=None, override=None):
             """"""
             return True
-        return dummy_marker        
-    compiled_marker = compile_marker(parse_marker(marker))
-    def marker_fn(environment=None, override=None):
-        """Extra updates environment"""
-        if override is None:
-            override = {}
-        if environment is None:
-            environment = default_environment()
-        environment.update(override)
-        return eval(compiled_marker, environment)
+    else:
+        compiled_marker = compile_marker(parse_marker(marker))
+        def marker_fn(environment=None, override=None):
+            """override updates environment"""
+            if override is None:
+                override = {}
+            if environment is None:
+                environment = default_environment()
+            environment.update(override)
+            return eval(compiled_marker, environment)
     marker_fn.__doc__ = marker
-    return marker_fn
+    _cache[marker] = marker_fn
+    return _cache[marker]
+
+as_function = compile # bw compat
 
 def interpret(marker, environment=None):
-    return as_function(marker)(environment)
+    return compile(marker)(environment)

File markerlib/test.py

 from nose.tools import assert_true, assert_false, assert_equal, raises
        
 def test_markers():
-    from .markers import interpret, default_environment, as_function
+    from .markers import interpret, default_environment, compile
     
     os_name = os.name
     
     raises_syntaxError()
     
     statement = "python_version == '5'"
-    assert_equal(as_function(statement).__doc__, statement)
+    assert_equal(compile(statement).__doc__, statement)
     
 def test_ast():
     try:
             
     NoneTransformer().visit(_markers_ast.parse('a.b = "c"'))
     NoneTransformer().visit(Node2())
-    
+    
 CHANGES = open(os.path.join(here, 'CHANGES.txt')).read()
 
 setup(name='markerlib',
-      version='0.3',
+      version='0.4',
       description='A compiler for PEP 345 environment markers.',
       long_description=README + '\n\n' +  CHANGES,
       classifiers=[
-        "Development Status :: 2 - Pre-Alpha",
+        "Development Status :: 4 - Beta",
         "Intended Audience :: Developers",
         "Programming Language :: Python",
         "Programming Language :: Python :: 2",
+        "Programming Language :: Python :: 3",
+        "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",
         ],
       author='Daniel Holth',
       author_email='dholth@fastmail.fm',