Skip to content
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

Tool for generating schema type annotations #7186

Open
wants to merge 7 commits into
base: master
Choose a base branch
from

Conversation

aljazerzen
Copy link
Contributor

@aljazerzen aljazerzen commented Apr 12, 2024

Our schema classes have generated getter methods for each of the fields:

class Pointer:
    source = so.SchemaField(
        so.InheritingObject,
        default=None, compcoef=None,
        inheritable=False
    )
 

    # this is auto generated by a meta class in objects.py
    def get_source(schema: s_schema.Schema) -> objects.InheritingObject: ...

This PR adds a tool that generates .pyi files in edb/schema/, which contain definitions for all of these generated getters.


We do have mypy extension that already picks-up these getters, even without .pyi definitions.

Regardless, this .pyi approach is useful because language servers (PyLance) cannot use mypy extension. Now, "go to definition", "show usages" and other code actions work.

There is a few drawbacks:

  • PyLance will not look at .pyi file when editing associated .py file. They suggest merging the two files.
  • In this example:
    subjexpr = constr.get_subjectexpr(ctx.env.schema)
    ... PyLance will understand that get_subjectexpr returns Expression, but it will infer type of subjexpr to be Any. What?

Because of these drawbacks, #7166 is still useful.

@aljazerzen aljazerzen changed the title schema type annotations Tool for generating schema type annotations Apr 12, 2024
@aljazerzen
Copy link
Contributor Author

The verdict here is:

  • we want this, but working better. This would best be done with these .pyi files being actual
    .py files in edb/schema/generated/ and the base classes adding the generated type-annotation classes as a mixin.

    # edb/schema/pointers.py
    
    class Pointer(..., PointerMixin):
        source = so.SchemaField(
          so.InheritingObject,
          default=None, compcoef=None,
          inheritable=False
        )
    
    # edb/schema/generated/pointers.py
    class PointerMixin:
        def get_source(schema: Schema) -> so.InheritingObject: ...
  • alternatively, we could stop creating these functions at run-time and just generate them in the mixin classes:

    # edb/schema/pointers.py
    
    class Pointer(..., PointerMixin):
        source = so.SchemaField(
          so.InheritingObject,
          default=None, compcoef=None,
          inheritable=False
        )
    
    # edb/schema/generated/pointers.py
    class PointerMixin:
        def get_source(self, schema: Schema) -> so.InheritingObject:
            self.get_field_value('source', schema)

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.

None yet

1 participant