diff --git a/ioh/__init__.pyi b/ioh/__init__.pyi index 09f407e4..5f8c3d29 100644 --- a/ioh/__init__.pyi +++ b/ioh/__init__.pyi @@ -28,7 +28,7 @@ class ProblemClass(enum.Enum): def problems(self): ... def get_problem(fid: int | str, instance: int = 1, dimension: int = 5, problem_class: ProblemClass = ...) -> ProblemType: ... -def wrap_problem(function: typing.Callable[[numpy.typing.NDArray], float], name: str = None, problem_class: ProblemClass = ..., dimension: int = 5, instance: int = 1, optimization_type: OptimizationType = ..., lb: VariableType = 0, ub: VariableType = 1, transform_variables: typing.Callable[[numpy.typing.NDArray, int], numpy.typing.NDArray | typing.Sequence[VariableType]] = None, transform_objectives: typing.Callable[[float, int], float] = None, calculate_objective: typing.Callable[[int, int], IntegerSolution | RealSolution] = None, constraints: list[IntegerConstraint | RealConstraint] = None) -> ProblemType: ... +def wrap_problem(function: typing.Callable[[numpy.typing.NDArray], float], name: str | None = None, problem_class: ProblemClass = ..., dimension: int = 5, instance: int = 1, optimization_type: OptimizationType = ..., lb: VariableType = 0, ub: VariableType = 1, transform_variables: typing.Callable[[numpy.typing.NDArray, int], numpy.typing.NDArray | typing.Sequence[VariableType]] | None = None, transform_objectives: typing.Callable[[float, int], float] | None = None, calculate_objective: typing.Callable[[int, int], IntegerSolution | RealSolution] | None = None, constraints: list[IntegerConstraint | RealConstraint] | None = None) -> ProblemType: ... def get_problem_id(problem_name: str, problem_class: ProblemClass) -> int: ... class Experiment: @@ -50,10 +50,10 @@ class Experiment: remove_data: Incomplete enforce_bounds: Incomplete old_logger: Incomplete - def __init__(self, algorithm: typing.Any, fids: list[int], iids: list[int], dims: list[int], reps: int = 1, problem_class: ProblemClass = ..., njobs: int = 1, logged: bool = True, logger_triggers: list[logger.trigger.Trigger] = ..., logger_additional_properties: list[logger.property.AbstractProperty] = [], output_directory: str = './', folder_name: str = 'ioh_data', algorithm_name: str = None, algorithm_info: str = 'algorithm_info', store_positions: bool = False, experiment_attributes: dict[str, str] = {}, run_attributes: list[str] = [], logged_attributes: list[str] = [], merge_output: bool = True, zip_output: bool = True, remove_data: bool = False, enforce_bounds: bool = False, old_logger: bool = False) -> None: ... + def __init__(self, algorithm: typing.Any, fids: list[int], iids: list[int], dims: list[int], reps: int = 1, problem_class: ProblemClass = ..., njobs: int = 1, logged: bool = True, logger_triggers: list[logger.trigger.Trigger] = ..., logger_additional_properties: list[logger.property.AbstractProperty] = [], output_directory: str = './', folder_name: str = 'ioh_data', algorithm_name: str | None = None, algorithm_info: str = 'algorithm_info', store_positions: bool = False, experiment_attributes: dict[str, str] = {}, run_attributes: list[str] = [], logged_attributes: list[str] = [], merge_output: bool = True, zip_output: bool = True, remove_data: bool = False, enforce_bounds: bool = False, old_logger: bool = False) -> None: ... def evaluate(self, ii: int, job: tuple[int, int, int]): ... - def apply(self, algorithm: any, problem: ProblemType): ... - def add_custom_problem(self, p: callable, name: str = None, **kwargs): ... + def apply(self, algorithm: typing.Any, problem: ProblemType): ... + def add_custom_problem(self, p: typing.Callable[..., typing.Any], name: str | None = None, **kwargs): ... def merge_output_to_single_folder(self, prefix: str, target_folder: str): ... def merge_tmp_folders(self) -> None: ... def run(self): ... diff --git a/ioh/iohcpp/__init__.pyi b/ioh/iohcpp/__init__.pyi index 1ecbee63..9615a9ad 100644 --- a/ioh/iohcpp/__init__.pyi +++ b/ioh/iohcpp/__init__.pyi @@ -705,9 +705,11 @@ class MetaData: def __repr__(self) -> str: ... - def __eq__(self, arg: MetaData, /) -> bool: ... + def __eq__(self, arg: object, /) -> bool: ... - __hash__: None = None + # nanobind stubgen emits the unhashable marker this way; mypy 2.x needs + # the ignore because object.__hash__ is typed as a callable. + __hash__ = None # type: ignore[assignment] class LogInfo: def __init__(self, evaluations: int, raw_y: float, raw_y_best: float, transformed_y: float, transformed_y_best: float, y: float, y_best: float, x: Sequence[float], violations: Sequence[float], penalties: Sequence[float], optimum: RealSolution, has_improved: bool = False) -> None: diff --git a/ioh/iohcpp/logger/__init__.pyi b/ioh/iohcpp/logger/__init__.pyi index 84aeff52..d6d0c717 100644 --- a/ioh/iohcpp/logger/__init__.pyi +++ b/ioh/iohcpp/logger/__init__.pyi @@ -12,10 +12,13 @@ from ioh.iohcpp.logger import ( eaf as eaf, eah as eah, old as old, - property as property, - trigger as trigger + trigger as trigger, ) +# Imported by its full path under a local alias: binding the submodule as +# `property` shadows the builtin decorator the class definitions below need. +import ioh.iohcpp.logger.property as logger_property + class Logger: """Base class for all loggers""" @@ -36,9 +39,9 @@ class Logger: class AbstractLogger(Logger): """Base class for loggers which track properties""" - def __init__(self, triggers: Sequence[trigger.Trigger] = [], properties: Sequence[property.AbstractProperty] = []) -> None: ... + def __init__(self, triggers: Sequence[trigger.Trigger] = [], properties: Sequence[logger_property.AbstractProperty] = []) -> None: ... - def watch(self, arg: property.AbstractProperty, /) -> None: ... + def watch(self, arg: logger_property.AbstractProperty, /) -> None: ... def attach_problem(self, problem: ioh.iohcpp.MetaData) -> None: """attach a problem (MetaData) to a logger""" @@ -55,7 +58,7 @@ class Combine(Logger): def append(self, arg: Logger, /) -> None: ... class FlatFile(AbstractLogger): - def __init__(self, triggers: Sequence[trigger.Trigger], properties: Sequence[property.AbstractProperty], filename: str = 'IOH.dat', output_directory: str | os.PathLike = './', separator: str = '\t', comment: str = '#', no_value: str = 'None', end_of_line: str = '\n', repeat_header: bool = False, store_positions: bool = False, common_header_titles: Sequence[str] = ...) -> None: + def __init__(self, triggers: Sequence[trigger.Trigger], properties: Sequence[logger_property.AbstractProperty], filename: str = 'IOH.dat', output_directory: str | os.PathLike = './', separator: str = '\t', comment: str = '#', no_value: str = 'None', end_of_line: str = '\n', repeat_header: bool = False, store_positions: bool = False, common_header_titles: Sequence[str] = ...) -> None: """ A logger which stores all tracked properties to a file. @@ -96,7 +99,7 @@ class FlatFile(AbstractLogger): """attach a problem (MetaData) to a logger""" @overload - def watch(self, arg: property.AbstractProperty, /) -> None: ... + def watch(self, arg: logger_property.AbstractProperty, /) -> None: ... @overload def watch(self, arg0: object, arg1: str, /) -> None: ... @@ -107,7 +110,7 @@ class FlatFile(AbstractLogger): def __repr__(self) -> str: ... class Store(AbstractLogger): - def __init__(self, triggers: Sequence[trigger.Trigger], properties: Sequence[property.AbstractProperty]) -> None: + def __init__(self, triggers: Sequence[trigger.Trigger], properties: Sequence[logger_property.AbstractProperty]) -> None: """ A logger which stores all tracked properties in memory. @@ -132,7 +135,7 @@ class Store(AbstractLogger): """attach a problem (MetaData) to a logger""" @overload - def watch(self, arg: property.AbstractProperty, /) -> None: ... + def watch(self, arg: logger_property.AbstractProperty, /) -> None: ... @overload def watch(self, arg0: object, arg1: str, /) -> None: @@ -145,7 +148,7 @@ class Store(AbstractLogger): def __repr__(self) -> str: ... class Analyzer(AbstractLogger): - def __init__(self, triggers: Sequence[trigger.Trigger] = ..., additional_properties: Sequence[property.AbstractProperty] = [], root: str | os.PathLike = ..., folder_name: str = 'ioh_data', algorithm_name: str = 'algorithm_name', algorithm_info: str = 'algorithm_info', store_positions: bool = False) -> None: + def __init__(self, triggers: Sequence[trigger.Trigger] = ..., additional_properties: Sequence[logger_property.AbstractProperty] = [], root: str | os.PathLike = ..., folder_name: str = 'ioh_data', algorithm_name: str = 'algorithm_name', algorithm_info: str = 'algorithm_info', store_positions: bool = False) -> None: """ A logger which stores all tracked properties to a file. @@ -195,7 +198,7 @@ class Analyzer(AbstractLogger): """attach a problem (MetaData) to a logger""" @overload - def watch(self, arg: property.AbstractProperty, /) -> None: ... + def watch(self, arg: logger_property.AbstractProperty, /) -> None: ... @overload def watch(self, arg0: object, arg1: str, /) -> None: ... diff --git a/ioh/iohcpp/problem/__init__.pyi b/ioh/iohcpp/problem/__init__.pyi index 5e7cb3a0..3ebd048d 100644 --- a/ioh/iohcpp/problem/__init__.pyi +++ b/ioh/iohcpp/problem/__init__.pyi @@ -34,7 +34,7 @@ class RealSingleObjective: """Remove the specified logger from the problem.""" @overload - def __call__(self, arg: Annotated[NDArray[numpy.float64], dict(shape=(None,), order='C', device='cpu', writable=False)], /) -> float: ... + def __call__(self, arg: Annotated[numpy.ndarray[tuple[int], numpy.dtype[numpy.float64]], dict(order='C', device='cpu', writable=False)], /) -> float: ... @overload def __call__(self, arg: Sequence[float], /) -> float: @@ -52,7 +52,7 @@ class RealSingleObjective: """ @overload - def __call__(self, arg: Annotated[NDArray[numpy.float64], dict(shape=(None, None), order='C', device='cpu', writable=False)], /) -> Annotated[NDArray[numpy.float64], dict(shape=(None,))]: ... + def __call__(self, arg: Annotated[numpy.ndarray[tuple[int, int], numpy.dtype[numpy.float64]], dict(order='C', device='cpu', writable=False)], /) -> Annotated[NDArray[numpy.float64], dict(shape=(None,))]: ... @overload def __call__(self, arg: Sequence[Sequence[float]], /) -> Annotated[NDArray[numpy.float64], dict(shape=(None,))]: @@ -185,7 +185,7 @@ class IntegerSingleObjective: """Remove the specified logger from the problem.""" @overload - def __call__(self, arg: Annotated[NDArray, dict(shape=(None,), order='C', device='cpu')], /) -> float: ... + def __call__(self, arg: Annotated[numpy.ndarray[tuple[int], numpy.dtype[numpy.integer]], dict(order='C', device='cpu')], /) -> float: ... @overload def __call__(self, arg: Sequence[int], /) -> float: @@ -203,7 +203,7 @@ class IntegerSingleObjective: """ @overload - def __call__(self, arg: Annotated[NDArray, dict(shape=(None, None), order='C', device='cpu')], /) -> Annotated[NDArray[numpy.float64], dict(shape=(None,))]: ... + def __call__(self, arg: Annotated[numpy.ndarray[tuple[int, int], numpy.dtype[numpy.integer]], dict(order='C', device='cpu')], /) -> Annotated[NDArray[numpy.float64], dict(shape=(None,))]: ... @overload def __call__(self, arg: Sequence[Sequence[int]], /) -> Annotated[NDArray[numpy.float64], dict(shape=(None,))]: diff --git a/ioh/py.typed b/ioh/py.typed new file mode 100644 index 00000000..e69de29b