Repository navigation
Support the S7 class reference of S7 > 0.2.1 - #739
Merged
Merged
Conversation
The development version of S7 (0.2.2.9000, RConsortium/S7#742) stores an object's class in a "_S7_class" attribute, generally a shared "S7_class_ref" environment, along with "_S7_version", instead of the "S7_class" attribute. Classes gain "S7_class_name", "S7_dispatch" and "S7_version" attributes, and `new_class()` wraps the constructor's environment into a new one holding the reference. Our S7, ggplot2 and ellmer constructors read `attr(x, "S7_class")` and ignored only that attribute, so with dev S7 the output fell back to low-level code, and constructing a generic repaired "_S7_class" with an environment address, which segfaulted under testthat's placeholder address. * `s7_class()` gets the class from either attribute, and `s7_internal_attrs` lists the attributes S7 sets itself, used in the ignore lists that listed "S7_class" * `new_class()` calls get the original constructor environment * `S7_object()` doesn't repair the "_S7_version" it sets Tests whose output legitimately differs (low level "next" constructions, base classes redefined in S7) are split by S7 version, the snapshots for S7 <= 0.2.1 are unchanged.
Instead of calling S7::S7_object() during construction to find out which "_S7_version" it sets, we check the S7 version and compare to the value set since S7 0.2.2.9000 (1L).
The class reference ("_S7_class", "_S7_version") is only in the
development version of S7 (0.2.2.9000). S7 0.2.2 is on CRAN and still
uses the "S7_class" attribute, but the tests and the version check of
the S7_object constructor used 0.2.1 as threshold, so CI (S7 0.2.2)
ran the blocks meant for the development version. Also removes the
snapshots CI committed from these runs.
The repair functions ignored "S7_class", "_S7_class" and "_S7_version" whatever the S7 version, but each version's constructors only set one set, so an object carrying the other version's attributes would have lost them. s7_internal_attrs() now depends on with_versions(S7 > "0.2.2"), and so do the class attributes ignored by the "new_class" constructor. The arguments of S7 object constructors still drop all three.
Read the class and check attributes according to the installed S7 version with with_versions(), consider S7 objects built by an S7 version storing the class differently as corrupted, and construct the "S7_class_ref" of S7 > 0.2.2 from its class rather than from a memory address. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #739 +/- ##
==========================================
- Coverage 82.53% 82.30% -0.24%
==========================================
Files 230 231 +1
Lines 8692 8730 +38
==========================================
+ Hits 7174 7185 +11
- Misses 1518 1545 +27 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes the
rcc-dev: S7failure on #733 (segfault intest-s7-S7_generic.R).What changed in S7: the development version (0.2.2.9000, RConsortium/S7#742) stores an object's class in a
_S7_classattribute, generally a sharedS7_class_refenvironment (stored as.S7_class_refin the class's environment) whose$classis the class, plus_S7_version, instead of theS7_classattribute. Classes gainS7_class_name,S7_dispatchandS7_versionattributes, andnew_class()wraps the constructor's environment into a new one holding.S7_class_ref.Fix — the installed S7 version decides, through
with_versions(S7 > "0.2.2"):s7_class(x)reads_S7_class(dereferenced) orS7_class;s7_internal_attrs()gives the attributes to ignorehas_foreign_s7_attrs(x): objects/generics built by an S7 version storing the class differently are corrupted (S7_object, S7_generic, ggplot2 S7 classes, ellmer types) and fall back to low-level construction, which rebuilds them exactlyis_corrupted_S7_class()does the same for classes (env wrapper /S7_version);new_classconstruction passes the original constructor env with S7 > 0.2.2"S7_class_ref"constructor (opts_S7_class_ref()):environment(<class code>)$.S7_class_ref, instead of an environment address; corrupted with S7 <= 0.2.2Tests: version-specific outputs split with
with_versions()at 0.2.2 (current CRAN). NewS7_class_reftest, and foreign-structure cases in theS7_objecttests for both versions.Tested locally, full suite: 0 failures with S7 0.2.1 and 0.2.2.9000; S7/ggplot2/ellmer tests also with 0.2.2.
🤖 Generated with Claude Code