Skip to content

[pull] master from ruby:master#1173

Merged
pull[bot] merged 31 commits into
turkdevops:masterfrom
ruby:master
Jul 2, 2026
Merged

[pull] master from ruby:master#1173
pull[bot] merged 31 commits into
turkdevops:masterfrom
ruby:master

Conversation

@pull

@pull pull Bot commented Jul 2, 2026

Copy link
Copy Markdown

See Commits and Changes for more details.


Created by pull[bot] (v2.0.0-alpha.4)

Can you help keep this open source service alive? 💖 Please sponsor : )

BurdetteLamar and others added 30 commits July 1, 2026 20:50
Bundler::DSLError#to_s read the offending line number from
`trace_line.split(":")[1]`. On Windows the backtrace path carries a drive
letter such as `C:`, so that field is the path rather than the number, and
the negative index that follows garbles the source snippet. Match the number
that sits right before `:in` or the end of the line instead.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Cover behavior documented in rdoc but not asserted in
test/ruby/test_string.rb:

* insert returns self
* boundary negative index -(length + 1) prepends
* out-of-range index (positive and negative) raises IndexError
* non-string argument raises TypeError
* frozen string raises FrozenError
* multibyte: index counts characters, not bytes
These guards no longer match current mswin behavior. The affected tests
pass reliably on an x64-mswin64_140 build, repeatedly and under -j16 for
the flaky-history ones.

Only the mswin conditions are removed. test_ractor and test_transcode
keep their darwin and s390x guards. test_thread_queue keeps the MinGW
omit and drops only the retired AppVeyor branch. test_box re-enables
box_1 only, since box_2 still crashes at process exit under mswin and
stays pended.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Loading the extension libraries in a box exceeds the default 10-second
assert_separately timeout under -j16 CI load. Use 60 seconds, matching
the sibling box test that already does.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Built only with --enable-libfyaml; without the flag the default libyaml
backend is unchanged. The parser and emitter are reimplemented against
libfyaml's event API in separate translation units guarded by
PSYCH_USE_LIBFYAML, and the backend is not supported on Windows.

ruby/psych@51f2493a2e

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Scalar type resolution happens in ScalarScanner, not the C backend, so
swapping to libfyaml alone still resolved yes/no/on/off to booleans. Key
the boolean set on Psych::BACKEND so the libyaml default keeps the YAML
1.1 set while the experimental libfyaml backend follows 1.2.

ruby/psych@b374869c59

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Create a fresh parser per parse instead of reusing one via
fy_parser_reset(), which left default tag handles unset and rejected
bare ("---"-less) tag-led documents. Recover the real message and
position by switching the parser's own diagnostic object to collect
mode; creating a replacement diag crashes libfyaml 0.9.6. Drop the
spurious empty tag directive libfyaml reports.

ruby/psych@d383361c23

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Drop the tag when plain_implicit or quoted_implicit is set, matching how
libyaml omits a tag that the value resolves to on reload; otherwise nil
emitted as "!<tag:yaml.org,2002:null>" instead of an empty scalar. Honor
the plain hint when choosing the scalar style, and restore the Check_Type
guards on anchor and tag so non-string arguments raise TypeError.

ruby/psych@ff15ddf399

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
libfyaml only consumes UTF-8, so a UTF-16 IO fed through the chunked
reader reached it as raw bytes and was rejected as invalid UTF-8. When
the IO's external encoding is UTF-16LE/BE, slurp the whole stream and
transcode it first; a 2-byte unit could otherwise straddle a read
boundary. Other non-UTF-8 encodings stay raw and libfyaml rejects them,
matching psych's UTF-8/UTF-16-only IO contract (Shift_JIS still raises).

ruby/psych@4bd1343551

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…cument

The xcalloc'd tag buffers leaked when StringValue, the tuple-length
check, or the emit raised mid-way. Wrap the work in rb_ensure so the
buffers are always freed, and keep the exported directive strings in a
Ruby array so the GC cannot reclaim them while their C pointers are in
use.

ruby/psych@6fdede0177

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Add a libfyaml? helper and guard the tests that intentionally diverge on
the experimental YAML 1.2 backend: yes/no/on/off are strings rather than
booleans, flow collections and block scalars are formatted differently,
tags and marks are reported differently, and non-ASCII tags/aliases are
rejected. test_boolean asserts the 1.2 string result directly; the
formatting and mark cases are skipped. The default libyaml build is
unaffected (every guard keys off Psych::BACKEND).

ruby/psych@67b6365f5a

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Mark the reconstructed SyntaxError message UTF-8 instead of US-ASCII, so
a diagnostic that embeds a multibyte snippet of the input does not raise
Encoding::CompatibilityError when concatenated with UTF-8. Add
RB_GC_GUARD for the anchor and tag strings in the emitter (matching the
existing guard on the scalar value) so their C pointers cannot dangle if
a GC runs inside fy_emit_event_create.

ruby/psych@1c73f43df1

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Cover what the libfyaml backend does distinctly, each placed with the
concern it belongs to: the Psych::BACKEND and Psych.libfyaml_version
checks in test_psych.rb, the YAML 1.2 "Norway problem" boolean case in
test_boolean.rb, and the "1.1 booleans are not quoted" emission case in
test_string.rb. The 1.2 assertions are skipped on the default libyaml
backend so the same suite passes under both.

ruby/psych@35d0a437a2

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Reject canonical output with NotImplementedError instead of silently
ignoring the request, and honor the implicit flag in start_sequence and
start_mapping so an implicit tag is not printed as a redundant verbose
tag. Relax the unquoted-boolean dump test to allow an optional document
end marker. Also correct the version docstrings and a stale comment
about how the parser collects diagnostics.

ruby/psych@23f60daff1

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The libfyaml-dev package on Ubuntu is 0.8, which segfaults psych's
emitter, while 0.9.6 (used on macOS via Homebrew) passes the whole suite.
Build the same 0.9.6 release from source in the Linux CI job, and reject
libfyaml older than 0.9 in extconf so users get a clear error instead of
a runtime crash. Also drop an unused variable in set_canonical.

ruby/psych@88ac4a0cc0

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
… integration connection tests

Create spec/bundler/fetcher/gem_remote_fetcher_local_ssl_server_spec.rb
adding non-PQC and PQC server/client connection integration tests.
As "Bundler::Fetcher local SSL server #connection PQC connects with client cert
auth" failed with the following error due to hardcoded `OpenSSL::PKey::RSA.new` in
`Bundler::Fetcher#connection`, fixed it to support ML-DSA ssl_client_cert.

```
$ bin/rspec spec/bundler/fetcher/gem_remote_fetcher_local_ssl_server_spec.rb
...
Failures:

  1) Bundler::Fetcher local SSL server #connection PQC connects with client cert auth
     Failure/Error: fetcher = Bundler::Fetcher.new(remote)

     OpenSSL::PKey::PKeyError:
       incorrect pkey type: UNDEF
     # /home/jaruga/.local/ruby-4.1.0-debug-3ef48ef9c8-openssl-4.1.0-7194354488/lib/ruby/4.1.0+1/openssl/pkey.rb:394:in 'OpenSSL::PKey::RSA#initialize'
     # /home/jaruga/.local/ruby-4.1.0-debug-3ef48ef9c8-openssl-4.1.0-7194354488/lib/ruby/4.1.0+1/openssl/pkey.rb:394:in 'Class#new'
     # /home/jaruga/.local/ruby-4.1.0-debug-3ef48ef9c8-openssl-4.1.0-7194354488/lib/ruby/4.1.0+1/openssl/pkey.rb:394:in 'OpenSSL::PKey::RSA.new'
     # ./bundler/lib/bundler/fetcher.rb:321:in 'Bundler::Fetcher#connection'
     # ./bundler/lib/bundler/fetcher.rb:140:in 'Bundler::Fetcher#initialize'
     # ./spec/bundler/fetcher/gem_remote_fetcher_local_ssl_server_spec.rb:69:in 'RSpec::ExampleGroups::BundlerFetcherLocalSSLServer#fetch_path'
     # ./spec/bundler/fetcher/gem_remote_fetcher_local_ssl_server_spec.rb:60:in 'block (4 levels) in <top (required)>'
...
```

Create test/rubygems/local_ssl_server_utilities.rb to manage utility methods
called by RubyGems test-unit and Bundler rspec tests.

Assisted-by: Claude:claude-opus-4-6[1m]

ruby/rubygems@6aea5fcc17
…:HTTP

The hardcoded Gem::Net::HTTP in Artifice.deactivate, is actually
the replaced Artifice::Net::HTTP. This doesn't restore the original
Gem::Net::HTTP.

Restore the saved original Gem::Net::HTTP in Artifice.deactivate

This issue caused the tests sometimes failed in
spec/bundler/fetcher/gem_remote_fetcher_local_ssl_server_spec.rb
using Artifice::Net::HTTP unintentionally. Because localhost is not included in
spec/support/artifice/helpers/endpoint.rb - permitted_hosts caused HTTP status 403
(response.body: "Host not permitted"). But Gem::Net::HTTP should be used in the
tests instead of Artifice::Net::HTTP. Possibly this issue happens when
Artifice.deactivate is called in other tests such as spec/commands/ssl_spec.rb.
That's why this issue sometimes happened rather than always.

```
  1) Bundler::Fetcher local SSL server #connection PQC connects
     Failure/Error: expect(response.code).to eq("200")

       expected: #<Encoding:UTF-8> "200"
            got: #<Encoding:ASCII-8BIT> "403"

       (compared using ==)
     # ./spec/bundler/fetcher/gem_remote_fetcher_local_ssl_server_spec.rb:49:in 'block (4 levels) in <top (required)>'
     # ./spec/spec_helper.rb:164:in 'block (4 levels) in <top (required)>'
     # ./spec/spec_helper.rb:164:in 'block (3 levels) in <top (required)>'
     # ./spec/support/helpers.rb:414:in 'block in Spec::Helpers#with_gem_path_as'
     # ./spec/support/helpers.rb:428:in 'Spec::Helpers#without_env_side_effects'
     # ./spec/support/helpers.rb:409:in 'Spec::Helpers#with_gem_path_as'
     # ./spec/spec_helper.rb:163:in 'block (2 levels) in <top (required)>'
     # ./lib/rubygems.rb:306:in 'Kernel#load'
     # ./lib/rubygems.rb:306:in 'Gem.activate_and_load_bin_path'
```

spec/commands/ssl_spec.rb
```
...
  after(:each) do
    ...
    Artifice.deactivate
    ...
  end
...
```

Assisted-by: Claude:claude-opus-4-6[1m]

ruby/rubygems@0ae3860638
…plicitly.

This commit fixes the following failures.
The `require "support/artifice/compact_index"` is not enough
because the file is not loaded when it is called second time.

```
  1) Bundler::ParallelInstaller connect to make jobserver takes all available slots
     Failure/Error: raise HTTPError, e.message

     Bundler::HTTPError:
       Could not reach host gem.repo2. Check your network connection and try again.
     # ./spec/bundler/installer/parallel_installer_spec.rb:151:in 'block (4 levels) in <top (required)>'
     # ./spec/bundler/installer/parallel_installer_spec.rb:221:in 'RSpec::ExampleGroups::BundlerParallelInstaller::ConnectToMakeJobserver#redefine_build_jobs'
     # ./spec/bundler/installer/parallel_installer_spec.rb:150:in 'block (3 levels) in <top (required)>'
     # ./spec/spec_helper.rb:164:in 'block (4 levels) in <top (required)>'
     # ./spec/spec_helper.rb:164:in 'block (3 levels) in <top (required)>'
     # ./spec/support/helpers.rb:414:in 'block in Spec::Helpers#with_gem_path_as'
     # ./spec/support/helpers.rb:428:in 'Spec::Helpers#without_env_side_effects'
     # ./spec/support/helpers.rb:409:in 'Spec::Helpers#with_gem_path_as'
     # ./spec/spec_helper.rb:163:in 'block (2 levels) in <top (required)>'
     # ./lib/rubygems.rb:306:in 'Kernel#load'
     # ./lib/rubygems.rb:306:in 'Gem.activate_and_load_bin_path'
     # ------------------
     # --- Caused by: ---
     # Bundler::HTTPError:
     #   Could not reach host gem.repo2. Check your network connection and try again.
     #   ./spec/bundler/installer/parallel_installer_spec.rb:151:in 'block (4 levels) in <top (required)>'
...
```

Assisted-by: Claude:claude-opus-4-6[1m]

ruby/rubygems@62d4fb06fc
Check for `step` before the length, although it looks impossible to
create 0-step `ArithmeticSequence` currently.
Move `Symbol#empty?` from the C `sym_empty` into `symbol.rb`, implemented as `RBOOL(RSTRING_LEN(rb_sym2str(self)) == 0)`, mirroring the existing Symbol#to_s and #name leaf builtins.

Also added an `annotate_builtin! ` in `zjit/src/cruby_methods.rs` to tell ZJIT that the method does not need GC now. 

`Symbol#empty?` as a leaf builtin, via `benchmark-driver` (`GC.disable`, `loop_count: 20_000_000`, Apple M1). Speedup vs master (CFUNC `sym_empty`):

| benchmark | interpreter | `--yjit` | `--zjit` |
|---|---:|---:|---:|
| `:"".empty?`       | **1.24x** | **1.30x** | **1.19x** |
| `:abcdefgh.empty?` | **1.19x** | **1.19x** | **1.17x** |

Windows native and WSL2 also get faster:

| benchmark | interpreter |
|---|---:|
| `:"".empty?`       | **1.47x** |
| `:abcdefgh.empty?` | **1.36x** |

### WSL2 (Ubuntu) `x86_64-linux`

| benchmark | interpreter | `--yjit` | `--zjit` |
|---|---:|---:|---:|
| `:"".empty?`       | **1.39x** | **1.33x** | **1.32x** |
| `:abcdefgh.empty?` | **1.37x** | **1.39x** | **1.33x** |
ruby/psych#805 added files psych_emitter_fy.c and
psych_parser_fy.c so we need to update the depend file too.
No need for a separate pass. We can handle it with the other
specialization.
Co-authored-by: Takashi Kokubun <takashikkbn@gmail.com>
@pull pull Bot locked and limited conversation to collaborators Jul 2, 2026
@pull pull Bot added the ⤵️ pull label Jul 2, 2026
@pull pull Bot merged commit 33e58bc into turkdevops:master Jul 2, 2026
1 of 3 checks passed
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants