<s> from __future__ import absolute_import , division , print_function <EOL> import abc <EOL> import functools <EOL> import itertools <EOL> import re <EOL> from . _compat import string_types , with_metaclass <EOL> from . version import Version , LegacyVersion , parse <EOL> class InvalidSpecifier ( ValueError ) : <EOL> """<STR_LIT>""" <EOL> class BaseSpecifier ( with_metaclass ( abc . ABCMeta , object ) ) : <EOL> @ abc . abstractmethod <EOL> def __str__ ( self ) : <EOL> """<STR_LIT>""" <EOL> @ abc . abstractmethod <EOL> def __hash__ ( self ) : <EOL> """<STR_LIT>""" <EOL> @ abc . abstractmethod <EOL> def __eq__ ( self , other ) : <EOL> """<STR_LIT>""" <EOL> @ abc . abstractmethod <EOL> def __ne__ ( self , other ) : <EOL> """<STR_LIT>""" <EOL> @ abc . abstractproperty <EOL> def prereleases ( self ) : <EOL> """<STR_LIT>""" <EOL> @ prereleases . setter <EOL> def prereleases ( self , value ) : <EOL> """<STR_LIT>""" <EOL> @ abc . abstractmethod <EOL> def contains ( self , item , prereleases = None ) : <EOL> """<STR_LIT>""" <EOL> @ abc . abstractmethod <EOL> def filter ( self , iterable , prereleases = None ) : <EOL> """<STR_LIT>""" <EOL> class _IndividualSpecifier ( BaseSpecifier ) : <EOL> _operators = { } <EOL> def __init__ ( self , spec = "<STR_LIT>" , prereleases = None ) : <EOL> match = self . _regex . search ( spec ) <EOL> if not match : <EOL> raise InvalidSpecifier ( "<STR_LIT>" . format ( spec ) ) <EOL> self . _spec = ( <EOL> match . group ( "<STR_LIT>" ) . strip ( ) , <EOL> match . group ( "<STR_LIT:version>" ) . strip ( ) , <EOL> ) <EOL> self . _prereleases = prereleases <EOL> def __repr__ ( self ) : <EOL> pre = ( <EOL> "<STR_LIT>" . format ( self . prereleases ) <EOL> if self . _prereleases is not None <EOL> else "<STR_LIT>" <EOL> ) <EOL> return "<STR_LIT>" . format ( <EOL> self . __class__ . __name__ , <EOL> str ( self ) , <EOL> pre , <EOL> ) <EOL> def __str__ ( self ) : <EOL> return "<STR_LIT>" . format ( * self . _spec ) <EOL> def __hash__ ( self ) : <EOL> return hash ( self . _spec ) <EOL> def __eq__ ( self , other ) : <EOL> if isinstance ( other , string_types ) : <EOL> try : <EOL> other = self . __class__ ( other ) <EOL> except InvalidSpecifier : <EOL> return NotImplemented <EOL> elif not isinstance ( other , self . __class__ ) : <EOL> return NotImplemented <EOL> return self . _spec == other . _spec <EOL> def __ne__ ( self , other ) : <EOL> if isinstance ( other , string_types ) : <EOL> try : <EOL> other = self . __class__ ( other ) <EOL> except InvalidSpecifier : <EOL> return NotImplemented <EOL> elif not isinstance ( other , self . __class__ ) : <EOL> return NotImplemented <EOL> return self . _spec != other . _spec <EOL> def _get_operator ( self , op ) : <EOL> return getattr ( self , "<STR_LIT>" . format ( self . _operators [ op ] ) ) <EOL> def _coerce_version ( self , version ) : <EOL> if not isinstance ( version , ( LegacyVersion , Version ) ) : <EOL> version = parse ( version ) <EOL> return version <EOL> @ property <EOL> def operator ( self ) : <EOL> return self . _spec [ <NUM_LIT:0> ] <EOL> @ property <EOL> def version ( self ) : <EOL> return self . _spec [ <NUM_LIT:1> ] <EOL> @ property <EOL> def prereleases ( self ) : <EOL> return self . _prereleases <EOL> @ prereleases . setter <EOL> def prereleases ( self , value ) : <EOL> self . _prereleases = value <EOL> def __contains__ ( self , item ) : <EOL> return self . contains ( item ) <EOL> def contains ( self , item , prereleases = None ) : <EOL> if prereleases is None : <EOL> prereleases = self . prereleases <EOL> item = self . _coerce_version ( item ) <EOL> if item . is_prerelease and not prereleases : <EOL> return False <EOL> return self . _get_operator ( self . operator ) ( item , self . version ) <EOL> def filter ( self , iterable , prereleases = None ) : <EOL> yielded = False <EOL> found_prereleases = [ ] <EOL> kw = { "<STR_LIT>" : prereleases if prereleases is not None else True } <EOL> for version in iterable : <EOL> parsed_version = self . _coerce_version ( version ) <EOL> if self . contains ( parsed_version , ** kw ) : <EOL> if ( parsed_version . is_prerelease <EOL> and not ( prereleases or self . prereleases ) ) : <EOL> found_prereleases . append ( version ) <EOL> else : <EOL> yielded = True <EOL> yield version <EOL> if not yielded and found_prereleases : <EOL> for version in found_prereleases : <EOL> yield version <EOL> class LegacySpecifier ( _IndividualSpecifier ) : <EOL> _regex = re . compile ( <EOL> r"""<STR_LIT>""" , <EOL> re . VERBOSE | re . IGNORECASE , <EOL> ) <EOL> _operators = { <EOL> "<STR_LIT>" : "<STR_LIT>" , <EOL> "<STR_LIT>" : "<STR_LIT>" , <EOL> "<STR_LIT>" : "<STR_LIT>" , <EOL> "<STR_LIT>" : "<STR_LIT>" , <EOL> "<STR_LIT:<>" : "<STR_LIT>" , <EOL> "<STR_LIT:>>" : "<STR_LIT>" , <EOL> } <EOL> def _coerce_version ( self , version ) : <EOL> if not isinstance ( version , LegacyVersion ) : <EOL> version = LegacyVersion ( str ( version ) ) <EOL> return version <EOL> def _compare_equal ( self , prospective , spec ) : <EOL> return prospective == self . _coerce_version ( spec ) <EOL> def _compare_not_equal ( self , prospective , spec ) : <EOL> return prospective != self . _coerce_version ( spec ) <EOL> def _compare_less_than_equal ( self , prospective , spec ) : <EOL> return prospective <= self . _coerce_version ( spec ) <EOL> def _compare_greater_than_equal ( self , prospective , spec ) : <EOL> return prospective >= self . _coerce_version ( spec ) <EOL> def _compare_less_than ( self , prospective , spec ) : <EOL> return prospective < self . _coerce_version ( spec ) <EOL> def _compare_greater_than ( self , prospective , spec ) : <EOL> return prospective > self . _coerce_version ( spec ) <EOL> def _require_version_compare ( fn ) : <EOL> @ functools . wraps ( fn ) <EOL> def wrapped ( self , prospective , spec ) : <EOL> if not isinstance ( prospective , Version ) : <EOL> return False <EOL> return fn ( self , prospective , spec ) <EOL> return wrapped <EOL> class Specifier ( _IndividualSpecifier ) : <EOL> _regex = re . compile ( <EOL> r"""<STR_LIT>""" , <EOL> re . VERBOSE | re . IGNORECASE , <EOL> ) <EOL> _operators = { <EOL> "<STR_LIT>" : "<STR_LIT>" , <EOL> "<STR_LIT>" : "<STR_LIT>" , <EOL> "<STR_LIT>" : "<STR_LIT>" , <EOL> "<STR_LIT>" : "<STR_LIT>" , <EOL> "<STR_LIT>" : "<STR_LIT>" , <EOL> "<STR_LIT:<>" : "<STR_LIT>" , <EOL> "<STR_LIT:>>" : "<STR_LIT>" , <EOL> "<STR_LIT>" : "<STR_LIT>" , <EOL> } <EOL> @ _require_version_compare <EOL> def _compare_compatible ( self , prospective , spec ) : <EOL> prefix = "<STR_LIT:.>" . join ( <EOL> list ( <EOL> itertools . takewhile ( <EOL> lambda x : ( not x . startswith ( "<STR_LIT>" ) <EOL> and not x . startswith ( "<STR_LIT>" ) ) , <EOL> _version_split ( spec ) , <EOL> ) <EOL> ) [ : - <NUM_LIT:1> ] <EOL> ) <EOL> prefix += "<STR_LIT>" <EOL> return ( self . _get_operator ( "<STR_LIT>" ) ( prospective , spec ) <EOL> and self . _get_operator ( "<STR_LIT>" ) ( prospective , prefix ) ) <EOL> @ _require_version_compare <EOL> def _compare_equal ( self , prospective , spec ) : <EOL> if spec . endswith ( "<STR_LIT>" ) : <EOL> spec = _version_split ( spec [ : - <NUM_LIT:2> ] ) <EOL> prospective = _version_split ( str ( prospective ) ) <EOL> prospective = prospective [ : len ( spec ) ] <EOL> spec , prospective = _pad_version ( spec , prospective ) <EOL> else : <EOL> spec = Version ( spec ) <EOL> if not spec . local : <EOL> prospective = Version ( prospective . public ) <EOL> return prospective == spec <EOL> @ _require_version_compare <EOL> def _compare_not_equal ( self , prospective , spec ) : <EOL> return not self . _compare_equal ( prospective , spec ) <EOL> @ _require_version_compare <EOL> def _compare_less_than_equal ( self , prospective , spec ) : <EOL> return prospective <= Version ( spec ) <EOL> @ _require_version_compare <EOL> def _compare_greater_than_equal ( self , prospective , spec ) : <EOL> return prospective >= Version ( spec ) <EOL> @ _require_version_compare <EOL> def _compare_less_than ( self , prospective , spec ) : <EOL> spec = Version ( spec ) <EOL> if not prospective < spec : <EOL> return False <EOL> if not spec . is_prerelease and prospective . is_prerelease : <EOL> if Version ( prospective . base_version ) == Version ( spec . base_version ) : <EOL> return False <EOL> return True <EOL> @ _require_version_compare <EOL> def _compare_greater_than ( self , prospective , spec ) : <EOL> spec = Version ( spec ) <EOL> if not prospective > spec : <EOL> return False <EOL> if not spec . is_postrelease and prospective . is_postrelease : <EOL> if Version ( prospective . base_version ) == Version ( spec . base_version ) : <EOL> return False <EOL> if prospective . local is not None : <EOL> if Version ( prospective . base_version ) == Version ( spec . base_version ) : <EOL> return False <EOL> return True <EOL> def _compare_arbitrary ( self , prospective , spec ) : <EOL> return str ( prospective ) . lower ( ) == str ( spec ) . lower ( ) <EOL> @ property <EOL> def prereleases ( self ) : <EOL> if self . _prereleases is not None : <EOL> return self . _prereleases <EOL> operator , version = self . _spec <EOL> if operator in [ "<STR_LIT>" , "<STR_LIT>" , "<STR_LIT>" , "<STR_LIT>" , "<STR_LIT>" ] : <EOL> if operator == "<STR_LIT>" and version . endswith ( "<STR_LIT>" ) : <EOL> version = version [ : - <NUM_LIT:2> ] <EOL> if parse ( version ) . is_prerelease : <EOL> return True <EOL> return False <EOL> @ prereleases . setter <EOL> def prereleases ( self , value ) : <EOL> self . _prereleases = value <EOL> _prefix_regex = re . compile ( r"<STR_LIT>" ) <EOL> def _version_split ( version ) : <EOL> result = [ ] <EOL> for item in version . split ( "<STR_LIT:.>" ) : <EOL> match = _prefix_regex . search ( item ) <EOL> if match : <EOL> result . extend ( match . groups ( ) ) <EOL> else : <EOL> result . append ( item ) <EOL> return result <EOL> def _pad_version ( left , right ) : <EOL> left_split , right_split = [ ] , [ ] <EOL> left_split . append ( list ( itertools . takewhile ( lambda x : x . isdigit ( ) , left ) ) ) <EOL> right_split . append ( list ( itertools . takewhile ( lambda x : x . isdigit ( ) , right ) ) ) <EOL> left_split . append ( left [ len ( left_split ) : ] ) <EOL> right_split . append ( left [ len ( right_split ) : ] ) <EOL> left_split . insert ( <EOL> <NUM_LIT:1> , <EOL> [ "<STR_LIT:0>" ] * max ( <NUM_LIT:0> , len ( right_split [ <NUM_LIT:0> ] ) - len ( left_split [ <NUM_LIT:0> ] ) ) , <EOL> ) <EOL> right_split . insert ( <EOL> <NUM_LIT:1> , <EOL> [ "<STR_LIT:0>" ] * max ( <NUM_LIT:0> , len ( left_split [ <NUM_LIT:0> ] ) - len ( right_split [ <NUM_LIT:0> ] ) ) , <EOL> ) <EOL> return ( <EOL> list ( itertools . chain ( * left_split ) ) , <EOL> list ( itertools . chain ( * right_split ) ) , <EOL> ) <EOL> class SpecifierSet ( BaseSpecifier ) : <EOL> def __init__ ( self , specifiers = "<STR_LIT>" , prereleases = None ) : <EOL> specifiers = [ s . strip ( ) for s in specifiers . split ( "<STR_LIT:U+002C>" ) if s . strip ( ) ] <EOL> parsed = set ( ) <EOL> for specifier in specifiers : <EOL> try : <EOL> parsed . add ( Specifier ( specifier ) ) <EOL> except InvalidSpecifier : <EOL> parsed . add ( LegacySpecifier ( specifier ) ) <EOL> self . _specs = frozenset ( parsed ) <EOL> self . _prereleases = prereleases <EOL> def __repr__ ( self ) : <EOL> pre = ( <EOL> "<STR_LIT>" . format ( self . prereleases ) <EOL> if self . _prereleases is not None <EOL> else "<STR_LIT>" <EOL> ) <EOL> return "<STR_LIT>" . format ( str ( self ) , pre ) <EOL> def __str__ ( self ) : <EOL> return "<STR_LIT:U+002C>" . join ( sorted ( str ( s ) for s in self . _specs ) ) <EOL> def __hash__ ( self ) : <EOL> return hash ( self . _specs ) <EOL> def __and__ ( self , other ) : <EOL> if isinstance ( other , string_types ) : <EOL> other = SpecifierSet ( other ) <EOL> elif not isinstance ( other , SpecifierSet ) : <EOL> return NotImplemented <EOL> specifier = SpecifierSet ( ) <EOL> specifier . _specs = frozenset ( self . _specs | other . _specs ) <EOL> if self . _prereleases is None and other . _prereleases is not None : <EOL> specifier . _prereleases = other . _prereleases <EOL> elif self . _prereleases is not None and other . _prereleases is None : <EOL> specifier . _prereleases = self . _prereleases <EOL> elif self . _prereleases == other . _prereleases : <EOL> specifier . _prereleases = self . _prereleases <EOL> else : <EOL> raise ValueError ( <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> ) <EOL> return specifier <EOL> def __eq__ ( self , other ) : <EOL> if isinstance ( other , string_types ) : <EOL> other = SpecifierSet ( other ) <EOL> elif isinstance ( other , _IndividualSpecifier ) : <EOL> other = SpecifierSet ( str ( other ) ) <EOL> elif not isinstance ( other , SpecifierSet ) : <EOL> return NotImplemented <EOL> return self . _specs == other . _specs <EOL> def __ne__ ( self , other ) : <EOL> if isinstance ( other , string_types ) : <EOL> other = SpecifierSet ( other ) <EOL> elif isinstance ( other , _IndividualSpecifier ) : <EOL> other = SpecifierSet ( str ( other ) ) <EOL> elif not isinstance ( other , SpecifierSet ) : <EOL> return NotImplemented <EOL> return self . _specs != other . _specs <EOL> def __len__ ( self ) : <EOL> return len ( self . _specs ) <EOL> def __iter__ ( self ) : <EOL> return iter ( self . _specs ) <EOL> @ property <EOL> def prereleases ( self ) : <EOL> if self . _prereleases is not None : <EOL> return self . _prereleases <EOL> if not self . _specs : <EOL> return None <EOL> return any ( s . prereleases for s in self . _specs ) <EOL> @ prereleases . setter <EOL> def prereleases ( self , value ) : <EOL> self . _prereleases = value <EOL> def __contains__ ( self , item ) : <EOL> return self . contains ( item ) <EOL> def contains ( self , item , prereleases = None ) : <EOL> if not isinstance ( item , ( LegacyVersion , Version ) ) : <EOL> item = parse ( item ) <EOL> if prereleases is None : <EOL> prereleases = self . prereleases <EOL> if not prereleases and item . is_prerelease : <EOL> return False <EOL> return all ( <EOL> s . contains ( item , prereleases = prereleases ) <EOL> for s in self . _specs <EOL> ) <EOL> def filter ( self , iterable , prereleases = None ) : <EOL> if prereleases is None : <EOL> prereleases = self . prereleases <EOL> if self . _specs : <EOL> for spec in self . _specs : <EOL> iterable = spec . filter ( iterable , prereleases = bool ( prereleases ) ) <EOL> return iterable <EOL> else : <EOL> filtered = [ ] <EOL> found_prereleases = [ ] <EOL> for item in iterable : <EOL> if not isinstance ( item , ( LegacyVersion , Version ) ) : <EOL> parsed_version = parse ( item ) <EOL> else : <EOL> parsed_version = item <EOL> if isinstance ( parsed_version , LegacyVersion ) : <EOL> continue <EOL> if parsed_version . is_prerelease and not prereleases : <EOL> if not filtered : <EOL> found_prereleases . append ( item ) <EOL> else : <EOL> filtered . append ( item ) <EOL> if not filtered and found_prereleases and prereleases is None : <EOL> return found_prereleases <EOL> return filtered </s>
