pydantic / pydantic-extra-types

Extra Pydantic types.
MIT License
200 stars 54 forks source link

Type Support for argparse.Namespace() #200

Open jude253 opened 3 months ago

jude253 commented 3 months ago

Hello,

I hope you are well. I really like Pydantic, and I've found it makes it much easier and also neater to work with classes in python.

Today, I tried to use it to put the arguments parsed from the command line with argparse as an attribute in class to use composition. The exact type name is argparse.Namespace. Because this wasn't able to work, I just converted the arguments to a default dictionary type and used that with pedantic.

This works, but I think it would be much nicer to have the argparse type be able to work work pydantic classes by default, this way I can use the built-in functionality of that, rather than just using dictionary keys to get the arguments.

Would it be possible to add this?

Thanks!

sydney-runkle commented 3 months ago

Reasonable request for pydantic-extra-types!

Viicos commented 3 months ago

I'm not sure I can see how argparse namespaces can be validated: they are just (dynamic) container classes:

class Namespace(_AttributeHolder):
    """Simple object for storing attributes.

    Implements equality by attribute names and values, and provides a simple
    string representation.
    """

    def __init__(self, **kwargs):
        for name in kwargs:
            setattr(self, name, kwargs[name])

Do you have an example of how validation would work?

jude253 commented 3 months ago

I'm not sure I can see how argparse namespaces can be validated: they are just (dynamic) container classes:

class Namespace(_AttributeHolder):
    """Simple object for storing attributes.

    Implements equality by attribute names and values, and provides a simple
    string representation.
    """

    def __init__(self, **kwargs):
        for name in kwargs:
            setattr(self, name, kwargs[name])

Do you have an example of how validation would work?

Hi @Viicos, you bring up a good point. I am not very familiar with the internals of pydantic and also the namespace class. I tried to add argparse.Namespace as a type in a pydantic class that inherits from BaseModel, but I got an error message that it couldn't be validated. I found this a little surprising because it's a built in type.

I believe the error message said to try to add a validation of that type to pydantic, but I don't know how to do that. I thought I would raise a ticket instead.

I can maybe look more into this, but it's not my area of expertise.

I do find it interesting though that if you put the dictionary version of the argparse.Namespace, it is able to work fine with pydantic. My understanding is that argparse.Namespace is essentially like dictionary with a few other special features such as being able to call the keys as if they are attributes and I think the .get() doesn't work.

I was thinking having support for cli arguments built into pydantic would be really nice to make making cli applications easier. Especially, making it easier to configure cli input types and commands using like types rather than specifying a lot of strings in dictionaries and stuff.

Do you have an example of how validation would work?

I can try to put together an example for validation as you asked. Do you have a good resource on how to do this though? I am not sure I fully understand what should go into like default validation.