Repository: openapi-generators/openapi-python-client (language: python)

Issue:
Invalid code generated for nullable discriminated union
**Describe the bug**

Given the schema below, using the generated code like:

```python
from test_client.models.demo import Demo
from test_client.models.a import A

Demo(example_union=A()).to_dict()
```

fails with:

```
Traceback (most recent call last):
  File "/Users/eric/Desktop/test/test.py", line 4, in <module>
    Demo(example_union=A()).to_dict()
  File "/Users/eric/Desktop/test/test_client/models/demo.py", line 32, in to_dict
    elif isinstance(self.example_union, Union["A", "B"]):
         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/eric/.pyenv/versions/3.12.1/lib/python3.12/typing.py", line 1564, in __instancecheck__
    return self.__subclasscheck__(type(obj))
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/eric/.pyenv/versions/3.12.1/lib/python3.12/typing.py", line 1568, in __subclasscheck__
    if issubclass(cls, arg):
       ^^^^^^^^^^^^^^^^^^^^
TypeError: issubclass() arg 2 must be a class, a tuple of classes, or a union
```

**OpenAPI Spec File**

```yaml
openapi: 3.0.3
info:
  title: Test
  version: 0.0.0
  description: test
paths: {}
components:
  schemas:
    Demo:
      type: object
      properties:
        example_union:
          allOf:
            - $ref: '#/components/schemas/ExampleUnion'
          nullable: true # <-- bug does not happen if this line is removed
    A:
      type: object
      properties:
        type:
          type: string
    B:
      type: object
      properties:
        type:
          type: string
    ExampleUnion:
      oneOf:
      - $ref: '#/components/schemas/A'
      - $ref: '#/components/schemas/B'
      discriminator:
        propertyName: type
        mapping:
          a: '#/components/schemas/A'
          b: '#/components/schemas/B'
```


**Desktop**
 - OS: macOS 14.3
 - Python Version: 3.12.1
 - openapi-python-client version: 0.17.2

**Additional context**

The failing generated code is:

```python
isinstance(self.example_union, Union["A", "B"])
```

Using `instanceof` on a `Union` with quoted types is not allowed:

```
>>> class A:
...     pass
...
>>> class B:
...     pass
...
>>> from typing import Union
>>> isinstance(None, Union[A, B])
False
>>> isinstance(None, Union["A", "B"])
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/eric/.pyenv/versions/3.12.1/lib/python3.12/typing.py", line 1564, in __instancecheck__
    return self.__subclasscheck__(type(obj))
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/eric/.pyenv/versions/3.12.1/lib/python3.12/typing.py", line 1568, in __subclasscheck__
    if issubclass(cls, arg):
       ^^^^^^^^^^^^^^^^^^^^
TypeError: issubclass() arg 2 must be a class, a tuple of classes, or a union
```


Discussion / hints:

Fix patch:
diff --git a/openapi_python_client/templates/model.py.jinja b/openapi_python_client/templates/model.py.jinja
index f8864b343..0df641ea4 100644
--- a/openapi_python_client/templates/model.py.jinja
+++ b/openapi_python_client/templates/model.py.jinja
@@ -109,6 +109,7 @@ field_dict.update({
 field_dict.update(self.additional_properties)
 {% endif %}
 {% endif %}
+{% if model.required_properties | length > 0 or model.optional_properties | length > 0 %}
 field_dict.update({
     {% for property in model.required_properties + model.optional_properties %}
     {% if property.required %}
@@ -116,6 +117,7 @@ field_dict.update({
     {% endif %}
     {% endfor %}
 })
+{% endif %}
 {% for property in model.optional_properties %}
 {% if not property.required %}
 if {{ property.python_name }} is not UNSET:


Test patch:
diff --git a/end_to_end_tests/golden-record/my_test_api_client/models/an_array_with_a_circular_ref_in_items_object_additional_properties_a_item.py b/end_to_end_tests/golden-record/my_test_api_client/models/an_array_with_a_circular_ref_in_items_object_additional_properties_a_item.py
index c90579e7e..eec98255f 100644
--- a/end_to_end_tests/golden-record/my_test_api_client/models/an_array_with_a_circular_ref_in_items_object_additional_properties_a_item.py
+++ b/end_to_end_tests/golden-record/my_test_api_client/models/an_array_with_a_circular_ref_in_items_object_additional_properties_a_item.py
@@ -32,8 +32,6 @@ def to_dict(self) -> Dict[str, Any]:
                     componentsschemas_an_array_with_a_circular_ref_in_items_object_additional_properties_b_item
                 )
 
-        field_dict.update({})
-
         return field_dict
 
     @classmethod
diff --git a/end_to_end_tests/golden-record/my_test_api_client/models/an_array_with_a_circular_ref_in_items_object_additional_properties_b_item.py b/end_to_end_tests/golden-record/my_test_api_client/models/an_array_with_a_circular_ref_in_items_object_additional_properties_b_item.py
index 732e8ea4c..479b177ea 100644
--- a/end_to_end_tests/golden-record/my_test_api_client/models/an_array_with_a_circular_ref_in_items_object_additional_properties_b_item.py
+++ b/end_to_end_tests/golden-record/my_test_api_client/models/an_array_with_a_circular_ref_in_items_object_additional_properties_b_item.py
@@ -32,8 +32,6 @@ def to_dict(self) -> Dict[str, Any]:
                     componentsschemas_an_array_with_a_circular_ref_in_items_object_additional_properties_a_item
                 )
 
-        field_dict.update({})
-
         return field_dict
 
     @classmethod
diff --git a/end_to_end_tests/golden-record/my_test_api_client/models/an_array_with_a_recursive_ref_in_items_object_additional_properties_item.py b/end_to_end_tests/golden-record/my_test_api_client/models/an_array_with_a_recursive_ref_in_items_object_additional_properties_item.py
index bd0472e21..301a66e0e 100644
--- a/end_to_end_tests/golden-record/my_test_api_client/models/an_array_with_a_recursive_ref_in_items_object_additional_properties_item.py
+++ b/end_to_end_tests/golden-record/my_test_api_client/models/an_array_with_a_recursive_ref_in_items_object_additional_properties_item.py
@@ -24,8 +24,6 @@ def to_dict(self) -> Dict[str, Any]:
                     componentsschemas_an_array_with_a_recursive_ref_in_items_object_additional_properties_item
                 )
 
-        field_dict.update({})
-
         return field_dict
 
     @classmethod
diff --git a/end_to_end_tests/golden-record/my_test_api_client/models/free_form_model.py b/end_to_end_tests/golden-record/my_test_api_client/models/free_form_model.py
index 327a5d3d7..f757b10ae 100644
--- a/end_to_end_tests/golden-record/my_test_api_client/models/free_form_model.py
+++ b/end_to_end_tests/golden-record/my_test_api_client/models/free_form_model.py
@@ -15,7 +15,6 @@ class FreeFormModel:
     def to_dict(self) -> Dict[str, Any]:
         field_dict: Dict[str, Any] = {}
         field_dict.update(self.additional_properties)
-        field_dict.update({})
 
         return field_dict
 
diff --git a/end_to_end_tests/golden-record/my_test_api_client/models/import_.py b/end_to_end_tests/golden-record/my_test_api_client/models/import_.py
index f5a7deecf..85cc594e7 100644
--- a/end_to_end_tests/golden-record/my_test_api_client/models/import_.py
+++ b/end_to_end_tests/golden-record/my_test_api_client/models/import_.py
@@ -15,7 +15,6 @@ class Import:
     def to_dict(self) -> Dict[str, Any]:
         field_dict: Dict[str, Any] = {}
         field_dict.update(self.additional_properties)
-        field_dict.update({})
 
         return field_dict
 
diff --git a/end_to_end_tests/golden-record/my_test_api_client/models/model_name.py b/end_to_end_tests/golden-record/my_test_api_client/models/model_name.py
index fa840976e..2a86db3a2 100644
--- a/end_to_end_tests/golden-record/my_test_api_client/models/model_name.py
+++ b/end_to_end_tests/golden-record/my_test_api_client/models/model_name.py
@@ -15,7 +15,6 @@ class ModelName:
     def to_dict(self) -> Dict[str, Any]:
         field_dict: Dict[str, Any] = {}
         field_dict.update(self.additional_properties)
-        field_dict.update({})
 
         return field_dict
 
diff --git a/end_to_end_tests/golden-record/my_test_api_client/models/model_reference_with_periods.py b/end_to_end_tests/golden-record/my_test_api_client/models/model_reference_with_periods.py
index 492b4f8f7..a5ff5d211 100644
--- a/end_to_end_tests/golden-record/my_test_api_client/models/model_reference_with_periods.py
+++ b/end_to_end_tests/golden-record/my_test_api_client/models/model_reference_with_periods.py
@@ -15,7 +15,6 @@ class ModelReferenceWithPeriods:
     def to_dict(self) -> Dict[str, Any]:
         field_dict: Dict[str, Any] = {}
         field_dict.update(self.additional_properties)
-        field_dict.update({})
 
         return field_dict
 
diff --git a/end_to_end_tests/golden-record/my_test_api_client/models/model_with_additional_properties_refed.py b/end_to_end_tests/golden-record/my_test_api_client/models/model_with_additional_properties_refed.py
index 4605b8801..b2500f68c 100644
--- a/end_to_end_tests/golden-record/my_test_api_client/models/model_with_additional_properties_refed.py
+++ b/end_to_end_tests/golden-record/my_test_api_client/models/model_with_additional_properties_refed.py
@@ -18,7 +18,6 @@ def to_dict(self) -> Dict[str, Any]:
         field_dict: Dict[str, Any] = {}
         for prop_name, prop in self.additional_properties.items():
             field_dict[prop_name] = prop.value
-        field_dict.update({})
 
         return field_dict
 
diff --git a/end_to_end_tests/golden-record/my_test_api_client/models/model_with_any_json_properties.py b/end_to_end_tests/golden-record/my_test_api_client/models/model_with_any_json_properties.py
index 49a66f7a5..6e669914a 100644
--- a/end_to_end_tests/golden-record/my_test_api_client/models/model_with_any_json_properties.py
+++ b/end_to_end_tests/golden-record/my_test_api_client/models/model_with_any_json_properties.py
@@ -34,7 +34,6 @@ def to_dict(self) -> Dict[str, Any]:
 
             else:
                 field_dict[prop_name] = prop
-        field_dict.update({})
 
         return field_dict
 
diff --git a/end_to_end_tests/golden-record/my_test_api_client/models/model_with_any_json_properties_additional_property_type_0.py b/end_to_end_tests/golden-record/my_test_api_client/models/model_with_any_json_properties_additional_property_type_0.py
index d167d50d7..6ae70905e 100644
--- a/end_to_end_tests/golden-record/my_test_api_client/models/model_with_any_json_properties_additional_property_type_0.py
+++ b/end_to_end_tests/golden-record/my_test_api_client/models/model_with_any_json_properties_additional_property_type_0.py
@@ -15,7 +15,6 @@ class ModelWithAnyJsonPropertiesAdditionalPropertyType0:
     def to_dict(self) -> Dict[str, Any]:
         field_dict: Dict[str, Any] = {}
         field_dict.update(self.additional_properties)
-        field_dict.update({})
 
         return field_dict
 
diff --git a/end_to_end_tests/golden-record/my_test_api_client/models/model_with_backslash_in_description.py b/end_to_end_tests/golden-record/my_test_api_client/models/model_with_backslash_in_description.py
index 5485cf978..5de43ddb9 100644
--- a/end_to_end_tests/golden-record/my_test_api_client/models/model_with_backslash_in_description.py
+++ b/end_to_end_tests/golden-record/my_test_api_client/models/model_with_backslash_in_description.py
@@ -17,7 +17,6 @@ class ModelWithBackslashInDescription:
     def to_dict(self) -> Dict[str, Any]:
         field_dict: Dict[str, Any] = {}
         field_dict.update(self.additional_properties)
-        field_dict.update({})
 
         return field_dict
 
diff --git a/end_to_end_tests/golden-record/my_test_api_client/models/model_with_circular_ref_in_additional_properties_a.py b/end_to_end_tests/golden-record/my_test_api_client/models/model_with_circular_ref_in_additional_properties_a.py
index 9e3f6c12c..4f1d59c57 100644
--- a/end_to_end_tests/golden-record/my_test_api_client/models/model_with_circular_ref_in_additional_properties_a.py
+++ b/end_to_end_tests/golden-record/my_test_api_client/models/model_with_circular_ref_in_additional_properties_a.py
@@ -22,7 +22,6 @@ def to_dict(self) -> Dict[str, Any]:
         field_dict: Dict[str, Any] = {}
         for prop_name, prop in self.additional_properties.items():
             field_dict[prop_name] = prop.to_dict()
-        field_dict.update({})
 
         return field_dict
 
diff --git a/end_to_end_tests/golden-record/my_test_api_client/models/model_with_circular_ref_in_additional_properties_b.py b/end_to_end_tests/golden-record/my_test_api_client/models/model_with_circular_ref_in_additional_properties_b.py
index 5b4f0c268..3f55584e5 100644
--- a/end_to_end_tests/golden-record/my_test_api_client/models/model_with_circular_ref_in_additional_properties_b.py
+++ b/end_to_end_tests/golden-record/my_test_api_client/models/model_with_circular_ref_in_additional_properties_b.py
@@ -22,7 +22,6 @@ def to_dict(self) -> Dict[str, Any]:
         field_dict: Dict[str, Any] = {}
         for prop_name, prop in self.additional_properties.items():
             field_dict[prop_name] = prop.to_dict()
-        field_dict.update({})
 
         return field_dict
 
diff --git a/end_to_end_tests/golden-record/my_test_api_client/models/model_with_primitive_additional_properties_a_date_holder.py b/end_to_end_tests/golden-record/my_test_api_client/models/model_with_primitive_additional_properties_a_date_holder.py
index 4693be0a1..b9920fc60 100644
--- a/end_to_end_tests/golden-record/my_test_api_client/models/model_with_primitive_additional_properties_a_date_holder.py
+++ b/end_to_end_tests/golden-record/my_test_api_client/models/model_with_primitive_additional_properties_a_date_holder.py
@@ -18,7 +18,6 @@ def to_dict(self) -> Dict[str, Any]:
         field_dict: Dict[str, Any] = {}
         for prop_name, prop in self.additional_properties.items():
             field_dict[prop_name] = prop.isoformat()
-        field_dict.update({})
 
         return field_dict
 
diff --git a/end_to_end_tests/golden-record/my_test_api_client/models/model_with_recursive_ref_in_additional_properties.py b/end_to_end_tests/golden-record/my_test_api_client/models/model_with_recursive_ref_in_additional_properties.py
index ea5b1211f..2ed2526f5 100644
--- a/end_to_end_tests/golden-record/my_test_api_client/models/model_with_recursive_ref_in_additional_properties.py
+++ b/end_to_end_tests/golden-record/my_test_api_client/models/model_with_recursive_ref_in_additional_properties.py
@@ -18,7 +18,6 @@ def to_dict(self) -> Dict[str, Any]:
         field_dict: Dict[str, Any] = {}
         for prop_name, prop in self.additional_properties.items():
             field_dict[prop_name] = prop.to_dict()
-        field_dict.update({})
 
         return field_dict
 
diff --git a/end_to_end_tests/golden-record/my_test_api_client/models/none.py b/end_to_end_tests/golden-record/my_test_api_client/models/none.py
index 724990e3e..3510497bf 100644
--- a/end_to_end_tests/golden-record/my_test_api_client/models/none.py
+++ b/end_to_end_tests/golden-record/my_test_api_client/models/none.py
@@ -15,7 +15,6 @@ class None_:
     def to_dict(self) -> Dict[str, Any]:
         field_dict: Dict[str, Any] = {}
         field_dict.update(self.additional_properties)
-        field_dict.update({})
 
         return field_dict
 
diff --git a/end_to_end_tests/golden-record/my_test_api_client/models/post_responses_unions_simple_before_complex_response_200a_type_1.py b/end_to_end_tests/golden-record/my_test_api_client/models/post_responses_unions_simple_before_complex_response_200a_type_1.py
index 018926222..601d17cf8 100644
--- a/end_to_end_tests/golden-record/my_test_api_client/models/post_responses_unions_simple_before_complex_response_200a_type_1.py
+++ b/end_to_end_tests/golden-record/my_test_api_client/models/post_responses_unions_simple_before_complex_response_200a_type_1.py
@@ -15,7 +15,6 @@ class PostResponsesUnionsSimpleBeforeComplexResponse200AType1:
     def to_dict(self) -> Dict[str, Any]:
         field_dict: Dict[str, Any] = {}
         field_dict.update(self.additional_properties)
-        field_dict.update({})
 
         return field_dict