Bug 1836201 - rubygem-psych: `<class:Parser>': superclass mismatch for class Mark (TypeError)
Summary: rubygem-psych: `<class:Parser>': superclass mismatch for class Mark (TypeError)
Keywords:
Status: CLOSED WONTFIX
Alias: None
Product: Red Hat Software Collections
Classification: Red Hat
Component: rh-ruby27
Version: rh-ruby27
Hardware: Unspecified
OS: Unspecified
unspecified
unspecified
Target Milestone: ---
: 3.7
Assignee: ruby maint
QA Contact: RHEL CS Apps Subsystem QE
Lenka Špačková
URL:
Whiteboard:
Depends On: 1835836
Blocks: 1842989
TreeView+ depends on / blocked
 
Reported: 2020-05-15 12:10 UTC by David Jež
Modified: 2021-11-15 07:27 UTC (History)
3 users (show)

Fixed In Version:
Doc Type: Known Issue
Doc Text:
rh-ruby27 component When a custom script requires the Psych YAML parser and afterwards uses the Gem.load_yaml method, running the script fails with the following error message: superclass mismatch for class Mark (TypeError) To work around this problem, add the gem 'psych' line to the script somewhere above the require 'psych' line: ... gem 'psych' ... require 'psych' Gem.load_yaml
Clone Of: 1835836
: 1842989 (view as bug list)
Environment:
Last Closed: 2021-11-15 07:27:04 UTC
Target Upstream Version:
Embargoed:


Attachments (Terms of Use)

Description David Jež 2020-05-15 12:10:53 UTC
We can see it also in rh-ruby27 collection.

+++ This bug was initially created as a clone of Bug #1835836 +++

Description of problem:

When rubygem-psych RPM is installed, run the following test.rb script. Then the following error happens.

```
$ gem info psych

*** LOCAL GEMS ***

psych (3.1.0)
    Authors: Aaron Patterson, SHIBATA Hiroshi, Charles Oliver Nutter
    Homepage: https://github.com/ruby/psych
    License: MIT
    Installed at: /usr/share/gems

    Psych is a YAML parser and emitter
```

```
$ cat test.rb 
require 'psych'
Gem.load_yaml
```

```
$ ruby test.rb
/usr/lib64/gems/ruby/psych-3.1.0/psych.so: warning: already initialized constant Psych::Parser::ANY
...

/usr/share/gems/gems/psych-3.1.0/lib/psych/parser.rb:34:in `<class:Parser>': superclass mismatch for class Mark (TypeError)
```


Version-Release number of selected component (if applicable):
ruby-2.7.1-130.fc33.x86_64
rubygem-psych-3.1.0-130.fc33.x86_64

How reproducible:


Steps to Reproduce:
1. Create this Ruby script.

```
$ cat test.rb 
require 'psych'
Gem.load_yaml
```

2. Run the script.

$ ruby test.rb 

Actual results:

```
$ ruby test.rb 
/usr/lib64/gems/ruby/psych-3.1.0/psych.so: warning: already initialized constant Psych::Parser::ANY
/usr/lib64/gems/ruby/psych-3.1.0/psych.so: warning: already initialized constant Psych::Parser::UTF8
/usr/lib64/gems/ruby/psych-3.1.0/psych.so: warning: already initialized constant Psych::Parser::UTF16LE
/usr/lib64/gems/ruby/psych-3.1.0/psych.so: warning: already initialized constant Psych::Parser::UTF16BE
/usr/share/gems/gems/psych-3.1.0/lib/psych/class_loader.rb:7: warning: already initialized constant Psych::ClassLoader::BIG_DECIMAL
/usr/share/ruby/psych/class_loader.rb:7: warning: previous definition of BIG_DECIMAL was here
/usr/share/gems/gems/psych-3.1.0/lib/psych/class_loader.rb:8: warning: already initialized constant Psych::ClassLoader::COMPLEX
/usr/share/ruby/psych/class_loader.rb:8: warning: previous definition of COMPLEX was here
/usr/share/gems/gems/psych-3.1.0/lib/psych/class_loader.rb:9: warning: already initialized constant Psych::ClassLoader::DATE
/usr/share/ruby/psych/class_loader.rb:9: warning: previous definition of DATE was here
/usr/share/gems/gems/psych-3.1.0/lib/psych/class_loader.rb:10: warning: already initialized constant Psych::ClassLoader::DATE_TIME
/usr/share/ruby/psych/class_loader.rb:10: warning: previous definition of DATE_TIME was here
/usr/share/gems/gems/psych-3.1.0/lib/psych/class_loader.rb:11: warning: already initialized constant Psych::ClassLoader::EXCEPTION
/usr/share/ruby/psych/class_loader.rb:11: warning: previous definition of EXCEPTION was here
/usr/share/gems/gems/psych-3.1.0/lib/psych/class_loader.rb:12: warning: already initialized constant Psych::ClassLoader::OBJECT
/usr/share/ruby/psych/class_loader.rb:12: warning: previous definition of OBJECT was here
/usr/share/gems/gems/psych-3.1.0/lib/psych/class_loader.rb:13: warning: already initialized constant Psych::ClassLoader::PSYCH_OMAP
/usr/share/ruby/psych/class_loader.rb:13: warning: previous definition of PSYCH_OMAP was here
/usr/share/gems/gems/psych-3.1.0/lib/psych/class_loader.rb:14: warning: already initialized constant Psych::ClassLoader::PSYCH_SET
/usr/share/ruby/psych/class_loader.rb:14: warning: previous definition of PSYCH_SET was here
/usr/share/gems/gems/psych-3.1.0/lib/psych/class_loader.rb:15: warning: already initialized constant Psych::ClassLoader::RANGE
/usr/share/ruby/psych/class_loader.rb:15: warning: previous definition of RANGE was here
/usr/share/gems/gems/psych-3.1.0/lib/psych/class_loader.rb:16: warning: already initialized constant Psych::ClassLoader::RATIONAL
/usr/share/ruby/psych/class_loader.rb:16: warning: previous definition of RATIONAL was here
/usr/share/gems/gems/psych-3.1.0/lib/psych/class_loader.rb:17: warning: already initialized constant Psych::ClassLoader::REGEXP
/usr/share/ruby/psych/class_loader.rb:17: warning: previous definition of REGEXP was here
/usr/share/gems/gems/psych-3.1.0/lib/psych/class_loader.rb:18: warning: already initialized constant Psych::ClassLoader::STRUCT
/usr/share/ruby/psych/class_loader.rb:18: warning: previous definition of STRUCT was here
/usr/share/gems/gems/psych-3.1.0/lib/psych/class_loader.rb:19: warning: already initialized constant Psych::ClassLoader::SYMBOL
/usr/share/ruby/psych/class_loader.rb:19: warning: previous definition of SYMBOL was here
/usr/share/gems/gems/psych-3.1.0/lib/psych/class_loader.rb:65: warning: already initialized constant Psych::ClassLoader::CACHE
/usr/share/ruby/psych/class_loader.rb:65: warning: previous definition of CACHE was here
/usr/share/gems/gems/psych-3.1.0/lib/psych/scalar_scanner.rb:9: warning: already initialized constant Psych::ScalarScanner::TIME
/usr/share/ruby/psych/scalar_scanner.rb:9: warning: previous definition of TIME was here
/usr/share/gems/gems/psych-3.1.0/lib/psych/scalar_scanner.rb:12: warning: already initialized constant Psych::ScalarScanner::FLOAT
/usr/share/ruby/psych/scalar_scanner.rb:12: warning: previous definition of FLOAT was here
/usr/share/gems/gems/psych-3.1.0/lib/psych/scalar_scanner.rb:17: warning: already initialized constant Psych::ScalarScanner::INTEGER
/usr/share/ruby/psych/scalar_scanner.rb:17: warning: previous definition of INTEGER was here
/usr/share/gems/gems/psych-3.1.0/lib/psych/nodes/stream.rb:13: warning: already initialized constant Psych::Nodes::Stream::ANY
/usr/share/ruby/psych/nodes/stream.rb:13: warning: previous definition of ANY was here
/usr/share/gems/gems/psych-3.1.0/lib/psych/nodes/stream.rb:16: warning: already initialized constant Psych::Nodes::Stream::UTF8
/usr/share/ruby/psych/nodes/stream.rb:16: warning: previous definition of UTF8 was here
/usr/share/gems/gems/psych-3.1.0/lib/psych/nodes/stream.rb:19: warning: already initialized constant Psych::Nodes::Stream::UTF16LE
/usr/share/ruby/psych/nodes/stream.rb:19: warning: previous definition of UTF16LE was here
/usr/share/gems/gems/psych-3.1.0/lib/psych/nodes/stream.rb:22: warning: already initialized constant Psych::Nodes::Stream::UTF16BE
/usr/share/ruby/psych/nodes/stream.rb:22: warning: previous definition of UTF16BE was here
/usr/share/gems/gems/psych-3.1.0/lib/psych/nodes/sequence.rb:43: warning: already initialized constant Psych::Nodes::Sequence::ANY
/usr/share/ruby/psych/nodes/sequence.rb:43: warning: previous definition of ANY was here
/usr/share/gems/gems/psych-3.1.0/lib/psych/nodes/sequence.rb:46: warning: already initialized constant Psych::Nodes::Sequence::BLOCK
/usr/share/ruby/psych/nodes/sequence.rb:46: warning: previous definition of BLOCK was here
/usr/share/gems/gems/psych-3.1.0/lib/psych/nodes/sequence.rb:49: warning: already initialized constant Psych::Nodes::Sequence::FLOW
/usr/share/ruby/psych/nodes/sequence.rb:49: warning: previous definition of FLOW was here
/usr/share/gems/gems/psych-3.1.0/lib/psych/nodes/scalar.rb:10: warning: already initialized constant Psych::Nodes::Scalar::ANY
/usr/share/ruby/psych/nodes/scalar.rb:10: warning: previous definition of ANY was here
/usr/share/gems/gems/psych-3.1.0/lib/psych/nodes/scalar.rb:13: warning: already initialized constant Psych::Nodes::Scalar::PLAIN
/usr/share/ruby/psych/nodes/scalar.rb:13: warning: previous definition of PLAIN was here
/usr/share/gems/gems/psych-3.1.0/lib/psych/nodes/scalar.rb:16: warning: already initialized constant Psych::Nodes::Scalar::SINGLE_QUOTED
/usr/share/ruby/psych/nodes/scalar.rb:16: warning: previous definition of SINGLE_QUOTED was here
/usr/share/gems/gems/psych-3.1.0/lib/psych/nodes/scalar.rb:19: warning: already initialized constant Psych::Nodes::Scalar::DOUBLE_QUOTED
/usr/share/ruby/psych/nodes/scalar.rb:19: warning: previous definition of DOUBLE_QUOTED was here
/usr/share/gems/gems/psych-3.1.0/lib/psych/nodes/scalar.rb:22: warning: already initialized constant Psych::Nodes::Scalar::LITERAL
/usr/share/ruby/psych/nodes/scalar.rb:22: warning: previous definition of LITERAL was here
/usr/share/gems/gems/psych-3.1.0/lib/psych/nodes/scalar.rb:25: warning: already initialized constant Psych::Nodes::Scalar::FOLDED
/usr/share/ruby/psych/nodes/scalar.rb:25: warning: previous definition of FOLDED was here
/usr/share/gems/gems/psych-3.1.0/lib/psych/nodes/mapping.rb:17: warning: already initialized constant Psych::Nodes::Mapping::ANY
/usr/share/ruby/psych/nodes/mapping.rb:17: warning: previous definition of ANY was here
/usr/share/gems/gems/psych-3.1.0/lib/psych/nodes/mapping.rb:20: warning: already initialized constant Psych::Nodes::Mapping::BLOCK
/usr/share/ruby/psych/nodes/mapping.rb:20: warning: previous definition of BLOCK was here
/usr/share/gems/gems/psych-3.1.0/lib/psych/nodes/mapping.rb:23: warning: already initialized constant Psych::Nodes::Mapping::FLOW
/usr/share/ruby/psych/nodes/mapping.rb:23: warning: previous definition of FLOW was here
/usr/share/gems/gems/psych-3.1.0/lib/psych/visitors/visitor.rb:11: warning: already initialized constant Psych::Visitors::Visitor::DISPATCH
/usr/share/ruby/psych/visitors/visitor.rb:11: warning: previous definition of DISPATCH was here
/usr/share/gems/gems/psych-3.1.0/lib/psych/visitors/to_ruby.rb:336: warning: already initialized constant Psych::Visitors::ToRuby::SHOVEL
/usr/share/ruby/psych/visitors/to_ruby.rb:336: warning: previous definition of SHOVEL was here
/usr/share/gems/gems/psych-3.1.0/lib/psych/handler.rb:27: warning: already initialized constant Psych::Handler::OPTIONS
/usr/share/ruby/psych/handler.rb:27: warning: previous definition of OPTIONS was here
/usr/share/gems/gems/psych-3.1.0/lib/psych/handler.rb:30: warning: already initialized constant Psych::Handler::EVENTS
/usr/share/ruby/psych/handler.rb:30: warning: previous definition of EVENTS was here
Traceback (most recent call last):
	9: from test.rb:2:in `<main>'
	8: from /usr/share/rubygems/rubygems.rb:696:in `load_yaml'
	7: from /usr/share/rubygems/rubygems/core_ext/kernel_require.rb:72:in `require'
	6: from /usr/share/rubygems/rubygems/core_ext/kernel_require.rb:72:in `require'
	5: from /usr/share/gems/gems/psych-3.1.0/lib/psych.rb:20:in `<top (required)>'
	4: from /usr/share/rubygems/rubygems/core_ext/kernel_require.rb:72:in `require'
	3: from /usr/share/rubygems/rubygems/core_ext/kernel_require.rb:72:in `require'
	2: from /usr/share/gems/gems/psych-3.1.0/lib/psych/parser.rb:2:in `<top (required)>'
	1: from /usr/share/gems/gems/psych-3.1.0/lib/psych/parser.rb:33:in `<module:Psych>'
/usr/share/gems/gems/psych-3.1.0/lib/psych/parser.rb:34:in `<class:Parser>': superclass mismatch for class Mark (TypeError)
```


Expected results:

The error does not happens. This issue does not happen on the upstream Ruby.

```
$ ruby test.rb 
$ echo $?
0
```

Additional info:

I think this issue is related to this upstream issue.
https://github.com/ruby/psych/issues/386

--- Additional comment from Jun Aruga on 2020-05-14 17:37:07 UTC ---

This issue also happen on f31 with:
  ruby-2.7.1-130.fc32.x86_64
  rubygems-3.1.2-130.fc32.noarch
  rubygem-psych-3.1.0-130.fc32.x86_64.
But it does not happen on f30 with:
  ruby-2.6.5-124.fc31.x86_64
  rubygems-3.0.3-124.fc31.noarch
  rubygem-psych-3.1.0-124.fc31.x86_64.

On f31, the result of `ruby test.rb` is like this.

```
$ ruby test.rb 
/usr/share/gems/gems/psych-3.1.0/lib/psych.rb:237: warning: already initialized constant Psych::LIBYAML_VERSION
/usr/share/ruby/psych.rb:237: warning: previous definition of LIBYAML_VERSION was here
/usr/share/gems/gems/psych-3.1.0/lib/psych.rb:239: warning: already initialized constant Psych::NOT_GIVEN
/usr/share/ruby/psych.rb:239: warning: previous definition of NOT_GIVEN was here

$ echo $?
0
```

--- Additional comment from Jun Aruga on 2020-05-14 18:21:48 UTC ---

Sorry for the 2 typos.

> This issue also happen on f31 with:

Correction
This issue also happen on f32 with:

> But it does not happen on f30 with:

Correction
But it does not happen on f31 with:

--- Additional comment from Vít Ondruch on 2020-05-14 20:52:39 UTC ---

> On f31, the result of `ruby test.rb` is like this.
> 
> ```
> $ ruby test.rb 
> /usr/share/gems/gems/psych-3.1.0/lib/psych.rb:237: warning: already
> initialized constant Psych::LIBYAML_VERSION
> /usr/share/ruby/psych.rb:237: warning: previous definition of
> LIBYAML_VERSION was here
> /usr/share/gems/gems/psych-3.1.0/lib/psych.rb:239: warning: already
> initialized constant Psych::NOT_GIVEN
> /usr/share/ruby/psych.rb:239: warning: previous definition of NOT_GIVEN was
> here
> 
> $ echo $?
> 0
> ```

IOW the issues is still the same, only the magnitude is different.

https://github.com/rubygems/rubygems/issues/3131

--- Additional comment from Mamoru TASAKA on 2020-05-14 23:51:14 UTC ---

This is the same as https://src.fedoraproject.org/rpms/rubygem-racc/pull-request/1#comment-37003

i.e.
```
require "psych"
gem "psych"
require "psych"
```

causes this error.

--- Additional comment from Jun Aruga on 2020-05-15 08:53:49 UTC ---

Thanks for the information. It's very helpful.

I found a temporary workflow to avoid this issue.

```
<mock-chroot> sh-5.0# diff -u /usr/share/rubygems/rubygems.rb{.orig,}
--- /usr/share/rubygems/rubygems.rb.orig	2020-03-31 12:44:55.000000000 +0200
+++ /usr/share/rubygems/rubygems.rb	2020-05-15 10:48:33.008250387 +0200
@@ -685,7 +685,7 @@
     return unless defined?(gem)
 
     begin
