Fix loading after ActiveSupport 6 subclass extensions - #336
Conversation
There was a problem hiding this comment.
Pull request overview
This PR addresses a load-order failure when ActiveSupport 5/6 subclass/descendant extensions are loaded before openai, by avoiding code paths that invoke OpenAI::Internal::Type::BaseModel.== during model alias initialization.
Changes:
- Reworks generated model
OrHashalias registration to avoidClass#subclassesand use superclass identity checks. - Adds an isolated regression test that simulates ActiveSupport 6’s
Class#descendants/#subclassesbehavior and assertsrequire "openai"succeeds.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| test/openai/load_order_test.rb | Adds a subprocess-based regression test covering the ActiveSupport 6-style subclass extensions load-order scenario. |
| lib/openai/models.rb | Changes how BaseModel subclasses are enumerated for OrHash alias registration to avoid triggering structural equality during load. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| subclasses = | ||
| ObjectSpace.each_object(base_model.singleton_class).select do |candidate| | ||
| !candidate.singleton_class? && candidate.superclass.equal?(base_model) | ||
| end |
HAYDEN-OAI
left a comment
There was a problem hiding this comment.
Reviewed exact commit 5f5a533 and the complete implementation and load-order regression case. On MRI Ruby 3.3.12, verified SDK loading both without ActiveSupport and with real ActiveSupport 5.2.8.1, 6.0.6.1, 6.1.7.10, 7.0.8.7, 7.1.5, and 8.0.3. All 2,266 generated model classes receive OrHash aliases, and public structural class equality remains unchanged. Ruby singleton-class inheritance makes ObjectSpace.each_object(base_model.singleton_class) correctly enumerate descendant classes; the existing automated concern is a false positive. No substantive issues found.
Summary
Class#subclasseswhile registering generated modelOrHashaliases because ActiveSupport 5 and 6 implement it through==BaseModelsubclasses and compare their superclass by object identityFixes #335.
Why this is narrow
This does not monkeypatch ActiveSupport or Ruby, and it does not change
BaseModel.==. The identity-safe enumeration is local to generated model initialization.Test plan
ruby -Itestover the load-order, BaseModel, Sorbet runtime, and structured-output tests (25 runs, 326 assertions)Companion generator change: openai/openai#1237327.