Import Functions

Learn how to import functions from other plugins written in different languages and use them in your own.

In Plugify, the Python language module allows you to import and use functions from plugins written in other languages. This is achieved through runtime-generated synthetic modules, which enable seamless inter-plugin communication. Additionally, stub files (.pyi) can be generated to provide type hints and function signatures for better development experience in IDEs like PyCharm or VSCode.

This guide explains how to import functions in Python and how to use stub files for development.

Overview

When importing functions from another plugin in Python:

  1. Runtime-Generated Modules: Plugify dynamically generates synthetic modules at runtime, allowing you to import and call functions from other plugins directly.
  2. Stub Files for Development: Stub files (.pyi) can be generated to provide type hints and function signatures. These files are not required for runtime execution but are useful for development.
  3. Direct Function Calls: Functions are called directly using the imported synthetic modules.

Importing Functions in Python

Import Synthetic Modules

To import functions from another plugin, use Plugify's import system to load the synthetic module for the target plugin.

plugin.py
import sys
from plugify.plugin import Plugin, Vector2, Vector3, Vector4, Matrix4x4
from plugify.pps import plugin_from_another_language as other_plugin
  • plugin_from_another_language: Replace this with the name of the plugin you want to import functions from.
  • other_plugin: This is the alias for the imported plugin module.

Call the Imported Functions

Once the synthetic module is imported, you can call its functions directly.

Example 1: Calling a Simple Function

plugin.py
def some_function():
    # Call a function from the imported plugin
    other_plugin.ParamCallback(
        111, 
        2.2, 
        5.1234, 
        Vector4(-125.1, -225.2, -325.3, -425.4), 
        [60000000, -700000000, 80000000000], 
        'D', 
        'pink metal', 
        'Y', 
        -100
    )
  • ParamCallback: This is an example function exported by the target plugin. Replace it with the actual function name.
  • Parameters: Pass the required parameters as defined by the function signature.

Example 2: Calling a Function with a Callback Parameter

If the imported function requires a callback as a parameter, you can define the callback in Python and pass it to the function. Here’s an example:

plugin.py
class CallbackHolder:
    @staticmethod
    def mock_func(u32, v3, u_vec):
        # Modify the parameters (passed by reference)
        u32 = 42
        v3 = Vector3(1.0, 2.0, 3.0)
        u_vec = [1, 2, 3]
        # Return the modified values in a tuple
        return None, u32, v3, u_vec

def func_call():
    # Call the imported function with the callback
    result = other_plugin.CallFuncCallback(CallbackHolder.mock_func)
    return result
  • CallFuncCallback: This is an example function that accepts a callback as a parameter.
  • mock_func: This is the callback function defined in Python. It modifies the parameters passed by reference and returns them in a tuple.
  • Return Values: The callback function returns None (for the void return type) and the modified parameters.

Using Stub Files for Development

Stub files (.pyi) are not required for runtime execution but are highly recommended for development. They provide type hints and function signatures, making it easier to understand the available functions and their parameters.

Generating Stub Files

Plugify provides a generator.py script to automatically generate stub files for imported plugins.

Locate the Generator Script:

  • The generator.py script is located in the generator folder of the Python language module.

Run the Generator Script:

  • Open a terminal or command prompt and navigate to the folder containing generator.py.
  • Run the script with the following command:
    python generator.py "path_to_plugin.pplugin" "output_folder"
    
    • path_to_plugin.pplugin: The path to the plugin manifest file (.pplugin) of the plugin you want to import functions from.
    • output_folder: The directory where the generated stub file will be saved.

Example:

python generator.py ./plugins/MyPlugin/MyPlugin.pplugin ./stubs/

Generated Stub File:

  • The script will generate a stub file (e.g., MyPlugin.pyi) in the specified output folder.
  • Example stub file content:
    MyPlugin.pyi
    from collections.abc import Callable
    from enum import IntEnum
    from plugify.plugin import Vector2, Vector3, Vector4, Matrix4x4
    
    # Generated from plugin_from_another_language.pplugin by https://github.com/untrustedmodders/plugify-module-python3.12/blob/main/generator/generator.py
    
    def ParamCallback(a: int, b: float, c: float, d: Vector4, e: list[int], f: str, g: str, h: str, k: int) -> None:
        ...
    

Using Stubs in Your IDE:

  • Place the generated stub file (.pyi) in your project directory (but not in the plugins folder).
  • IDEs like PyCharm and VSCode will use the stub file to provide type hints and autocompletion.

PyCharm Stub Support:

VSCode Stub Support:

  • VSCode supports stub files by configuring the python.analysis.stubPath setting in your workspace or user settings. Add the path to the folder containing your stub files (e.g., ./stubs/) to enable type hints and autocompletion.
  • Example settings.json configuration:
    {
      "python.analysis.stubPath": "./stubs"
    }
    

Notes

  • Stub Files Are Optional: Stub files are only for development and should not be included in your plugin's runtime folder.
  • Runtime Efficiency: Since Python is dynamically typed, function calls are resolved at runtime without the need for pre-compiled headers or stubs.

By following this guide, you can easily import and use functions from other plugins in your Python plugin, while leveraging stub files for a better development experience.