Daniel Holth avatar Daniel Holth committed b62968c Draft

impractical to support _markerlib on Python < 2.6 (no compile(ast))

Comments (0)

Files changed (4)

_markerlib/__init__.py

+"""Used by pkg_resources to interpret PEP 345 environment markers."""
 from _markerlib.markers import default_environment, compile, interpret, as_function

_markerlib/_markers_ast.py

-# -*- coding: utf-8 -*-
-"""
-Just enough of ast.py for markers.py
-"""
-
-from _ast import AST, PyCF_ONLY_AST
-
-def parse(source, filename='<unknown>', mode='exec'):
-    """
-    Parse the source into an AST node.
-    Equivalent to compile(source, filename, mode, PyCF_ONLY_AST).
-    """
-    return compile(source, filename, mode, PyCF_ONLY_AST)
-
-def copy_location(new_node, old_node):
-    """
-    Copy source location (`lineno` and `col_offset` attributes) from
-    *old_node* to *new_node* if possible, and return *new_node*.
-    """
-    for attr in 'lineno', 'col_offset':
-        if attr in old_node._attributes and attr in new_node._attributes \
-           and hasattr(old_node, attr):
-            setattr(new_node, attr, getattr(old_node, attr))
-    return new_node
-
-def iter_fields(node):
-    """
-    Yield a tuple of ``(fieldname, value)`` for each field in ``node._fields``
-    that is present on *node*.
-    """
-    for field in node._fields:
-        try:
-            yield field, getattr(node, field)
-        except AttributeError:
-            pass
-
-class NodeVisitor(object):
-    """
-    A node visitor base class that walks the abstract syntax tree and calls a
-    visitor function for every node found.  This function may return a value
-    which is forwarded by the `visit` method.
-
-    This class is meant to be subclassed, with the subclass adding visitor
-    methods.
-
-    Per default the visitor functions for the nodes are ``'visit_'`` +
-    class name of the node.  So a `TryFinally` node visit function would
-    be `visit_TryFinally`.  This behavior can be changed by overriding
-    the `visit` method.  If no visitor function exists for a node
-    (return value `None`) the `generic_visit` visitor is used instead.
-
-    Don't use the `NodeVisitor` if you want to apply changes to nodes during
-    traversing.  For this a special visitor exists (`NodeTransformer`) that
-    allows modifications.
-    """
-
-    def visit(self, node):
-        """Visit a node."""
-        method = 'visit_' + node.__class__.__name__
-        visitor = getattr(self, method, self.generic_visit)
-        return visitor(node)
-
-#    def generic_visit(self, node):
-#        """Called if no explicit visitor function exists for a node."""
-#        for field, value in iter_fields(node):
-#            if isinstance(value, list):
-#                for item in value:
-#                    if isinstance(item, AST):
-#                        self.visit(item)
-#            elif isinstance(value, AST):
-#                self.visit(value)
-
-
-class NodeTransformer(NodeVisitor):
-    """
-    A :class:`NodeVisitor` subclass that walks the abstract syntax tree and
-    allows modification of nodes.
-
-    The `NodeTransformer` will walk the AST and use the return value of the
-    visitor methods to replace or remove the old node.  If the return value of
-    the visitor method is ``None``, the node will be removed from its location,
-    otherwise it is replaced with the return value.  The return value may be the
-    original node in which case no replacement takes place.
-
-    Here is an example transformer that rewrites all occurrences of name lookups
-    (``foo``) to ``data['foo']``::
-
-       class RewriteName(NodeTransformer):
-
-           def visit_Name(self, node):
-               return copy_location(Subscript(
-                   value=Name(id='data', ctx=Load()),
-                   slice=Index(value=Str(s=node.id)),
-                   ctx=node.ctx
-               ), node)
-
-    Keep in mind that if the node you're operating on has child nodes you must
-    either transform the child nodes yourself or call the :meth:`generic_visit`
-    method for the node first.
-
-    For nodes that were part of a collection of statements (that applies to all
-    statement nodes), the visitor may also return a list of nodes rather than
-    just a single node.
-
-    Usually you use the transformer like this::
-
-       node = YourTransformer().visit(node)
-    """
-
-    def generic_visit(self, node):
-        for field, old_value in iter_fields(node):
-            old_value = getattr(node, field, None)
-            if isinstance(old_value, list):
-                new_values = []
-                for value in old_value:
-                    if isinstance(value, AST):
-                        value = self.visit(value)
-                        if value is None:
-                            continue
-                        elif not isinstance(value, AST):
-                            new_values.extend(value)
-                            continue
-                    new_values.append(value)
-                old_value[:] = new_values
-            elif isinstance(old_value, AST):
-                new_node = self.visit(old_value)
-                if new_node is None:
-                    delattr(node, field)
-                else:
-                    setattr(node, field, new_node)
-        return node
-    

_markerlib/markers.py

     platform.version = platform.version()
     platform.machine = platform.machine()
     platform.python_implementation = platform.python_implementation()
-    a free string, like '2.4', or 'win32'
+    a free string, like '2.6', or 'win32'
 """
 
 __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
-try:
-    from ast import parse, copy_location, NodeTransformer
-except ImportError: # pragma no coverage
-    from markerlib._markers_ast import parse, copy_location, NodeTransformer
+from ast import Compare, BoolOp, Attribute, Name, Load, Str, cmpop, boolop
+from ast import parse, copy_location, NodeTransformer
 
 import os
 import platform
     _cache[marker] = marker_fn
     return _cache[marker]
 
-as_function = compile # bw compat
-
 def interpret(marker, environment=None):
     return compile(marker)(environment)
             marker_fn.__doc__ = marker
             return marker_fn
         try:
-            from _markerlib import as_function
+            from _markerlib import compile as compile_marker
         except ImportError:
-            as_function = dummy_marker
+            compile_marker = dummy_marker
         dm = self.__dep_map = {None: []}
 
         reqs = []
         for req in self._parsed_pkg_info.get_all('Requires-Dist') or []:
             distvers, mark = self._preparse_requirement(req)
             parsed = parse_requirements(distvers).next()
-            parsed.marker_fn = as_function(mark)
+            parsed.marker_fn = compile_marker(mark)
             reqs.append(parsed)
             
         def reqs_for_extra(extra):
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.