Skip to content

Commit f56521a

Browse files
committed
fix: Handle empty weeks array in ScheduleLeagueV2 parser
Fixes parsing issue for older seasons (e.g., 2015-16) where the weeks array is empty. The parser now returns default headers when weeks array is empty instead of raising IndexError. Changes: - Modified NBAStatsScheduleLeagueV2Parser.get_weeks_headers() to handle empty weeks arrays gracefully - Added comprehensive unit tests for both old (empty weeks) and new (populated weeks) response formats - Created Python test data file for minimal, fast test fixtures - Added full API response example to docs/nba_api/stats/endpoints/responses/ All 243 unit tests pass.
1 parent 89b2443 commit f56521a

File tree

7 files changed

+162372
-2
lines changed

7 files changed

+162372
-2
lines changed

docs/nba_api/stats/endpoints/responses/scheduleleaguev2.json

Lines changed: 161812 additions & 0 deletions
Large diffs are not rendered by default.

src/nba_api/stats/library/parserv3.py

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -386,8 +386,24 @@ def get_data_sets(self):
386386
return results
387387

388388
def get_weeks_headers(self):
389-
tmp = self.nba_dict[list(self.nba_dict.keys())[1]]["weeks"][0]
390-
headers = tuple(["leagueId", "seasonYear"] + [header for header in tmp.keys()])
389+
weeks = self.nba_dict[list(self.nba_dict.keys())[1]]["weeks"]
390+
if not weeks:
391+
# Return default headers when weeks array is empty (e.g., older seasons)
392+
headers = tuple(
393+
[
394+
"leagueId",
395+
"seasonYear",
396+
"weekNumber",
397+
"weekName",
398+
"startDate",
399+
"endDate",
400+
]
401+
)
402+
else:
403+
tmp = weeks[0]
404+
headers = tuple(
405+
["leagueId", "seasonYear"] + [header for header in tmp.keys()]
406+
)
391407
return headers
392408

393409
def get_weeks_data(self):

tests/unit/stats/__init__.py

Whitespace-only changes.

tests/unit/stats/endpoints/__init__.py

Whitespace-only changes.

tests/unit/stats/endpoints/data/__init__.py

