Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 25 Mar 2022 13:50:38 GMT
From:      Po-Chuan Hsieh <sunpoet@FreeBSD.org>
To:        ports-committers@FreeBSD.org, dev-commits-ports-all@FreeBSD.org, dev-commits-ports-main@FreeBSD.org
Subject:   git: 331d3b8ebe69 - main - misc/py-xgboost: Fix build with setuptools 58.0.0+
Message-ID:  <202203251350.22PDocXC037212@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch main has been updated by sunpoet:

URL: https://cgit.FreeBSD.org/ports/commit/?id=331d3b8ebe694fa472655db79db12ad1c73ee1b3

commit 331d3b8ebe694fa472655db79db12ad1c73ee1b3
Author:     Po-Chuan Hsieh <sunpoet@FreeBSD.org>
AuthorDate: 2022-03-25 13:33:00 +0000
Commit:     Po-Chuan Hsieh <sunpoet@FreeBSD.org>
CommitDate: 2022-03-25 13:38:17 +0000

    misc/py-xgboost: Fix build with setuptools 58.0.0+
    
    With hat:       python
---
 misc/py-xgboost/Makefile         |   3 +
 misc/py-xgboost/files/patch-2to3 | 375 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 378 insertions(+)

diff --git a/misc/py-xgboost/Makefile b/misc/py-xgboost/Makefile
index 33321c2507ae..ecce53c63555 100644
--- a/misc/py-xgboost/Makefile
+++ b/misc/py-xgboost/Makefile
@@ -35,6 +35,9 @@ POST_PLIST=	fix-plist
 fix-plist: # https://github.com/dmlc/xgboost/issues/5705
 	@${REINPLACE_CMD} 's|.*libxgboost${PYTHON_EXT_SUFFIX}.so$$||' ${TMPPLIST}
 
+post-install:
+	${PYTHON_CMD} -m compileall -d ${PYTHON_SITELIBDIR} ${STAGEDIR}${PYTHON_SITELIBDIR}
+
 do-test: # tests fail w/out CUDA: https://github.com/dmlc/xgboost/issues/6881
 	@cd ${WRKSRC}/.. && ${PYTHON_CMD} -m pytest
 
diff --git a/misc/py-xgboost/files/patch-2to3 b/misc/py-xgboost/files/patch-2to3
new file mode 100644
index 000000000000..54eac41ed210
--- /dev/null
+++ b/misc/py-xgboost/files/patch-2to3
@@ -0,0 +1,375 @@
+--- xgboost/callback.py.orig	2022-01-17 08:52:31 UTC
++++ xgboost/callback.py
+@@ -319,7 +319,7 @@ def _aggcv(rlist):
+             cvmap[(metric_idx, k)].append(float(v))
+     msg = idx
+     results = []
+-    for (metric_idx, k), v in sorted(cvmap.items(), key=lambda x: x[0][0]):
++    for (metric_idx, k), v in sorted(list(cvmap.items()), key=lambda x: x[0][0]):
+         v = numpy.array(v)
+         if not isinstance(msg, STRING_TYPES):
+             msg = msg.decode()
+@@ -595,10 +595,10 @@ class EarlyStopping(TrainingCallback):
+                         evals_log: TrainingCallback.EvalsLog) -> bool:
+         epoch += self.starting_round  # training continuation
+         msg = 'Must have at least 1 validation dataset for early stopping.'
+-        assert len(evals_log.keys()) >= 1, msg
++        assert len(list(evals_log.keys())) >= 1, msg
+         data_name = ''
+         if self.data:
+-            for d, _ in evals_log.items():
++            for d, _ in list(evals_log.items()):
+                 if d == self.data:
+                     data_name = d
+             if not data_name:
+@@ -672,8 +672,8 @@ class EvaluationMonitor(TrainingCallback):
+ 
+         msg: str = f'[{epoch}]'
+         if rabit.get_rank() == self.printer_rank:
+-            for data, metric in evals_log.items():
+-                for metric_name, log in metric.items():
++            for data, metric in list(evals_log.items()):
++                for metric_name, log in list(metric.items()):
+                     stdv: Optional[float] = None
+                     if isinstance(log[-1], tuple):
+                         score = log[-1][0]
+--- xgboost/compat.py.orig	2022-01-17 08:52:31 UTC
++++ xgboost/compat.py
+@@ -48,14 +48,14 @@ except ImportError:
+ 
+ # sklearn
+ try:
+-    from sklearn.base import BaseEstimator
+-    from sklearn.base import RegressorMixin, ClassifierMixin
+-    from sklearn.preprocessing import LabelEncoder
++    from .sklearn.base import BaseEstimator
++    from .sklearn.base import RegressorMixin, ClassifierMixin
++    from .sklearn.preprocessing import LabelEncoder
+ 
+     try:
+-        from sklearn.model_selection import KFold, StratifiedKFold
++        from .sklearn.model_selection import KFold, StratifiedKFold
+     except ImportError:
+-        from sklearn.cross_validation import KFold, StratifiedKFold
++        from .sklearn.cross_validation import KFold, StratifiedKFold
+ 
+     SKLEARN_INSTALLED = True
+ 
+@@ -71,7 +71,7 @@ try:
+         def to_json(self):
+             '''Returns a JSON compatible dictionary'''
+             meta = {}
+-            for k, v in self.__dict__.items():
++            for k, v in list(self.__dict__.items()):
+                 if isinstance(v, np.ndarray):
+                     meta[k] = v.tolist()
+                 else:
+@@ -82,7 +82,7 @@ try:
+             # pylint: disable=attribute-defined-outside-init
+             '''Load the encoder back from a JSON compatible dict.'''
+             meta = {}
+-            for k, v in doc.items():
++            for k, v in list(doc.items()):
+                 if k == 'classes_':
+                     self.classes_ = np.array(v)
+                     continue
+--- xgboost/core.py.orig	2022-01-17 08:52:31 UTC
++++ xgboost/core.py
+@@ -142,7 +142,7 @@ def _expect(expectations, got):
+ 
+ def _log_callback(msg: bytes) -> None:
+     """Redirect logs from native library into Python console"""
+-    print(py_str(msg))
++    print((py_str(msg)))
+ 
+ 
+ def _get_log_callback_func():
+@@ -479,7 +479,7 @@ def _deprecate_positional_args(f):
+     kwonly_args = []
+     all_args = []
+ 
+-    for name, param in sig.parameters.items():
++    for name, param in list(sig.parameters.items()):
+         if param.kind == Parameter.POSITIONAL_OR_KEYWORD:
+             all_args.append(name)
+         elif param.kind == Parameter.KEYWORD_ONLY:
+@@ -1346,7 +1346,7 @@ class Booster(object):
+     def _configure_metrics(self, params: Union[Dict, List]) -> Union[Dict, List]:
+         if isinstance(params, dict) and 'eval_metric' in params \
+            and isinstance(params['eval_metric'], list):
+-            params = dict((k, v) for k, v in params.items())
++            params = dict((k, v) for k, v in list(params.items()))
+             eval_metrics = params['eval_metric']
+             params.pop("eval_metric", None)
+             params = list(params.items())
+@@ -1577,7 +1577,7 @@ class Booster(object):
+         **kwargs
+             The attributes to set. Setting a value to None deletes an attribute.
+         """
+-        for key, value in kwargs.items():
++        for key, value in list(kwargs.items()):
+             if value is not None:
+                 if not isinstance(value, STRING_TYPES):
+                     raise ValueError("Set Attr only accepts string values")
+@@ -1650,7 +1650,7 @@ class Booster(object):
+            value of the specified parameter, when params is str key
+         """
+         if isinstance(params, Mapping):
+-            params = params.items()
++            params = list(params.items())
+         elif isinstance(params, STRING_TYPES) and value is not None:
+             params = [(params, value)]
+         for key, val in params:
+--- xgboost/dask.py.orig	2022-01-17 08:52:31 UTC
++++ xgboost/dask.py
+@@ -49,9 +49,9 @@ from .sklearn import _cls_predict_proba
+ from .sklearn import XGBRanker
+ 
+ if TYPE_CHECKING:
+-    from dask import dataframe as dd
+-    from dask import array as da
+-    import dask
++    from .dask import dataframe as dd
++    from .dask import array as da
++    from . import dask
+     import distributed
+ else:
+     dd = LazyLoader('dd', globals(), 'dask.dataframe')
+@@ -152,7 +152,7 @@ def _start_tracker(n_workers: int) -> Dict[str, Any]:
+ 
+ def _assert_dask_support() -> None:
+     try:
+-        import dask  # pylint: disable=W0621,W0611
++        from . import dask  # pylint: disable=W0621,W0611
+     except ImportError as e:
+         raise ImportError(
+             "Dask needs to be installed in order to use this module"
+@@ -394,7 +394,7 @@ class DaskDMatrix:
+         # [(x0, x1, ..), (y0, y1, ..), ..] in delayed form
+ 
+         # delay the zipped result
+-        parts = list(map(dask.delayed, zip(*parts)))  # pylint: disable=no-member
++        parts = list(map(dask.delayed, list(zip(*parts))))  # pylint: disable=no-member
+         # At this point, the mental model should look like:
+         # [(x0, y0, ..), (x1, y1, ..), ..] in delayed form
+ 
+@@ -414,7 +414,7 @@ class DaskDMatrix:
+ 
+         worker_map: Dict[str, "distributed.Future"] = defaultdict(list)
+ 
+-        for key, workers in who_has.items():
++        for key, workers in list(who_has.items()):
+             worker_map[next(iter(workers))].append(key_to_partition[key])
+ 
+         self.worker_map = worker_map
+@@ -803,7 +803,7 @@ def _dmatrix_from_list_of_parts(
+ async def _get_rabit_args(n_workers: int, client: "distributed.Client") -> List[bytes]:
+     '''Get rabit context arguments from data distribution in DaskDMatrix.'''
+     env = await client.run_on_scheduler(_start_tracker, n_workers)
+-    rabit_args = [f"{k}={v}".encode() for k, v in env.items()]
++    rabit_args = [f"{k}={v}".encode() for k, v in list(env.items())]
+     return rabit_args
+ 
+ # train and predict methods are supposed to be "functional", which meets the
+@@ -930,7 +930,7 @@ async def _train_async(
+ 
+         results = await client.gather(futures, asynchronous=True)
+ 
+-        return list(filter(lambda ret: ret is not None, results))[0]
++        return list([ret for ret in results if ret is not None])[0]
+ 
+ 
+ def train(                      # pylint: disable=unused-argument
+@@ -1579,7 +1579,7 @@ class DaskScikitLearnBase(XGBModel):
+ 
+     def __getstate__(self) -> Dict:
+         this = self.__dict__.copy()
+-        if "_client" in this.keys():
++        if "_client" in list(this.keys()):
+             del this["_client"]
+         return this
+ 
+@@ -1711,7 +1711,7 @@ class DaskXGBRegressor(DaskScikitLearnBase, XGBRegress
+         callbacks: Optional[List[TrainingCallback]] = None,
+     ) -> "DaskXGBRegressor":
+         _assert_dask_support()
+-        args = {k: v for k, v in locals().items() if k not in ("self", "__class__")}
++        args = {k: v for k, v in list(locals().items()) if k not in ("self", "__class__")}
+         return self._client_sync(self._fit_async, **args)
+ 
+ 
+@@ -1814,7 +1814,7 @@ class DaskXGBClassifier(DaskScikitLearnBase, XGBClassi
+         callbacks: Optional[List[TrainingCallback]] = None
+     ) -> "DaskXGBClassifier":
+         _assert_dask_support()
+-        args = {k: v for k, v in locals().items() if k not in ("self", "__class__")}
++        args = {k: v for k, v in list(locals().items()) if k not in ("self", "__class__")}
+         return self._client_sync(self._fit_async, **args)
+ 
+     async def _predict_proba_async(
+@@ -2002,7 +2002,7 @@ class DaskXGBRanker(DaskScikitLearnBase, XGBRankerMixI
+         callbacks: Optional[List[TrainingCallback]] = None
+     ) -> "DaskXGBRanker":
+         _assert_dask_support()
+-        args = {k: v for k, v in locals().items() if k not in ("self", "__class__")}
++        args = {k: v for k, v in list(locals().items()) if k not in ("self", "__class__")}
+         return self._client_sync(self._fit_async, **args)
+ 
+     # FIXME(trivialfis): arguments differ due to additional parameters like group and qid.
+@@ -2067,7 +2067,7 @@ class DaskXGBRFRegressor(DaskXGBRegressor):
+         callbacks: Optional[List[TrainingCallback]] = None
+     ) -> "DaskXGBRFRegressor":
+         _assert_dask_support()
+-        args = {k: v for k, v in locals().items() if k not in ("self", "__class__")}
++        args = {k: v for k, v in list(locals().items()) if k not in ("self", "__class__")}
+         _check_rf_callback(early_stopping_rounds, callbacks)
+         super().fit(**args)
+         return self
+@@ -2131,7 +2131,7 @@ class DaskXGBRFClassifier(DaskXGBClassifier):
+         callbacks: Optional[List[TrainingCallback]] = None
+     ) -> "DaskXGBRFClassifier":
+         _assert_dask_support()
+-        args = {k: v for k, v in locals().items() if k not in ("self", "__class__")}
++        args = {k: v for k, v in list(locals().items()) if k not in ("self", "__class__")}
+         _check_rf_callback(early_stopping_rounds, callbacks)
+         super().fit(**args)
+         return self
+--- xgboost/plotting.py.orig	2022-01-17 08:52:31 UTC
++++ xgboost/plotting.py
+@@ -81,7 +81,7 @@ def plot_importance(booster, ax=None, height=0.2,
+         tuples = sorted(tuples, key=lambda x: x[1])[-max_num_features:]
+     else:
+         tuples = sorted(tuples, key=lambda x: x[1])
+-    labels, values = zip(*tuples)
++    labels, values = list(zip(*tuples))
+ 
+     if ax is None:
+         _, ax = plt.subplots(1, 1)
+@@ -177,13 +177,13 @@ def to_graphviz(booster, fmap='', num_trees=0, rankdir
+     # squash everything back into kwargs again for compatibility
+     parameters = 'dot'
+     extra = {}
+-    for key, value in kwargs.items():
++    for key, value in list(kwargs.items()):
+         extra[key] = value
+ 
+     if rankdir is not None:
+         kwargs['graph_attrs'] = {}
+         kwargs['graph_attrs']['rankdir'] = rankdir
+-    for key, value in extra.items():
++    for key, value in list(extra.items()):
+         if kwargs.get("graph_attrs", None) is not None:
+             kwargs['graph_attrs'][key] = value
+         else:
+--- xgboost/sklearn.py.orig	2022-01-17 08:52:31 UTC
++++ xgboost/sklearn.py
+@@ -455,7 +455,7 @@ class XGBModel(XGBModelBase):
+         booster : a xgboost booster of underlying model
+         """
+         if not self.__sklearn_is_fitted__():
+-            from sklearn.exceptions import NotFittedError
++            from .sklearn.exceptions import NotFittedError
+             raise NotFittedError('need to call fit or load_model beforehand')
+         return self._Booster
+ 
+@@ -476,7 +476,7 @@ class XGBModel(XGBModelBase):
+ 
+         # this concatenates kwargs into parameters, enabling `get_params` for
+         # obtaining parameters from keyword parameters.
+-        for key, value in params.items():
++        for key, value in list(params.items()):
+             if hasattr(self, key):
+                 setattr(self, key, value)
+             else:
+@@ -526,14 +526,14 @@ class XGBModel(XGBModelBase):
+             internal = {}
+             while stack:
+                 obj = stack.pop()
+-                for k, v in obj.items():
++                for k, v in list(obj.items()):
+                     if k.endswith('_param'):
+-                        for p_k, p_v in v.items():
++                        for p_k, p_v in list(v.items()):
+                             internal[p_k] = p_v
+                     elif isinstance(v, dict):
+                         stack.append(v)
+ 
+-            for k, v in internal.items():
++            for k, v in list(internal.items()):
+                 if k in params and params[k] is None:
+                     params[k] = parse_parameter(v)
+         except ValueError:
+@@ -549,7 +549,7 @@ class XGBModel(XGBModelBase):
+             "enable_categorical"
+         }
+         filtered = {}
+-        for k, v in params.items():
++        for k, v in list(params.items()):
+             if k not in wrapper_specific and not callable(v):
+                 filtered[k] = v
+         return filtered
+@@ -568,7 +568,7 @@ class XGBModel(XGBModelBase):
+ 
+     def save_model(self, fname: Union[str, os.PathLike]) -> None:
+         meta = {}
+-        for k, v in self.__dict__.items():
++        for k, v in list(self.__dict__.items()):
+             if k == '_le':
+                 meta['_le'] = self._le.to_json()
+                 continue
+@@ -607,7 +607,7 @@ class XGBModel(XGBModelBase):
+             return
+         meta = json.loads(meta_str)
+         states = {}
+-        for k, v in meta.items():
++        for k, v in list(meta.items()):
+             if k == '_le':
+                 self._le = XGBoostLabelEncoder()
+                 self._le.from_json(v)
+@@ -660,7 +660,7 @@ class XGBModel(XGBModelBase):
+ 
+     def _set_evaluation_result(self, evals_result: TrainingCallback.EvalsLog) -> None:
+         if evals_result:
+-            for val in evals_result.items():
++            for val in list(evals_result.items()):
+                 evals_result_key = list(val[1].keys())[0]
+                 evals_result[val[0]][evals_result_key] = val[1][evals_result_key]
+             self.evals_result_ = evals_result
+@@ -1455,7 +1455,7 @@ class XGBRFClassifier(XGBClassifier):
+         feature_weights: Optional[array_like] = None,
+         callbacks: Optional[List[TrainingCallback]] = None
+     ) -> "XGBRFClassifier":
+-        args = {k: v for k, v in locals().items() if k not in ("self", "__class__")}
++        args = {k: v for k, v in list(locals().items()) if k not in ("self", "__class__")}
+         _check_rf_callback(early_stopping_rounds, callbacks)
+         super().fit(**args)
+         return self
+@@ -1526,7 +1526,7 @@ class XGBRFRegressor(XGBRegressor):
+         feature_weights: Optional[array_like] = None,
+         callbacks: Optional[List[TrainingCallback]] = None
+     ) -> "XGBRFRegressor":
+-        args = {k: v for k, v in locals().items() if k not in ("self", "__class__")}
++        args = {k: v for k, v in list(locals().items()) if k not in ("self", "__class__")}
+         _check_rf_callback(early_stopping_rounds, callbacks)
+         super().fit(**args)
+         return self
+--- xgboost/training.py.orig	2022-01-17 08:52:31 UTC
++++ xgboost/training.py
+@@ -452,7 +452,7 @@ def cv(params, dtrain, num_boost_round=10, nfold=3, st
+         if 'eval_metric' in params:
+             params['eval_metric'] = _metrics
+     else:
+-        params = dict((k, v) for k, v in params.items())
++        params = dict((k, v) for k, v in list(params.items()))
+ 
+     if (not metrics) and 'eval_metric' in params:
+         if isinstance(params['eval_metric'], list):
+@@ -506,7 +506,7 @@ def cv(params, dtrain, num_boost_round=10, nfold=3, st
+             results[key + '-std'].append(std)
+ 
+         if should_break:
+-            for k in results.keys():  # pylint: disable=consider-iterating-dictionary
++            for k in list(results.keys()):  # pylint: disable=consider-iterating-dictionary
+                 results[k] = results[k][:(booster.best_iteration + 1)]
+             break
+     if as_pandas:



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202203251350.22PDocXC037212>