Unverified Commit 3fad53bc authored by James Lamb's avatar James Lamb Committed by GitHub
Browse files

[R-package] make finalize() in R6 classes private (#6833)

parent 604e2c5e
......@@ -53,7 +53,7 @@ Suggests:
Depends:
R (>= 3.5)
Imports:
R6 (>= 2.0),
R6 (>= 2.4.0),
data.table (>= 1.9.6),
graphics,
jsonlite (>= 1.0),
......
......@@ -11,16 +11,6 @@ Booster <- R6::R6Class(
record_evals = list(),
data_processor = NULL,
# Finalize will free up the handles
finalize = function() {
.Call(
LGBM_BoosterFree_R
, private$handle
)
private$handle <- NULL
return(invisible(NULL))
},
# Initialize will create a starter booster
initialize = function(params = list(),
train_set = NULL,
......@@ -711,6 +701,17 @@ Booster <- R6::R6Class(
set_objective_to_none = FALSE,
train_set_version = 0L,
fast_predict_config = list(),
# finalize() will free up the handles
finalize = function() {
.Call(
LGBM_BoosterFree_R
, private$handle
)
private$handle <- NULL
return(invisible(NULL))
},
# Predict data
inner_predict = function(idx) {
......
......@@ -30,16 +30,6 @@ Dataset <- R6::R6Class(
cloneable = FALSE,
public = list(
# Finalize will free up the handles
finalize = function() {
.Call(
LGBM_DatasetFree_R
, private$handle
)
private$handle <- NULL
return(invisible(NULL))
},
# Initialize will create a starter dataset
initialize = function(data,
params = list(),
......@@ -210,7 +200,7 @@ Dataset <- R6::R6Class(
if (is.null(private$raw_data)) {
stop(paste0(
"Attempting to create a Dataset without any raw data. "
, "This can happen if you have called Dataset$finalize() or if this Dataset was saved with saveRDS(). "
, "This can happen if the Dataset's finalizer was called or if this Dataset was saved with saveRDS(). "
, "To avoid this error in the future, use lgb.Dataset.save() or "
, "Dataset$save_binary() to save lightgbm Datasets."
))
......@@ -608,7 +598,7 @@ Dataset <- R6::R6Class(
# If updating failed but raw data is available, modify the params
# on the R side and re-set ("deconstruct") the Dataset
private$params <- new_params
self$finalize()
private$finalize()
})
}
return(invisible(self))
......@@ -649,7 +639,7 @@ Dataset <- R6::R6Class(
private$categorical_feature <- categorical_feature
# Finalize and return self
self$finalize()
private$finalize()
return(invisible(self))
},
......@@ -681,7 +671,7 @@ Dataset <- R6::R6Class(
private$reference <- reference
# Finalize and return self
self$finalize()
private$finalize()
return(invisible(self))
},
......@@ -713,6 +703,16 @@ Dataset <- R6::R6Class(
info = NULL,
version = 0L,
# finalize() will free up the handles
finalize = function() {
.Call(
LGBM_DatasetFree_R
, private$handle
)
private$handle <- NULL
return(invisible(NULL))
},
get_handle = function() {
# Get handle and construct if needed
......@@ -749,7 +749,7 @@ Dataset <- R6::R6Class(
private$predictor <- predictor
# Finalize and return self
self$finalize()
private$finalize()
return(invisible(self))
}
......
......@@ -8,24 +8,6 @@ Predictor <- R6::R6Class(
cloneable = FALSE,
public = list(
# Finalize will free up the handles
finalize = function() {
# Check the need for freeing handle
if (private$need_free_handle) {
.Call(
LGBM_BoosterFree_R
, private$handle
)
private$handle <- NULL
}
return(invisible(NULL))
},
# Initialize will create a starter model
initialize = function(modelfile, params = list(), fast_predict_config = list()) {
private$params <- .params2str(params = params)
......@@ -531,5 +513,17 @@ Predictor <- R6::R6Class(
.equal_or_both_null(private$fast_predict_config$num_iteration, num_iteration)
)
}
# finalize() will free up the handles
, finalize = function() {
if (private$need_free_handle) {
.Call(
LGBM_BoosterFree_R
, private$handle
)
private$handle <- NULL
}
return(invisible(NULL))
}
)
)
......@@ -270,7 +270,7 @@ void _DatasetFinalizer(SEXP handle) {
SEXP LGBM_NullBoosterHandleError_R() {
Rf_error(
"Attempting to use a Booster which no longer exists and/or cannot be restored. "
"This can happen if you have called Booster$finalize() "
"This can happen if the Booster's finalizer was called "
"or if this Booster was saved through saveRDS() using 'serializable=FALSE'.");
return R_NilValue;
}
......@@ -285,7 +285,7 @@ void _AssertDatasetHandleNotNull(SEXP handle) {
if (Rf_isNull(handle) || !R_ExternalPtrAddr(handle)) {
Rf_error(
"Attempting to use a Dataset which no longer exists. "
"This can happen if you have called Dataset$finalize() or if this Dataset was saved with saveRDS(). "
"This can happen if the Dataset's finalizer was called or if this Dataset was saved with saveRDS(). "
"To avoid this error in the future, use lgb.Dataset.save() or Dataset$save_binary() to save lightgbm Datasets.");
}
}
......
library(Matrix)
test_that("Predictor$finalize() should not fail", {
test_that("Predictor's finalizer should not fail", {
X <- as.matrix(as.integer(iris[, "Species"]), ncol = 1L)
y <- iris[["Sepal.Length"]]
dtrain <- lgb.Dataset(X, label = y)
......@@ -21,11 +21,11 @@ test_that("Predictor$finalize() should not fail", {
expect_false(.is_null_handle(predictor$.__enclos_env__$private$handle))
predictor$finalize()
predictor$.__enclos_env__$private$finalize()
expect_true(.is_null_handle(predictor$.__enclos_env__$private$handle))
# calling finalize() a second time shouldn't cause any issues
predictor$finalize()
predictor$.__enclos_env__$private$finalize()
expect_true(.is_null_handle(predictor$.__enclos_env__$private$handle))
})
......
......@@ -351,7 +351,7 @@ test_that("Dataset$update_params() works correctly for recognized Dataset parame
}
})
test_that("Dataset$finalize() should not fail on an already-finalized Dataset", {
test_that("Dataset's finalizer should not fail on an already-finalized Dataset", {
dtest <- lgb.Dataset(
data = test_data
, label = test_label
......@@ -361,11 +361,11 @@ test_that("Dataset$finalize() should not fail on an already-finalized Dataset",
dtest$construct()
expect_false(.is_null_handle(dtest$.__enclos_env__$private$handle))
dtest$finalize()
dtest$.__enclos_env__$private$finalize()
expect_true(.is_null_handle(dtest$.__enclos_env__$private$handle))
# calling finalize() a second time shouldn't cause any issues
dtest$finalize()
dtest$.__enclos_env__$private$finalize()
expect_true(.is_null_handle(dtest$.__enclos_env__$private$handle))
})
......
test_that("Booster$finalize() should not fail", {
test_that("Booster's finalizer should not fail", {
X <- as.matrix(as.integer(iris[, "Species"]), ncol = 1L)
y <- iris[["Sepal.Length"]]
dtrain <- lgb.Dataset(X, label = y)
......@@ -15,11 +15,11 @@ test_that("Booster$finalize() should not fail", {
expect_false(.is_null_handle(bst$.__enclos_env__$private$handle))
bst$finalize()
bst$.__enclos_env__$private$finalize()
expect_true(.is_null_handle(bst$.__enclos_env__$private$handle))
# calling finalize() a second time shouldn't cause any issues
bst$finalize()
bst$.__enclos_env__$private$finalize()
expect_true(.is_null_handle(bst$.__enclos_env__$private$handle))
})
......@@ -195,7 +195,7 @@ test_that("Loading a Booster from a text file works", {
lgb.save(bst, model_file)
# finalize the booster and destroy it so you know we aren't cheating
bst$finalize()
bst$.__enclos_env__$private$finalize()
expect_null(bst$.__enclos_env__$private$handle)
rm(bst)
......@@ -238,7 +238,7 @@ test_that("boosters with linear models at leaves can be written to text file and
preds <- predict(bst, X)
model_file <- tempfile(fileext = ".model")
lgb.save(bst, model_file)
bst$finalize()
bst$.__enclos_env__$private$finalize()
expect_null(bst$.__enclos_env__$private$handle)
rm(bst)
......@@ -275,7 +275,7 @@ test_that("Loading a Booster from a string works", {
model_string <- bst$save_model_to_string()
# finalize the booster and destroy it so you know we aren't cheating
bst$finalize()
bst$.__enclos_env__$private$finalize()
expect_null(bst$.__enclos_env__$private$handle)
rm(bst)
......@@ -313,7 +313,7 @@ test_that("Saving a large model to string should work", {
expect_gt(nchar(model_string), 1024L * 1024L)
# finalize the booster and destroy it so you know we aren't cheating
bst$finalize()
bst$.__enclos_env__$private$finalize()
expect_null(bst$.__enclos_env__$private$handle)
rm(bst)
......@@ -383,7 +383,7 @@ test_that("If a string and a file are both passed to lgb.load() the file is used
lgb.save(bst, model_file)
# finalize the booster and destroy it so you know we aren't cheating
bst$finalize()
bst$.__enclos_env__$private$finalize()
expect_null(bst$.__enclos_env__$private$handle)
rm(bst)
......@@ -1508,7 +1508,7 @@ test_that("boosters with linear models at leaves can be written to RDS and re-lo
preds <- predict(bst, X)
model_file <- tempfile(fileext = ".rds")
saveRDS(bst, file = model_file)
bst$finalize()
bst$.__enclos_env__$private$finalize()
expect_null(bst$.__enclos_env__$private$handle)
rm(bst)
......@@ -1562,7 +1562,7 @@ test_that("Booster's print, show, and summary work correctly", {
.has_expected_content_for_fitted_model(log_txt)
#--- should not fail for finalized models ---#
model$finalize()
model$.__enclos_env__$private$finalize()
# print()
log_txt <- capture.output({
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment