Skip to content

Commit

Permalink
Merge pull request #11 from jumptrading/yanked
Browse files Browse the repository at this point in the history
Ignore yanked releases and invalid versions
  • Loading branch information
wimglenn committed Mar 14, 2024
2 parents 34f323d + 04b2a80 commit c618dfb
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 12 deletions.
35 changes: 28 additions & 7 deletions luddite.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#!/usr/bin/env python
# coding: utf-8
from __future__ import unicode_literals, print_function
from __future__ import print_function
from __future__ import unicode_literals

import argparse
import json
Expand All @@ -9,7 +10,9 @@
import sys
from concurrent.futures import ThreadPoolExecutor

from packaging.requirements import Requirement, InvalidRequirement
from packaging.requirements import InvalidRequirement
from packaging.requirements import Requirement
from packaging.version import InvalidVersion
from packaging.version import Version

try:
Expand All @@ -23,7 +26,7 @@
sys.stdout = codecs.getwriter("utf8")(sys.stdout)


__version__ = "1.0.2"
__version__ = "1.0.4"


DEFAULT_FNAME = "requirements.txt"
Expand Down Expand Up @@ -94,10 +97,23 @@ def get_data_pypi(name, index=DEFAULT_INDEX):
return data


def _safe_version(v):
try:
return Version(v)
except InvalidVersion:
pass


def get_versions_pypi(name, index=DEFAULT_INDEX):
data = get_data_pypi(name, index)
version_numbers = sorted(data["releases"], key=Version)
return tuple(version_numbers)
versions = []
for raw_version, details in data["releases"].items():
version = _safe_version(raw_version)
if version is not None:
if any(not d.get("yanked", False) for d in details):
versions.append((version, raw_version))
versions.sort()
return tuple(v for (_, v) in versions)


def get_version_pypi(name, index=DEFAULT_INDEX):
Expand All @@ -122,8 +138,13 @@ def get_data_devpi(name, index):

def get_versions_devpi(name, index):
data = get_data_devpi(name, index)
version_numbers = sorted(data["result"], key=Version)
return tuple(version_numbers)
versions = []
for raw_version, details in data["result"].items():
version = _safe_version(raw_version)
if version is not None:
versions.append((version, raw_version))
versions.sort()
return tuple(v for (_, v) in versions)


def get_version_devpi(name, index):
Expand Down
3 changes: 1 addition & 2 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

setup(
name="luddite",
version="1.0.3",
version="1.0.4",
author="Wim Glenn",
author_email="hey@wimglenn.com",
url="https://github.com/jumptrading/luddite",
Expand All @@ -29,7 +29,6 @@
"pytest-cov",
"pytest-mock",
"pytest-socket",
"coveralls",
],
},
options={"bdist_wheel": {"universal": True}},
Expand Down
40 changes: 37 additions & 3 deletions test_luddite.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# coding: utf-8
from __future__ import unicode_literals

import json
import sys
from subprocess import CalledProcessError

Expand Down Expand Up @@ -104,7 +105,12 @@ def test_parse_reqs_file_with_index(tmpdir):

def test_parse_reqs_file_with_two_indices(tmpdir):
reqs = tmpdir.join("reqs.txt")
reqs.write("-i http://myindex\n--index-url=http://anotherindexwtf\nabc==1.0\ndef==2.0")
reqs.write(
"-i http://myindex\n"
"--index-url=http://anotherindexwtf\n"
"abc==1.0\n"
"def==2.0"
)
file = luddite.RequirementsFile(reqs)
with pytest.raises(luddite.MultipleIndicesError):
file.index
Expand Down Expand Up @@ -182,7 +188,10 @@ def test_guess_index_type_pypi(mocker):
def test_guess_index_type_devpi(mocker):
mock_response = mocker.MagicMock()
mock_response.code = 200
mock_response.headers = {"Content-type": "awesomesauce", "X-Devpi-Server-Version": "4.0.0\r\n"}
mock_response.headers = {
"Content-type": "awesomesauce",
"X-Devpi-Server-Version": "4.0.0\r\n",
}
mocker.patch("luddite.urlopen", return_value=mock_response)
assert luddite.guess_index_type("http://test-index/") == "devpi"

Expand Down Expand Up @@ -219,7 +228,14 @@ def test_integration(tmpdir, capsys, mocker, monkeypatch):
mock_response = mocker.MagicMock()
mock_response.code = 200
mock_response.headers.get_content_charset.return_value = "utf-8"
mock_response.read.return_value = b'{"releases": ["1.0", "1.1", "1.4"]}'
releases = {
"releases": {
"1.0": [{"yanked": False}],
"1.1": [{"yanked": False}],
"1.4": [{"yanked": False}],
}
}
mock_response.read.return_value = json.dumps(releases).encode()
mocker.patch("luddite.urlopen", return_value=mock_response)
mocker.patch("sys.argv", "luddite -i http://index-from-cmdline".split())

Expand Down Expand Up @@ -264,3 +280,21 @@ def test_integration(tmpdir, capsys, mocker, monkeypatch):
distextra[x,y]==1.2.3 ! distextra 1.2.3 is not in the index (from versions: 1.0, 1.1, 1.4)
"""
)


def test_yanked_versions_skipped(mocker):
mock_response = mocker.MagicMock()
mock_response.code = 200
releases = {
"releases": {
"1.1": [{}],
"1.4": [{"yanked": False}],
"1.3": [{"yanked": True}],
"1.2": [{"yanked": False}],
}
}
mock_response.read.return_value = json.dumps(releases).encode()
mocker.patch("luddite.urlopen", return_value=mock_response)
mocker.patch("luddite.get_charset", return_value="utf-8")
vs = luddite.get_versions_pypi("dist", "http://myindex/+simple/")
assert vs == ("1.1", "1.2", "1.4")

0 comments on commit c618dfb

Please sign in to comment.