From 00cb1ed09cd8de505160d7b5464875dbed796054 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Wed, 4 Jun 2025 20:30:46 +0000 Subject: [PATCH] Fix: Make fcntl usage conditional in mcpm share for Windows compatibility The `fcntl` module is not available on Windows, and its direct import was causing `ImportError` when `mcpm share` was invoked or its module (src/mcpm/commands/share.py) was loaded on Windows systems. This commit makes the import and usage of `fcntl` within the `make_non_blocking` function conditional on `os.name == 'posix'`. On non-POSIX systems (like Windows), the function will now do nothing. The existing code for reading from subprocess pipes in `mcpm share` utilizes `select.select()` with timeouts and handles `IOError`/`OSError` exceptions. This setup is expected to provide sufficient non-blocking behavior for reading subprocess output on Windows, even without an explicit `fcntl` call to set `O_NONBLOCK`. Note: Full dynamic testing of `mcpm share` on a Windows-like environment was not possible due to a Python version mismatch (environment: 3.10.17, project requires: >=3.11) in the available testing sandbox. This change addresses the direct `ImportError`. --- src/mcpm/commands/share.py | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/mcpm/commands/share.py b/src/mcpm/commands/share.py index 51411b1a..16c53dcb 100644 --- a/src/mcpm/commands/share.py +++ b/src/mcpm/commands/share.py @@ -29,11 +29,15 @@ def find_mcp_proxy() -> Optional[str]: def make_non_blocking(file_obj): """Make a file object non-blocking.""" - import fcntl - - fd = file_obj.fileno() - fl = fcntl.fcntl(fd, fcntl.F_GETFL) - fcntl.fcntl(fd, fcntl.F_SETFL, fl | os.O_NONBLOCK) + if os.name == 'posix': + import fcntl + + fd = file_obj.fileno() + fl = fcntl.fcntl(fd, fcntl.F_GETFL) + fcntl.fcntl(fd, fcntl.F_SETFL, fl | os.O_NONBLOCK) + # On other platforms (e.g., Windows), we rely on the behavior of select() + # and the non-blocking nature of readline() on Popen streams, + # or the existing try-except for IOError/OSError. def wait_for_random_port(process: subprocess.Popen, timeout: int = 20) -> Optional[int]: