Skip to content

feat: override IO::File::open for mocked file compatibility#220

Draft
Koan-Bot wants to merge 2 commits intocpanel:masterfrom
atoomic:koan.atoomic/io-file-compat
Draft

feat: override IO::File::open for mocked file compatibility#220
Koan-Bot wants to merge 2 commits intocpanel:masterfrom
atoomic:koan.atoomic/io-file-compat

Conversation

@Koan-Bot
Copy link
Contributor

What

Override IO::File::open so that IO::File->new($mocked_file) works correctly with mocked files.

Why

IO::File::open() uses CORE::open internally, which bypasses CORE::GLOBAL::open. This means any module using IO::File (e.g. Config::MySQL::Reader via Mixin::Linewise::Readers) would silently ignore mocked files — reading from the real filesystem or failing.

Fixes #39.

How

  • Save original IO::File::open and replace with _io_file_open_override
  • The override checks if the target file is in %files_being_mocked
  • If mocked: ties the existing IO::File glob (no new handle creation needed) via _io_file_mock_open
  • If not mocked: goto &$_orig_io_file_open passes through to the original
  • Numeric sysopen modes already work (they go through CORE::GLOBAL::sysopen), so those are just forwarded

Same pattern as the Cwd::abs_path override (PR #211) — intercept at the namespace level when internal code bypasses CORE::GLOBAL.

Testing

  • t/io_file_compat.t: 13 test groups covering IO::File->new with read/write/append/r+ modes, 2-arg embedded mode, $fh->open() method, getline(), sysopen numeric modes, and non-existent mock files.

🤖 Generated with Claude Code

@Koan-Bot
Copy link
Contributor Author

Rebase: feat: override IO::File::open for mocked file compatibility

Branch koan.atoomic/io-file-compat has been rebased onto master and force-pushed.

Actions

  • Rebased koan.atoomic/io-file-compat onto origin/master
  • Force-pushed koan.atoomic/io-file-compat to origin

Automated by Kōan

@Koan-Bot Koan-Bot force-pushed the koan.atoomic/io-file-compat branch 2 times, most recently from 4816643 to 0c75b5c Compare February 25, 2026 05:04
@Koan-Bot Koan-Bot force-pushed the koan.atoomic/io-file-compat branch from 0c75b5c to ac7e277 Compare February 25, 2026 18:03
@Koan-Bot
Copy link
Contributor Author

Rebased onto upstream/master

Resolved conflict in BEGIN block — added truncate override (from merged PRs #223, #199) alongside the IO::File override.

Clean rebase, 2 commits preserved.

@Koan-Bot Koan-Bot force-pushed the koan.atoomic/io-file-compat branch 3 times, most recently from a7a17e4 to 1e5285f Compare February 26, 2026 19:35
Koan-Bot and others added 2 commits February 26, 2026 14:01
IO::File::open() uses CORE::open internally, which bypasses
CORE::GLOBAL::open and makes IO::File->new() ignore mocked files.

Fix: replace IO::File::open with a wrapper that checks if the target
file is mocked. If mocked, tie the existing IO::File glob directly
(avoiding the need to create a new handle). If not mocked, fall
through to the original IO::File::open via goto.

This follows the same pattern as the Cwd::abs_path override (PR cpanel#211)
— intercept at the namespace level when C/XS code bypasses CORE::GLOBAL.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When _io_file_open_override passed numeric modes to sysopen(),
__sysopen replaced $_[0] with a new IO::File glob — but the
original IO::File glob held by the caller was never updated.

For mocked files, convert sysopen flags to string modes and use
_io_file_mock_open which ties the existing glob in place. Only
fall through to real sysopen for non-mocked files.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@Koan-Bot Koan-Bot force-pushed the koan.atoomic/io-file-compat branch from 1e5285f to 24f4723 Compare February 26, 2026 21:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

Doesn't work with Config::MySQL::Reader ( and maybe IO::File )

1 participant