-      gem 'psych', '>= 2.0.0'
+      # gem 'psych', '>= 2.0.0'
     rescue Gem::LoadError
       # It's OK if the user does not have the psych gem installed.  We will
       # attempt to require the stdlib version
```

Then the above test.rb works.

```
$ ruby test.rb 

$ echo $?
0
```

As a long term solution in Fedora, I think that it's better to change rubygem-psych to the default bundled gem like rubygem-racc did.

--- Additional comment from Vít Ondruch on 2020-05-15 08:58:48 UTC ---

As a long term, RubyGems should not call `gem` command. There used to be the Syck/Psych switch, which was partly removed, but not entirely. I was looking into this a bit, but it is unfortunately rabbit hole.

--- Additional comment from Jun Aruga on 2020-05-15 09:47:04 UTC ---

> I found a temporary workflow to avoid this issue.

Or like this in safer manner.

```
<mock-chroot> sh-5.0# diff -u /usr/share/rubygems/rubygems.rb{.orig,}
--- /usr/share/rubygems/rubygems.rb.orig	2020-03-31 12:44:55.000000000 +0200
+++ /usr/share/rubygems/rubygems.rb	2020-05-15 11:43:34.851595500 +0200
@@ -685,7 +685,11 @@
     return unless defined?(gem)
 
     begin
