Skip to content

Conversation

Copy link

Copilot AI commented Oct 21, 2025

  • Explore repository structure and understand the issue
  • Verify that OSError fix is already in place (commit 14d3707)
  • Verify that changelog entry was processed for pytest 8.3.0
  • Add comprehensive test for OSError handling in get_user()
  • Address review feedback: skip on non-Windows platforms and use direct values
  • Run tests to verify the fix works correctly

Summary

Successfully addressed the Python 3.13+/Windows tmpdir crash issue. The code fix was already present in the main branch (added in commit 14d3707 and released in pytest 8.3.0), but was missing comprehensive test coverage.

Changes Made:

  • Added test_get_user_handles_oserror() in testing/test_tmpdir.py
  • Test skips on non-Windows platforms (follows existing pattern)
  • Test removes all four environment variables (LOGNAME, USER, LNAME, USERNAME) directly
  • This properly tests the Python 3.13+ behavior where OSError is raised when these vars are missing

Review Feedback Addressed:

  • Updated test to skip on non-affected platforms using @pytest.mark.skipif(not sys.platform.startswith("win"), reason="win only")
  • Changed from mocking getpass.getuser() to directly removing environment variables using monkeypatch.delenv()
  • Removes all four env vars that Python 3.13's getpass.getuser() checks

Test Details:
The test validates that when all username environment variables are removed on Windows, get_user() returns None instead of crashing. On Python 3.13+, this exercises the OSError handling path. On older Python versions, it may use fallback mechanisms but should still return None.

Original prompt

This section details on the original issue you should resolve

<issue_title>Pytest tmpdir crashes on Python 3.13+/Windows when no username env vars are set (getpass.getuser now raises OSError)</issue_title>
<issue_description>Bug report generated by co-pilot EXCEPT me having to edit a bunch since it was confusing and too much blabbing:

Summary:
On Python 3.13 and 3.14 (RC) under Windows, pytest fails early with OSError: No username set in the environment if none of LOGNAME, USER, LNAME, USERNAME are present. The failure originates in _pytest/tmpdir.get_user(), which only catches ImportError and KeyError, but Python 3.13 changed getpass.getuser() to raise OSError when no username can be derived. This was previously tolerated.

Environment:

  • OS: Windows 10/11 (64-bit)
  • Python: 3.13.0 / 3.14.0rc3 (installed via uv python install 3.13 3.14)
  • Pytest: 7.4.3 (also reproduced with latest 7.x)
  • Invocation context: Subprocess without username env vars (custom runner; uv seems to sanitize environment)

Relevant Python change:
Per Python 3.13 getpass.py (getuser docstring): Behavior changed to consistently raise OSError when no environment user identifiers exist and pwd (Unix-only) is not available.
Observed Error (truncated): OSError: No username set in the environment File .../Lib/getpass.py:236, in getuser raise OSError('No username set in the environment') from e

Pytest stack location: _in _pytest/tmpdir.py: get_user() calls getpass.getuser() without handling OSError.

Minimal Reproduction (Windows, Python 3.13+):
Create a clean directory with a trivial test file:

echo "def test_ok(): pass" > test_sample.py

Launch Python with some variables cleared:

  • LOGNAME, USER, LNAME, USERNAME all set to ""

Execute:
python -c "import os, subprocess; [os.environ.pop(v,None) for v in ['LOGNAME','USER','LNAME','USERNAME']]; import pytest; raise SystemExit(pytest.main(['-q']))"

Result:
pytest crashes with OSError before collection finishes.

    def getuser():
        """Get the username from the environment or password database.

        First try various environment variables, then the password
        database.  This works on Windows as long as USERNAME is set.
        Any failure to find a username raises OSError.

        .. versionchanged:: 3.13
            Previously, various exceptions beyond just :exc:`OSError`
            were raised.
        """

        for name in ('LOGNAME', 'USER', 'LNAME', 'USERNAME'):
            user = os.environ.get(name)
            if user:
                return user

        try:
>           import pwd
E           ModuleNotFoundError: No module named 'pwd'

C:\Users\shg\AppData\Roaming\uv\python\cpython-3.13.5-windows-x86_64-none\Lib\getpass.py:172: ModuleNotFoundError

The above exception was the direct cause of the following exception:

    def getuser():
        """Get the username from the environment or password database.

        First try various environment variables, then the password
        database.  This works on Windows as long as USERNAME is set.
        Any failure to find a username raises OSError.

        .. versionchanged:: 3.13
            Previously, various exceptions beyond just :exc:`OSError`
            were raised.
        """

        for name in ('LOGNAME', 'USER', 'LNAME', 'USERNAME'):
            user = os.environ.get(name)
            if user:
                return user

        try:
            import pwd
            return pwd.getpwuid(os.getuid())[0]
        except (ImportError, KeyError) as e:
>           raise OSError('No username set in the environment') from e
E           OSError: No username set in the environment

Actual: Session aborts with uncaught OSError.

Root Cause:
Python 3.13 tighten semantics:
getpass.getuser() now raises OSError when no identifier found. Pytest’s get_user only catches ImportError and KeyError: except (ImportError, KeyError): return None Missing OSError handling lets the exception propagate.
Proposed Fix: Expand exception clause to include OSError.

Rationale:

Restores pre-3.13 resilient behavior.

Narrow catch still specific to getpass failure modes; avoids masking unrelated errors.
Workaround (for users now): Set an env var before running pytest

e.g. in conftest.py:

import os
if not any(os.environ.get(n) for n in ('LOGNAME','USER','LNAME','USERNAME')): os.environ['USERNAME'] = 'tester'

Or inject in tox.ini: [testenv] setenv = USERNAME = tester

Impact:
Any Windows/CI environment invoking pytest under Python 3.13+ without a username env var will fail until patched. Silent in earlier versions because getpass.getuser() returned a fallback or raised only ImportError/KeyError.
Regression Risk: Low. Adding OSError aligns with documented new behavior. Does not affect normal environments where env vars are present.</issue_description>

<agent_instructions>create the suggested minimal bugfix and accompany it with a minimal unittest and the requ...

Fixes #13835


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

Copilot AI changed the title [WIP] Fix pytest tmpdir crash on Python 3.13+ Windows Add test coverage for OSError handling in get_user() for Python 3.13+ compatibility Oct 21, 2025
Copilot finished work on behalf of RonnyPfannschmidt October 21, 2025 20:20
"""
import getpass

def mock_getuser():
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot this tests the wrong thing

The test shoul skip on non affected platforms and use direct values

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated in commit 9c8e8d8. The test now:

  • Skips on non-Windows platforms using @pytest.mark.skipif(not sys.platform.startswith("win"), reason="win only")
  • Uses direct environment variable removal with monkeypatch.delenv() for all four variables (LOGNAME, USER, LNAME, USERNAME) instead of mocking

Copilot finished work on behalf of RonnyPfannschmidt October 21, 2025 21:57
@RonnyPfannschmidt
Copy link
Member

closing this a as failed experiment - the prompt to make the ai do it seems to be about as much effort as doing it manually

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Pytest tmpdir crashes on Python 3.13+/Windows when no username env vars are set (getpass.getuser now raises OSError)

2 participants