Skip to content

Commit

Permalink
Merge pull request #1434 from dstufft/vendor-pkg-resources
Browse files Browse the repository at this point in the history
Vendor pkg_resources
  • Loading branch information
dstufft committed Jan 7, 2014
2 parents 964c1ce + eeea3b7 commit 18c18de
Show file tree
Hide file tree
Showing 18 changed files with 2,935 additions and 77 deletions.
7 changes: 7 additions & 0 deletions CHANGES.txt
@@ -1,6 +1,13 @@
Changelog
=========

1.5.1 (unreleased)
------------------

* Remove the version requirement for setuptools so that it still functions with
setuptools < 0.8 installed (Pull #1434).


1.5 (2014-01-01)
----------------

Expand Down
8 changes: 8 additions & 0 deletions pip/_vendor/README.rst
Expand Up @@ -9,6 +9,14 @@ Modifications
=============

* html5lib has been modified to import six from pip._vendor
* pkg_resources has been modified to import _markerlib from pip._vendor
* markerlib has been modified to import it's API from pip._vendor


Markerlib and pkg_resources
===========================

Markerlib and pkg_resources has been pulled in from setuptools 2.0.2


Note to Downstream Distributors
Expand Down
16 changes: 16 additions & 0 deletions pip/_vendor/_markerlib/__init__.py
@@ -0,0 +1,16 @@
try:
import ast
from pip._vendor._markerlib.markers import default_environment, compile, interpret
except ImportError:
if 'ast' in globals():
raise
def default_environment():
return {}
def compile(marker):
def marker_fn(environment=None, override=None):
# 'empty markers are True' heuristic won't install extra deps.
return not marker.strip()
marker_fn.__doc__ = marker
return marker_fn
def interpret(marker, environment=None, override=None):
return compile(marker)()
119 changes: 119 additions & 0 deletions pip/_vendor/_markerlib/markers.py
@@ -0,0 +1,119 @@
# -*- coding: utf-8 -*-
"""Interpret PEP 345 environment markers.
EXPR [in|==|!=|not in] EXPR [or|and] ...
where EXPR belongs to any of those:
python_version = '%s.%s' % (sys.version_info[0], sys.version_info[1])
python_full_version = sys.version.split()[0]
os.name = os.name
sys.platform = sys.platform
platform.version = platform.version()
platform.machine = platform.machine()
platform.python_implementation = platform.python_implementation()
a free string, like '2.6', or 'win32'
"""

__all__ = ['default_environment', 'compile', 'interpret']

import ast
import os
import platform
import sys
import weakref

_builtin_compile = compile

try:
from platform import python_implementation
except ImportError:
if os.name == "java":
# Jython 2.5 has ast module, but not platform.python_implementation() function.
def python_implementation():
return "Jython"
else:
raise


# restricted set of variables
_VARS = {'sys.platform': sys.platform,
'python_version': '%s.%s' % sys.version_info[:2],
# FIXME parsing sys.platform is not reliable, but there is no other
# way to get e.g. 2.7.2+, and the PEP is defined with sys.version
'python_full_version': sys.version.split(' ', 1)[0],
'os.name': os.name,
'platform.version': platform.version(),
'platform.machine': platform.machine(),
'platform.python_implementation': python_implementation(),
'extra': None # wheel extension
}

for var in list(_VARS.keys()):
if '.' in var:
_VARS[var.replace('.', '_')] = _VARS[var]

def default_environment():
"""Return copy of default PEP 385 globals dictionary."""
return dict(_VARS)

class ASTWhitelist(ast.NodeTransformer):
def __init__(self, statement):
self.statement = statement # for error messages

ALLOWED = (ast.Compare, ast.BoolOp, ast.Attribute, ast.Name, ast.Load, ast.Str)
# Bool operations
ALLOWED += (ast.And, ast.Or)
# Comparison operations
ALLOWED += (ast.Eq, ast.Gt, ast.GtE, ast.In, ast.Is, ast.IsNot, ast.Lt, ast.LtE, ast.NotEq, ast.NotIn)

def visit(self, node):
"""Ensure statement only contains allowed nodes."""
if not isinstance(node, self.ALLOWED):
raise SyntaxError('Not allowed in environment markers.\n%s\n%s' %
(self.statement,
(' ' * node.col_offset) + '^'))
return ast.NodeTransformer.visit(self, node)

def visit_Attribute(self, node):
"""Flatten one level of attribute access."""
new_node = ast.Name("%s.%s" % (node.value.id, node.attr), node.ctx)
return ast.copy_location(new_node, node)

def parse_marker(marker):
tree = ast.parse(marker, mode='eval')
new_tree = ASTWhitelist(marker).generic_visit(tree)
return new_tree

def compile_marker(parsed_marker):
return _builtin_compile(parsed_marker, '<environment marker>', 'eval',
dont_inherit=True)

_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 marker_fn(environment=None, override=None):
""""""
return True
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
_cache[marker] = marker_fn
return _cache[marker]

def interpret(marker, environment=None):
return compile(marker)(environment)

0 comments on commit 18c18de

Please sign in to comment.