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

Implement Python unions #2427

Merged
merged 16 commits into from
Mar 17, 2023
Merged

Implement Python unions #2427

merged 16 commits into from
Mar 17, 2023

Conversation

crisidev
Copy link
Contributor

@crisidev crisidev commented Mar 2, 2023

Motivation and Context

Continue work on #1367.

Description

Implement support for the union shape in the Python server.

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

@crisidev crisidev added enhancement New feature or request python-server Python server SDK labels Mar 2, 2023
@github-actions
Copy link

github-actions bot commented Mar 2, 2023

A new generated diff is ready to view.

A new doc preview is ready to view.

@unexge
Copy link
Contributor

unexge commented Mar 2, 2023

Wonder if we can leverage type narrowing here.

So we generate the following:

#[pyo3]
struct Square;

#[pyo3]
struct Circle;

// :type typing.Union[Square, Circle]:
enum Shape {
    Square(Square),
    Circle(Circle),
}

impl IntoPy<PyObject> for Shape {
    fn into_py(self, py: Python<'_>) -> PyObject {
        match self {
            Shape::Square(s) => s,
            Shape::Circle(c) => c,
        }
    }
}

impl FromPyObject<'_> for Shape {
    fn extract(obj: &PyAny) -> PyResult<Self>{
        if let Ok(s) = obj.extract::<Square> {
            Ok(Shape::Square(s))
        } else if let Ok(c) = obj.extract::<Circle> {
            Ok(Shape::Circle(c))
        } else {
            Err("invalid shape")
        }
    }
}

and users can write:

# We will generate this type-stub for enums:
Shape = Square | Circle

def stringfy(shape: Shape) -> str:
    if isinstance(shape, Square):
        return "■"
    # Here type-checker knows `shape` must be `Circle`
    return "●"

I believe with Python 3.10 they can even write:

def stringfy(shape: Shape) -> str:
    match shape:
        case Square:
            return "■"
        case Circle:
            return "●"
        case _:
            raise NotReachable()

🤯

@github-actions
Copy link

github-actions bot commented Mar 7, 2023

@crisidev
Copy link
Contributor Author

crisidev commented Mar 7, 2023

Wonder if we can leverage type narrowing here.

So we generate the following:

Unfortunately that is not enough as it will not cover nested unions like

union Something {
    member_a: AnotherUnion
    member_b: Integer
}

union AnotherUnion {
    member_a: Integer
    member_b: String
}

@github-actions
Copy link

github-actions bot commented Mar 7, 2023

@github-actions
Copy link

github-actions bot commented Mar 9, 2023

@github-actions
Copy link

github-actions bot commented Mar 9, 2023

A new generated diff is ready to view.

A new doc preview is ready to view.

@github-actions
Copy link

github-actions bot commented Mar 9, 2023

A new generated diff is ready to view.

A new doc preview is ready to view.

@crisidev crisidev marked this pull request as ready for review March 9, 2023 18:01
@crisidev crisidev requested review from a team as code owners March 9, 2023 18:01
@github-actions
Copy link

github-actions bot commented Mar 9, 2023

A new generated diff is ready to view.

A new doc preview is ready to view.

@github-actions
Copy link

A new generated diff is ready to view.

A new doc preview is ready to view.

@github-actions
Copy link

A new generated diff is ready to view.

A new doc preview is ready to view.

Copy link
Contributor

@unexge unexge left a comment

Choose a reason for hiding this comment

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

Thank you for doing this 🎉

@github-actions
Copy link

A new generated diff is ready to view.

A new doc preview is ready to view.

@github-actions
Copy link

A new generated diff is ready to view.

A new doc preview is ready to view.

@github-actions
Copy link

A new generated diff is ready to view.

A new doc preview is ready to view.

@crisidev crisidev disabled auto-merge March 16, 2023 18:10
@github-actions
Copy link

A new generated diff is ready to view.

A new doc preview is ready to view.

@github-actions
Copy link

A new generated diff is ready to view.

A new doc preview is ready to view.

@unexge unexge added this pull request to the merge queue Mar 17, 2023
@unexge unexge merged commit 48eda40 into main Mar 17, 2023
@unexge unexge deleted the oxipy-unions branch March 17, 2023 15:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request python-server Python server SDK
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants