Skip to content

Added version sorting on Web and Removed obsolete versions #52887

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 13 commits into from
Closed
65 changes: 65 additions & 0 deletions scripts/tests/test_pandas_web.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
from unittest.mock import (
MagicMock,
patch,
)

from web.pandas_web import Preprocessors


def test_home_add_releases():
# Prepare test data
releases = [
{
"tag_name": "v1.0.0",
"prerelease": False,
"published_at": "2021-04-01T00:00:00Z",
"assets": [{"browser_download_url": "https://example.com/download"}],
},
{
"tag_name": "v2.0.0",
"prerelease": False,
"published_at": "2022-01-01T00:00:00Z",
"assets": [{"browser_download_url": "https://example.com/download"}],
},
{
"tag_name": "v1.5.4",
"prerelease": False,
"published_at": "2023-08-01T00:00:00Z",
"assets": [],
},
{
"tag_name": "v1.5.3",
"prerelease": False,
"published_at": "2021-07-01T00:00:00Z",
"assets": [],
},
{
"tag_name": "v1.5.2",
"prerelease": False,
"published_at": "2021-06-01T00:00:00Z",
"assets": [],
},
]
github_repo_url = "pandas-dev/pandas"
context = {
"main": {
"github_repo_url": github_repo_url,
"production_url": "https://example.com/",
},
"target_path": "/tmp",
"releases": [],
}

# Mock the requests module to return the test data
resp = MagicMock()
resp.status_code = 200
resp.json.return_value = releases
with patch("requests.get", return_value=resp):
# Call the function being tested
Preprocessors.home_add_releases(context)

# Assert that releases were correctly added to the context
assert len(context["releases"]) == 3
assert context["releases"][0]["name"] == "2.0.0"
assert context["releases"][1]["name"] == "1.5.4"
assert context["releases"][2]["name"] == "1.0.0"
19 changes: 18 additions & 1 deletion web/pandas_web.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
import feedparser
import jinja2
import markdown
from packaging import version
import requests
import yaml

Expand Down Expand Up @@ -223,7 +224,23 @@ def home_add_releases(context):
with open(pathlib.Path(context["target_path"]) / "releases.json", "w") as f:
json.dump(releases, f, default=datetime.datetime.isoformat)

for release in releases:
# Map to create a list of (version, realse) pairs from releases
parsed_releases = map(lambda r: (version.parse(r["tag_name"]), r), releases)

# Sort the releases in descending order
sorted_releases = sorted(parsed_releases, reverse=True)

# Gathers minor versions that are NOT obsolete
latest_releases = []
prev_version = version.Version("0.0.0")
for v, release in sorted_releases:
if (v.major, v.minor) == (prev_version.major, prev_version.minor):
# This release is of obsolete version, so skip
continue
latest_releases.append(release)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you can use v here instead of release. Since str(v) == release I think the render on the website should stay the same. And you don't need to make releases and sorted_releases lists (or generators) of tuples, but only of Version objects, which makes things easier.

Copy link
Author

@Masnan-306 Masnan-306 May 1, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think str(v) == release is true judging from the code below. I think there are fields like assets and tag_name in each release. So I may not understand what you mean here.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@datapythonista Hi, can you give some more clarifications on this?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for the delay. So, here you keep a tuple to deal with versions: (Version(1, 5, 2), '1.5.2'). You use the first element to compare versions, and the second to display it in the template. But the template will parse to string whatever you give it when creating the html. And this is true:

>>> from packaging import version
>>> v152 = version.Version('1.5.2')
>>> str(v152)
'1.5.2'

The second element in the tuple is not needed, since you can give the first one to the template, and when rendered it will become the second. So, you can just use Version(...) instead of the tuple, and simplify the code, which is a bit tricky to follow.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi, I am still a little confused. The first element in the tuple is indeed the objectVersion(...), but it is parsed from release[tag_name] but not from release directly. Since each release is a dictionary with many fields including assets, tag_name, published_at etc, I can only think of making them key-values pairs in the list (v, release) and sort the list by the key values v. In other word, the list latest_releases consists of tuple like (Version(1,5,2), {...}) instead of (Version(1, 5, 2), '1.5.2'). So, I'm sorting the dictionaries by the versions and then feed the dictionaries to the next loop.

prev_version = v

for release in latest_releases:
if release["prerelease"]:
continue
published = datetime.datetime.strptime(
Expand Down
1 change: 1 addition & 0 deletions web/pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[tool.pytest.ini_options]
65 changes: 65 additions & 0 deletions web/tests/test_pandas_web.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
from unittest.mock import (
MagicMock,
patch,
)

from web.pandas_web import Preprocessors


def test_home_add_releases():
# Prepare test data
releases = [
{
"tag_name": "v1.0.0",
"prerelease": False,
"published_at": "2021-04-01T00:00:00Z",
"assets": [{"browser_download_url": "https://example.com/download"}],
},
{
"tag_name": "v2.0.0",
"prerelease": False,
"published_at": "2022-01-01T00:00:00Z",
"assets": [{"browser_download_url": "https://example.com/download"}],
},
{
"tag_name": "v1.5.4",
"prerelease": False,
"published_at": "2023-08-01T00:00:00Z",
"assets": [],
},
{
"tag_name": "v1.5.3",
"prerelease": False,
"published_at": "2021-07-01T00:00:00Z",
"assets": [],
},
{
"tag_name": "v1.5.2",
"prerelease": False,
"published_at": "2021-06-01T00:00:00Z",
"assets": [],
},
]
github_repo_url = "pandas-dev/pandas"
context = {
"main": {
"github_repo_url": github_repo_url,
"production_url": "https://example.com/",
},
"target_path": "/tmp",
"releases": [],
}

# Mock the requests module to return the test data
resp = MagicMock()
resp.status_code = 200
resp.json.return_value = releases
with patch("requests.get", return_value=resp):
# Call the function being tested
Preprocessors.home_add_releases(context)

# Assert that releases were correctly added to the context
assert len(context["releases"]) == 3
assert context["releases"][0]["name"] == "2.0.0"
assert context["releases"][1]["name"] == "1.5.4"
assert context["releases"][2]["name"] == "1.0.0"