[cython/cython] Adds support for `typing.Union` (PR #6206)

0 views
Skip to first unread message

Matus Valo

unread,
May 20, 2024, 4:21:09 PM5/20/24
to cython/cython, Subscribed

This PR adds support of typing.Union. It is optimised to fused type.

Note

This PR does not support Union of None. Hence Union[int, None] will trigger an error.

Currently only as a draft. The test suite is passing but needs #6204 merged to master.


You can view, comment on, or merge this pull request online at:

  https://github.com/cython/cython/pull/6206

Commit Summary

File Changes

(6 files)

Patch Links:


Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you are subscribed to this thread.Message ID: <cython/cython/pull/6206@github.com>

bzoracler

unread,
May 21, 2024, 12:47:31 AM5/21/24
to cython/cython, Subscribed

As I understand, this can be considered work towards some of the union semantics outlined in #4631.

I don't think Cython fused types should be expressed by Python unions. Constrained type variables would be a more natural fit. Consider the following example, which fails to compile in Cython:

ctypedef fused char_or_float:
    char
    double

cpdef char_or_float plus_one(char_or_float var):
    return 0.0
cpdef char_or_float plus_one(char_or_float var):
    return 0.0
           ^
error: Cannot assign type 'double' to 'char'

In Python, if char_or_float was a union type, this example is perfectly valid. A constrained type variable on the other hand would behave like Cython, raising type-checking errors with roughly equivalent semantics to Cython. See the following example (mypy Playground, Pyright playground):

import typing as t

char_or_float_union: t.TypeAlias = str | float
char_or_float_typevar = t.TypeVar("char_or_float_typevar", str, float)

def plus_one_union(var: char_or_float_union) -> char_or_float_union:
    return 0.0  # No errors

def plus_one_typevar(var: char_or_float_typevar) -> char_or_float_typevar:
    return 0.0  # mypy: Incompatible return value type (got "float", expected "str")  [return-value]


Reply to this email directly, view it on GitHub, or unsubscribe.

You are receiving this because you are subscribed to this thread.Message ID: <cython/cython/pull/6206/c2121732660@github.com>

Matus Valo

unread,
May 21, 2024, 2:11:10 AM5/21/24
to cython/cython, Subscribed

I don't think Cython fused types should be expressed by Python unions.

I see your point and I agree with your example. But I think this should be more optimisation technique than expression of type. I don't see any wrong to optimise Union[] type with fused type where it make sense. E.g. when function contains parameter with the Union[] type, cython can pick optimised version of function. Of course we cannot optimise/translate Union[] type to fused of result type.

But maybe I am missing something that's why i created draft to get feedback.


Reply to this email directly, view it on GitHub, or unsubscribe.

You are receiving this because you are subscribed to this thread.Message ID: <cython/cython/pull/6206/c2121822705@github.com>

da-woods

unread,
May 21, 2024, 3:12:47 AM5/21/24
to cython/cython, Subscribed

Yeah it's a fair point and we don't want to break too much working code by using type-hints in an odd way. The only thing about fused return types is that they're ignored in a def function, so anyone hitting this is already partly into cdef/cpdef functions so they aren't breaking real pure Python code.

Just thinking about other places it can break:

  • Annotations on classes
  • Multiple arguments with the same fused type are assumed to all be the same type

Constrained type variables [...]

Reading the documentation, that looks like a better fit for what we're trying to write.

I'm personally pretty sceptical of the more advanced features of typing - the advantage of Union is that people will at least know about it. (But for me in my own code, Union is the absolute limit of how far I'm prepared to take annotation typing). Constrained type variables look like an obscure detail of a wider "generics" feature.

So I'm a little unsure of what's best to do here.


Reply to this email directly, view it on GitHub, or unsubscribe.

You are receiving this because you are subscribed to this thread.Message ID: <cython/cython/pull/6206/c2121914609@github.com>

Matus Valo

unread,
May 21, 2024, 2:55:44 PM5/21/24
to cython/cython, Subscribed

I'm personally pretty sceptical of the more advanced features of typing

Me too. I think implementing more advanced typing features seems to be complex task. My personal motivation of this PR is to implement following optional type using | but I end up implementing optional type using Union[] which naturally lead to this PR. Later on, I would like to add support of None too.

So I'm a little unsure of what's best to do here.

I would optimise what does make sense and has reasonable complexity. Rest I would ignore as we ignore types now. Currently, I don't know what is exact scope of optimisation but hopefully we will figure out in time.


Reply to this email directly, view it on GitHub, or unsubscribe.

You are receiving this because you are subscribed to this thread.Message ID: <cython/cython/pull/6206/c2123252048@github.com>

Reply all
Reply to author
Forward
0 new messages