from __future__ import annotations

from typing import Any, Optional

class FunctionCache:
    def __init__(self) -> None: ...
    def convert_with_cache(self, func: Any): ...
    def exist(self, func: Any): ...

def convert_to_static(function: Any): ...

class CacheKey:
    function_spec: Any = ...
    input_args_with_spec: Any = ...
    input_kwargs_with_spec: Any = ...
    class_instance: Any = ...
    kwargs: Any = ...
    def __init__(
        self,
        function_spec: Any,
        input_args_with_spec: Any,
        input_kwargs_with_spec: Any,
        class_instance: Any,
        **kwargs: Any,
    ) -> None: ...
    @classmethod
    def from_func_and_args(cls, function_spec: Any, args: Any, kwargs: Any, class_instance: Any): ...
    def __hash__(self) -> Any: ...
    def __eq__(self, other: Any) -> Any: ...
    def __neq__(self, other: Any): ...

class StaticFunction:
    def __init__(self, function: Any, input_spec: Optional[Any] = ..., **kwargs: Any) -> None: ...
    def train(self) -> None: ...
    def eval(self) -> None: ...
    def __get__(self, instance: Any, owner: Any): ...
    def __call__(self, *args: Any, **kwargs: Any): ...
    def get_concrete_program(self, *args: Any, **kwargs: Any): ...
    def get_traced_count(self): ...
    @property
    def code(self): ...
    @property
    def dygraph_function(self): ...
    @property
    def concrete_program(self): ...
    def concrete_program_specify_input_spec(self, input_spec: Optional[Any] = ..., with_hook: bool = ...): ...
    @property
    def inputs(self): ...
    @property
    def outputs(self): ...
    @property
    def main_program(self): ...
    @property
    def program_cache(self): ...
    @property
    def function_spec(self): ...

class HookHelper:
    func: Any = ...
    class_instance: Any = ...
    with_hook: Any = ...
    need_apply_hook: Any = ...
    def __init__(self, func: Any, class_instance: Any, with_hook: bool = ...) -> None: ...
    def apply_pre_hooks(self, inputs: Any): ...
    def apply_post_hooks(self, inputs: Any, outputs: Any): ...

class ConcreteProgram:
    inputs: Any = ...
    outputs: Any = ...
    main_program: Any = ...
    startup_program: Any = ...
    parameters: Any = ...
    function: Any = ...
    kwargs: Any = ...
    def __init__(
        self,
        inputs: Any,
        outputs: Any,
        parameters: Any,
        function: Any,
        main_program: Any,
        startup_program: Optional[Any] = ...,
        **kwargs: Any,
    ) -> None: ...
    @staticmethod
    def from_func_spec(func_spec: Any, input_spec: Any, input_kwargs_spec: Any, class_instance: Any, **kwargs: Any): ...

class ProgramCache:
    def __init__(self) -> None: ...
    def __getitem__(self, item: Any): ...
    def get_program(self, item: Any): ...
    def last(self): ...
    def __len__(self): ...
    def concrete_programs(self): ...

class ProgramTranslator:
    def __new__(cls, *args: Any, **kwargs: Any): ...
    @classmethod
    def get_instance(cls): ...
    @classmethod
    def reset(cls) -> None: ...
    enable_to_static: bool = ...
    def __init__(self) -> None: ...
    def enable(self, enable_to_static: Any) -> None: ...
    def get_output(self, dygraph_func: Any, *args: Any, **kwargs: Any): ...
    def get_func(self, dygraph_func: Any): ...
    def get_program(self, dygraph_func: Any, *args: Any, **kwargs: Any): ...
    def get_code(self, dygraph_func: Any): ...
    def get_program_cache(self): ...