-      gem 'psych', '>= 2.0.0'
+      begin
+        require 'psych'
+      rescue ::LoadError
+        gem 'psych', '>= 2.0.0'
+      end
     rescue Gem::LoadError
       # It's OK if the user does not have the psych gem installed.  We will
       # attempt to require the stdlib version
```

--- Additional comment from Jun Aruga on 2020-05-15 10:53:55 UTC ---

Here is a list of the rubygem packages depending on psych.
When loading the rubygem package and calling Gem.load_yaml, this issue happen.
https://rubygems.org/gems/psych/reverse_dependencies

Rubocop had had the issue. But the project dropped the psych dependency later to avoid the issue.
https://github.com/rubocop-hq/rubocop/commit/95d2110e49e160ffb785a74b22727593f17d552b

Comment 4 Vít Ondruch 2020-05-15 15:04:57 UTC
(In reply to Jun Aruga from comment #3)
> The following script works,
> 
> ```
> gem 'psych'
> require 'psych'
> gem 'psych'
> require 'psych'
> ```
> 
> while the following script does not work.
> 
> ```
> require 'psych'
> gem 'psych'
> require 'psych'
> ```

The issue is more complex, but `gem 'psych'` is approximately equivalent to `RUBYOPT=-I/usr/share/gems/gems/psych-3.1.0/lib/:/usr/lib64/gems/ruby/psych-3.1.0/`, so it changes where the Psych is loaded from.

Comment 19 RHEL Program Management 2021-11-15 07:27:04 UTC
After evaluating this issue, there are no plans to address it further or fix it in an upcoming release.  Therefore, it is being closed.  If plans change such that this issue will be fixed in an upcoming release, then the bug can be reopened.


Note You need to log in before you can comment on or make changes to this bug.