Commit 47bbc3c4 authored by Jason Madden's avatar Jason Madden Committed by Jim Fulton

Sort distributions when computing a signature. (#393)

This fixes #392.

Previously under Python 3 (probably prior to 3.6, when dicts became
ordered by default) or under Python 2 with ``-R`` or
``PYTHONHASHSEED=random`` the results were undefined because dict
iteration order is undefined.

The value being sorted is complex and defined by
pkg_resources.Distribution:

```    @property
    def hashcmp(self):
        return (
            self.parsed_version,
            self.precedence,
            self.key,
            _remove_md5_fragment(self.location),
            self.py_version or '',
            self.platform or '',
        )

    def __hash__(self):
        return hash(self.hashcmp)

    def __lt__(self, other):
        return self.hashcmp < other.hashcmp
...
```
parent afadf99b
...@@ -4,7 +4,14 @@ Change History ...@@ -4,7 +4,14 @@ Change History
2.9.4 (unreleased) 2.9.4 (unreleased)
================== ==================
- Nothing changed yet. - Sort the distributions used to compute ``__buildout_signature__`` to
ensure reproducibility under Python 3 or under Python 2 when ``-R``
is used on ``PYTHONHASHSEED`` is set to ``random``. Fixes `issue 392
<https://github.com/buildout/buildout/issues/392>`_.
**NOTE**: This may cause existing ``.installed.cfg`` to be
considered outdated and lead to parts being reinstalled spuriously
under Python 2.
2.9.3 (2017-03-30) 2.9.3 (2017-03-30)
......
...@@ -1821,7 +1821,7 @@ def _dir_hash(dir): ...@@ -1821,7 +1821,7 @@ def _dir_hash(dir):
def _dists_sig(dists): def _dists_sig(dists):
seen = set() seen = set()
result = [] result = []
for dist in dists: for dist in sorted(dists):
if dist in seen: if dist in seen:
continue continue
seen.add(dist) seen.add(dist)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment