Skip to content

Commit

Permalink
Reserve some property names (#484)
Browse files Browse the repository at this point in the history
* Reserve some property names

closes #425

* allow property name `levels`

* Also, disallow `...` as a prop name.
  • Loading branch information
t-kalinowski authored Oct 31, 2024
1 parent 5935df1 commit b95b192
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 0 deletions.
14 changes: 14 additions & 0 deletions R/class.R
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ new_class <- function(
# Combine properties from parent, overriding as needed
all_props <- attr(parent, "properties", exact = TRUE) %||% list()
new_props <- as_properties(properties)
check_prop_names(new_props)
all_props[names(new_props)] <- new_props

if (is.null(constructor)) {
Expand Down Expand Up @@ -327,3 +328,16 @@ str.S7_object <- function(object, ..., nest.lev = 0) {
S7_class <- function(object) {
attr(object, "S7_class", exact = TRUE)
}


check_prop_names <- function(properties, error_call = sys.call(-1L)) {
# these attributes have special C handlers in base R
forbidden <- c("names", "dim", "dimnames", "class",
"tsp", "comment", "row.names", "...")
forbidden <- intersect(forbidden, names(properties))
if (length(forbidden)) {
msg <- paste0("property can't be named: ",
paste0(forbidden, collapse = ", "))
stop(simpleError(msg, error_call))
}
}
18 changes: 18 additions & 0 deletions tests/testthat/_snaps/class.md
Original file line number Diff line number Diff line change
Expand Up @@ -225,3 +225,21 @@
Error:
! Can not combine S7 class objects

# can't create class with reserved property names

Code
new_class("foo", properties = list(names = class_character))
Condition
Error in `new_class()`:
! property can't be named: names
Code
new_class("foo", properties = list(dim = NULL | class_integer))
Condition
Error in `new_class()`:
! property can't be named: dim
Code
new_class("foo", properties = list(dim = NULL | class_integer, dimnames = class_list))
Condition
Error in `new_class()`:
! property can't be named: dim, dimnames

10 changes: 10 additions & 0 deletions tests/testthat/test-class.R
Original file line number Diff line number Diff line change
Expand Up @@ -243,3 +243,13 @@ test_that("can round trip to disk and back", {

expect_equal(f2, f)
})


test_that("can't create class with reserved property names", {
expect_snapshot(error = TRUE, {
new_class("foo", properties = list(names = class_character))
new_class("foo", properties = list(dim = NULL | class_integer))
new_class("foo", properties = list(dim = NULL | class_integer,
dimnames = class_list))
})
})

0 comments on commit b95b192

Please sign in to comment.