microsoft / yardl

Tooling for streaming instrument data
https://microsoft.github.io/yardl/
MIT License
29 stars 5 forks source link

Invalid Python generated for records containing optional generic fields #95

Closed naegelejd closed 8 months ago

naegelejd commented 8 months ago

Using yardl 2d61ba3df57d55d91c4b3e499121b9dc8f923700 with the following minimal model:

MyRecord: !record
  fields:
    myField: RecordWithGenericOptional<string>

RecordWithGenericOptional<T>: !record
  fields:
    value: T?

The generated types.py does not properly initialize the inner record class. See generated classes below:

class RecordWithGenericOptional(typing.Generic[T]):
    value: typing.Optional[T]

    def __init__(self, *,
        value: typing.Optional[T],
    ):
        self.value = value

    ...

class MyRecord:
    my_field: RecordWithGenericOptional[str]

    def __init__(self, *,
        my_field: typing.Optional[RecordWithGenericOptional[str]] = None,
    ):
        self.my_field = my_field if my_field is not None else RecordWithGenericOptional()

    ...

Python throws a TypeError when creating an instance of MyRecord:

In [1]: import combined

In [2]: combined.MyRecord()
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Cell In[2], line 1
----> 1 combined.MyRecord()

File /workspaces/yardl/joe/issue-switch-over-union/python/combined/types.py:45, in MyRecord.__init__(self, my_field)
     42 def __init__(self, *,
     43     my_field: typing.Optional[RecordWithGenericOptional[str]] = None,
     44 ):
---> 45     self.my_field = my_field if my_field is not None else RecordWithGenericOptional()

TypeError: RecordWithGenericOptional.__init__() missing 1 required keyword-only argument: 'value'

In RecordWithGenericOptional.__init__, value should be instantiated with a default value of None because it is Optional.

However, yardl currently omits default values for all generic types: https://github.com/microsoft/yardl/blob/2d61ba3df57d55d91c4b3e499121b9dc8f923700/tooling/internal/python/types/types.go#L181-L187