Skip to content

Commit b95b192

Browse files
authored
Reserve some property names (#484)
* Reserve some property names closes #425 * allow property name `levels` * Also, disallow `...` as a prop name.
1 parent 5935df1 commit b95b192

File tree

3 files changed

+42
-0
lines changed

3 files changed

+42
-0
lines changed

R/class.R

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,7 @@ new_class <- function(
130130
# Combine properties from parent, overriding as needed
131131
all_props <- attr(parent, "properties", exact = TRUE) %||% list()
132132
new_props <- as_properties(properties)
133+
check_prop_names(new_props)
133134
all_props[names(new_props)] <- new_props
134135

135136
if (is.null(constructor)) {
@@ -327,3 +328,16 @@ str.S7_object <- function(object, ..., nest.lev = 0) {
327328
S7_class <- function(object) {
328329
attr(object, "S7_class", exact = TRUE)
329330
}
331+
332+
333+
check_prop_names <- function(properties, error_call = sys.call(-1L)) {
334+
# these attributes have special C handlers in base R
335+
forbidden <- c("names", "dim", "dimnames", "class",
336+
"tsp", "comment", "row.names", "...")
337+
forbidden <- intersect(forbidden, names(properties))
338+
if (length(forbidden)) {
339+
msg <- paste0("property can't be named: ",
340+
paste0(forbidden, collapse = ", "))
341+
stop(simpleError(msg, error_call))
342+
}
343+
}

tests/testthat/_snaps/class.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,3 +225,21 @@
225225
Error:
226226
! Can not combine S7 class objects
227227

228+
# can't create class with reserved property names
229+
230+
Code
231+
new_class("foo", properties = list(names = class_character))
232+
Condition
233+
Error in `new_class()`:
234+
! property can't be named: names
235+
Code
236+
new_class("foo", properties = list(dim = NULL | class_integer))
237+
Condition
238+
Error in `new_class()`:
239+
! property can't be named: dim
240+
Code
241+
new_class("foo", properties = list(dim = NULL | class_integer, dimnames = class_list))
242+
Condition
243+
Error in `new_class()`:
244+
! property can't be named: dim, dimnames
245+

tests/testthat/test-class.R

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,3 +243,13 @@ test_that("can round trip to disk and back", {
243243

244244
expect_equal(f2, f)
245245
})
246+
247+
248+
test_that("can't create class with reserved property names", {
249+
expect_snapshot(error = TRUE, {
250+
new_class("foo", properties = list(names = class_character))
251+
new_class("foo", properties = list(dim = NULL | class_integer))
252+
new_class("foo", properties = list(dim = NULL | class_integer,
253+
dimnames = class_list))
254+
})
255+
})

0 commit comments

Comments
 (0)