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

Convert all positional arguments to keyword-only #3270

Merged
merged 19 commits into from Feb 22, 2022

Conversation

higucheese
Copy link
Contributor

Motivation

This PR is based on #2911, but simply changing the order of positional arguments of create_study or load_study can confuse users. So this aims to encourage them to use keyword-only arguments first without any changes to the interface. Once users get used to keyword-only arguments, it gets much easier to align their arguments.

Description of the changes

  • Change all positional arguments of {create,load,delete,copy}_study() to keyword-only arguments.
  • When a caller of {create,load,delete,copy}_study() sets values as positional arguments, the decorator _convert_positional_args converts them to keyword arguments according to the signature of the decorated function and sets a warning.

optuna/study/study.py Outdated Show resolved Hide resolved
@nzw0301 nzw0301 added sprint-20220130 PR from the online sprint event Jan 30, 2022. v3 Issue/PR for Optuna version 3. optuna.study Related to the `optuna.study` submodule. This is automatically labeled by github-actions. labels Jan 30, 2022
@codecov-commenter
Copy link

codecov-commenter commented Jan 30, 2022

Codecov Report

Merging #3270 (8a5eeaa) into master (9595571) will decrease coverage by 0.03%.
The diff coverage is 97.22%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #3270      +/-   ##
==========================================
- Coverage   91.76%   91.73%   -0.04%     
==========================================
  Files         146      155       +9     
  Lines       12091    12167      +76     
==========================================
+ Hits        11095    11161      +66     
- Misses        996     1006      +10     
Impacted Files Coverage Δ
optuna/cli.py 20.56% <ø> (ø)
optuna/integration/allennlp/_pruner.py 84.72% <ø> (ø)
optuna/study/study.py 96.10% <90.00%> (+0.12%) ⬆️
optuna/_convert_positional_args.py 100.00% <100.00%> (ø)
optuna/storages/_heartbeat.py 92.85% <0.00%> (-7.15%) ⬇️
optuna/integration/botorch.py 97.80% <0.00%> (-0.88%) ⬇️
optuna/study/_optimize.py 98.30% <0.00%> (-0.02%) ⬇️
optuna/storages/_redis.py 95.79% <0.00%> (ø)
optuna/samplers/__init__.py 100.00% <0.00%> (ø)
optuna/samplers/_tpe/sampler.py 96.98% <0.00%> (ø)
... and 15 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 9595571...8a5eeaa. Read the comment docs.

@nzw0301
Copy link
Collaborator

nzw0301 commented Jan 30, 2022

Can we add tests for this decorator? experimental decorator's test might be useful.

f"{func.__name__}: Positional arguments are deprecated."
" Please give all values as keyword arguments."
)
for val, arg_name in zip(args, list(signature(func).parameters)):
Copy link
Member

@hvy hvy Jan 30, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given this order-dependent logic, it might be a good idea to leave a code comment (somewhere in _convert_positional_args ?) for maintainers that the order of arguments (although keyword-only) may not be changed at the decorated functions.

Copy link
Member

@hvy hvy Jan 31, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, how about having _convert_positional_args take a sequence of argument names instead of an integer count? Although it'd make the caller side more verbose, it'll be more robust to these types of, possibly unintentional, changes.

@_convert_positional_args(
    previous_positional_arg_names=[
        "storage",
        "sampler",
        "pruner",
        "study_name",
        "direction",
        "load_if_exists"
    ]
)
def create_study(
    *,
    storage: Optional[Union[str, storages.BaseStorage]] = None,
    sampler: Optional["samplers.BaseSampler"] = None,
    pruner: Optional[pruners.BasePruner] = None,
    study_name: Optional[str] = None,
    direction: Optional[Union[str, StudyDirection]] = None,
    load_if_exists: bool = False,
    directions: Optional[Sequence[Union[str, StudyDirection]]] = None,
) -> Study:
    ...

Implemented something like this. Note that this logic does not require the inspect module.
I also included some changes from AssertionError to TypeError. These errors are user-facing so we should probably try sticking to the latter.

def _convert_positional_args(
    *, previous_positional_arg_names: Sequence[str],
) -> Callable[[Callable[..., _T]], Callable[..., _T]]:
    def decorator(func: Callable[..., _T]) -> Callable[..., _T]:
        @wraps(func)
        def wrapper(*args: Any, **kwargs: Any) -> _T:
            # Warn the first thing we do.
            if len(args) >= 1:
                warnings.warn(
                    f"{func.__name__}: Positional arguments are deprecated."
                    " Please give all values as keyword arguments."
                )
            # Raise TypeErrors mimicking Python standard behavior.
            if len(args) > len(previous_positional_arg_names):
                raise TypeError(
                    f"{func.__name__}() takes {len(previous_positional_arg_names)} positional"
                    f" arguments but {len(args)} were given."
                )
            for val, arg_name in zip(args, previous_positional_arg_names):
                if arg_name in kwargs:
                    raise TypeError(
                        f"{func.__name__}() got multiple values for argument '{arg_name}'."
                    )
                kwargs[arg_name] = val
            return func(**kwargs)

        return wrapper

    return decorator

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good! I'll replace assertions with TypeError which can inform users more than them.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Respond in 2ce7150 (add comment) and fdcf2e0 (raise TypeError), f8d64b9 (arg_names as input)

@hvy
Copy link
Member

hvy commented Jan 30, 2022

Was taking a quick look at the CI failure, it seemed unrelated to the change in this PR. 🤔

optuna/study/study.py Outdated Show resolved Hide resolved
@hvy
Copy link
Member

hvy commented Jan 30, 2022

The CI failures

tests/integration_tests/test_pytorch_distributed.py:161: error: Item "None" of "Optional[Study]" has no attribute "ask"
tests/integration_tests/test_pytorch_distributed.py:179: error: Item "None" of "Optional[Study]" has no attribute "ask"
Found 2 errors in 1 file (checked 263 source files)
Error: Process completed with exit code 1.

https://github.com/optuna/optuna/runs/4995573671?check_suite_focus=true

are caused by the changes in this PR, sorry.

Not entire understood the details but using @overload https://mypy.readthedocs.io/en/stable/generics.html#decorator-factories seems to fix the issue, tried verifying it locally.
(C.f. https://www.python.org/dev/peps/pep-0484/ for more about @overload)

Something along

import typing

F = typing.TypeVar('F', bound=Callable[..., Any])

@typing.overload
def _convert_positional_args(__func: F) -> F: ...

@typing.overload
def _convert_positional_args(*, n_positional_args: int = 0) -> Callable[[F], F]: ...

def _convert_positional_args(__func: Callable[..., Any] = None, *, n_positional_args: int = 0):
    def decorator(func: Callable[..., Any]):
        @wraps(func)
        def wrapper(*args, **kwargs) -> Any:
            assert len(args) <= n_positional_args, "Too many positional arguments."
            if len(args) >= 1:
                warnings.warn(
                    f"{func.__name__}: Positional arguments are deprecated."
                    " Please give all values as keyword arguments."
                )
            for val, arg_name in zip(args, list(signature(func).parameters)):
                assert arg_name not in kwargs
                kwargs[arg_name] = val
            return func(**kwargs)
        return wrapper
    if __func is not None:
        return decorator(__func)
    else:
        return decorator

Edit: F should be renamed _F, etc. before being employed. The code is just a demonstration.

@hvy hvy self-assigned this Jan 30, 2022
@toshihikoyanase
Copy link
Member

@nzw0301 Could you continue the review, please?

@higucheese
Copy link
Contributor Author

higucheese commented Jan 31, 2022

In commit 7282913, the most important change is here.

-        def wrapper(*args: Any, **kwargs: Any) -> Any:
+        def wrapper(*args: Any, **kwargs: Any) -> _T:

The typevar _T is inferred as Study for decorated functions, {create,load}_study and None for {delete,copy}_study. Then, a return type of decorated create_study is correctly inferred as Study which has ask() attribute. It was inferred as Optional[Study] before this fix and mypy did not allow calling its ask() without checking if it was not None.

@higucheese
Copy link
Contributor Author

I tried the hvy-san's suggestion using @overload, but it seemed that mypy failed to decide types in _convert_positional_args because there was no return type annotation for functions.
Like,

optuna/study/study.py:59: error: Function is missing a return type annotation
optuna/study/study.py:60: error: Function is missing a return type annotation
optuna/study/study.py:62: error: Function is missing a type annotation for one or more arguments

@higucheese
Copy link
Contributor Author

For the remaining feedbacks, I'll respond after tomorrow.

@hvy
Copy link
Member

hvy commented Jan 31, 2022

Ah, that makes sense. Thanks. 🙇
As long as this private decorator is typed to return Callable[[Callable[..., _T]], Callable[..., _T]], I could in my environment omit the _T return annotation for wrapper and it still worked. Just a side note.

def decorator(func: Callable[..., _T]) -> Callable[..., _T]:
@wraps(func)
def wrapper(*args: Any, **kwargs: Any) -> _T:
assert len(previous_positional_arg_names) <= len(signature(func).parameters), (
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To check previous_positional_arg_names list is valid, I add signature info. of function and compare them here. This helps developers to keep mapping previous signature to new signature, but my concern is that this is just a runtime overhead for users...

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good. With this logic, my understanding is that there's a runtime overhead in each invocation to the decorator function, but we only need to perform this check once, when applying the decorator, i.e. during module import? We can do this moving this assertion to an outer scope, right below def decorator(func ...):.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! Fixed in 9e6b9ad and it works as intended.

@higucheese
Copy link
Contributor Author

I have added decorator tests. Please take a look.

@hvy
Copy link
Member

hvy commented Feb 3, 2022

Left a single comment but logic seems good otherwise.

Cc. @himkt, did you want to verify this with VSCode?

@himkt
Copy link
Member

himkt commented Feb 4, 2022

Screen Shot 2022-02-04 at 12 22 15

Screen Shot 2022-02-04 at 12 23 52

Given study = create_study() study is correctly recognized as Study (before study is recognized as Any). 🎉
Although keyword arguments is correctly displayed (I'm not sure why...), it would not be blocked.

@hvy
Copy link
Member

hvy commented Feb 4, 2022

it would not be blocked.

Sorry, wasn't entire sure what you meant with "blocked" here. Would you mind explaining a bit more? 🙇
And, thanks a lot for the quick verification!

@himkt
Copy link
Member

himkt commented Feb 4, 2022

Sorry for the ambiguous comment @hvy.
I think it is ideal to show keyword only arguments (e.g. FrozenTrial.suggest_float looks like the image below) as well (in create_study, ... is displayed). But I'm not sure if it is possible to show them with decorator so I use "not be blocked".

Screen Shot 2022-02-04 at 14 51 13

@hvy
Copy link
Member

hvy commented Feb 4, 2022

Just got clarified by @himkt that the current behavior fine and that it's not blocked in any sense.
I also think that the logic looks good. Just that we could address https://github.com/optuna/optuna/pull/3270/files#r798350198. @higucheese what do you think?

@higucheese
Copy link
Contributor Author

I have introduced ParamSpec which is officially available in typing since version 3.10 (so typing_extensions is necessary now) and that helps to infer the arguments of the outer function from the arguments of the inner function. Then, all arguments of XXX_study() are properly inferred like
param_spec

8510858 is a fix for argument mismatch caused by the change of XXX_study().

@higucheese
Copy link
Contributor Author

According to https://github.com/optuna/optuna/runs/5075685882, we have to add typing_extensions to requirements (under checking?) and a check if it is available. Are there any rules to introduce new module?

@himkt
Copy link
Member

himkt commented Feb 5, 2022

Thank you @higucheese for investigating and improving typing stuff!

we have to add typing_extensions to requirements (under checking?)

If we add typing_extensions to checking extras, it needs to use optuna._imports for lazy importing. I think it's okay to add it to install_requires because typing_extensions is official package provided by python org and has no external dependencies.

Are there any rules to introduce new module?

We don't have the explicit rule for that and carefully consider for each case.
@hvy What do you think about introducing typing_extensions to install_requires?


log:

> pip install .                                                                                                                                                                                                  2022-02-05 14:45:30
Processing /Users/himkt/work/github.com/himkt/optuna
  Installing build dependencies ... done
...
Successfully installed Mako-1.1.6 MarkupSafe-2.0.1 PrettyTable-3.0.0 PyYAML-6.0 alembic-1.7.6 attrs-21.4.0 autopage-0.5.0 cliff-3.10.0 cmaes-0.8.2 cmd2-2.3.3 colorlog-6.6.0 greenlet-1.1.2 numpy-1.22.2 optuna-3.0.0a1.dev0 packaging-21.3 pbr-5.8.0 pyparsing-3.0.7 pyperclip-1.8.2 scipy-1.7.3 sqlalchemy-1.4.31 stevedore-3.5.0 tqdm-4.62.3 wcwidth-0.2.5
WARNING: You are using pip version 21.3.1; however, version 22.0.3 is available.
You should consider upgrading via the '/Users/himkt/work/github.com/himkt/optuna/venv_tiny/bin/python3 -m pip install --upgrade pip' command.
>
>
> python -c 'import optuna'                                                                                                                                                                                      2022-02-05 14:46:01
Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "/Users/himkt/work/github.com/himkt/optuna/optuna/__init__.py", line 7, in <module>
    from optuna import multi_objective
  File "/Users/himkt/work/github.com/himkt/optuna/optuna/multi_objective/__init__.py", line 2, in <module>
    from optuna.multi_objective import samplers  # NOQA
  File "/Users/himkt/work/github.com/himkt/optuna/optuna/multi_objective/samplers/__init__.py", line 1, in <module>
    from optuna.multi_objective.samplers._adapter import _MultiObjectiveSamplerAdapter  # NOQA
  File "/Users/himkt/work/github.com/himkt/optuna/optuna/multi_objective/samplers/_adapter.py", line 6, in <module>
    from optuna.samplers import BaseSampler
  File "/Users/himkt/work/github.com/himkt/optuna/optuna/samplers/__init__.py", line 1, in <module>
    from optuna.samplers._base import BaseSampler
  File "/Users/himkt/work/github.com/himkt/optuna/optuna/samplers/_base.py", line 8, in <module>
    from optuna.study import Study
  File "/Users/himkt/work/github.com/himkt/optuna/optuna/study/__init__.py", line 4, in <module>
    from optuna.study.study import copy_study
  File "/Users/himkt/work/github.com/himkt/optuna/optuna/study/study.py", line 19, in <module>
    from typing_extensions import ParamSpec
ModuleNotFoundError: No module named 'typing_extensions'

@nzw0301
Copy link
Collaborator

nzw0301 commented Feb 6, 2022

@himkt could you jump in this PR as a reviewer instead of me?

@himkt
Copy link
Member

himkt commented Feb 6, 2022

Sure, assigned!

@nzw0301 nzw0301 removed their assignment Feb 6, 2022
@higucheese
Copy link
Contributor Author

For the suggestion, I am going to do the move by myself if it's no trouble (This PR is not the kind of thing that needs to be merged in a hurry, is it?).

@higucheese
Copy link
Contributor Author

On a side note, certain users unfamiliar with libraries enforcing keyword arguments may find this change a bit obtrusive. Let's keep #2911 open for feedback.

Do we need any comments (or printing info.) to lead users to the issue?

@himkt
Copy link
Member

himkt commented Feb 9, 2022

This PR is not the kind of thing that needs to be merged in a hurry, is it?

Thank you so much, no extra rush. 👍

@higucheese
Copy link
Contributor Author

I moved convert_positional_args to optuna/ with some additional description. PTAL. 🙇

@himkt himkt self-requested a review February 9, 2022 14:55
@hvy
Copy link
Member

hvy commented Feb 11, 2022

Do we need any comments (or printing info.) to lead users to the issue?

Sounds good, I think including the URL to #2911 in the warning message could be user friendly. It'll go against moving this decorator to optuna/, but I'd image we could create a more general issue and change the URL if this decorator is to be applied to other functions outside the study. What do you think? @higucheese , @himkt

Copy link
Member

@hvy hvy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks a lot for the quick updates!

optuna/_convert_positional_args.py Outdated Show resolved Hide resolved
tests/test_convert_positional_args.py Outdated Show resolved Hide resolved
tests/test_convert_positional_args.py Outdated Show resolved Hide resolved
tests/test_convert_positional_args.py Outdated Show resolved Hide resolved
tests/test_convert_positional_args.py Outdated Show resolved Hide resolved
tests/test_convert_positional_args.py Outdated Show resolved Hide resolved
tests/test_convert_positional_args.py Outdated Show resolved Hide resolved
tests/test_convert_positional_args.py Outdated Show resolved Hide resolved
"to_storage",
"to_study_name",
],
warning_stacklevel=3,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

Copy link
Member

@himkt himkt Feb 22, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

[memo]

  • warning_stacklevel == 2 (default)
> python sam.py                                                                                                                                                                                                                    2022-02-22 10:49:18
[I 2022-02-22 10:49:23,077] A new study created in RDB with name: test
/Users/himkt/work/github.com/himkt/optuna/sam.py:5: ExperimentalWarning: copy_study is experimental (supported from v2.8.0). The interface can change in the future.
  optuna.copy_study("test", "sqlite:////tmp/tmp.db", "sqlite:////tmp/tmp2.db")
/Users/himkt/work/github.com/himkt/optuna/optuna/_experimental.py:68: FutureWarning: copy_study(): Please give all values as keyword arguments. See https://github.com/optuna/optuna/issues/3324 for details.
  return func(*args, **kwargs)  # type: ignore
[I 2022-02-22 10:49:23,135] A new study created in RDB with name: test
/Users/himkt/work/github.com/himkt/optuna/optuna/study/study.py:1446: ExperimentalWarning: add_trials is experimental (supported from v2.5.0). The interface can change in the future.
  to_study.add_trials(from_study.get_trials(deepcopy=False))
  • warning_stacklevel == 3
> python sam.py                                                                                                                                                                                                                    2022-02-22 10:49:34
[I 2022-02-22 10:49:37,185] A new study created in RDB with name: test
/Users/himkt/work/github.com/himkt/optuna/sam.py:5: ExperimentalWarning: copy_study is experimental (supported from v2.8.0). The interface can change in the future.
  optuna.copy_study("test", "sqlite:////tmp/tmp.db", "sqlite:////tmp/tmp2.db")
/Users/himkt/work/github.com/himkt/optuna/sam.py:5: FutureWarning: copy_study(): Please give all values as keyword arguments. See https://github.com/optuna/optuna/issues/3324 for details.
  optuna.copy_study("test", "sqlite:////tmp/tmp.db", "sqlite:////tmp/tmp2.db")
[I 2022-02-22 10:49:37,249] A new study created in RDB with name: test
/Users/himkt/work/github.com/himkt/optuna/optuna/study/study.py:1447: ExperimentalWarning: add_trials is experimental (supported from v2.5.0). The interface can change in the future.
  to_study.add_trials(from_study.get_trials(deepcopy=False))

@higucheese
Copy link
Contributor Author

It'll go against moving this decorator to optuna/, but I'd image we could create a more general issue and change the URL if this decorator is to be applied to other functions outside the study.

Sounds good. We can summarize our purpose and historical reasons of this change in the new issue.

Copy link
Member

@hvy hvy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank a lot for the long running PR, LGTM!

Again, I think including the issue url to the warning message could be friendly, it's not a strong opinion though.

@higucheese
Copy link
Contributor Author

Sorry for my late responding. I created #3324 to describe the purpose of these changes and updated the warning comment.

@himkt
Copy link
Member

himkt commented Feb 21, 2022

Thank you for the update! I'll check it tomorrow.

Copy link
Member

@himkt himkt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you so much @higucheese! LGTM.


I just found warning message is repeatedly displayed if stacklevel is 2 (it doesn't happen on an interactive environment). I was concerning the problem of the massive warning as in #3301. But I confirm it doesn't affect other places so I think it is acceptable.

  • warn_stacklevel == 2 (default)
> python main.py                                                                                                                                                                                                                   2022-02-22 10:57:33
/Users/himkt/work/github.com/himkt/optuna/main.py:8: FutureWarning: create_study(): Please give all values as keyword arguments. See https://github.com/optuna/optuna/issues/3324 for details.
  study = optuna.create_study("sqlite:////tmp/tmp.db", study_name="test1")
[I 2022-02-22 10:57:35,472] A new study created in RDB with name: test1
/Users/himkt/work/github.com/himkt/optuna/main.py:9: FutureWarning: create_study(): Please give all values as keyword arguments. See https://github.com/optuna/optuna/issues/3324 for details.
  study = optuna.create_study("sqlite:////tmp/tmp.db", study_name="test2")
[I 2022-02-22 10:57:35,492] A new study created in RDB with name: test2
/Users/himkt/work/github.com/himkt/optuna/optuna/trial/_trial.py:169: FutureWarning: UniformDistribution has been deprecated in v3.0.0. This feature will be removed in v6.0.0. See https://github.com/optuna/optuna/releases/tag/v3.0.0. Use :class:`~optuna.distributions.FloatDistribution` instead.
  distribution = UniformDistribution(low=low, high=high)
/Users/himkt/work/github.com/himkt/optuna/optuna/distributions.py:561: FutureWarning: UniformDistribution has been deprecated in v3.0.0. This feature will be removed in v6.0.0. See https://github.com/optuna/optuna/releases/tag/v3.0.0. Use :class:`~optuna.distributions.FloatDistribution` instead.
  return cls(**json_dict["attributes"])
[I 2022-02-22 10:57:35,523] Trial 0 finished with value: 5.472289124011194 and parameters: {'v': 5.472289124011194}. Best is trial 0 with value: 5.472289124011194.
[I 2022-02-22 10:57:35,540] Trial 1 finished with value: 1.8239470731739338 and parameters: {'v': 1.8239470731739338}. Best is trial 1 with value: 1.8239470731739338.
[I 2022-02-22 10:57:35,556] Trial 2 finished with value: 3.1063082890049643 and parameters: {'v': 3.1063082890049643}. Best is trial 1 with value: 1.8239470731739338.
  • warn_stacklevel == 1
> python main.py                                                                                                                                                                                                                   2022-02-22 10:59:12
/Users/himkt/work/github.com/himkt/optuna/optuna/_convert_positional_args.py:40: FutureWarning: create_study(): Please give all values as keyword arguments. See https://github.com/optuna/optuna/issues/3324 for details.
  warnings.warn(
[I 2022-02-22 10:59:16,198] A new study created in RDB with name: test1
[I 2022-02-22 10:59:16,221] A new study created in RDB with name: test2
/Users/himkt/work/github.com/himkt/optuna/optuna/trial/_trial.py:169: FutureWarning: UniformDistribution has been deprecated in v3.0.0. This feature will be removed in v6.0.0. See https://github.com/optuna/optuna/releases/tag/v3.0.0. Use :class:`~optuna.distributions.FloatDistribution` instead.
  distribution = UniformDistribution(low=low, high=high)
/Users/himkt/work/github.com/himkt/optuna/optuna/distributions.py:561: FutureWarning: UniformDistribution has been deprecated in v3.0.0. This feature will be removed in v6.0.0. See https://github.com/optuna/optuna/releases/tag/v3.0.0. Use :class:`~optuna.distributions.FloatDistribution` instead.
  return cls(**json_dict["attributes"])
[I 2022-02-22 10:59:16,259] Trial 0 finished with value: 1.4824433429684192 and parameters: {'v': 1.4824433429684192}. Best is trial 0 with value: 1.4824433429684192.
[I 2022-02-22 10:59:16,278] Trial 1 finished with value: 4.64190930455168 and parameters: {'v': 4.64190930455168}. Best is trial 0 with value: 1.4824433429684192.
[I 2022-02-22 10:59:16,297] Trial 2 finished with value: 0.16982925381998415 and parameters: {'v': 0.16982925381998415}. Best is trial 2 with value: 0.16982925381998415.
diff --git a/optuna/_convert_positional_args.py b/optuna/_convert_positional_args.py
index cfcd6b4b4..f9936e93b 100644
--- a/optuna/_convert_positional_args.py
+++ b/optuna/_convert_positional_args.py
@@ -36,6 +36,7 @@ def convert_positional_args(
         def converter_wrapper(*args: Any, **kwargs: Any) -> _T:

             if len(args) >= 1:
+                warning_stacklevel = 1
                 warnings.warn(
                     f"{func.__name__}(): Please give all values as keyword arguments."
                     " See https://github.com/optuna/optuna/issues/3324 for details.",

@himkt himkt added this to the v3.0.0-b0 milestone Feb 22, 2022
@himkt himkt merged commit 7278248 into optuna:master Feb 22, 2022
@himkt himkt added the feature Change that does not break compatibility, but affects the public interfaces. label Feb 22, 2022
@hvy
Copy link
Member

hvy commented Feb 24, 2022

Thanks @himkt for the review, and again @higucheese for the PR.
Not entirely sure but maybe it's because with this deeper stack level, the warning/stack start to differ, and thus treated as different warnings, with the code that you provide. Study names differ.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature Change that does not break compatibility, but affects the public interfaces. optuna.study Related to the `optuna.study` submodule. This is automatically labeled by github-actions. sprint-20220130 PR from the online sprint event Jan 30, 2022. v3 Issue/PR for Optuna version 3.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants