diff --git a/fastf1/core.py b/fastf1/core.py index 582b6b495..dd4f7af64 100644 --- a/fastf1/core.py +++ b/fastf1/core.py @@ -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): @@ -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): @@ -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): diff --git a/fastf1/ergast/interface.py b/fastf1/ergast/interface.py index aa0a17286..7e47ba395 100644 --- a/fastf1/ergast/interface.py +++ b/fastf1/ergast/interface.py @@ -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): @@ -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): diff --git a/fastf1/events.py b/fastf1/events.py index 272bc6f06..b5bffd777 100644 --- a/fastf1/events.py +++ b/fastf1/events.py @@ -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): @@ -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 diff --git a/fastf1/tests/test_events.py b/fastf1/tests/test_events.py index 010d79121..5969184f8 100644 --- a/fastf1/tests/test_events.py +++ b/fastf1/tests/test_events.py @@ -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)