diff --git a/README.md b/README.md index da9fb7a..141379d 100644 --- a/README.md +++ b/README.md @@ -258,7 +258,7 @@ A Session created by the library sends a package-specific User-Agent: python-mlb-statsapi/ ``` -For this release's currently declared package metadata that resolves to `python-mlb-statsapi/1.0.0`. The version is read from the installed distribution metadata, so it always matches the installed release. Only the `User-Agent` header is set; other Requests defaults such as `Accept-Encoding` remain intact, and the header carries no identifiers beyond the package name and version. +For this release's currently declared package metadata that resolves to `python-mlb-statsapi/1.0.1`. The version is read from the installed distribution metadata, so it always matches the installed release. Only the `User-Agent` header is set; other Requests defaults such as `Accept-Encoding` remain intact, and the header carries no identifiers beyond the package name and version. Headers on a caller-injected Session are left untouched, so applications that set their own User-Agent keep it. diff --git a/docs/http-transport.md b/docs/http-transport.md index 371ca8a..4b24695 100644 --- a/docs/http-transport.md +++ b/docs/http-transport.md @@ -198,7 +198,7 @@ python-mlb-statsapi/ With the package version currently declared in project metadata that resolves to: ```text -python-mlb-statsapi/1.0.0 +python-mlb-statsapi/1.0.1 ``` The version comes from the installed package metadata, so it always matches diff --git a/docs/releases/1.0.1.md b/docs/releases/1.0.1.md new file mode 100644 index 0000000..1c3e6c4 --- /dev/null +++ b/docs/releases/1.0.1.md @@ -0,0 +1,27 @@ +# python-mlb-statsapi 1.0.1 + +## Fixed + +* Schedule queries using `gamePks` no longer require a date. +* Fixed `Mlb.get_schedule()` returning early when `gamePks` was provided without a date. +* Fixed `Mlb.get_scheduled_games_by_date()` returning early when `gamePks` was provided without a date. + +Example: + +```python +from mlbstatsapi import Mlb + +with Mlb() as mlb: + games = mlb.get_scheduled_games_by_date(gamePks=831508) +``` + +## Python support + +python-mlb-statsapi requires Python >=3.10. + +CI validates Python 3.10, 3.11, 3.12, 3.13, and 3.14 +(3.10 through 3.14). + +## Related issue + +Fixes #245. diff --git a/mlbstatsapi/mlb_api.py b/mlbstatsapi/mlb_api.py index 0f3384f..6216fc7 100644 --- a/mlbstatsapi/mlb_api.py +++ b/mlbstatsapi/mlb_api.py @@ -809,11 +809,11 @@ def get_schedule(self, """ if start_date and end_date: - params['startDate'] = start_date - params['endDate'] = end_date + params["startDate"] = start_date + params["endDate"] = end_date elif date and not (start_date or end_date): - params['date'] = date - else: + params["date"] = date + elif "gamePks" not in params: return None @@ -886,14 +886,14 @@ def get_scheduled_games_by_date(self, date: str = None, >>> mlb.get_game_ids() """ if start_date and end_date: - params['startDate'] = start_date - params['endDate'] = end_date + params["startDate"] = start_date + params["endDate"] = end_date elif date and not (start_date or end_date): - params['date'] = date - else: + params["date"] = date + elif "gamePks" not in params: return None - params['sportId'] = sport_id + params["sportId"] = sport_id games = [] diff --git a/pyproject.toml b/pyproject.toml index d802765..c4f2fea 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "python-mlb-statsapi" -version = "1.0.0" +version = "1.0.1" description = "mlbstatsapi python wrapper" authors = [ "Matthew Spah ", diff --git a/tests/test_release_validation.py b/tests/test_release_validation.py index a4533bb..fd759ea 100644 --- a/tests/test_release_validation.py +++ b/tests/test_release_validation.py @@ -40,14 +40,16 @@ # Release notes for the version this branch is preparing. Kept explicit so the # current-document checks do not depend on the pyproject version bump, which is # owned by a separate issue. -CURRENT_RELEASE_NOTES = RELEASE_NOTES_DIR / "1.0.0.md" +CURRENT_RELEASE_NOTES = RELEASE_NOTES_DIR / "1.0.1.md" # Historical notes keep their own version-specific statements and must not be # rewritten to match the current release. + HISTORICAL_RELEASE_NOTES = ( RELEASE_NOTES_DIR / "0.7.1.md", RELEASE_NOTES_DIR / "0.8.0.md", RELEASE_NOTES_DIR / "0.9.0.md", + RELEASE_NOTES_DIR / "1.0.0.md", ) # Deterministic CI contract for the 1.0 release. diff --git a/tests/test_schedule_regressions.py b/tests/test_schedule_regressions.py new file mode 100644 index 0000000..fccb93f --- /dev/null +++ b/tests/test_schedule_regressions.py @@ -0,0 +1,92 @@ +from unittest.mock import patch + +from mlbstatsapi import Mlb, MlbResult + + +GAME_PK = 831508 + + +def _empty_schedule_result() -> MlbResult: + """Return a valid empty schedule response without calling the MLB API.""" + return MlbResult( + status_code=200, + message="OK", + data={"dates": []}, + ) + + +def test_get_scheduled_games_by_date_allows_gamepk_without_date(): + """ + Regression test for #245. + + A gamePk is a valid selector for the MLB schedule endpoint and should not + require a date. The current bug returns None before the adapter is called. + + This test verifies that a gamePk-only request reaches the adapter and that + the expected parameters are passed through without adding date parameters. + """ + with Mlb() as mlb: + # Replace the real HTTP call with a deterministic fake response. + with patch.object( + mlb._mlb_adapter_v1, + "get", + return_value=_empty_schedule_result(), + ) as adapter_get: + mlb.get_scheduled_games_by_date(gamePks=GAME_PK) + + # The important regression check: the method must not return before + # attempting the schedule request. + adapter_get.assert_called_once() + + call = adapter_get.call_args + + # Verify that the correct MLB endpoint would have been requested. + assert call.kwargs["endpoint"] == "schedule" + + params = call.kwargs["ep_params"] + + # gamePks should be preserved as a valid schedule selector. + assert params["gamePks"] == GAME_PK + + # sportId is still expected to use its existing default. + assert params["sportId"] == 1 + + # A gamePk-only lookup should not invent any date constraints. + assert "date" not in params + assert "startDate" not in params + assert "endDate" not in params + + +def test_get_schedule_allows_gamepk_without_date(): + """ + Verify that get_schedule() has the same gamePk-only behavior. + + While #245 was reported against get_scheduled_games_by_date(), get_schedule() + contains the same early date validation and can fail for the same reason. + """ + with Mlb() as mlb: + # Prevent a real network request while recording how the adapter is used. + with patch.object( + mlb._mlb_adapter_v1, + "get", + return_value=_empty_schedule_result(), + ) as adapter_get: + mlb.get_schedule(gamePks=GAME_PK) + + # gamePks alone should be enough for execution to reach the adapter. + adapter_get.assert_called_once() + + call = adapter_get.call_args + + assert call.kwargs["endpoint"] == "schedule" + + params = call.kwargs["ep_params"] + + # Preserve the caller's gamePk filter and the normal sportId default. + assert params["gamePks"] == GAME_PK + assert params["sportId"] == 1 + + # No date parameters should be required for a gamePk-specific lookup. + assert "date" not in params + assert "startDate" not in params + assert "endDate" not in params \ No newline at end of file