-
-
Notifications
You must be signed in to change notification settings - Fork 64
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
is there a way to mark fields as mutually_exclusive_group? #467
Comments
@kschwab Could you please take a look here? |
No, currently from typing import Optional
from typing_extensions import Self
from pydantic import BaseModel, model_validator
class MyModel(BaseModel):
a: Optional[str] = None
b: Optional[str] = None
@model_validator(mode='after')
def check_a_b_exclusion(self) -> Self:
if self.a is not None and self.b is not None:
raise ValueError("'a' and 'b' are mutually exclusive.")
return self
MyModel()
MyModel(a='hi')
MyModel(b='hi')
MyModel(a='hi', b='hi') # raises validation error Perhaps we can find a way that simplifies the above for convenience, i.e. provide a pre-canned validator for mutual exclusion. |
thanks, currently I am using validator, but it does not provide the relationship in help message, I basically have to manually add them in the field description. It would be nice if there is kind of annotation we can use to mark the group, so it can automatically validate and also shows in the help message. |
Most of the mutually exclusive flags can be easily replaced by choice options, for example For options, since we can have subcommand as union I get inspired by using Union to handle the mutually exclusive group more naturally. The simple type like, int, str, bool, etc, automatically working already, then we can basically determine what to do based on the type. However, more tricky thing is the mutually exclusive options that has same type, this happens when we can describe something in different ways, and any path results in the same final result. So far in pydantic we have to use 2 options to do this: A more complicated case is the mutually exclusive item is actually a group of options, which actually is not supported in argparse:
If we use union in this case, it does not give desired help output and it also does not give out error when we specify the conflict options. for example:
It gives:
We would expect something like
and if we specify the conflict options like example help output of argparse:
example help output of pydantic setting:
example code:
|
the expected output I wanted for better Union field support:
|
if we allow some kind of marking we can do:
Then the help will be:
|
@braindevices I agree the above outcome would be ideal. I think it's a little clunkier in practice, where we would need to use class Settings(BaseSettings):
radius: Annotated[Optional[float], CliMutuallyExclusiveGroup("Circle")] = None
diameter: Annotated[Optional[float], CliMutuallyExclusiveGroup("Circle")] = None
perimeter: Annotated[Optional[float], CliMutuallyExclusiveGroup("Circle")] = None However, I think providing class Circle(CliMutuallyExclusiveGroup):
radius: Optional[float] = None
diameter: Optional[float] = None
perimeter: Optional[float] = None
class Settings(BaseSettings):
circle: Circle The above is nice from an implementation point of view as it keeps things simple, but also allows for more flexibility. e.g., |
Yes I actually prefer your way. Thanks! |
@kschwab @braindevices Thanks both this issue. @kschwab do we need any action here? should we keep the issue open? |
@hramezani yes, we can keep it open. I will open PR in next few days to resolve. |
the argparser allow add_mutually_exclusive_group, is there similar feature in pydantic settings?
The text was updated successfully, but these errors were encountered: