Repository: optuna/optuna
Pull request: Add `number` property to `FixedTrial` and `BaseTrial`.
This PR adds `number` property to FixedTrial and BaseTrial.
The constructor of FixedTrial is changed to accept the `number` argument to make testings easier.

This PR resolves #426.

Problem statement:
"number" with FixedTrial might be useful
When testing optuna objective, `FixedTrial` are suggested to be used.
And, when saving machine learning models, `Trial.number` are suggested to be used to identify the trial.
However, `FixedTrial` don't have `number`/`trial_id` feature which prevents testing of objective.
Thus adding mock function of `number` might be helpful for testing.

Hints from issue discussion:
Thank you for your request.
We agree with your opinion and would like to add `number` method (property) to `BaseTrial` and `FixedTrial` classes.
(Conversely, `trial_id` property will be removed from `Trial` class in the future because the direct access to the ID by users has been deprecated.)
I added "contribution-welcome" label to this issue.

Commit message: Add number property to `trial.BaseTrial` interface.

Patch to review:
diff --git a/optuna/trial.py b/optuna/trial.py
index 3edf5e9f93a..551b3f02548 100644
--- a/optuna/trial.py
+++ b/optuna/trial.py
@@ -109,6 +109,12 @@ def datetime_start(self):
 
         raise NotImplementedError
 
+    @property
+    def number(self):
+        # type: () -> int
+
+        raise NotImplementedError
+
 
 class Trial(BaseTrial):
     """A trial is a process of evaluating an objective function.
@@ -927,8 +933,8 @@ def objective(trial):
 
     """
 
-    def __init__(self, params):
-        # type: (Dict[str, Any]) -> None
+    def __init__(self, params, number=0):
+        # type: (Dict[str, Any], int) -> None
 
         self._params = params
         self._suggested_params = {}  # type: Dict[str, Any]
@@ -936,6 +942,7 @@ def __init__(self, params):
         self._user_attrs = {}  # type: Dict[str, Any]
         self._system_attrs = {}  # type: Dict[str, Any]
         self._datetime_start = datetime.now()
+        self._number = number
 
     def suggest_float(self, name, low, high, *, log=False):
         # type: (str, float, float, bool) -> float
@@ -1050,6 +1057,12 @@ def datetime_start(self):
 
         return self._datetime_start
 
+    @property
+    def number(self):
+        # type: () -> int
+
+        return self._number
+
 
 def _adjust_discrete_uniform_high(name, low, high, q):
     # type: (str, float, float, float) -> float
diff --git a/tests/test_trial.py b/tests/test_trial.py
index a3e8cec47fa..f655bf21bec 100644
--- a/tests/test_trial.py
+++ b/tests/test_trial.py
@@ -421,6 +421,14 @@ def test_fixed_trial_datetime_start():
     assert trial.datetime_start is not None
 
 
+def test_fixed_trial_number():
+    # type: () -> None
+
+    params = {"x": 1}
+    trial = FixedTrial(params, 2)
+    assert trial.number == 2
+
+
 @parametrize_storage
 def test_relative_parameters(storage_init_func):
     # type: (typing.Callable[[], storages.BaseStorage]) -> None


Code review comments:
diff_hunk: @@ -109,6 +109,12 @@ def datetime_start(self):
 
         raise NotImplementedError
 
+    @property
+    def number(self):
+        # type: () -> int
path: optuna/trial.py
text: @user1:
Optuna dropped Python2 support and we can use a function annotation now. Please use it instead of the type comment. (See https://github.com/optuna/optuna/issues/711)
```suggestion
    def number(self) -> int:
```

@author:
Thank you for pointing it out. I resolved it.

diff_hunk: @@ -1050,6 +1057,12 @@ def datetime_start(self):
 
         return self._datetime_start
 
+    @property
+    def number(self):
+        # type: () -> int
path: optuna/trial.py
text: @user1:
ditto.
```suggestion
    def number(self) -> int:
```

diff_hunk: @@ -421,6 +421,14 @@ def test_fixed_trial_datetime_start():
     assert trial.datetime_start is not None
 
 
+def test_fixed_trial_number():
+    # type: () -> None
path: tests/test_trial.py
text: @user1:
ditto.

```suggestion
def test_fixed_trial_number() -> None:
```