Skip to content

Conversation

@ThisIsLamer
Copy link

Fixed substitution of types when using Union

@overload
def get(self, type: Literal[Parameter.A]) -> Response1: ...

@overload
def get(self, type: Literal[Parameter.B]) -> Response2: ...

@overload
def get(self, type: Literal[Parameter.C]) -> Response3: ...

@overload
def get(self, type: Literal[Parameter.D]) -> Response4: ...

@get("test/resources?type={type}")
def get(self, type: TypeParameter) -> Union[Response1, Response2, Response3, Response4]:
    pass

@ponytailer
Copy link
Owner

Fixed substitution of types when using Union

@overload

def get(self, type: Literal[Parameter.A]) -> Response1: ...



@overload

def get(self, type: Literal[Parameter.B]) -> Response2: ...



@overload

def get(self, type: Literal[Parameter.C]) -> Response3: ...



@overload

def get(self, type: Literal[Parameter.D]) -> Response4: ...



@get("test/resources?type={type}")

def get(self, type: TypeParameter) -> Union[Response1, Response2, Response3, Response4]:

    pass

Thanks for your pr. Add the unit tests for it please.

@codecov-commenter
Copy link

codecov-commenter commented Nov 27, 2025

⚠️ Please install the 'codecov app svg image' to ensure uploads and comments are reliably processed by Codecov.

Codecov Report

❌ Patch coverage is 90.00000% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 88.60%. Comparing base (bb3de54) to head (fd06301).

Files with missing lines Patch % Lines
pydantic_client/sync_client.py 90.00% 1 Missing ⚠️
❗ Your organization needs to install the Codecov GitHub app to enable full functionality.
Additional details and impacted files
@@           Coverage Diff           @@
##             main     #144   +/-   ##
=======================================
  Coverage   88.59%   88.60%           
=======================================
  Files           8        8           
  Lines         491      500    +9     
=======================================
+ Hits          435      443    +8     
- Misses         56       57    +1     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@ponytailer
Copy link
Owner

ponytailer commented Nov 27, 2025

In your example, different requests lead to different responses, which is understandable.
However, this is not reflected in the test cases; and even though the current handling method is sufficiently accurate, corner cases will always be encountered.


# type = A
class A(BaseModel):
    name: str
    book: Optional[xxxx]

    def get_1(self): pass

# type = B
class B(BaseModel):
    name: str
    other_book: Optional[yyyy]
    
    def get_2(self): pass

response = {"name": "xxxxx"}

# request type is B

expected_b = get_union(type=B)
expected_b.get_2()   # raise error

I think it would be reasonable to have a request-to-response type mapping handler to handle this situation.

@get("/types?type={type}", response_type_handler=type_handler)
def get_type(self, type: str) -> Union[A, B, C]: ...


def type_handler(request_info: RequestInfo):
     match request_info.params["type"]:
         case "A": return A
         case "B": return B
         ...

json={"type": "B", "value": 42}
)
m.get('http://example.com/types?type=A', json={"name": "test_A", "book": "test_book"})
m.get('http://example.com/types?type=B', json={"name": "test_B", "other_book": "test_other_book"})
Copy link
Owner

Choose a reason for hiding this comment

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

I mean:

json={"name": "test_A"}
json={"name": "test_B"}

other fields are optional.

@ponytailer
Copy link
Owner

When the required field is the same and the optional field is different in the response model, and the response data only has the value of the required field, your code has no way to handle this situation correctly.

@ThisIsLamer
Copy link
Author

To be honest, I don't understand what needs to be done in the test, even with all the explanations, I brought it closer to the option I use in my project, the problem is that if you make the first name key in both types, then the type check will not happen, everything will work in the IDE, but the first type of the two will be in the test in any case, in order for it to work, you need to add those parameters that are individual for each type.

@ThisIsLamer
Copy link
Author

Well, you made the pull request yourself, I think mine can be rejected.

@ponytailer
Copy link
Owner

Well, you made the pull request yourself, I think mine can be rejected.

I'm pondering if there's a way to solve this problem while ensuring ease of use. However, I don't have enough time to figure it out. If you're willing, you could help me solve this problem, rather than just solving the one you encountered.thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants