Coder Social home page Coder Social logo

add tagged union about pydantic-core HOT 8 CLOSED

PrettyWood avatar PrettyWood commented on May 16, 2024
add tagged union

from pydantic-core.

Comments (8)

samuelcolvin avatar samuelcolvin commented on May 16, 2024

As you may already know I love unions: smart, strict and tagged ones 😄

What about trade unions?


syntax looks good.

Questions:

  1. Does the field have to be a literal? I think yes.
  2. We currently have multiple different sorts of literal, are you going to allow all of them?
  3. Maybe this should be a separate validator? Not for performance, more to make it less complex and easier to develop.
  4. How are you going to implement it? perhaps you could expose some of the logic in literal as public functions, then reuse them in TaggedUnion? The other option is to change the schema syntax to add a intermediate dict under choice that can include "tags" - this would make generating schema more complex, but it would avoid the need (at least in pydantic-core schema) for the tag as a field, and would make your logic much simpler, you could also limit tags to being string more explicitly. Something like:
'type': 'model',
'fields': {
    'pet': {
        'schema': {
            'type': 'union',
            'tag': 'species',
            'choices': [
                {
                    'tag': 'cat',
                    'schema': {
                        'type': 'model',
                        'fields': {
                            'species': {'schema': {'type': 'literal', 'expected': ['cat']}},
                            'lives': {'schema': {'type': 'int'}, 'default': 9},
                        },
                    }
                },
                {
                    'tag': 'dog',
                    # or maybe
                    'tags': ['dog', 'fox'],
                    {
                        'type': 'model',
                        'fields': {
                            # note that here we don't **need** to have species as a field
                            'barks': {'schema': {'type': 'bool'}},
                        },
                    },
                  }
            ],
        }
    },
},

This is completely up to you, I can see both working and we can probably support both in pydantic.

from pydantic-core.

PrettyWood avatar PrettyWood commented on May 16, 2024

Does the field have to be a literal? I think yes.

Yes I think we need to check for tagged unions that

  • all fields are models
  • all models have a field with the tag name and a type literal
  • all literal values have no overlap
    and then cache them into a Hashmap (or even FxHashMap?) for immediate validator lookup

We currently have multiple different sorts of literal, are you going to allow all of them?

I was planning to only support string literals (so LiteralSingleString and LiteralMultipleStrings). We could support int literals but I've never seen a usecase in my life so 🤷

Maybe this should be a separate validator? Not for performance, more to make it less complex and easier to develop.

Yep I was tempted! Maybe suggest tagged-union as type. I'll probably go with this approach

The other option is to change the schema syntax to add a intermediate dict under choice that can include "tags"

Probably a good idea! It should avoid adding public methods on fields just for tagged unions. I'll play a bit with the code tonight and come back with a proposal 👍

from pydantic-core.

samuelcolvin avatar samuelcolvin commented on May 16, 2024

sounds good, just strings (both single and multiple) makes sense so they fix into map.

If we went with the different schema, then we no longer care that all choices are models, since we only look at the tag or tags key.

Probably a good idea! It should avoid adding public methods on fields just for tagged unions.

If we did go with the first syntax, no need to add new methods to the trait, just implement that logic as standalone functions in literal.rs, then import and use them in union.rs as well as in the build functions in literal types.

from pydantic-core.

samuelcolvin avatar samuelcolvin commented on May 16, 2024

Might be worth looking at LookupKey in #88 we could reuse it in tagged unions to allow the tag to be somewhere other than the top level dict while reusing existing logic.

from pydantic-core.

samuelcolvin avatar samuelcolvin commented on May 16, 2024

Might be worth looking at LookupKey in #88 we could reuse it in tagged unions to allow the tag to be somewhere other than the top level dict while reusing existing logic.

This is what pydantic/pydantic#4180 wants.

Having thought about this more, I think moving tag / tags into a parent dict and reusing LookupKey is a good idea. LookupKey is now well optimised with support for reusing PyStrings etc.

from pydantic-core.

samuelcolvin avatar samuelcolvin commented on May 16, 2024

@PrettyWood any idea when you might get to work on this?

I need it for #131.

No big hurry. I'm happy to wait a while or take over this if you think you'll be able to work on it.

from pydantic-core.

PrettyWood avatar PrettyWood commented on May 16, 2024

@samuelcolvin I'm still on holiday until Sunday. And I'll first work on launching Q3 for my company before working more on OSS (even though I'd love to right now).
I had planned to start working on it in 2-3 weeks. I didn't know you needed it too 😆
IMO if you can work on it right now it's better. I know you have everything in mind and probably want to release a v1 asap.
I have only my phone on me but it should be enough to review the code if you wish 🙂

from pydantic-core.

samuelcolvin avatar samuelcolvin commented on May 16, 2024

Understood. Enjoy your holiday and don't worry about it.

I'll let you know when I have a PR and it's completely up to you if you want to review it.

from pydantic-core.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.