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

[python-package] drop Python 3.6 support, use dataclasses #5765

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 15 additions & 10 deletions python-package/lightgbm/callback.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
# coding: utf-8
"""Callbacks library."""
import collections
from dataclasses import dataclass
from functools import partial
from typing import Any, Callable, Dict, List, Tuple, Union
from typing import TYPE_CHECKING, Any, Callable, Dict, List, Optional, Tuple, Union

from .basic import Booster, _ConfigAliases, _LGBM_BoosterEvalMethodResultType, _log_info, _log_warning

if TYPE_CHECKING:
from .engine import CVBooster
Comment on lines +10 to +11
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

See https://mypy.readthedocs.io/en/stable/runtime_troubles.html#import-cycles for an explanation of this.

Adding this pattern to avoid cyclical imports... engine.CVBooster is needed for the type annotation on CallbackEnv.model, but engine.py also tries to import all of callback's contents.

from . import callback


from .basic import _ConfigAliases, _LGBM_BoosterEvalMethodResultType, _log_info, _log_warning

__all__ = [
'early_stopping',
Expand Down Expand Up @@ -39,14 +44,14 @@ def __init__(self, best_iteration: int, best_score: _EvalResultTuple) -> None:


# Callback environment used by callbacks
CallbackEnv = collections.namedtuple(
"CallbackEnv",
["model",
"params",
"iteration",
"begin_iteration",
"end_iteration",
"evaluation_result_list"])
@dataclass
class CallbackEnv:
model: Union[Booster, "CVBooster"]
params: Dict[str, Any]
iteration: int
begin_iteration: int
end_iteration: int
evaluation_result_list: Optional[List[_LGBM_BoosterEvalMethodResultType]]


def _format_eval_result(value: _EvalResultTuple, show_stdv: bool) -> str:
Expand Down
17 changes: 11 additions & 6 deletions python-package/lightgbm/dask.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@
It is based on dask-lightgbm, which was based on dask-xgboost.
"""
import socket
from collections import defaultdict, namedtuple
from collections import defaultdict
from copy import deepcopy
from dataclasses import dataclass
from enum import Enum, auto
from functools import partial
from typing import Any, Dict, Iterable, List, Optional, Tuple, Type, Union
Expand Down Expand Up @@ -37,7 +38,11 @@
_DaskPart = Union[np.ndarray, pd_DataFrame, pd_Series, ss.spmatrix]
_PredictionDtype = Union[Type[np.float32], Type[np.float64], Type[np.int32], Type[np.int64]]

_HostWorkers = namedtuple('_HostWorkers', ['default', 'all'])

@dataclass
class _HostWorkers:
default: str
all_workers: List[str]


class _DatasetNames(Enum):
Expand Down Expand Up @@ -105,9 +110,9 @@ def _group_workers_by_host(worker_addresses: Iterable[str]) -> Dict[str, _HostWo
if not hostname:
raise ValueError(f"Could not parse host name from worker address '{address}'")
if hostname not in host_to_workers:
host_to_workers[hostname] = _HostWorkers(default=address, all=[address])
host_to_workers[hostname] = _HostWorkers(default=address, all_workers=[address])
else:
host_to_workers[hostname].all.append(address)
host_to_workers[hostname].all_workers.append(address)
return host_to_workers


Expand All @@ -124,7 +129,7 @@ def _assign_open_ports_to_workers(
"""
host_ports_futures = {}
for hostname, workers in host_to_workers.items():
n_workers_in_host = len(workers.all)
n_workers_in_host = len(workers.all_workers)
host_ports_futures[hostname] = client.submit(
_find_n_open_ports,
n=n_workers_in_host,
Expand All @@ -135,7 +140,7 @@ def _assign_open_ports_to_workers(
found_ports = client.gather(host_ports_futures)
worker_to_port = {}
for hostname, workers in host_to_workers.items():
for worker, port in zip(workers.all, found_ports[hostname]):
for worker, port in zip(workers.all_workers, found_ports[hostname]):
worker_to_port[worker] = port
return worker_to_port

Expand Down
2 changes: 1 addition & 1 deletion python-package/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -349,7 +349,7 @@ def run(self) -> None:
description='LightGBM Python Package',
long_description=readme,
long_description_content_type='text/x-rst',
python_requires='>=3.6',
python_requires='>=3.7',
install_requires=[
'wheel',
'numpy',
Expand Down