Skip to content

Unexpected primitive based Enum (de)serialization #51016

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

Open
2 tasks done
mixilchenko opened this issue May 23, 2025 · 4 comments
Open
2 tasks done

Unexpected primitive based Enum (de)serialization #51016

mixilchenko opened this issue May 23, 2025 · 4 comments
Labels
area:core area:serialization kind:bug This is a clearly a bug needs-triage label for new issues that we didn't triage yet

Comments

@mixilchenko
Copy link
Contributor

Apache Airflow version

main (development)

If "Other Airflow 2 version" selected, which one?

No response

What happened?

When enumeration inherits some primitive type (e.g. str, int), deserialization makes the value primitive as well.

import enum
from airflow.serialization.serde import deserialize, serialize

class MyEnum(enum.IntEnum):
    A = 1
    B = 2

value = MyEnum.A
res = deserialize(serialize(value))
assert res is MyEnum.A, f'{type(res)=}, {res=}'
# AssertionError: type(res)=<class 'int'>, res=1

What you think should happen instead?

This is little unexpected for me as a user and for mypy

@task
def my_task(v: MyEnum):
    assert is instance(v, MyEnum), 'fine for mypy, fails in runtime'
    v = MyEnum(v)
...
my_task(MyEnum.A)

The other issue is that if I add airflow compatible custom serialization the result is incorrect too

class MyEnum(enum.IntEnum):
    A = 1
    B = 2

    def serialize(self):
        return f'{self.name}.{self.value}'

res = serialize(MyEnum.A)
assert res == 'A.1', f'{type(res)=}, {res=}'
# AssertionError: type(res)=<class 'int'>, res=1

I would expect one of

  • implement default serialization and deserialization for enums
  • fail with TypeError: cannot serialize object of type <enumeration 'MyEnum'> unless it implements the interface and is registered for deserialization (as it happens for enums that do not inherit primitive)

How to reproduce

See the snippet above

Operating System

Debian GNU/Linux 12 (bookworm)

Versions of Apache Airflow Providers

No response

Deployment

Virtualenv installation

Deployment details

No response

Anything else?

No response

Are you willing to submit PR?

  • Yes I am willing to submit a PR!

Code of Conduct

@mixilchenko mixilchenko added kind:bug This is a clearly a bug area:core labels May 23, 2025
Copy link

boring-cyborg bot commented May 23, 2025

Thanks for opening your first issue here! Be sure to follow the issue template! If you are willing to raise PR to address this issue please do so, no need to wait for approval.

@mixilchenko mixilchenko added the needs-triage label for new issues that we didn't triage yet label May 23, 2025
@amoghrajesh
Copy link
Contributor

@mixilchenko i think we need to have a serializer + deserializer that does this properly for Enum types. Would you wanna work on this?

@Lcrs123
Copy link

Lcrs123 commented May 26, 2025

The other issue is that if I add airflow compatible custom serialization the result is incorrect too

I've come across this problem before and was thinking about opening an issue. If your custom type inherits from a python primitive, the sequence of checks that airflow does will always result in it using the de/serialize methods for the primitive type, even if you have defined custom de/serialize methods in your class yourself.

Maybe the order of checks should be changed? If the developer went through the trouble of defining the custom methods himself, he obviously wants them to be used, and not the default ones.

@amarlearning
Copy link
Contributor

Hi @amoghrajesh, I would like to work on this issue :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area:core area:serialization kind:bug This is a clearly a bug needs-triage label for new issues that we didn't triage yet
Projects
None yet
Development

No branches or pull requests

4 participants