Skip to content

Commit 753f1e7

Browse files
committed
add custom lazy_fixture for pytest 8.0 compatibility
1 parent 84b5828 commit 753f1e7

11 files changed

Lines changed: 145 additions & 78 deletions

tests/conftest.py

Lines changed: 95 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@
77

88

99
import os
10+
import typing
11+
import dataclasses
12+
1013
import pytest
1114
import numpy as np
1215
import pandas as pd
@@ -214,7 +217,6 @@ def fixture_derived_gps_l1_reversed(android_gps_l1):
214217

215218

216219
@pytest.fixture(name="android_state")
217-
@pytest.mark.filterwarnings("ignore:.*not found*: RuntimeWarning")
218220
def fixture_android_state(android_derived):
219221
"""State estimate corresponding to Android measurements for GPS L1.
220222
@@ -800,3 +802,95 @@ def fixture_solve_wls(derived_2021):
800802
"""
801803
state_estimate = solve_wls(derived_2021)
802804
return state_estimate
805+
806+
# lazy_fixture implementation from https://github.com/TvoroG/pytest-lazy-fixture/issues/65
807+
808+
@dataclasses.dataclass
809+
class LazyFixture:
810+
"""Lazy fixture dataclass."""
811+
812+
name: str
813+
814+
def lazy_fixture(name: str) -> LazyFixture:
815+
"""Mark a fixture as lazy."""
816+
return LazyFixture(name)
817+
818+
def is_lazy_fixture(value: object) -> bool:
819+
"""Check whether a value is a lazy fixture."""
820+
return isinstance(value, LazyFixture)
821+
822+
823+
def pytest_make_parametrize_id(
824+
config: pytest.Config,
825+
val: object,
826+
argname: str,
827+
) -> typing.Union[str,None]:
828+
"""Inject lazy fixture parametrized id.
829+
830+
Reference:
831+
- https://bit.ly/48Off6r
832+
833+
Args:
834+
config (pytest.Config): pytest configuration.
835+
value (object): fixture value.
836+
argname (str): automatic parameter name.
837+
838+
Returns:
839+
str: new parameter id.
840+
"""
841+
if is_lazy_fixture(val):
842+
return typing.cast(LazyFixture, val).name
843+
return None
844+
845+
846+
@pytest.hookimpl(tryfirst=True)
847+
def pytest_fixture_setup(
848+
fixturedef: pytest.FixtureDef,
849+
request: pytest.FixtureRequest,
850+
) -> typing.Union[object,None]:
851+
"""Lazy fixture setup hook.
852+
853+
This hook will never take over a fixture setup but just simply will
854+
try to resolve recursively any lazy fixture found in request.param.
855+
856+
Reference:
857+
- https://bit.ly/3SyvsXJ
858+
859+
Args:
860+
fixturedef (pytest.FixtureDef): fixture definition object.
861+
request (pytest.FixtureRequest): fixture request object.
862+
863+
Returns:
864+
object | None: fixture value or None otherwise.
865+
"""
866+
867+
if hasattr(request, "param"):
868+
if isinstance(request.param,np.ndarray) and request.param.size > 0:
869+
request.param = _resolve_lazy_fixture(request.param, request)
870+
elif isinstance(request.param,np.ndarray) and request.param.size <= 0:
871+
return None
872+
elif request.param:
873+
request.param = _resolve_lazy_fixture(request.param, request)
874+
return None
875+
876+
877+
def _resolve_lazy_fixture(__val: object, request: pytest.FixtureRequest) -> object:
878+
"""Lazy fixture resolver.
879+
880+
Args:
881+
__val (object): fixture value object.
882+
request (pytest.FixtureRequest): pytest fixture request object.
883+
884+
Returns:
885+
object: resolved fixture value.
886+
"""
887+
if isinstance(__val, tuple):
888+
return tuple(_resolve_lazy_fixture(v, request) for v in __val)
889+
if isinstance(__val, list):
890+
return list(_resolve_lazy_fixture(v, request) for v in __val)
891+
if isinstance(__val, typing.Mapping):
892+
return {k: _resolve_lazy_fixture(v, request) for k, v in __val.items()}
893+
if not is_lazy_fixture(__val):
894+
return __val
895+
lazy_obj = typing.cast(LazyFixture, __val)
896+
return request.getfixturevalue(lazy_obj.name)

tests/navdata/test_navdata.py

Lines changed: 41 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@
1111
import pytest
1212
import numpy as np
1313
import pandas as pd
14-
from pytest_lazyfixture import lazy_fixture
1514

15+
from conftest import lazy_fixture
1616
from gnss_lib_py.navdata.navdata import NavData
1717