Whitespace-only changes.
Lines changed: 311 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,311 @@
1+
"""Test data for ScheduleLeagueV2 endpoint.
2+
3+
Contains minimal fixtures representing two different API response formats:
4+
- SCHEDULELEAGUEV2_2020_21: Response with populated weeks array (newer seasons)
5+
- SCHEDULELEAGUEV2_2015_16: Response with empty weeks array (older seasons)
6+
7+
Full API responses are available in:
8+
docs/nba_api/stats/endpoints/responses/scheduleleaguev2_*.json
9+
"""
10+
11+
# Minimal fixture with weeks data (2020-21 style)
12+
SCHEDULELEAGUEV2_2020_21 = {
13+
"meta": {
14+
"version": 1,
15+
"request": "http://nba.cloud/league/00/2020-21/scheduleleaguev2",
16+
"time": "2025-04-10T14:11:47.1147Z",
17+
},
18+
"leagueSchedule": {
19+
"seasonYear": "2020-21",
20+
"leagueId": "00",
21+
"gameDates": [
22+
{
23+
"gameDate": "12/11/2020 00:00:00",
24+
"games": [
25+
{
26+
"gameId": "0012000001",
27+
"gameCode": "20201211/ORLATL",
28+
"gameStatus": 3,
29+
"gameStatusText": "Final",
30+
"gameSequence": 1,
31+
"gameDateEst": "2020-12-11T00:00:00Z",
32+
"gameTimeEst": "1900-01-01T19:00:00Z",
33+
"gameDateTimeEst": "2020-12-11T19:00:00Z",
34+
"gameDateUTC": "2020-12-11T05:00:00Z",
35+
"gameTimeUTC": "1900-01-01T00:00:00Z",
36+
"gameDateTimeUTC": "2020-12-12T00:00:00Z",
37+
"awayTeamTime": "2020-12-11T19:00:00Z",
38+
"homeTeamTime": "2020-12-11T19:00:00Z",
39+
"day": "Fri",
40+
"monthNum": 12,
41+
"weekNumber": 0,
42+
"weekName": "",
43+
"ifNecessary": "false",
44+
"seriesGameNumber": "",
45+
"gameLabel": "",
46+
"gameSubLabel": "",
47+
"seriesText": "Preseason",
48+
"arenaName": "State Farm Arena",
49+
"arenaState": "GA",
50+
"arenaCity": "Atlanta",
51+
"postponedStatus": "A",
52+
"branchLink": "",
53+
"gameSubtype": "",
54+
"isNeutral": False,
55+
"broadcasters": {
56+
"nationalBroadcasters": [],
57+
"nationalRadioBroadcasters": [],
58+
"nationalOttBroadcasters": [],
59+
"homeTvBroadcasters": [
60+
{
61+
"broadcasterScope": "home",
62+
"broadcasterMedia": "tv",
63+
"broadcasterId": 1234,
64+
"broadcasterDisplay": "Bally Sports",
65+
"broadcasterAbbreviation": "BSSO",
66+
"tapeDelayComments": "",
67+
"broadcasterVideoLink": "",
68+
"broadcasterDescription": "",
69+
"broadcasterTeamId": 1610612737,
70+
}
71+
],
72+
"homeRadioBroadcasters": [],
73+
"homeOttBroadcasters": [],
74+
"awayTvBroadcasters": [],
75+
"awayRadioBroadcasters": [],
76+
"awayOttBroadcasters": [],
77+
},
78+
"homeTeam": {
79+
"teamId": 1610612737,
80+
"teamName": "Hawks",
81+
"teamCity": "Atlanta",
82+
"teamTricode": "ATL",
83+
"teamSlug": "hawks",
84+
"wins": 0,
85+
"losses": 0,
86+
"score": 128,
87+
"seed": None,
88+
},
89+
"awayTeam": {
90+
"teamId": 1610612753,
91+
"teamName": "Magic",
92+
"teamCity": "Orlando",
93+
"teamTricode": "ORL",
94+
"teamSlug": "magic",
95+
"wins": 0,
96+
"losses": 0,
97+
"score": 96,
98+
"seed": None,
99+
},
100+
"pointsLeaders": [
101+
{
102+
"personId": 1628973,
103+
"firstName": "Trae",
104+
"lastName": "Young",
105+
"teamId": 1610612737,
106+
"teamCity": "Atlanta",
107+
"teamName": "Hawks",
108+
"teamTricode": "ATL",
109+
"points": 21.0,
110+
}
111+
],
112+
}
113+
],
114+
},
115+
{
116+
"gameDate": "12/12/2020 00:00:00",
117+
"games": [
118+
{
119+
"gameId": "0012000002",
120+
"gameCode": "20201212/DETBKN",
121+
"gameStatus": 3,
122+
"gameStatusText": "Final",
123+
"gameSequence": 1,
124+
"gameDateEst": "2020-12-12T00:00:00Z",
125+
"gameTimeEst": "1900-01-01T19:30:00Z",
126+
"gameDateTimeEst": "2020-12-12T19:30:00Z",
127+
"gameDateUTC": "2020-12-12T05:00:00Z",
128+
"gameTimeUTC": "1900-01-01T00:30:00Z",
129+
"gameDateTimeUTC": "2020-12-13T00:30:00Z",
130+
"awayTeamTime": "2020-12-12T19:30:00Z",
131+
"homeTeamTime": "2020-12-12T19:30:00Z",
132+
"day": "Sat",
133+
"monthNum": 12,
134+
"weekNumber": 0,
135+
"weekName": "",
136+
"ifNecessary": "false",
137+
"seriesGameNumber": "",
138+
"gameLabel": "",
139+
"gameSubLabel": "",
140+
"seriesText": "Preseason",
141+
"arenaName": "Barclays Center",
142+
"arenaState": "NY",
143+
"arenaCity": "Brooklyn",
144+
"postponedStatus": "A",
145+
"branchLink": "",
146+
"gameSubtype": "",
147+
"isNeutral": False,
148+
"broadcasters": {
149+
"nationalBroadcasters": [],
150+
"nationalRadioBroadcasters": [],
151+
"nationalOttBroadcasters": [],
152+
"homeTvBroadcasters": [],
153+
"homeRadioBroadcasters": [],
154+
"homeOttBroadcasters": [],
155+
"awayTvBroadcasters": [],
156+
"awayRadioBroadcasters": [],
157+
"awayOttBroadcasters": [],
158+
},
159+
"homeTeam": {
160+
"teamId": 1610612751,
161+
"teamName": "Nets",
162+
"teamCity": "Brooklyn",
163+
"teamTricode": "BKN",
164+
"teamSlug": "nets",
165+
"wins": 0,
166+
"losses": 0,
167+
"score": 119,
168+
"seed": None,
169+
},
170+
"awayTeam": {
171+
"teamId": 1610612765,
172+
"teamName": "Pistons",
173+
"teamCity": "Detroit",
174+
"teamTricode": "DET",
175+
"teamSlug": "pistons",
176+
"wins": 0,
177+
"losses": 0,
178+
"score": 114,
179+
"seed": None,
180+
},
181+
"pointsLeaders": [],
182+
}
183+
],
184+
},
185+
],
186+
"weeks": [
187+
{
188+
"weekNumber": 1,
189+
"weekName": "Week 1",
190+
"startDate": "2020-12-22T00:00:00Z",
191+
"endDate": "2020-12-27T00:00:00Z",
192+
},
193+
{
194+
"weekNumber": 2,
195+
"weekName": "Week 2",
196+
"startDate": "2020-12-28T00:00:00Z",
197+
"endDate": "2021-01-03T00:00:00Z",
198+
},
199+
],
200+
},
201+
}
202+
203+
204+
# Minimal fixture with EMPTY weeks array (2015-16 style)
205+
SCHEDULELEAGUEV2_2015_16 = {
206+
"meta": {
207+
"version": 1,
208+
"request": "http://nba.cloud/league/00/2015-16/scheduleleaguev2",
209+
"time": "2025-04-10T14:13:53.1353Z",
210+
},
211+
"leagueSchedule": {
212+
"seasonYear": "2015-16",
213+
"leagueId": "00",
214+
"gameDates": [
215+
{
216+
"gameDate": "10/02/2015 00:00:00",
217+
"games": [
218+
{
219+
"gameId": "0011500001",
220+
"gameCode": "20151002/DENLAC",
221+
"gameStatus": 3,
222+
"gameStatusText": "Final",
223+
"gameSequence": 1,
224+
"gameDateEst": "2015-10-02T00:00:00Z",
225+
"gameTimeEst": "1900-01-01T22:30:00Z",
226+
"gameDateTimeEst": "2015-10-02T22:30:00Z",
227+
"gameDateUTC": "2015-10-02T04:00:00Z",
228+
"gameTimeUTC": "1900-01-01T02:30:00Z",
229+
"gameDateTimeUTC": "2015-10-03T02:30:00Z",
230+
"awayTeamTime": "2015-10-02T20:30:00Z",
231+
"homeTeamTime": "2015-10-02T19:30:00Z",
232+
"day": "Fri",
233+
"monthNum": 10,
234+
"weekNumber": 0,
235+
"weekName": "",
236+
"ifNecessary": "false",
237+
"seriesGameNumber": "",
238+
"gameLabel": "",
239+
"gameSubLabel": "",
240+
"seriesText": "Preseason",
241+
"arenaName": "STAPLES Center",
242+
"arenaState": "CA",
243+
"arenaCity": "Los Angeles",
244+
"postponedStatus": "A",
245+
"branchLink": "",
246+
"gameSubtype": "",
247+
"isNeutral": False,
248+
"broadcasters": {
249+
"nationalBroadcasters": [
250+
{
251+
"broadcasterScope": "natl",
252+
"broadcasterMedia": "tv",
253+
"broadcasterId": 7,
254+
"broadcasterDisplay": "NBA TV",
255+
"broadcasterAbbreviation": "NBATV",
256+
"tapeDelayComments": "",
257+
"broadcasterVideoLink": "",
258+
"broadcasterDescription": "",
259+
"broadcasterTeamId": 0,
260+
}
261+
],
262+
"nationalRadioBroadcasters": [],
263+
"nationalOttBroadcasters": [],
264+
"homeTvBroadcasters": [],
265+
"homeRadioBroadcasters": [],
266+
"homeOttBroadcasters": [],
267+
"awayTvBroadcasters": [],
268+
"awayRadioBroadcasters": [],
269+
"awayOttBroadcasters": [],
270+
},
271+
"homeTeam": {
272+
"teamId": 1610612747,
273+
"teamName": "Lakers",
274+
"teamCity": "Los Angeles",
275+
"teamTricode": "LAL",
276+
"teamSlug": "lakers",
277+
"wins": 0,
278+
"losses": 0,
279+
"score": 98,
280+
"seed": None,
281+
},
282+
"awayTeam": {
283+
"teamId": 1610612743,
284+
"teamName": "Nuggets",
285+
"teamCity": "Denver",
286+
"teamTricode": "DEN",
287+
"teamSlug": "nuggets",
288+
"wins": 0,
289+
"losses": 0,
290+
"score": 95,
291+
"seed": None,
292+
},
293+
"pointsLeaders": [
294+
{
295+
"personId": 2544,
296+
"firstName": "LeBron",
297+
"lastName": "James",
298+
"teamId": 1610612747,
299+
"teamCity": "Los Angeles",
300+
"teamName": "Lakers",
301+
"teamTricode": "LAL",
302+
"points": 12.0,
303+
}
304+
],
305+
}
306+
],
307+
}
308+
],
309+
"weeks": [],
310+
},
311+
}

0 commit comments

Comments
 (0)