Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore(typing): resolve time unit/zone set invariance #2012

Merged
merged 4 commits into from
Feb 15, 2025

Conversation

dangotbanned
Copy link
Member

@dangotbanned dangotbanned commented Feb 14, 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

image

@dangotbanned dangotbanned marked this pull request as ready for review February 14, 2025 17:44
Copy link
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 have a question relevant for 50% of the changes 🙈

@@ -1241,15 +1242,15 @@ def check_column_names_are_unique(columns: list[str]) -> None:
def _parse_time_unit_and_time_zone(
time_unit: TimeUnit | Iterable[TimeUnit] | None,
time_zone: str | timezone | Iterable[str | timezone | None] | None,
) -> tuple[set[str], set[str | None]]:
time_units = (
) -> tuple[set[TimeUnit], AbstractSet[str | None]]:
Copy link
Member

Choose a reason for hiding this comment

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

Why wouldn't

Suggested change
) -> tuple[set[TimeUnit], AbstractSet[str | None]]:
) -> tuple[set[TimeUnit], set[str | None]]:

not work?

I though AbstractSet was deprecated

Copy link
Member Author

Choose a reason for hiding this comment

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

Good question @FBruzzesi

It very much is deprecated, but until we up our minimum python to 3.9 we can't use this as a generic https://docs.python.org/3/library/collections.abc.html#collections.abc.Set

AbstractSet and Set both have a covariant TypeVar in the stubs https://github.com/python/typeshed/blob/cc8ca939c0477a49fcce0554fa1743bd5c656a11/stdlib/typing.pyi#L627

Copy link
Member

@FBruzzesi FBruzzesi Feb 14, 2025

Choose a reason for hiding this comment

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

I feel like I am missing something, how come that for one variable we can use it and not for the other?

Even with a py3.8 venv I am getting no issues with pyright after annotating the return type and the respective variables to set[TimeUnit] and set[str | None] 🤔

Copy link
Member Author

@dangotbanned dangotbanned Feb 14, 2025

Choose a reason for hiding this comment

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

Even with a py3.8 venv I am getting no issues with pyright after annotating the return type and the respective variables to set[TimeUnit] and set[str | None] 🤔

Hmm, I'll need to take a look at this tomorrow.
IIRC, the difference was set[TimeUnit] can be used now because because it isn't a union.
But set[str | None] got expanded to set[str] | set[None] | set[str | None] - which was the issue

Copy link
Member Author

Choose a reason for hiding this comment

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

AbstractSet[str | None] can match any of or all of those 3 (because of the variance)

Copy link
Member

Choose a reason for hiding this comment

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

Thanks for explaining! I am approving this in the meanwhile, but let me know if you manage to double check whenever you have the time 🙏🏼

Copy link
Member Author

Choose a reason for hiding this comment

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

Thanks @FBruzzesi will do!

Absolutely need some time away from typing after #2007 😵

Copy link
Member Author

Choose a reason for hiding this comment

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

Okay so I know what the issue was now @FBruzzesi

By using AbstractSet, we can safely drop the inline time_zones annotation.

Note

I forgot to do this though 🤦‍♂️

Image 1

image

We can also switch every annotation to set[str | None], as you discovered in #2012 (comment):

Image 2

image

But this requires annotating it like that one every usage.
Dropping the inline annotation shows the warning:

Image 3

image

Originally, I added a new alias for this - but later scrapped it since it only appears in these two functions:

_TimeZones: TypeAlias = AbstractSet[str | None]]

However, leaving the variables to inference only works for pyright sadly:

# mypy
narwhals/utils.py:1257: error: Argument 1 to <set> has incompatible type "str"; expected "None"  [arg-type]
narwhals/utils.py:1259: error: Set comprehension has incompatible type set[str | None]; expected set[str]  [misc]
narwhals/utils.py:1259: error: Set comprehension has incompatible type set[str | None]; expected set[None]  [misc]

I'm just pushing a little tweak that makes more sense to me

Copy link
Member Author

Choose a reason for hiding this comment

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

See (b38403c)

Copy link
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 🚀

NarwhalsKittyGIF

@MarcoGorelli
Copy link
Member

thanks all!

@MarcoGorelli MarcoGorelli merged commit 2e693e8 into main Feb 15, 2025
27 of 28 checks passed
@MarcoGorelli MarcoGorelli deleted the fix-typing-time-units branch February 15, 2025 11:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants