The non-exported shallow is supposed to operate on data.frame arguments since 1.14.2. But:
> df=data.frame(a=1:10)
> attributes(data.table:::shallow(df))
$names
[1] "a"
$class
[1] "data.frame"
$row.names
[1] 1 2 3 4 5 6 7 8 9 10
$.internal.selfref
<pointer: 0x56250b748b10>
It appears setselfref is called regardless of if the input is indeed a data.table.
Also, test 1984.27 was supposed to catch it - but the way data frames/tables comparison is coded in test currently it doesn't. The culprit are these lines in the comparison:
setattr(xc,".internal.selfref",NULL) # test 2212
setattr(yc,".internal.selfref",NULL)
# Output of sessionInfo()
R4.0.5, data.table 1.14.3