Python itertools.dropwhile() Examples

The following are 30 code examples for showing how to use itertools.dropwhile(). These examples are extracted from open source projects. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example.

You may check out the related API usage on the sidebar.

You may also want to check out all available functions/classes of the module itertools , or try the search function .

Example 1
Project: linter-pylama   Author: AtomLinter   File: violations.py    License: MIT License 6 votes vote down vote up
def lines(self):
        """Return the source code lines for this error."""
        source = ''
        lines = self.definition.source
        offset = self.definition.start
        lines_stripped = list(reversed(list(dropwhile(is_blank,
                                                      reversed(lines)))))
        numbers_width = len(str(offset + len(lines_stripped)))
        line_format = '{{:{}}}:{{}}'.format(numbers_width)
        for n, line in enumerate(lines_stripped):
            if line:
                line = ' ' + line
            source += line_format.format(n + offset, line)
            if n > 5:
                source += '        ...\n'
                break
        return source 
Example 2
Project: cloudbridge   Author: CloudVE   File: resources.py    License: MIT License 6 votes vote down vote up
def __init__(self, provider, objects, limit=None, marker=None):
        self._objects = objects
        limit = limit or provider.config.default_result_limit
        total_size = len(objects)
        if marker:
            from_marker = itertools.dropwhile(
                lambda obj: not obj.id == marker, objects)
            # skip one past the marker
            next(from_marker, None)
            objects = list(from_marker)
        is_truncated = len(objects) > limit
        results = list(itertools.islice(objects, limit))
        super(ClientPagedResultList, self).__init__(
            is_truncated,
            results[-1].id if is_truncated else None,
            True, total=total_size,
            data=results) 
Example 3
Project: yaql   Author: openstack   File: queries.py    License: Apache License 2.0 6 votes vote down vote up
def skip_while(collection, predicate):
    """:yaql:skipWhile

    Skips elements from the collection as long as the predicate is true.
    Then returns an iterator to collection of remaining elements

    :signature: collection.skipWhile(predicate)
    :receiverArg collection: input collection
    :argType collection: iterable
    :arg predicate: function of one argument to apply to every collection value
    :argType predicate: lambda
    :returnType: iterator

    .. code::

        yaql> [1, 2, 3, 4, 5].skipWhile($ < 3)
        [3, 4, 5]
    """
    return itertools.dropwhile(predicate, collection) 
Example 4
Project: linter-pylama   Author: AtomLinter   File: parser.py    License: MIT License 5 votes vote down vote up
def source(self):
        """Return the source code for the definition."""
        full_src = self._source[self._slice]

        def is_empty_or_comment(line):
            return line.strip() == '' or line.strip().startswith('#')

        filtered_src = dropwhile(is_empty_or_comment, reversed(full_src))
        return ''.join(reversed(list(filtered_src))) 
Example 5
Project: linehaul   Author: pypa   File: test_strategies.py    License: Apache License 2.0 5 votes vote down vote up
def _ver_2_list(version):
        version = [int(i) for i in version.split(".")]
        return list(
            reversed(list(itertools.dropwhile(lambda i: i == 0, reversed(version))))
        ) 
Example 6
Project: GTDWeb   Author: lanbing510   File: makemessages.py    License: GNU General Public License v2.0 5 votes vote down vote up
def write_pot_file(potfile, msgs):
    """
    Write the :param potfile: POT file with the :param msgs: contents,
    previously making sure its format is valid.
    """
    if os.path.exists(potfile):
        # Strip the header
        msgs = '\n'.join(dropwhile(len, msgs.split('\n')))
    else:
        msgs = msgs.replace('charset=CHARSET', 'charset=UTF-8')
    with io.open(potfile, 'a', encoding='utf-8') as fp:
        fp.write(msgs) 
Example 7
Project: lambda-packs   Author: ryfeus   File: arffread.py    License: MIT License 5 votes vote down vote up
def go_data(ofile):
    """Skip header.

    the first next() call of the returned iterator will be the @data line"""
    return itertools.dropwhile(lambda x: not r_datameta.match(x), ofile)


