Skip to content
This repository has been archived by the owner on Jul 17, 2024. It is now read-only.

Commit

Permalink
chore: Change class and decorators locations to match new layout
Browse files Browse the repository at this point in the history
- In general, ai.timefold.solver.core.api.x and its subpackages ->
  timefold.solver.x.

- Exception for ai.timefold.solver.core.api.solver, which it and
  its subpackages -> timefold.solver.

- ai.timefold.solver.core.x and its subpackages -> timefold.solver.x
  (test and config).

- Use dynamic __all__ when not TYPE_CHECKING for score and domain,
  since they have some classes that require the JVM to be started
  When TYPE_CHECKING, there are stub classes that the TYPE_CHECKER
  will see.

- Remove `@incremental_score_calculator` decorator, since it been replaced
  by `IncrementalScoreCalculator` ABC.

- Create an empty Constraint stub so users can reference it in their type
  signatures without importing something from Java.
  • Loading branch information
Christopher-Chianelli committed May 2, 2024
1 parent 2708167 commit d5440fe
Show file tree
Hide file tree
Showing 51 changed files with 334 additions and 381 deletions.
6 changes: 3 additions & 3 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,9 +98,9 @@ def find_stub_files(stub_root: str):
'License :: OSI Approved :: Apache Software License',
'Operating System :: OS Independent'
],
packages=['timefold.solver', 'timefold.solver.api', 'timefold.solver.annotation',
'timefold.solver.config', 'timefold.solver.constraint', 'timefold.solver.score',
'timefold.solver.test', 'timefold.solver.valuerange',
packages=['timefold.solver', 'timefold.solver.domain',
'timefold.solver.config', 'timefold.solver.score',
'timefold.solver.test',
'jpyinterpreter',
'java-stubs', 'jpype-stubs', 'ai-stubs'],
package_dir={
Expand Down
5 changes: 2 additions & 3 deletions tests/test_collectors.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
from timefold.solver.api import *
from timefold.solver.annotation import *
from timefold.solver import *
from timefold.solver.domain import *
from timefold.solver.score import *
from timefold.solver.config import *
from timefold.solver.constraint import *

from dataclasses import dataclass, field
from typing import Annotated, List
Expand Down
5 changes: 2 additions & 3 deletions tests/test_constraint_streams.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
from timefold.solver.api import *
from timefold.solver.annotation import *
from timefold.solver import *
from timefold.solver.domain import *
from timefold.solver.score import *
from timefold.solver.config import *
from timefold.solver.constraint import *

import inspect
import re
Expand Down
3 changes: 1 addition & 2 deletions tests/test_constraint_verifier.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import pytest

from timefold.solver.annotation import *
from timefold.solver.domain import *
from timefold.solver.score import *
from timefold.solver.config import *
from timefold.solver.constraint import *
from timefold.solver.test import *

from typing import Annotated, List
Expand Down
5 changes: 2 additions & 3 deletions tests/test_custom_shadow_variables.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
from typing import Annotated, Optional, List
from dataclasses import dataclass, field

from timefold.solver.api import *
from timefold.solver.annotation import *
from timefold.solver import *
from timefold.solver.domain import *
from timefold.solver.config import *
from timefold.solver.constraint import *
from timefold.solver.score import *


Expand Down
6 changes: 2 additions & 4 deletions tests/test_domain.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
from timefold.solver.api import *
from timefold.solver.annotation import *
from timefold.solver import *
from timefold.solver.domain import *
from timefold.solver.config import *
from timefold.solver.constraint import *
from timefold.solver.score import *
from timefold.solver.valuerange import *

from dataclasses import dataclass, field
from typing import Annotated, Optional, List
Expand Down
4 changes: 2 additions & 2 deletions tests/test_easy_score_calculator.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from timefold.solver.api import *
from timefold.solver.annotation import *
from timefold.solver import *
from timefold.solver.domain import *
from timefold.solver.config import *
from timefold.solver.score import *

Expand Down
6 changes: 2 additions & 4 deletions tests/test_incremental_score_calculator.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
from timefold.solver.api import *
from timefold.solver.annotation import *
from timefold.solver import *
from timefold.solver.domain import *
from timefold.solver.config import *
from timefold.solver.score import *
from timefold.solver.constraint import *

import pytest
from dataclasses import dataclass, field
Expand Down Expand Up @@ -315,7 +314,6 @@ def get_indictment_map(self):

def test_error_message_for_missing_methods():
with pytest.raises(TypeError): # Exact error message from ABC changes between versions
@incremental_score_calculator
class IncrementalScoreCalculatorMissingMethods(IncrementalScoreCalculator):
def before_entity_added(self, entity):
pass
Expand Down
5 changes: 2 additions & 3 deletions tests/test_inverse_relation.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
from timefold.solver.api import *
from timefold.solver.annotation import *
from timefold.solver import *
from timefold.solver.domain import *
from timefold.solver.config import *
from timefold.solver.score import *
from timefold.solver.constraint import *

from dataclasses import dataclass, field
from typing import Annotated, List
Expand Down
5 changes: 2 additions & 3 deletions tests/test_pinning.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
from timefold.solver.api import *
from timefold.solver.annotation import *
from timefold.solver import *
from timefold.solver.domain import *
from timefold.solver.config import *
from timefold.solver.score import *
from timefold.solver.constraint import *

from dataclasses import dataclass, field
from typing import Annotated, List
Expand Down
5 changes: 2 additions & 3 deletions tests/test_solution_manager.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
from timefold.solver.api import *
from timefold.solver.annotation import *
from timefold.solver import *
from timefold.solver.domain import *
from timefold.solver.config import *
from timefold.solver.score import *
from timefold.solver.constraint import *

from dataclasses import dataclass, field
from typing import Annotated, List
Expand Down
3 changes: 1 addition & 2 deletions tests/test_solver_config.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
from timefold.solver.annotation import *
from timefold.solver.domain import *
from timefold.solver.config import *
from timefold.solver.constraint import *
from timefold.solver.score import *

import pathlib
Expand Down
5 changes: 2 additions & 3 deletions tests/test_solver_configuration.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
from timefold.solver.api import *
from timefold.solver.annotation import *
from timefold.solver import *
from timefold.solver.domain import *
from timefold.solver.config import *
from timefold.solver.constraint import *
from timefold.solver.score import *

from dataclasses import dataclass, field
Expand Down
5 changes: 2 additions & 3 deletions tests/test_solver_events.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
from timefold.solver.api import *
from timefold.solver.annotation import *
from timefold.solver import *
from timefold.solver.domain import *
from timefold.solver.config import *
from timefold.solver.constraint import *
from timefold.solver.score import *

from dataclasses import dataclass, field
Expand Down
5 changes: 2 additions & 3 deletions tests/test_solver_factory.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
from timefold.solver.api import *
from timefold.solver.annotation import *
from timefold.solver import *
from timefold.solver.domain import *
from timefold.solver.config import *
from timefold.solver.constraint import *
from timefold.solver.score import *

from dataclasses import dataclass, field
Expand Down
5 changes: 2 additions & 3 deletions tests/test_solver_manager.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
from timefold.solver.api import *
from timefold.solver.annotation import *
from timefold.solver import *
from timefold.solver.domain import *
from timefold.solver.config import *
from timefold.solver.constraint import *
from timefold.solver.score import *

import pytest
Expand Down
5 changes: 2 additions & 3 deletions tests/test_solver_problem_change.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
from timefold.solver.api import *
from timefold.solver.annotation import *
from timefold.solver import *
from timefold.solver.domain import *
from timefold.solver.config import *
from timefold.solver.constraint import *
from timefold.solver.score import *

from dataclasses import dataclass, field
Expand Down
5 changes: 2 additions & 3 deletions tests/test_user_error.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
from timefold.solver.api import *
from timefold.solver.annotation import *
from timefold.solver import *
from timefold.solver.domain import *
from timefold.solver.config import *
from timefold.solver.constraint import *
from timefold.solver.score import *

import pytest
Expand Down
5 changes: 2 additions & 3 deletions tests/test_vehicle_routing.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
from datetime import datetime, timedelta

from timefold.solver.api import *
from timefold.solver.annotation import *
from timefold.solver import *
from timefold.solver.domain import *
from timefold.solver.config import *
from timefold.solver.constraint import ConstraintFactory
from timefold.solver.score import *

from typing import Annotated, List, Optional
Expand Down
17 changes: 8 additions & 9 deletions timefold-solver-python-core/src/main/python/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,15 @@
the JVM. If you want to pass custom arguments to the JVM,
use init before decorators and any timefold.solver.types imports.
"""
import timefold.solver.api as api
import timefold.solver.annotation as annotation
from ._problem_change import *
from ._solution_manager import *
from ._solver import *
from ._solver_factory import *
from ._solver_manager import *

import timefold.solver.domain as domain
import timefold.solver.config as config
import timefold.solver.constraint as constraint
import timefold.solver.score as score
import timefold.solver.test as test
import timefold.solver.valuerange as valuerange

from ._timefold_java_interop import init, set_class_output_directory

__all__ = [# Subpackages
'api', 'annotation', 'config', 'constraint', 'test', 'valuerange',
# Setup Functions
'init', 'set_class_output_directory']
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from .._jpype_type_conversions import PythonBiFunction
from ._jpype_type_conversions import PythonBiFunction
from typing import Awaitable, TypeVar, TYPE_CHECKING
from asyncio import Future, get_event_loop, CancelledError

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
from .._timefold_java_interop import get_class

from abc import ABC, abstractmethod
from typing import TypeVar, Optional, Callable, TYPE_CHECKING, Generic
from types import FunctionType
Expand All @@ -8,13 +6,13 @@
update_python_object_from_java,
translate_python_bytecode_to_java_bytecode)
from jpype import JOverride, JImplements
from traceback import print_exc

if TYPE_CHECKING:
from ai.timefold.solver.core.api.solver.change import (ProblemChangeDirector as _ProblemChangeDirector)

Solution_ = TypeVar('Solution_')


class ProblemChangeDirector:
_delegate: '_ProblemChangeDirector'
_java_solution: Solution_
Expand Down
55 changes: 55 additions & 0 deletions timefold-solver-python-core/src/main/python/_solution_manager.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
from ._solver_factory import SolverFactory
from ._solver_manager import SolverManager
from .score import ScoreAnalysis, ScoreExplanation

from typing import TypeVar, Generic, TYPE_CHECKING, Any

if TYPE_CHECKING:
# These imports require a JVM to be running, so only import if type checking
from .score import Score
from ai.timefold.solver.core.api.solver import SolutionManager as _JavaSolutionManager

Solution_ = TypeVar('Solution_')
ProblemId_ = TypeVar('ProblemId_')
Score_ = TypeVar('Score_', bound='Score')
Justification_ = TypeVar('Justification_', bound='ConstraintJustification')


class SolutionManager(Generic[Solution_]):
_delegate: '_JavaSolutionManager'

def __init__(self, delegate: '_JavaSolutionManager'):
self._delegate = delegate

@staticmethod
def create(solver_factory: SolverFactory[Solution_] | SolverManager[Solution_, Any]) -> \
'SolutionManager[Solution_]':
from ai.timefold.solver.core.api.solver import SolutionManager as JavaSolutionManager
return SolutionManager(JavaSolutionManager.create(solver_factory._delegate))

def update(self, solution: Solution_, solution_update_policy=None) -> 'Score':
# TODO handle solution_update_policy
from jpyinterpreter import convert_to_java_python_like_object, update_python_object_from_java
java_solution = convert_to_java_python_like_object(solution)
out = self._delegate.update(java_solution)
update_python_object_from_java(java_solution)
return out

def analyze(self, solution: Solution_, score_analysis_fetch_policy=None, solution_update_policy=None) \
-> 'ScoreAnalysis':
# TODO handle policies
from jpyinterpreter import convert_to_java_python_like_object
return ScoreAnalysis(self._delegate.analyze(convert_to_java_python_like_object(solution)))

def explain(self, solution: Solution_, solution_update_policy=None) -> 'ScoreExplanation':
# TODO handle policies
from jpyinterpreter import convert_to_java_python_like_object
return ScoreExplanation(self._delegate.explain(convert_to_java_python_like_object(solution)))

def recommend_fit(self, solution: Solution_, entity_or_element, proposition_function,
score_analysis_fetch_policy=None):
# TODO
raise NotImplementedError


__all__ = ['SolutionManager']
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

if TYPE_CHECKING:
# These imports require a JVM to be running, so only import if type checking
from ..score import Score
from .score import Score
from ai.timefold.solver.core.api.solver import Solver as _JavaSolver

Solution_ = TypeVar('Solution_')
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from ._solver import Solver
from ..config import SolverConfig, SolverConfigOverride
from .config import SolverConfig, SolverConfigOverride

from typing import TypeVar, Generic, TYPE_CHECKING
from jpype import JClass
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from ._problem_change import ProblemChange, ProblemChangeWrapper
from ..config import SolverConfigOverride
from .config import SolverConfigOverride
from ._solver_factory import SolverFactory
from ._future import wrap_completable_future

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@
from java.lang import ClassLoader
from ai.timefold.solver.core.api.score.stream import (Constraint as _Constraint,
ConstraintFactory as _ConstraintFactory)
from ai.timefold.solver.core.api.score.calculator import IncrementalScoreCalculator as _IncrementalScoreCalculator
from ai.timefold.solver.core.api.domain.variable import VariableListener as _VariableListener

Solution_ = TypeVar('Solution_')
ProblemId_ = TypeVar('ProblemId_')
Expand Down

This file was deleted.

8 changes: 0 additions & 8 deletions timefold-solver-python-core/src/main/python/api/__init__.py

This file was deleted.

Loading

0 comments on commit d5440fe

Please sign in to comment.