@@ -318,10 +318,10 @@ access the names of those built-in events by importing from ``homeassistant.cons
318318
319319 from homeassistant.const import EVENT_CALL_SERVICE
320320
321- Function Decorators
322- -------------------
321+ Function Trigger Decorators
322+ ---------------------------
323323
324- There are three decorators for defining state, time and event triggers and two decorators for
324+ There are four decorators for defining state, time, event and MQTT triggers, and two decorators for
325325defining whether any trigger actually causes the function to run (i.e., is active), based on
326326state-based expressions or one or more time-windows. The decorators should appear immediately before
327327the function they refer to. A single function can have any or all of the decorator types specified,
@@ -715,18 +715,6 @@ the message arrived on.
715715NOTE: The `MQTT Integration in Home Assistant <https://www.home-assistant.io/integrations/mqtt/ >`__
716716must be set up to use ``@mqtt_trigger ``.
717717
718- @task_unique
719- ^^^^^^^^^^^^
720-
721- .. code :: python
722-
723- @task_unique (task_name, kill_me = False )
724-
725- This decorator is equivalent to calling ``task.unique() `` at the start of the function when that
726- function is triggered. Like all the decorators, if the function is called directly from another
727- Python function, this decorator has no effect. See `this section <#task-unique-function >`__ for more
728- details.
729-
730718@state_active
731719^^^^^^^^^^^^^
732720
@@ -791,6 +779,61 @@ true if the current time doesn’t match any of the “not” (negative) specifi
791779allows multiple arguments with and without ``not ``. The condition will be met if the current time
792780matches any of the positive arguments, and none of the negative arguments.
793781
782+ Other Function Decorators
783+ -------------------------
784+
785+ @pyscript_compile
786+ ^^^^^^^^^^^^^^^^^
787+
788+ By default in pysript all functions are async, so they cannot be used as callbacks or methods
789+ in python packages that expect regular functions, or used with built-in functions like ``map ``
790+ or special class methods that are called by python internals (eg, ``__getattr__ `` or ``__del__ ``).
791+
792+ The ``@pyscript_compile `` decorator causes the function to be treated as native Python and
793+ compiled, which results in a regular python function being defined, and it will run at full
794+ compiled speed.
795+
796+ For example:
797+
798+ .. code :: python
799+
800+ @pyscript_compile
801+ def incr (x ):
802+ return x + 1
803+
804+ x = list (map (incr, [0 , 5 , 10 ]))
805+
806+ sets ``x `` to ``[1, 6, 11] ``.
807+
808+ One use for ``@pyscript_compile `` is to encapsulate functions that block (eg, doing I/O), so they can
809+ be called from ``task.executor ``. This might be a more convenient way to create native python functions
810+ called by ``task.executor ``, instead of moving them all to an external module or package outside
811+ of ``config/pyscript ``. This example reads a file using a native compiled function called by
812+ ``task.executor ``:
813+
814+ .. code :: python
815+
816+ @pyscript_compile
817+ def read_file (file_name ):
818+ try :
819+ with open (file_name, encoding = " utf-8" ) as file_desc:
820+ return file_desc.read(), None
821+ except Exception as exc:
822+ return None , exc
823+
824+ contents, exception = task.executor(read_file, " config/configuration.yaml" )
825+ if exception:
826+ raise exception
827+ log.info(f " contents = { contents} " )
828+
829+ This is an experimental feature and might change in the future. Restrictions include:
830+
831+ - since it's native python, the function cannot use any pyscript-specific features;
832+ but since it's native python, all language features are available, including ``open ``,
833+ ``yield `` etc
834+ - closure (binding) of variables in an inner function with `@pyscript_compile ` doesn't
835+ work; this might be supported in the future
836+
794837@service
795838^^^^^^^^
796839
@@ -828,6 +871,18 @@ Alternatively, if the ``doc_string`` starts with ``yaml``, the rest of the strin
828871 elif action == " fire" and id is not None :
829872 event.fire(id )
830873
874+ @task_unique
875+ ^^^^^^^^^^^^
876+
877+ .. code :: python
878+
879+ @task_unique (task_name, kill_me = False )
880+
881+ This decorator is equivalent to calling ``task.unique() `` at the start of the function when that
882+ function is triggered. Like all the decorators, if the function is called directly from another
883+ Python function, this decorator has no effect. See `this section <#task-unique-function >`__ for more
884+ details.
885+
831886Functions
832887---------
833888
0 commit comments