Skip to content

Commit

Permalink
MNT: compatibility with pandas>=2.1.0 and upcoming deprecations
Browse files Browse the repository at this point in the history
  • Loading branch information
theOehrly committed Oct 10, 2023
1 parent 97c4ec8 commit 8b6c834
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 52 deletions.
45 changes: 19 additions & 26 deletions fastf1/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -210,10 +210,7 @@ def __init__(self,

@property
def _constructor(self):
def _new(*args, **kwargs):
return Telemetry(*args, **kwargs).__finalize__(self)

return _new
return Telemetry

@property
def base_class_view(self):
Expand Down Expand Up @@ -2434,23 +2431,21 @@ def __init__(self,

@property
def _constructor(self):
def _new(*args, **kwargs):
return Laps(*args, **kwargs).__finalize__(self)

return _new
return Laps

@property
def _constructor_sliced(self):
def _new(*args, **kwargs):
name = kwargs.get('name')
if name and (name in self.columns):
# vertical slice
return pd.Series(*args, **kwargs).__finalize__(self)
return Lap

def _constructor_sliced_from_mgr(self, mgr, axes):
if axes[0] is self.index:
# horizontal slice
return Lap(*args, **kwargs).__finalize__(self)
ser = pd.Series._from_mgr(mgr, axes)
ser._name = None # caller is responsible for setting real name
return ser

return _new
# vertical slice
return super()._constructor_sliced_from_mgr(mgr, axes)

@property
def base_class_view(self):
Expand Down Expand Up @@ -3387,23 +3382,21 @@ def __repr__(self):

@property
def _constructor(self):
def _new(*args, **kwargs):
return SessionResults(*args, **kwargs).__finalize__(self)

return _new
return SessionResults

@property
def _constructor_sliced(self):
def _new(*args, **kwargs):
name = kwargs.get('name')
if name and (name in self.columns):
# vertical slice
return pd.Series(*args, **kwargs).__finalize__(self)
return DriverResult

def _constructor_sliced_from_mgr(self, mgr, axes):
if axes[0] is self.index:
# horizontal slice
return DriverResult(*args, **kwargs).__finalize__(self)
ser = pd.Series._from_mgr(mgr, axes)
ser._name = None # caller is responsible for setting real name
return ser

return _new
# vertical slice
return super()._constructor_sliced_from_mgr(mgr, axes)

@property
def base_class_view(self):
Expand Down
25 changes: 10 additions & 15 deletions fastf1/ergast/interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -165,23 +165,21 @@ def _flatten_element(cls, nested: dict, category: dict, cast: bool):

@property
def _constructor(self):
def _new(*args, **kwargs):
return ErgastResultFrame(*args, **kwargs).__finalize__(self)

return _new
return ErgastResultFrame

@property
def _constructor_sliced(self):
def _new(*args, **kwargs):
name = kwargs.get('name')
if name and (name in self.columns):
# vertical slice
return pd.Series(*args, **kwargs).__finalize__(self)
return ErgastResultSeries

def _constructor_sliced_from_mgr(self, mgr, axes):
if axes[0] is self.index:
# horizontal slice
return ErgastResultSeries(*args, **kwargs).__finalize__(self)
ser = pd.Series._from_mgr(mgr, axes)
ser._name = None # caller is responsible for setting real name
return ser

return _new
# vertical slice
return super()._constructor_sliced_from_mgr(mgr, axes)

@property
def base_class_view(self):
Expand All @@ -202,10 +200,7 @@ def __init__(self, *args, **kwargs):

@property
def _constructor(self):
def _new(*args, **kwargs):
return ErgastResultSeries(*args, **kwargs).__finalize__(self)

return _new
return ErgastResultSeries


class ErgastRawResponse(ErgastResponseMixin, list):
Expand Down
23 changes: 12 additions & 11 deletions fastf1/events.py
Original file line number Diff line number Diff line change
Expand Up @@ -801,17 +801,21 @@ def __repr__(self):

@property
def _constructor(self):
def _new(*args, **kwargs):
return EventSchedule(*args, **kwargs).__finalize__(self)

return _new
return EventSchedule

@property
def _constructor_sliced(self):
def _new(*args, **kwargs):
return Event(*args, **kwargs).__finalize__(self)
return Event

def _constructor_sliced_from_mgr(self, mgr, axes):
if axes[0] is self.index:
# horizontal slice
ser = pd.Series._from_mgr(mgr, axes)
ser._name = None # caller is responsible for setting real name
return ser

return _new
# vertical slice
return super()._constructor_sliced_from_mgr(mgr, axes)

@property
def base_class_view(self):
Expand Down Expand Up @@ -942,10 +946,7 @@ def __init__(self, *args, year: int = None, **kwargs):

@property
def _constructor(self):
def _new(*args, **kwargs):
return Event(*args, **kwargs).__finalize__(self)

return _new
return Event

def is_testing(self) -> bool:
"""Return `True` or `False`, depending on whether this event is a
Expand Down
20 changes: 20 additions & 0 deletions fastf1/tests/test_events.py
Original file line number Diff line number Diff line change
Expand Up @@ -238,3 +238,23 @@ def test_event_get_nonexistent_session_date():
event = fastf1.get_event(2020, 13)
with pytest.raises(ValueError, match="does not exist"):
event.get_session_date('FP2')


def test_events_constructors():
frame = fastf1.events.EventSchedule({'RoundNumber': [1, 2, 3],
'Country': ['a', 'b', 'c']})

# test slicing to frame
assert isinstance(frame.iloc[1:], fastf1.events.EventSchedule)

# test horizontal slicing
assert isinstance(frame.iloc[0], fastf1.events.Event)
assert isinstance(frame.iloc[0], pd.Series)

# test vertical slicing
assert not isinstance(frame.loc[:, 'Country'], fastf1.events.Event)
assert isinstance(frame.loc[:, 'Country'], pd.Series)

# test base class view
assert isinstance(frame.base_class_view, pd.DataFrame)
assert not isinstance(frame.base_class_view, fastf1.events.EventSchedule)

0 comments on commit 8b6c834

Please sign in to comment.