1818
def test_init_blank():
@@ -563,168 +563,145 @@ def test_rename_mapper_and_rows(df_simple):
563563
assert data["floats"].dtype == np.float64
564564
assert data["strings"].dtype == object
565565

566-
567-
568-
@pytest.fixture(name="df_rows",
569-
params=[
570-
lazy_fixture("df_simple")
571-
])
572-
def return_df_rows(request):
573-
"""Extract and return rows from the DataFrame for testing
574-
575-
Parameters
576-
----------
577-
pandas_df : pd.DataFrame
578-
Dataframe for testing values
579-
580-
Returns
581-
-------
582-
names : np.ndarray
583-
String entries in 'names' column of the DataFrame
584-
integers : np.ndarray
585-
Numeric entries in 'integers' column of the DataFrame
586-
floats : np.ndarray
587-
Numeric entries in 'floats' column of the DataFrame
588-
strings : np.ndarray
589-
String entries in 'strings' column of the DataFrame
590-
"""
591-
pandas_df = request.param
592-
names = np.asarray(pandas_df['names'].values, dtype=object)
593-
integers = np.reshape(np.asarray(pandas_df['integers'].values,
594-
dtype=np.float64), [1, -1])
595-
floats = np.reshape(np.asarray(pandas_df['floats'].values,
596-
dtype=np.float64), [1, -1])
597-
strings = np.asarray(pandas_df['strings'].values, dtype=object)
598-
return [names, integers, floats, strings]
599-
600-
601566
@pytest.fixture(name="integers")
602-
def fixture_integers(df_rows):
567+
def fixture_integers(df_simple):
603568
"""Return data corresponding to the integers label from the test data
604569
605570
Parameters
606571
----------
607-
df_rows : list
608-
List of rows from the testing data
572+
df_simple : pd.DataFrame
573+
pd.DataFrame to initialize NavData with.
609574
610575
Returns
611576
-------
612577
integers : np.ndarray
613578
Array of numeric entries in 'integers' label of data
614579
"""
615-
_, integers, _, _ = df_rows
580+
integers = np.reshape(np.asarray(df_simple['integers'].values,
581+
dtype=np.float64), [1, -1])
582+
616583
return integers
617584

618585
@pytest.fixture(name="floats")
619-
def fixture_floats(df_rows):
586+
def fixture_floats(df_simple):
620587
"""Return data corresponding to the floats label from the test data
621588
622589
Parameters
623590
----------
624-
df_rows : list
625-
List of rows from the testing data
591+
df_simple : pd.DataFrame
592+
pd.DataFrame to initialize NavData with.
626593
627594
Returns
628595
-------
629596
floats : np.ndarray
630597
Array of numeric entries in 'floats' label of data
631598
"""
632-
_, _, floats, _ = df_rows
599+
floats = np.reshape(np.asarray(df_simple['floats'].values,
600+
dtype=np.float64), [1, -1])
633601
return floats
634602

635603

636604
@pytest.fixture(name="strings")
637-
def fixture_strings(df_rows):
605+
def fixture_strings(df_simple):
638606
"""Return data corresponding to the strings label from the test data
639607
640608
Parameters
641609
----------
642-
df_rows : list
643-
List of rows from the testing data
610+
df_simple : pd.DataFrame
611+
pd.DataFrame to initialize NavData with.
644612
645613
Returns
646614
-------
647615
strings : np.ndarray
648616
Array of string entries in 'strings' label of data
649617
"""
650-
_, _, _, strings = df_rows
618+
strings = np.asarray(df_simple['strings'].values, dtype=object)
651619
return strings
652620

653621

654622
@pytest.fixture(name="int_flt")
655-
def fixture_int_flt(df_rows):
623+
def fixture_int_flt(df_simple):
656624
"""Return data corresponding to the integers and floats.
657625
658626
Labeled from the test data.
659627
660628
Parameters
661629
----------
662-
df_rows : list
663-
List of rows from the testing data
630+
df_simple : pd.DataFrame
631+
pd.DataFrame to initialize NavData with.
664632
665633
Returns
666634
-------
667635
int_flt : np.ndarray
668636
2D array of numeric entries in 'integers' and 'floats' labels of data
669637
"""
670-
_, integers, floats, _ = df_rows
638+
integers = np.reshape(np.asarray(df_simple['integers'].values,
639+
dtype=np.float64), [1, -1])
640+
floats = np.reshape(np.asarray(df_simple['floats'].values,
641+
dtype=np.float64), [1, -1])
642+
671643
int_flt = np.vstack((integers, floats))
672644
return int_flt
673645

674646

