~ibmcharmers/charms/xenial/ibm-cinder-storwize-svc/trunk

« back to all changes in this revision

Viewing changes to .tox/py35/lib/python3.5/site-packages/packaging/requirements.py

  • Committer: Ankammarao
  • Date: 2017-03-06 05:11:42 UTC
  • Revision ID: achittet@in.ibm.com-20170306051142-dpg27z4es1k56hfn
Marked tests folder executable

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# This file is dual licensed under the terms of the Apache License, Version
 
2
# 2.0, and the BSD License. See the LICENSE file in the root of this repository
 
3
# for complete details.
 
4
from __future__ import absolute_import, division, print_function
 
5
 
 
6
import string
 
7
import re
 
8
 
 
9
from pyparsing import stringStart, stringEnd, originalTextFor, ParseException
 
10
from pyparsing import ZeroOrMore, Word, Optional, Regex, Combine
 
11
from pyparsing import Literal as L  # noqa
 
12
from six.moves.urllib import parse as urlparse
 
13
 
 
14
from .markers import MARKER_EXPR, Marker
 
15
from .specifiers import LegacySpecifier, Specifier, SpecifierSet
 
16
 
 
17
 
 
18
class InvalidRequirement(ValueError):
 
19
    """
 
20
    An invalid requirement was found, users should refer to PEP 508.
 
21
    """
 
22
 
 
23
 
 
24
ALPHANUM = Word(string.ascii_letters + string.digits)
 
25
 
 
26
LBRACKET = L("[").suppress()
 
27
RBRACKET = L("]").suppress()
 
28
LPAREN = L("(").suppress()
 
29
RPAREN = L(")").suppress()
 
30
COMMA = L(",").suppress()
 
31
SEMICOLON = L(";").suppress()
 
32
AT = L("@").suppress()
 
33
 
 
34
PUNCTUATION = Word("-_.")
 
35
IDENTIFIER_END = ALPHANUM | (ZeroOrMore(PUNCTUATION) + ALPHANUM)
 
36
IDENTIFIER = Combine(ALPHANUM + ZeroOrMore(IDENTIFIER_END))
 
37
 
 
38
NAME = IDENTIFIER("name")
 
39
EXTRA = IDENTIFIER
 
40
 
 
41
URI = Regex(r'[^ ]+')("url")
 
42
URL = (AT + URI)
 
43
 
 
44
EXTRAS_LIST = EXTRA + ZeroOrMore(COMMA + EXTRA)
 
45
EXTRAS = (LBRACKET + Optional(EXTRAS_LIST) + RBRACKET)("extras")
 
46
 
 
47
VERSION_PEP440 = Regex(Specifier._regex_str, re.VERBOSE | re.IGNORECASE)
 
48
VERSION_LEGACY = Regex(LegacySpecifier._regex_str, re.VERBOSE | re.IGNORECASE)
 
49
 
 
50
VERSION_ONE = VERSION_PEP440 ^ VERSION_LEGACY
 
51
VERSION_MANY = Combine(VERSION_ONE + ZeroOrMore(COMMA + VERSION_ONE),
 
52
                       joinString=",", adjacent=False)("_raw_spec")
 
53
_VERSION_SPEC = Optional(((LPAREN + VERSION_MANY + RPAREN) | VERSION_MANY))
 
54
_VERSION_SPEC.setParseAction(lambda s, l, t: t._raw_spec or '')
 
55
 
 
56
VERSION_SPEC = originalTextFor(_VERSION_SPEC)("specifier")
 
57
VERSION_SPEC.setParseAction(lambda s, l, t: t[1])
 
58
 
 
59
MARKER_EXPR = originalTextFor(MARKER_EXPR())("marker")
 
60
MARKER_EXPR.setParseAction(
 
61
    lambda s, l, t: Marker(s[t._original_start:t._original_end])
 
62
)
 
63
MARKER_SEPERATOR = SEMICOLON
 
64
MARKER = MARKER_SEPERATOR + MARKER_EXPR
 
65
 
 
66
VERSION_AND_MARKER = VERSION_SPEC + Optional(MARKER)
 
67
URL_AND_MARKER = URL + Optional(MARKER)
 
68
 
 
69
NAMED_REQUIREMENT = \
 
70
    NAME + Optional(EXTRAS) + (URL_AND_MARKER | VERSION_AND_MARKER)
 
71
 
 
72
REQUIREMENT = stringStart + NAMED_REQUIREMENT + stringEnd
 
73
 
 
74
 
 
75
class Requirement(object):
 
76
    """Parse a requirement.
 
77
 
 
78
    Parse a given requirement string into its parts, such as name, specifier,
 
79
    URL, and extras. Raises InvalidRequirement on a badly-formed requirement
 
80
    string.
 
81
    """
 
82
 
 
83
    # TODO: Can we test whether something is contained within a requirement?
 
84
    #       If so how do we do that? Do we need to test against the _name_ of
 
85
    #       the thing as well as the version? What about the markers?
 
86
    # TODO: Can we normalize the name and extra name?
 
87
 
 
88
    def __init__(self, requirement_string):
 
89
        try:
 
90
            req = REQUIREMENT.parseString(requirement_string)
 
91
        except ParseException as e:
 
92
            raise InvalidRequirement(
 
93
                "Invalid requirement, parse error at \"{0!r}\"".format(
 
94
                    requirement_string[e.loc:e.loc + 8]))
 
95
 
 
96
        self.name = req.name
 
97
        if req.url:
 
98
            parsed_url = urlparse.urlparse(req.url)
 
99
            if not (parsed_url.scheme and parsed_url.netloc) or (
 
100
                    not parsed_url.scheme and not parsed_url.netloc):
 
101
                raise InvalidRequirement("Invalid URL given")
 
102
            self.url = req.url
 
103
        else:
 
104
            self.url = None
 
105
        self.extras = set(req.extras.asList() if req.extras else [])
 
106
        self.specifier = SpecifierSet(req.specifier)
 
107
        self.marker = req.marker if req.marker else None
 
108
 
 
109
    def __str__(self):
 
110
        parts = [self.name]
 
111
 
 
112
        if self.extras:
 
113
            parts.append("[{0}]".format(",".join(sorted(self.extras))))
 
114
 
 
115
        if self.specifier:
 
116
            parts.append(str(self.specifier))
 
117
 
 
118
        if self.url:
 
119
            parts.append("@ {0}".format(self.url))
 
120
 
 
121
        if self.marker:
 
122
            parts.append("; {0}".format(self.marker))
 
123
 
 
124
        return "".join(parts)
 
125
 
 
126
    def __repr__(self):
 
127
        return "<Requirement({0!r})>".format(str(self))