fugue-project / fugue

A unified interface for distributed computing. Fugue executes SQL, Python, Pandas, and Polars code on Spark, Dask and Ray without any rewrites.
https://fugue-tutorials.readthedocs.io/
Apache License 2.0
1.97k stars 94 forks source link

[COMPATIBILITY] DataFrameFunctionWrapper for Callable in the context of PEP 585 #551

Open kondziolka9ld opened 2 weeks ago

kondziolka9ld commented 2 weeks ago

I have noticed that typing.Callable has been marked as deprecated starting from python 3.9 (PEP 585). I mean for example Callable (here) and Optional[Callable] (here). Are there any plans to update fugue according to PEP 585? For these two cases (Callable and Optional[Callable] I can prepare PR.

goodwanghan commented 1 week ago

So this is going to be a big refactoring. The reason we have not done it is because we are still supporting Python 3.8 which is going to be deprecated this October. Our plan is to support end of life Pythons for an additional half year.

I understand by importing __future__ we can make it compatible. But then this import will be in every file. So I am not sure if we should do that now or wait until Feb/Mar 2025 to simply deprecate Python 3.8?

Thoughts?

kondziolka9ld commented 1 week ago

@goodwanghan thank you for your answer! I see rationales behind waiting for EOL of python3.8. Anyway, for now, I do not consider rewriting all imports from typing.Callable to collections.abc.Callable. I think about adding support for collections.abc.Callable and collections.abc.Optional[Callable]. So something like:

@fugue_annotated_param(
    "Callable",
    "F",
    lambda annotation: (
        annotation == Callable
        or annotation == callable  # pylint: disable=comparison-with-callable
        or str(annotation).startswith("typing.Callable") or str(annotation).startswith("collections.abc.Callable")
    ),
)
class _CallableParam(AnnotatedParam):
    pass

@fugue_annotated_param(
    "Callable",
    "f",
    lambda annotation: (
        annotation == Optional[Callable]
        or annotation == Optional[callable]
        or str(annotation).startswith("typing.Union[typing.Callable")  # 3.8-
        or str(annotation).startswith("typing.Optional[typing.Callable") or str(annotation).startswith("Optional[collections.abc.Callable]")  # 3.9+
    ),
)
class _OptionalCallableParam(AnnotatedParam):
    pass

Does it make sense? It would make this code compatible to python-3.9 and still works with python-3.8.

goodwanghan commented 1 week ago

ah, yes it makes sense. That sounds good, please feel free to create a PR for that.

Thanks!

celestinoxp commented 1 week ago

@kondziolka9ld ping...

kondziolka9ld commented 1 week ago

@goodwanghan I created a PR. Please review it.