675647
@pytest.fixture(name="nm_str")
676-
def fixture_nm_str(df_rows):
648+
def fixture_nm_str(df_simple):
677649
"""Return data corresponding to the names and strings label from the test data
678650
679651
Parameters
680652
----------
681-
df_rows : list
682-
List of rows from the testing data
653+
df_simple : pd.DataFrame
654+
pd.DataFrame to initialize NavData with.
683655
684656
Returns
685657
-------
686658
nm_str : np.ndarray
687659
2D array of numeric entries in 'names' and 'strings' labels of data
688660
"""
689-
names, _, _, strings = df_rows
661+
names = np.asarray(df_simple['names'].values, dtype=object)
662+
strings = np.asarray(df_simple['strings'].values, dtype=object)
690663
nm_str = np.vstack((names, strings))
691664
return nm_str
692665

693666

694667
@pytest.fixture(name="str_nm")
695-
def fixture_str_nm(df_rows):
668+
def fixture_str_nm(df_simple):
696669
"""Return data corresponding to the strings and names label from the test data
697670
698671
Parameters
699672
----------
700-
df_rows : list
701-
List of rows from the testing data
673+
df_simple : pd.DataFrame
674+
pd.DataFrame to initialize NavData with.
702675
703676
Returns
704677
-------
705678
str_nm : np.ndarray
706679
2D array of numeric entries in 'strings' and 'names' labels of data
707680
"""
708-
names, _, _, strings = df_rows
681+
names = np.asarray(df_simple['names'].values, dtype=object)
682+
strings = np.asarray(df_simple['strings'].values, dtype=object)
709683
str_nm = np.vstack((strings, names))
710684
return str_nm
711685

712686

713687
@pytest.fixture(name="flt_int_slc")
714-
def fixture_flt_int_slc(df_rows):
688+
def fixture_flt_int_slc(df_simple):
715689
"""Return data corresponding to the names and strings label from the test data
716690
717691
Parameters
718692
----------
719-
df_rows : list
720-
List of rows from the testing data
693+
df_simple : pd.DataFrame
694+
pd.DataFrame to initialize NavData with.
721695
722696
Returns
723697
-------
724698
flt_int_slc : np.ndarray
725699
2D array of some numeric entries in 'integers' and 'floats' labels of data
726700
"""
727-
_, integers, floats, _ = df_rows
701+
integers = np.reshape(np.asarray(df_simple['integers'].values,
702+
dtype=np.float64), [1, -1])
703+
floats = np.reshape(np.asarray(df_simple['floats'].values,
704+
dtype=np.float64), [1, -1])
728705
flt_int_slc = np.vstack((integers, floats))[:, 3:]
729706
return flt_int_slc
730707

tests/parsers/test_android.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@
1212
import pytest
1313
import numpy as np
1414
import pandas as pd
15-
from pytest_lazyfixture import lazy_fixture
1615

16+
from conftest import lazy_fixture
1717
from gnss_lib_py.parsers import android
1818
from gnss_lib_py.parsers.google_decimeter import AndroidDerived2023
1919
from gnss_lib_py.navdata.navdata import NavData

tests/parsers/test_nmea.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@
1010

1111
import numpy as np
1212
import pytest
13-
from pytest_lazyfixture import lazy_fixture
1413

14+
from conftest import lazy_fixture
1515
from gnss_lib_py.parsers.nmea import Nmea
1616

1717
# pylint: disable=protected-access

tests/parsers/test_rinex_obs.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@
99

1010
import pytest
1111
import numpy as np
12-
from pytest_lazyfixture import lazy_fixture
1312

13+
from conftest import lazy_fixture
1414
from gnss_lib_py.parsers.rinex_obs import RinexObs
1515
from gnss_lib_py.navdata.operations import loop_time
1616

tests/utils/test_coordinates.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,12 @@
55
__authors__ = "Ashwin Kanhere, Derek Knowles"
66
__date__ = "21 Jun 2022"
77

8-
import os
9-
108
import pytest
119
import numpy as np
12-
from pytest_lazyfixture import lazy_fixture
1310

11+
from conftest import lazy_fixture
1412
import gnss_lib_py.utils.constants as consts
1513
from gnss_lib_py.navdata.navdata import NavData
16-
from gnss_lib_py.parsers.google_decimeter import AndroidDerived2022
1714
from gnss_lib_py.utils.coordinates import ecef_to_el_az, add_el_az
1815
from gnss_lib_py.utils.coordinates import geodetic_to_ecef
1916
from gnss_lib_py.utils.coordinates import ecef_to_geodetic, LocalCoord

tests/utils/test_dop.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,9 @@
99
import copy
1010

1111
import pytest
12-
from pytest_lazyfixture import lazy_fixture
13-
1412
import numpy as np
1513

14+
from conftest import lazy_fixture
1615
from gnss_lib_py.navdata.navdata import NavData
1716
from gnss_lib_py.navdata.operations import loop_time
1817

0 commit comments

Comments
 (0)