#----------------
# Parsing header
#---------------- 
Example 8
Project: deimos   Author: mesosphere-backup   File: docker.py    License: Apache License 2.0 5 votes vote down vote up
def split_on(iterable, element):
    preceding = list(takewhile(lambda _: _ != element, iterable))
    following = list(dropwhile(lambda _: _ != element, iterable))
    return preceding, (following[1:] if len(following) > 0 else None) 
Example 9
Project: FIR   Author: certsocietegenerale   File: querysets.py    License: GNU General Public License v3.0 5 votes vote down vote up
def order_by(self, *field_names):
        '''
        Returns a list of the QuerySetSequence items with the ordering changed.
        '''
        # construct a comparator function based on the field names prefixes
        reverses = [1] * len(field_names)
        field_names = list(field_names)
        for i in range(len(field_names)):
            field_name = field_names[i]
            if field_name[0] == '-':
                reverses[i] = -1
                field_names[i] = field_name[1:]

        # wanna iterable and attrgetter returns single item if 1 arg supplied
        def fields_getter(i):
            return chain_sing(attrgetter(*field_names)(i))

        # comparator gets the first non-zero value of the field comparison
        # results taking into account reverse order for fields prefixed with '-'
        def comparator(i1, i2):
            return dropwhile(
                __not__,
                mul_it(map(cmp, fields_getter(i1), fields_getter(i2)), reverses)
            ).next()

        # return new sorted list
        return sorted(self.collapse(), cmp=comparator) 
Example 10
Project: tap-hubspot   Author: singer-io   File: __init__.py    License: GNU Affero General Public License v3.0 5 votes vote down vote up
def get_streams_to_sync(streams, state):
    target_stream = singer.get_currently_syncing(state)
    result = streams
    if target_stream:
        skipped = list(itertools.takewhile(
            lambda x: x.tap_stream_id != target_stream, streams))
        rest = list(itertools.dropwhile(
            lambda x: x.tap_stream_id != target_stream, streams))
        result = rest + skipped # Move skipped streams to end
    if not result:
        raise Exception('Unknown stream {} in state'.format(target_stream))
    return result 
Example 11
Project: BERT   Author: yyht   File: convolution.py    License: Apache License 2.0 5 votes vote down vote up
def new_parameters(self, input_shape, input_dtype, rng):
    del input_dtype
    if len(input_shape) > 4:
      self._check_nhwc()
      new_batch_dim = six.moves.reduce(operator.mul, input_shape[:-3])
      input_shape = [new_batch_dim] + list(input_shape[-3:])
    kernel_shape = self._kernel_shape(input_shape)
    bias_shape = [self._filters if c == 'C' else 1 for c in self._out_spec]
    bias_shape = tuple(itertools.dropwhile(lambda x: x == 1, bias_shape))
    w = self._kernel_initializer(kernel_shape, rng)
    b = self._bias_initializer(bias_shape, rng)
    return (w, b) 
Example 12
Project: MadMax   Author: nevillegrech   File: memtypes.py    License: BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
def meet(cls, a: 'VariableStack', b: 'VariableStack') -> 'VariableStack':
        """
        Return the meet of the given stacks, taking the element-wise meets of their
        contained Variables from the top down.
        """

        pairs = zip_longest(reversed(a.value), reversed(b.value),
                            fillvalue=Variable.bottom())
        max_size = a.max_size if a.max_size < b.max_size else b.max_size
        return cls(dropwhile(lambda x: x.is_bottom,
                             [Variable.meet(*p) for p in pairs][::-1]),
                   max_size) 
Example 13
Project: Computable   Author: ktraunmueller   File: arffread.py    License: MIT License 5 votes vote down vote up
def go_data(ofile):
    """Skip header.

    the first next() call of the returned iterator will be the @data line"""
    return itertools.dropwhile(lambda x: not r_datameta.match(x), ofile)


#----------------
# Parsing header
#---------------- 
Example 14
Project: airflow   Author: apache   File: test_spark_sql.py    License: Apache License 2.0 5 votes vote down vote up
def get_after(sentinel, iterable):
    """Get the value after `sentinel` in an `iterable`"""
    truncated = dropwhile(lambda el: el != sentinel, iterable)
    next(truncated)
    return next(truncated) 
Example 15
Project: trax   Author: google   File: convolution.py    License: Apache License 2.0 5 votes vote down vote up
def init_weights_and_state(self, input_signature):
    input_shape = input_signature.shape
    if len(input_shape) > 4:
      self._check_nhwc()
      new_batch_dim = functools.reduce(operator.mul, input_shape[:-3])
      input_shape = [new_batch_dim] + list(input_shape[-3:])
    kernel_shape = self._kernel_shape(input_shape)
    bias_shape = [self._filters if c == 'C' else 1 for c in self._out_spec]
    bias_shape = tuple(itertools.dropwhile(lambda x: x == 1, bias_shape))
    rng1, rng2 = fastmath.random.split(self.rng, 2)
    w = self._kernel_initializer(kernel_shape, rng1)
    b = self._bias_initializer(bias_shape, rng2)
    self.weights = (w, b) 
Example 16
Project: picklable-itertools   Author: mila-iqia   File: __init__.py    License: MIT License 5 votes vote down vote up
def test_dropwhile():
    base = (verify_same, dropwhile, itertools.dropwhile, None)
    yield base + (bool,)
    yield base + (bool, [])
    yield base + (bool, [5, 5, 2, 0, 0])
    yield base + (bool, [1, 2, 0, 4, 0])
    yield base + (partial(lt, 3), range(5, 0, -1))
    base = (verify_pickle, dropwhile, itertools.dropwhile)
    yield base + (2, 1, bool, [5, 5, 2, 0, 0])
    yield base + (2, 0, bool, [5, 5, 2, 0, 0])
    yield base + (3, 0, bool, [1, 2, 0, 4, 0])
    yield base + (3, 2, bool, [1, 2, 0, 4, 0]) 
Example 17
Project: angr   Author: angr   File: callstack.py    License: BSD 2-Clause "Simplified" License 5 votes vote down vote up
def _rfind(lst, item):
        """
        Reverse look-up.

        :param list lst: The list to look up in.
        :param item: The item to look for.
        :return: Offset of the item if found. A ValueError is raised if the item is not in the list.
        :rtype: int
        """

        try:
            return dropwhile(lambda x: lst[x] != item,
                             next(reversed(range(len(lst)))))
        except Exception:
            raise ValueError("%s not in the list" % item) 
Example 18
Project: blueoil   Author: blue-oil   File: operators.py    License: Apache License 2.0 5 votes vote down vote up
def _check_consistency(self) -> None:
        super()._check_consistency()
        # No. 1 ... Pad additional shape if the lengths are not equal
        a_shape = self.input_ops['A'].shape
        b_shape = self.input_ops['B'].shape
        len_diff = len(a_shape) - len(b_shape)
        if (len_diff != 0):
            head = [1 for i in range(abs(len_diff))]
            if len_diff > 0:
                b_shape = [*head, *b_shape]
            else:
                a_shape = [*head, *a_shape]
        # No. 2 ... Check the numbers at each dimension are the same, or one of them has 1
        length = len(a_shape)
        ash = self._input_ops["A"].shape
        bsh = self._input_ops["B"].shape
        for i in range(length):
            message = f'operands could not be broadcast together with shapes {ash} {bsh}'
            self._assert(a_shape[i] == b_shape[i] or a_shape[i] == 1 or b_shape[i] == 1, message)
        # No. 3 ... Check the output shape is consistent with the two operands
        output_shape = [max(a, b) for a, b in zip(a_shape, b_shape)]
        message = f'output shape {self.shape} does not match with two operands {ash} {bsh}'
        self._assert(output_shape == self.shape, message)

        # we only implement depth-wise broadcast on C
        ash_reduced = [x for x in dropwhile(lambda x: x == 1, ash)]
        bsh_reduced = [x for x in dropwhile(lambda x: x == 1, bsh)]
        self.is_depthwise = ((len(ash_reduced) == 1) or (len(bsh_reduced) == 1)) and\
                            (ash_reduced[-1] == bsh_reduced[-1]) 
Example 19
Project: blueoil   Author: blue-oil   File: operators.py    License: Apache License 2.0 5 votes vote down vote up
def _check_consistency(self) -> None:
        super()._check_consistency()
        # No. 1 ... Pad additional shape if the lengths are not equal
        a_shape = self.input_ops['A'].shape
        b_shape = self.input_ops['B'].shape
        len_diff = len(a_shape) - len(b_shape)
        if (len_diff != 0):
            head = [1 for i in range(abs(len_diff))]
            if len_diff > 0:
                b_shape = [*head, *b_shape]
            else:
                a_shape = [*head, *a_shape]
        # No. 2 ... Check the numbers at each dimension are the same, or one of them has 1
        length = len(a_shape)
        ash = self._input_ops["A"].shape
        bsh = self._input_ops["B"].shape
        for i in range(length):
            message = f'operands could not be broadcast together with shapes {ash} {bsh}'
            self._assert(a_shape[i] == b_shape[i] or a_shape[i] == 1 or b_shape[i] == 1, message)
        # No. 3 ... Check the output shape is consistent with the two operands
        output_shape = [max(a, b) for a, b in zip(a_shape, b_shape)]
        message = f'output shape {self.shape} does not match with two operands {ash} {bsh}'
        self._assert(output_shape == self.shape, message)

        # we only implement depth-wise broadcast on C
        ash_reduced = [x for x in dropwhile(lambda x: x == 1, ash)]
        bsh_reduced = [x for x in dropwhile(lambda x: x == 1, bsh)]
        self.is_depthwise = ((len(ash_reduced) == 1) or (len(bsh_reduced) == 1)) and \
                            (ash_reduced[-1] == bsh_reduced[-1]) 
Example 20
Project: mergify-engine   Author: Mergifyio   File: action.py    License: Apache License 2.0 5 votes vote down vote up
def _get_commit_message(pull_request, mode="default"):
        if mode == "title+body":
            # Include PR number to mimic default GitHub format
            return f"{pull_request.title} (#{pull_request.number})", pull_request.body

        if not pull_request.body:
            return

        found = False
        message_lines = []

        for line in pull_request.body.split("\n"):
            if MARKDOWN_COMMIT_MESSAGE_RE.match(line):
                found = True
            elif found and MARKDOWN_TITLE_RE.match(line):
                break
            elif found:
                message_lines.append(line)

        # Remove the first empty lines
        message_lines = list(
            itertools.dropwhile(lambda x: not x.strip(), message_lines)
        )

        if found and message_lines:
            title = message_lines.pop(0)

            # Remove the empty lines between title and message body
            message_lines = list(
                itertools.dropwhile(lambda x: not x.strip(), message_lines)
            )

            return (
                pull_request.render_template(title.strip()),
                pull_request.render_template(
                    "\n".join(line.strip() for line in message_lines)
                ),
            ) 
Example 21
Project: GraphicDesignPatternByPython   Author: Relph1119   File: arffread.py    License: MIT License 5 votes vote down vote up
def go_data(ofile):
    """Skip header.

    the first next() call of the returned iterator will be the @data line"""
    return itertools.dropwhile(lambda x: not r_datameta.match(x), ofile)


#----------------
# Parsing header
#---------------- 
Example 22
Project: hask   Author: billpmurphy   File: List.py    License: BSD 2-Clause "Simplified" License 5 votes vote down vote up
def dropWhile(p, xs):
    """
    dropWhile :: (a -> Bool) -> [a] -> [a]

    dropWhile(p, xs) returns the suffix remaining after takeWhile(p, xs)
    """
    return L[itertools.dropwhile(p, xs)] 
Example 23
Project: riko   Author: nerevu   File: utils.py    License: MIT License 5 votes vote down vote up
def _gen_words(match, splits):
    groups = list(it.dropwhile(lambda x: not x, match.groups()))

    for s in splits:
        try:
            num = int(s)
        except ValueError:
            word = s
        else:
            word = next(it.islice(groups, num, num + 1))

        yield word 
Example 24
Project: soph   Author: Linusp   File: pig_latin.py    License: MIT License 5 votes vote down vote up
def pig_latin(word):
    if is_vowel(word[0]):
        return word + 'yay'
    else:
        remain = ''.join(dropwhile(is_consonant, word))
        removed = word[:len(word) - len(remain)]
        return remain + removed + 'ay' 
Example 25
Project: cloudify-manager   Author: cloudify-cosmo   File: test_executions.py    License: Apache License 2.0 5 votes vote down vote up
def test_bad_update_execution_status(self):
        execution = self.test_get_execution_by_id()
        resource_path = '/executions/{0}'.format(execution['id'])
        expected_error = manager_exceptions.InvalidExecutionUpdateStatus()
        expected_message = (
            'Invalid relationship - can\'t change status from {0} to {1}'
            ' for "{2}" execution while running "{3}" workflow.')

        force_cancelling_invalid_future_statuses = (
            ExecutionState.ACTIVE_STATES + [ExecutionState.TERMINATED])
        cancelling_invalid_future_statuses = dropwhile(
            lambda status: status == ExecutionState.CANCELLING,
            force_cancelling_invalid_future_statuses)
        invalid_status_map = {
            ExecutionState.TERMINATED: ExecutionState.STATES,
            ExecutionState.FAILED: ExecutionState.STATES,
            ExecutionState.CANCELLED: ExecutionState.STATES,
            ExecutionState.CANCELLING: cancelling_invalid_future_statuses,
            ExecutionState.FORCE_CANCELLING:
                force_cancelling_invalid_future_statuses,
        }

        def assert_invalid_update():
            self._modify_execution_status_in_database(
                execution=execution, new_status=last_status)
            response = self.patch(resource_path, {'status': next_status})
            self.assertEqual(
                expected_error.status_code, response.status_code)
            self.assertEqual(
                expected_error.error_code, response.json['error_code'])
            self.assertEqual(
                expected_message.format(last_status,
                                        next_status,
                                        execution['id'],
                                        execution['workflow_id']),
                response.json['message'])

        for last_status, status_list in invalid_status_map.items():
            for next_status in status_list:
                assert_invalid_update() 
Example 26
Project: recruit   Author: Frank-qlu   File: version.py    License: Apache License 2.0 4 votes vote down vote up
def _cmpkey(epoch, release, pre, post, dev, local):
    # When we compare a release version, we want to compare it with all of the
    # trailing zeros removed. So we'll use a reverse the list, drop all the now
    # leading zeros until we come to something non zero, then take the rest
    # re-reverse it back into the correct order and make it a tuple and use
    # that for our sorting key.
    release = tuple(
        reversed(list(
            itertools.dropwhile(
                lambda x: x == 0,
                reversed(release),
            )
        ))
    )

    # We need to "trick" the sorting algorithm to put 1.0.dev0 before 1.0a0.
    # We'll do this by abusing the pre segment, but we _only_ want to do this
    # if there is not a pre or a post segment. If we have one of those then
    # the normal sorting rules will handle this case correctly.
    if pre is None and post is None and dev is not None:
        pre = -Infinity
    # Versions without a pre-release (except as noted above) should sort after
    # those with one.
    elif pre is None:
        pre = Infinity

    # Versions without a post segment should sort before those with one.
    if post is None:
        post = -Infinity

    # Versions without a development segment should sort after those with one.
    if dev is None:
        dev = Infinity

    if local is None:
        # Versions without a local segment should sort before those with one.
        local = -Infinity
    else:
        # Versions with a local segment need that segment parsed to implement
        # the sorting rules in PEP440.
        # - Alpha numeric segments sort before numeric segments
        # - Alpha numeric segments sort lexicographically
        # - Numeric segments sort numerically
        # - Shorter versions sort before longer versions when the prefixes
        #   match exactly
        local = tuple(
            (i, "") if isinstance(i, int) else (-Infinity, i)
            for i in local
        )

    return epoch, release, pre, post, dev, local 
Example 27
Project: jbox   Author: jpush   File: version.py    License: MIT License 4 votes vote down vote up
def _cmpkey(epoch, release, pre, post, dev, local):
    # When we compare a release version, we want to compare it with all of the
    # trailing zeros removed. So we'll use a reverse the list, drop all the now
    # leading zeros until we come to something non zero, then take the rest
    # re-reverse it back into the correct order and make it a tuple and use
    # that for our sorting key.
    release = tuple(
        reversed(list(
            itertools.dropwhile(
                lambda x: x == 0,
                reversed(release),
            )
        ))
    )

    # We need to "trick" the sorting algorithm to put 1.0.dev0 before 1.0a0.
    # We'll do this by abusing the pre segment, but we _only_ want to do this
    # if there is not a pre or a post segment. If we have one of those then
    # the normal sorting rules will handle this case correctly.
    if pre is None and post is None and dev is not None:
        pre = -Infinity
    # Versions without a pre-release (except as noted above) should sort after
    # those with one.
    elif pre is None:
        pre = Infinity

    # Versions without a post segment should sort before those with one.
    if post is None:
        post = -Infinity

    # Versions without a development segment should sort after those with one.
    if dev is None:
        dev = Infinity

    if local is None:
        # Versions without a local segment should sort before those with one.
        local = -Infinity
    else:
        # Versions with a local segment need that segment parsed to implement
        # the sorting rules in PEP440.
        # - Alpha numeric segments sort before numeric segments
        # - Alpha numeric segments sort lexicographically
        # - Numeric segments sort numerically
        # - Shorter versions sort before longer versions when the prefixes
        #   match exactly
        local = tuple(
            (i, "") if isinstance(i, int) else (-Infinity, i)
            for i in local
        )

    return epoch, release, pre, post, dev, local 
Example 28
Project: jbox   Author: jpush   File: version.py    License: MIT License 4 votes vote down vote up
def _cmpkey(epoch, release, pre, post, dev, local):
    # When we compare a release version, we want to compare it with all of the
    # trailing zeros removed. So we'll use a reverse the list, drop all the now
    # leading zeros until we come to something non zero, then take the rest
    # re-reverse it back into the correct order and make it a tuple and use
    # that for our sorting key.
    release = tuple(
        reversed(list(
            itertools.dropwhile(
                lambda x: x == 0,
                reversed(release),
            )
        ))
    )

    # We need to "trick" the sorting algorithm to put 1.0.dev0 before 1.0a0.
    # We'll do this by abusing the pre segment, but we _only_ want to do this
    # if there is not a pre or a post segment. If we have one of those then
    # the normal sorting rules will handle this case correctly.
    if pre is None and post is None and dev is not None:
        pre = -Infinity
    # Versions without a pre-release (except as noted above) should sort after
    # those with one.
    elif pre is None:
        pre = Infinity

    # Versions without a post segment should sort before those with one.
    if post is None:
        post = -Infinity

    # Versions without a development segment should sort after those with one.
    if dev is None:
        dev = Infinity

    if local is None:
        # Versions without a local segment should sort before those with one.
        local = -Infinity
    else:
        # Versions with a local segment need that segment parsed to implement
        # the sorting rules in PEP440.
        # - Alpha numeric segments sort before numeric segments
        # - Alpha numeric segments sort lexicographically
        # - Numeric segments sort numerically
        # - Shorter versions sort before longer versions when the prefixes
        #   match exactly
        local = tuple(
            (i, "") if isinstance(i, int) else (-Infinity, i)
            for i in local
        )

    return epoch, release, pre, post, dev, local 
