iuke-tier@ey m@iii@g oii uiow@@edu
2025-Dec-20 14:10 UTC
[Rd] non-API ATTRIB and SET_ATTRIB will be dropped soon
As part of clarifying and tightening the R API for packages the
non-API entry points ATTRIB and SET_ATTRIB will be removed from
installed header files and, where possible, hidden from package
access. Both expose internal structure that might need to be changed
and also make it too easy to inadvertently break consistency
assumptions about the values of some attributes. Using these
functions is will now result in check NOTEs. These check NOTEs will
soon be replaced by WARNINGs; this will probably happen by the end of
January. The 'Working with attributes' section in the 'Writing R
Extensions' list some alternatives. Additional functions for working
with attributes, without exposing internal attributes structure, could
be added if they are needed.
Best,
luke
--
Luke Tierney
Ralph E. Wareham Professor of Mathematical Sciences
University of Iowa Phone: 319-335-3386
Department of Statistics and Fax: 319-335-3017
Actuarial Science
241 Schaeffer Hall email: luke-tierney at uiowa.edu
Iowa City, IA 52242 WWW: http://www.stat.uiowa.edu
Dear Luke, On Sat, 20 Dec 2025 08:10:30 -0600 (CST) luke-tierney--- via R-devel <r-devel at r-project.org> wrote:> The 'Working with attributes' section in the 'Writing R Extensions' > list some alternatives. Additional functions for working with > attributes, without exposing internal attributes structure, could be > added if they are needed.Two tangentially related questions: 1. Should packages use the return value of Rf_setAttrib()? I've noticed that some branches taken by the code (e.g. setAttrib(foo, R_CommentSymbol, bar)) return R_NilValue, while others return the newly installed attribute value. I'm asking because data.table needs to resize a temporary data frame that it owns, and for this purpose it needs to mutate its 'row.names' attribute in compact integer form. The current code walks the ATTRIB() list in search of the desired attribute, since Rf_getAttrib() would return an ALTREP form instead. We'll probably replace it with R_mapAttrib(), but I'm curious about alternatives. 2. In R_mapAttrib(), while walking ATTRIB(), the code always protects the current pair 'a', and then it protects CAR(a) and TAG(a) before calling the user-provided callback. Why protect TAG(a)? Because it's a good practice to protect arguments of user callbacks, or because it's really possible for TAG() of an attribute pair to become garbage-collected? -- Best regards, Ivan