Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cant use lambda as python planning entity attribute #1283

Open
luxaritas opened this issue Dec 20, 2024 · 0 comments
Open

Cant use lambda as python planning entity attribute #1283

luxaritas opened this issue Dec 20, 2024 · 0 comments
Labels
bug Something isn't working process/needs triage Requires initial assessment of validity, priority etc.

Comments

@luxaritas
Copy link
Contributor

luxaritas commented Dec 20, 2024

Describe the bug
When instantiating a planning entity with a lambda as an attribute, an error will be thrown at runtime

Expected behavior
It should work equivalently to passing a function defined with def

Actual behavior

Traceback (most recent call last):
  File "/home/jonathan/Development/eterna/OpenKnotScorePipeline/repro.py", line 49, in <module>
    solver_factory.build_solver().solve(problem)
  File "/home/jonathan/Development/eterna/OpenKnotScorePipeline/.venv/lib/python3.12/site-packages/timefold/solver/_solver.py", line 115, in solve
    return unwrap_python_like_object(java_solution)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/jonathan/Development/eterna/OpenKnotScorePipeline/.venv/lib/python3.12/site-packages/_jpyinterpreter/conversions.py", line 682, in unwrap_python_like_object
    update_python_object_from_java(python_like_object, clone_map)
  File "/home/jonathan/Development/eterna/OpenKnotScorePipeline/.venv/lib/python3.12/site-packages/_jpyinterpreter/conversions.py", line 740, in update_python_object_from_java
    getattr(java_object, '$writeFieldsToCPythonReference')(JProxy(OpaquePythonReference,
  File "/home/jonathan/Development/eterna/OpenKnotScorePipeline/.venv/lib/python3.12/site-packages/_jpyinterpreter/jvm_setup.py", line 188, in accept
    unwrapped_object = unwrap_python_like_object(value,
                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/jonathan/Development/eterna/OpenKnotScorePipeline/.venv/lib/python3.12/site-packages/_jpyinterpreter/conversions.py", line 593, in unwrap_python_like_object
    out.append(unwrap_python_like_object(item, clone_map, default))
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/jonathan/Development/eterna/OpenKnotScorePipeline/.venv/lib/python3.12/site-packages/_jpyinterpreter/conversions.py", line 682, in unwrap_python_like_object
    update_python_object_from_java(python_like_object, clone_map)
  File "/home/jonathan/Development/eterna/OpenKnotScorePipeline/.venv/lib/python3.12/site-packages/_jpyinterpreter/conversions.py", line 740, in update_python_object_from_java
    getattr(java_object, '$writeFieldsToCPythonReference')(JProxy(OpaquePythonReference,
  File "/home/jonathan/Development/eterna/OpenKnotScorePipeline/.venv/lib/python3.12/site-packages/_jpyinterpreter/jvm_setup.py", line 188, in accept
    unwrapped_object = unwrap_python_like_object(value,
                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/jonathan/Development/eterna/OpenKnotScorePipeline/.venv/lib/python3.12/site-packages/_jpyinterpreter/conversions.py", line 726, in unwrap_python_like_object
    return getattr(importlib.import_module(module_name), function_name)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AttributeError: module '__main__' has no attribute '$_60_$lambda$_62_$'

To Reproduce

from typing import Annotated, Callable
from dataclasses import dataclass, field
from timefold.solver.domain import (
    PlanningVariable,
    PlanningEntityCollectionProperty,
    PlanningScore, ValueRangeProvider,
    planning_entity, planning_solution
)
from timefold.solver.score import HardSoftScore, constraint_provider
from timefold.solver import SolverFactory
from timefold.solver.config import SolverConfig, ScoreDirectorFactoryConfig, TerminationConfig, Duration

@planning_entity
@dataclass
class ResourceConfiguration:
    f: Callable[[int], int]

    cpus: Annotated[int, PlanningVariable(value_range_provider_refs = ['cpu_range'])] = 1

    def get_cpu_range(self) -> Annotated[list[int], ValueRangeProvider(id='cpu_range')]:
        return list(range(1, 5))

@planning_solution
@dataclass
class Schedule:
    resource_configurations: Annotated[list[ResourceConfiguration], PlanningEntityCollectionProperty]

    score: Annotated[HardSoftScore, PlanningScore] = field(default=None)

@constraint_provider
def constraints(factory):
    return [
        factory.for_each(ResourceConfiguration).penalize(HardSoftScore.ONE_HARD).as_constraint('static')
    ]

solver_factory = SolverFactory.create(
    SolverConfig(
        solution_class=Schedule,
        entity_class_list=[ResourceConfiguration],
        score_director_factory_config=ScoreDirectorFactoryConfig(
            constraint_provider_function=constraints
        ),
        termination_config=TerminationConfig(
            spent_limit=Duration(seconds=1)
        )
    )
)
problem = Schedule([ResourceConfiguration(lambda x: x*2, 1)])
solver_factory.build_solver().solve(problem)

Environment

Timefold Solver Version or Git ref:
1.17.0

Output of java -version:

openjdk version "23" 2024-09-17
OpenJDK Runtime Environment (build 23)
OpenJDK 64-Bit Server VM (build 23, mixed mode, sharing)

Output of uname -a or ver:

Linux 6.6.63-1-MANJARO #1 SMP PREEMPT_DYNAMIC Sat Nov 23 02:15:34 UTC 2024 x86_64 GNU/Linux
@luxaritas luxaritas added bug Something isn't working process/needs triage Requires initial assessment of validity, priority etc. labels Dec 20, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working process/needs triage Requires initial assessment of validity, priority etc.
Projects
None yet
Development

No branches or pull requests

1 participant