Example 29
Project: python-netsurv   Author: sofia-netsurv   File: version.py    License: MIT License 4 votes vote down vote up
def _cmpkey(epoch, release, pre, post, dev, local):
    # When we compare a release version, we want to compare it with all of the
    # trailing zeros removed. So we'll use a reverse the list, drop all the now
    # leading zeros until we come to something non zero, then take the rest
    # re-reverse it back into the correct order and make it a tuple and use
    # that for our sorting key.
    release = tuple(
        reversed(list(
            itertools.dropwhile(
                lambda x: x == 0,
                reversed(release),
            )
        ))
    )

    # We need to "trick" the sorting algorithm to put 1.0.dev0 before 1.0a0.
    # We'll do this by abusing the pre segment, but we _only_ want to do this
    # if there is not a pre or a post segment. If we have one of those then
    # the normal sorting rules will handle this case correctly.
    if pre is None and post is None and dev is not None:
        pre = -Infinity
    # Versions without a pre-release (except as noted above) should sort after
    # those with one.
    elif pre is None:
        pre = Infinity

    # Versions without a post segment should sort before those with one.
    if post is None:
        post = -Infinity

    # Versions without a development segment should sort after those with one.
    if dev is None:
        dev = Infinity

    if local is None:
        # Versions without a local segment should sort before those with one.
        local = -Infinity
    else:
        # Versions with a local segment need that segment parsed to implement
        # the sorting rules in PEP440.
        # - Alpha numeric segments sort before numeric segments
        # - Alpha numeric segments sort lexicographically
        # - Numeric segments sort numerically
        # - Shorter versions sort before longer versions when the prefixes
        #   match exactly
        local = tuple(
            (i, "") if isinstance(i, int) else (-Infinity, i)
            for i in local
        )

    return epoch, release, pre, post, dev, local 
Example 30
Project: python-netsurv   Author: sofia-netsurv   File: version.py    License: MIT License 4 votes vote down vote up
def _cmpkey(epoch, release, pre, post, dev, local):
    # When we compare a release version, we want to compare it with all of the
    # trailing zeros removed. So we'll use a reverse the list, drop all the now
    # leading zeros until we come to something non zero, then take the rest
    # re-reverse it back into the correct order and make it a tuple and use
    # that for our sorting key.
    release = tuple(
        reversed(list(itertools.dropwhile(lambda x: x == 0, reversed(release))))
    )

    # We need to "trick" the sorting algorithm to put 1.0.dev0 before 1.0a0.
    # We'll do this by abusing the pre segment, but we _only_ want to do this
    # if there is not a pre or a post segment. If we have one of those then
    # the normal sorting rules will handle this case correctly.
    if pre is None and post is None and dev is not None:
        pre = -Infinity
    # Versions without a pre-release (except as noted above) should sort after
    # those with one.
    elif pre is None:
        pre = Infinity

    # Versions without a post segment should sort before those with one.
    if post is None:
        post = -Infinity

    # Versions without a development segment should sort after those with one.
    if dev is None:
        dev = Infinity

    if local is None:
        # Versions without a local segment should sort before those with one.
        local = -Infinity
    else:
        # Versions with a local segment need that segment parsed to implement
        # the sorting rules in PEP440.
        # - Alpha numeric segments sort before numeric segments
        # - Alpha numeric segments sort lexicographically
        # - Numeric segments sort numerically
        # - Shorter versions sort before longer versions when the prefixes
        #   match exactly
        local = tuple((i, "") if isinstance(i, int) else (-Infinity, i) for i in local)

    return epoch, release, pre, post, dev, local