Allow generating a Python model class even if it's just an alias for another schema #1104
Replies: 2 comments 1 reply
-
I have spiked a rough implementation of this, btw— I don't think it is terribly difficult. |
Beta Was this translation helpful? Give feedback.
-
This sounds like a great idea, and actually I wonder if we should make this the only behavior (as a breaking change) to avoid sharp edges for future users. It would also greatly simplify #1103 it seems like. It was a long time ago, but I believe the reason we generated aliases was to work around a behavior with a particular server framework which was auto-generating new types per-endpoint instead of re-using the same definition—causing unnecessary noise in generated code. However, I think generating aliases doesn't align with the design of this generator in a few ways, now:
So unless anyone has a good reason why we should keep aliasing (other than backwards compatibility), I'd suggest we go ahead with removing it to simplify everything. |
Beta Was this translation helpful? Give feedback.
-
Given these two schemas—
—the parser's current behavior is to treat
Cat
as simply an alias forAnimal
. It does not get its own Python class, and if any endpoints refer toCat
, the generated code for them simply uses theAnimal
class instead.That behavior is clear enough, but I think it is arguably not always desirable.
Suppose I'm designing an API where there are several kinds of animals, and they all have the same basic properties defined by Animal. At first, I may not have implemented any properties beyond those common ones; there's no logical difference between the Cat model and Animal. But I might still want to be able to distinguish between Animal and Cat in type annotations in my code, to keep track of when I am doing cat-specific things. For the same reason, I might expect that the generated methods for cat-related endpoints would take or return a Cat rather than an Animal. But with the current implementation, that's not an option.
Now imagine that I decide to add an optional property that only exists for Cat:
Now if I regenerate a client from this spec, I will see a separate Cat class, and the endpoint methods related to cats will now use this class instead of Animal. That's a fairly large change— and potentially a breaking one, since there is no subclass relationship between Cat and Animal in the generated code so mypy will see them as entirely incompatible types.
Another, more basic rationale for wanting to keep these types distinct is: the author of the spec chose to define them with separate names. Regardless of why they chose to do so, that is information that's in the spec, and it's probably meant to tell users something about the intended usage. But we're currently discarding it.
I don't think that the
class_overrides
option serves as a workaround for this: it allows you to rename a class, but only if we were already going to generate Python code for that class. So I'm recommending adding a new boolean config option (not sure of the name, maybealways_generate_classes
) that would cause a Cat class to be generated in this case— keeping the default behavior unchanged for backward compatibility.Beta Was this translation helpful? Give feedback.
All reactions