Skip to content

tests: Add backcompat for time_unit#3098

Merged
dangotbanned merged 4 commits intomainfrom
fix-time-unit-warnings
Sep 6, 2025
Merged

tests: Add backcompat for time_unit#3098
dangotbanned merged 4 commits intomainfrom
fix-time-unit-warnings

Conversation

@dangotbanned
Copy link
Copy Markdown
Member

@dangotbanned dangotbanned commented Sep 6, 2025

What type of PR is this? (check all applicable)

  • 💾 Refactor
  • ✨ Feature
  • 🐛 Bug Fix
  • 🔧 Optimization
  • 📝 Documentation
  • ✅ Test
  • 🐳 Other

Related issues

Checklist

  • Code follows style guide (ruff)
  • Tests added
  • Documented the changes

If you have comments or can explain your changes, please do so below

Will avoid introducing 22 new warnings in the other PR

@dangotbanned dangotbanned added ci tests pandas-like Issue is related to pandas-like backends duckdb Issue is related to duckdb backend labels Sep 6, 2025
@dangotbanned dangotbanned marked this pull request as ready for review September 6, 2025 17:30
Copy link
Copy Markdown
Member

@FBruzzesi FBruzzesi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @dangotbanned, I left a couple of non-blocking comments

Comment on lines +232 to +238
if _CONSTRUCTOR_FIXTURE_NAMES.isdisjoint(request.fixturenames): # pragma: no cover
msg = (
f"`time_unit_compat` requires the test function to use a `constructor*` fixture.\n"
f"Hint:\n\n"
f"Try adding one of these as a parameter:\n {sorted(_CONSTRUCTOR_FIXTURE_NAMES)!r}"
)
raise NotImplementedError(msg)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am having a brain fart - what's happening here?
IIUC it's a way to avoid using this function outside a test that has a constructor. I must say that the "hint" was not very clear to me 🙈

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am having a brain fart - what's happening here?

😂

So pretty recently I added a constructor_pandas_like fixture and learned a bit more pytest 😄

So the first check is to make sure the test function which request: pytest.FixtureRequest came from has got one of these 3 as a parameter

narwhals/tests/utils.py

Lines 55 to 57 in 3b3b481

_CONSTRUCTOR_FIXTURE_NAMES = frozenset[str](
("constructor_eager", "constructor", "constructor_pandas_like")
)

If it does, then request.node.callspec.id ...

narwhals/tests/utils.py

Lines 240 to 241 in 3b3b481

request_id = request.node.callspec.id
if "duckdb" in request_id:

... will be this string ...

timestamp_test.py::test_timestamp_datetimes_tz_aware[duckdb-ms-ms-expected8]'
#                                                    ^^^^^^^^^^^^^^^^^^^^^^

... which gets the name from here

narwhals/tests/conftest.py

Lines 217 to 234 in 3b3b481

EAGER_CONSTRUCTORS: dict[str, ConstructorEager] = {
"pandas": pandas_constructor,
"pandas[nullable]": pandas_nullable_constructor,
"pandas[pyarrow]": pandas_pyarrow_constructor,
"pyarrow": pyarrow_table_constructor,
"modin": modin_constructor,
"modin[pyarrow]": modin_pyarrow_constructor,
"cudf": cudf_constructor,
"polars[eager]": polars_eager_constructor,
}
LAZY_CONSTRUCTORS: dict[str, ConstructorLazy] = {
"dask": dask_lazy_p2_constructor,
"polars[lazy]": polars_lazy_constructor,
"duckdb": duckdb_lazy_constructor,
"pyspark": pyspark_lazy_constructor, # type: ignore[dict-item]
"sqlframe": sqlframe_pyspark_lazy_constructor,
"ibis": ibis_lazy_constructor,
}

But why?

I don't know about you, but I've been bitten a few times by getting this pattern wrong

if "dask" in str(constructor):
pytest.skip(reason="https://github.com/narwhals-dev/narwhals/issues/2808")
if any(x in str(constructor) for x in ("duckdb", "pyspark", "ibis")):
request.applymarker(
pytest.mark.xfail(reason="Backend timestamp conversion not yet implemented")
)
unsupported_backends = (
"pandas_constructor",
"pandas_nullable_constructor",
"cudf",
"modin_constructor",
)
if any(x in str(constructor) for x in unsupported_backends):
pytest.skip("Backend does not support date type")
dates = {"a": [datetime(2001, 1, 1), None, datetime(2001, 1, 3)]}
if "dask" in str(constructor):

Mainly with

  • "pyarrow" unintentionally matching pandas-like
  • always forgetting how to select every/a subset of pandas 😞

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bringing this all back ...

time_unit_compat should just require that you've written a test like any of these:

def test_concat_diagonal(
    constructor: Constructor, request: pytest.FixtureRequest
) -> None:

def test_array_dunder(
    request: pytest.FixtureRequest, constructor_eager: ConstructorEager
) -> None:

Then once you're in the test, you can do this without even knowing about constructor 🤯

def test_array_dunder(
    request: pytest.FixtureRequest, constructor_eager: ConstructorEager
) -> None:
    replaced = time_unit_compat("us", request)

Copy link
Copy Markdown
Member Author

@dangotbanned dangotbanned Sep 6, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Then once you're in the test, you can do this without even knowing about constructor 🤯

It was specifically that part I was thinking might lead to someone hitting that error message

@FBruzzesi
Copy link
Copy Markdown
Member

FBruzzesi commented Sep 6, 2025

Thanks @dangotbanned, feel free to merge if you are happy with it

@dangotbanned dangotbanned merged commit 2190c2e into main Sep 6, 2025
30 of 31 checks passed
@dangotbanned dangotbanned deleted the fix-time-unit-warnings branch September 6, 2025 21:05
dangotbanned added a commit that referenced this pull request Sep 6, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci duckdb Issue is related to duckdb backend pandas-like Issue is related to pandas-like backends tests

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants