Skip to content

Conversation

dmamelin
Copy link
Contributor

@dmamelin dmamelin commented Oct 15, 2025

This PR is a reworked and improved version of pyscript_autocomplete.
Better docstrings and more accurate type definitions for the Pyscript runtime and for Home Assistant domains, services, and entities with attributes.

How it works:

  • Entity collection: pyscript.generate_stubs reads the HA entity registry, skips disabled entries, and records each entity along with its attributes. Attributes with names that aren’t valid Python identifiers are listed and excluded from the final code.
  • Entity class generation: For each domain, a _domain_state class (subclass of StateVal) is created with the discovered attributes. Then a domain class is built where each entity is declared as a field of that state class.
  • Service collection: Using async_get_all_descriptions, all HA service definitions are extracted. The generator converts selectors into python types, handles required/default fields and descriptions, and generates functions both at the domain level (as @staticmethod) and on the entity state class (if the service supports a target).
  • AST-based code generation: Classes, declarations, and functions are constructed using the Python AST to ensure valid syntax, then converted to source with ast.unparse.
  • File writing: The generator copies the bundled pyscript_builtins.py and writes the generated module to /pyscript/modules/stubs/.
  • Ignored imports: from stubs import and from stubs.* import statements are ignored at runtime. Theoretically this could be a breaking change, but in practice, no one keeps real code in stubs.

Example for time domain:

class _time_state(StateVal):

    def set_value(self, time: str):
        """Sets the time.

        Args:
            time: The time to set. Example: 22:15"""
        ...

class time:
    time_settings_test: _time_state

    @staticmethod
    def set_value(*, entity_id: str, time: str):
        """Sets the time.

        Args:
            entity_id: Entity ID
            time: The time to set. Example: 22:15"""
        ...

In my HA installation, the generator produced about 5,900 lines of code, and it works perfectly.
Tested with PyCharm, VS Code, and Studio Code Server.
pycharm

@ALERTua
Copy link
Contributor

ALERTua commented Oct 15, 2025

you rock!

@ALERTua
Copy link
Contributor

ALERTua commented Oct 16, 2025

Executing

action: pyscript.generate_stubs
data: {}

resulted in

status: Error
message: " '/config/pyscript/modules/stubs' is not writable."

as /config/pyscript/modules/stubs did not exist.
Manual directory creation fixed the error

status: OK

Other than that, adding

from stubs.pyscript_builtins import *
from stubs.pyscript_generated import *

to my scripts resulted in flawless highlighting!

It would be great to have the highlighting built-in into pyscript!

@dmamelin
Copy link
Contributor Author

dmamelin commented Oct 16, 2025

It would be great to have the highlighting built-in into pyscript!

Yeah, without proper IDE support, it’s really hard to write automations more complex than turning on a light from a motion sensor :)

@ALERTua
Copy link
Contributor

ALERTua commented Oct 16, 2025

stubs directory creation error was fixed with 75769e3
I have found no more problems.

@craigbarratt
Copy link
Member

Wow, this is impressive! Thanks for the contribution. Still reading through the code, and so far looks great. I'll definitely merge this - hopefully tomorrow afternoon.

@dmamelin
Copy link
Contributor Author

Thanks! I’m glad it looks good so far. I can make any fixes or changes if needed.

@craigbarratt craigbarratt merged commit cbb2f44 into custom-components:master Oct 17, 2025
6 checks passed
@dmamelin dmamelin deleted the feature/stub-generator branch October 18, 2025 15:29
@redlefloh
Copy link

OMG, this is brilliant, thanks so much! Can't wait for it. When will we see this surfacing in HACS?

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.

4 participants