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

Add utilities for auto-generating param Python types #636

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

philippjfr
Copy link
Member

@philippjfr philippjfr commented Jun 7, 2022

This is an attempt at implementing a solution for #376

Major, major HACKALERT for now as there a large number of unsafe/incomplete details here:

  • Implementations of pytype properties not complete
  • Mapping of Parameterized to ast.ClassDef node not entirely safe
  • Mapping of Parameter to ast.Assign/ast.AnnAssign node not entirely safe
  • Formatting of types returned by pytype property into valid type definition string not safe
    • Handle all built-in types
    • Standardize on int | None or Union[int, None] rather than Optional[int]
  • Insertion of type definition assumes:
    • Default spacing pname =
    • No existing type definitions, i.e. pname: int = will not work
  • Missing handling of imports for inserted type definitions
    • Assumes typing module has been imported. Should eventually check if typing is imported and allow configurability between import typing and from typing import ...
    • Any custom types are not imported (could be handled in many cases by extracting the ClassSelector/List class_ definition from the ast node), but e.g. param.Array -> np.ndarray would require checking if numpy has been imported and if not adding the import.

Further work for viability:

  • Add CLI to run against package/module
  • Add checker to pass/fail if there is type mismatch between parameter defs and type defs
  • Figure out what's needed for creating https://pre-commit.com/ plugin

Example

Here is an example of the types generated for panel.viewable.Layoutable (doc definitions omitted for readability):

class Layoutable(param.Parameterized):
    """
    Layoutable defines shared style and layout related parameters
    for all Panel components with a visual representation.
    """

    align: typing.Any = param.ClassSelector(default='start',
                                class_=(str, tuple))

    aspect_ratio: typing.Any = param.Parameter(default=None)

    background: typing.Any = param.Parameter(default=None)

    css_classes: typing.Optional[typing.List[typing.Any]] = param.List(default=None)

    width: typing.Optional[int] = param.Integer(default=None, bounds=(0, None))

    height: typing.Optional[int] = param.Integer(default=None, bounds=(0, None))

    min_width: typing.Optional[int] = param.Integer(default=None, bounds=(0, None))

    min_height: typing.Optional[int] = param.Integer(default=None, bounds=(0, None))

    max_width: typing.Optional[int] = param.Integer(default=None, bounds=(0, None))

    max_height: typing.Optional[int] = param.Integer(default=None, bounds=(0, None))

    margin: typing.Any = param.Parameter(default=5)

    width_policy: typing.Any = param.ObjectSelector(
        default="auto", objects=['auto', 'fixed', 'fit', 'min', 'max'])

    height_policy: typing.Any = param.ObjectSelector(
        default="auto", objects=['auto', 'fixed', 'fit', 'min', 'max'])

    sizing_mode: typing.Any = param.ObjectSelector(default=None, objects=[
        'fixed', 'stretch_width', 'stretch_height', 'stretch_both',
        'scale_width', 'scale_height', 'scale_both', None])

    visible: bool = param.Boolean(default=True)

@MarcSkovMadsen
Copy link
Collaborator

MarcSkovMadsen commented Jun 8, 2022

Do you handle adding required imports to the top of the module?

That was one of the hard things for me when experimenting with stubs for Panel as you might have to add some deeply nested Bokeh import.

Update: ahh. It's on the todo list.

@MarcSkovMadsen
Copy link
Collaborator

My vote would go for using | over Union if possible.

But it might not matter to the end user not reading the code. VS Code translates to | in tooltips automatically I believe.

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