From fbb980d9d3bc3bd2a2a5510279277e05e7c7467e Mon Sep 17 00:00:00 2001 From: Philip Hyunsu Cho Date: Sat, 19 Dec 2020 23:35:13 -0800 Subject: [PATCH] Expand `~` into the home directory on Linux and MacOS (#6531) --- R-package/R/xgb.Booster.R | 1 + R-package/R/xgb.DMatrix.R | 2 ++ R-package/R/xgb.DMatrix.save.R | 1 + R-package/R/xgb.dump.R | 1 + R-package/R/xgb.save.R | 1 + python-package/xgboost/core.py | 18 +++++++++++------- python-package/xgboost/data.py | 3 ++- 7 files changed, 19 insertions(+), 8 deletions(-) diff --git a/R-package/R/xgb.Booster.R b/R-package/R/xgb.Booster.R index acc040c4b81c..426c78a95942 100644 --- a/R-package/R/xgb.Booster.R +++ b/R-package/R/xgb.Booster.R @@ -11,6 +11,7 @@ xgb.Booster.handle <- function(params = list(), cachelist = list(), if (typeof(modelfile) == "character") { ## A filename handle <- .Call(XGBoosterCreate_R, cachelist) + modelfile <- path.expand(modelfile) .Call(XGBoosterLoadModel_R, handle, modelfile[1]) class(handle) <- "xgb.Booster.handle" if (length(params) > 0) { diff --git a/R-package/R/xgb.DMatrix.R b/R-package/R/xgb.DMatrix.R index fb28ed2759ea..1144bb95670b 100644 --- a/R-package/R/xgb.DMatrix.R +++ b/R-package/R/xgb.DMatrix.R @@ -27,6 +27,7 @@ xgb.DMatrix <- function(data, info = list(), missing = NA, silent = FALSE, ...) if (length(data) > 1) stop("'data' has class 'character' and length ", length(data), ".\n 'data' accepts either a numeric matrix or a single filename.") + data <- path.expand(data) handle <- .Call(XGDMatrixCreateFromFile_R, data, as.integer(silent)) } else if (is.matrix(data)) { handle <- .Call(XGDMatrixCreateFromMat_R, data, missing) @@ -65,6 +66,7 @@ xgb.get.DMatrix <- function(data, label = NULL, missing = NA, weight = NULL) { warning("xgboost: label will be ignored.") } if (is.character(data)) { + data <- path.expand(data) dtrain <- xgb.DMatrix(data[1]) } else if (inherits(data, "xgb.DMatrix")) { dtrain <- data diff --git a/R-package/R/xgb.DMatrix.save.R b/R-package/R/xgb.DMatrix.save.R index 85e328a1f0bf..11edec7bc00b 100644 --- a/R-package/R/xgb.DMatrix.save.R +++ b/R-package/R/xgb.DMatrix.save.R @@ -19,6 +19,7 @@ xgb.DMatrix.save <- function(dmatrix, fname) { if (!inherits(dmatrix, "xgb.DMatrix")) stop("dmatrix must be xgb.DMatrix") + fname <- path.expand(fname) .Call(XGDMatrixSaveBinary_R, dmatrix, fname[1], 0L) return(TRUE) } diff --git a/R-package/R/xgb.dump.R b/R-package/R/xgb.dump.R index d79799b3cb19..ba84966001fa 100644 --- a/R-package/R/xgb.dump.R +++ b/R-package/R/xgb.dump.R @@ -66,6 +66,7 @@ xgb.dump <- function(model, fname = NULL, fmap = "", with_stats=FALSE, if (is.null(fname)) { return(model_dump) } else { + fname <- path.expand(fname) writeLines(model_dump, fname[1]) return(TRUE) } diff --git a/R-package/R/xgb.save.R b/R-package/R/xgb.save.R index 1e68cd0adae8..42ecb4153a84 100644 --- a/R-package/R/xgb.save.R +++ b/R-package/R/xgb.save.R @@ -42,6 +42,7 @@ xgb.save <- function(model, fname) { if (inherits(model, "xgb.DMatrix")) " Use xgb.DMatrix.save to save an xgb.DMatrix object." else "") } model <- xgb.Booster.complete(model, saveraw = FALSE) + fname <- path.expand(fname) .Call(XGBoosterSaveModel_R, model$handle, fname[1]) return(TRUE) } diff --git a/python-package/xgboost/core.py b/python-package/xgboost/core.py index 6426be00d190..6288d8a29d97 100644 --- a/python-package/xgboost/core.py +++ b/python-package/xgboost/core.py @@ -645,8 +645,9 @@ def save_binary(self, fname, silent=True): silent : bool (optional; default: True) If set, the output is suppressed. """ + fname = os.fspath(os.path.expanduser(fname)) _check_call(_LIB.XGDMatrixSaveBinary(self.handle, - c_str(os.fspath(fname)), + c_str(fname), ctypes.c_int(silent))) def set_label(self, label): @@ -1677,8 +1678,9 @@ def save_model(self, fname): """ if isinstance(fname, (STRING_TYPES, os.PathLike)): # assume file name + fname = os.fspath(os.path.expanduser(fname)) _check_call(_LIB.XGBoosterSaveModel( - self.handle, c_str(os.fspath(fname)))) + self.handle, c_str(fname))) else: raise TypeError("fname must be a string or os PathLike") @@ -1717,8 +1719,9 @@ def load_model(self, fname): if isinstance(fname, (STRING_TYPES, os.PathLike)): # assume file name, cannot use os.path.exist to check, file can be # from URL. + fname = os.fspath(os.path.expanduser(fname)) _check_call(_LIB.XGBoosterLoadModel( - self.handle, c_str(os.fspath(fname)))) + self.handle, c_str(fname))) elif isinstance(fname, bytearray): buf = fname length = c_bst_ulong(len(buf)) @@ -1756,7 +1759,8 @@ def dump_model(self, fout, fmap='', with_stats=False, dump_format="text"): Format of model dump file. Can be 'text' or 'json'. """ if isinstance(fout, (STRING_TYPES, os.PathLike)): - fout = open(os.fspath(fout), 'w') + fout = os.fspath(os.path.expanduser(fout)) + fout = open(fout, 'w') need_close = True else: need_close = False @@ -1790,7 +1794,7 @@ def get_dump(self, fmap='', with_stats=False, dump_format="text"): Format of model dump. Can be 'text', 'json' or 'dot'. """ - fmap = os.fspath(fmap) + fmap = os.fspath(os.path.expanduser(fmap)) length = c_bst_ulong() sarr = ctypes.POINTER(ctypes.c_char_p)() if self.feature_names is not None and fmap == '': @@ -1870,7 +1874,7 @@ def get_score(self, fmap='', importance_type='weight'): importance_type: str, default 'weight' One of the importance types defined above. """ - fmap = os.fspath(fmap) + fmap = os.fspath(os.path.expanduser(fmap)) if getattr(self, 'booster', None) is not None and self.booster not in {'gbtree', 'dart'}: raise ValueError('Feature importance is not defined for Booster type {}' .format(self.booster)) @@ -1963,7 +1967,7 @@ def trees_to_dataframe(self, fmap=''): The name of feature map file. """ # pylint: disable=too-many-locals - fmap = os.fspath(fmap) + fmap = os.fspath(os.path.expanduser(fmap)) if not PANDAS_INSTALLED: raise Exception(('pandas must be available to use this method.' 'Install pandas before calling again.')) diff --git a/python-package/xgboost/data.py b/python-package/xgboost/data.py index 2babeafea2eb..8f555d654f57 100644 --- a/python-package/xgboost/data.py +++ b/python-package/xgboost/data.py @@ -486,7 +486,8 @@ def _is_uri(data): def _from_uri(data, missing, feature_names, feature_types): _warn_unused_missing(data, missing) handle = ctypes.c_void_p() - _check_call(_LIB.XGDMatrixCreateFromFile(c_str(os.fspath(data)), + data = os.fspath(os.path.expanduser(data)) + _check_call(_LIB.XGDMatrixCreateFromFile(c_str(data), ctypes.c_int(1), ctypes.byref(handle))) return handle, feature_names, feature_types