Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: closes #11343's [attr-defined] type errors #11345

28 changes: 19 additions & 9 deletions src/_pytest/compat.py
Original file line number Diff line number Diff line change
Expand Up @@ -313,16 +313,26 @@ def safe_isclass(obj: object) -> bool:
return False


def get_user_id() -> int | None:
"""Return the current user id, or None if we cannot get it reliably on the current platform."""
# win32 does not have a getuid() function.
# On Emscripten, getuid() is a stub that always returns 0.
if sys.platform in ("win32", "emscripten"):
def get_user_id(*, UNRELIABLE: int = -1) -> int | None:
Copy link
Member

Choose a reason for hiding this comment

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

Did you mean this extra argument as some future-proofing?

I think this is the wrong approach: the caller should not need to know which is the value that represents an error from os.getuid. If it ever varies between platforms, it should be handled internally by get_user_id itself.

Now, if your intent is to improve reliability, instead of the hardcoded value we had before, you can move it to a constant:

UNRELIABLE = -1
return uid if uid != UNRELIABLE else None

(Also parameters should be camel case).

"""Return the current user id, or None if we cannot get it reliably on
the current platform.

:param UNRELIABLE:
The platform-specific constant which indicates that the retrieved uid
is unreliable. The default value, -1, is a common unreliability
indicator on UNIX-like systems.
:return: The user id or None
nicoddemus marked this conversation as resolved.
Show resolved Hide resolved
"""
# mypy follows the version and platform checking expectation of PEP 484:
# https://mypy.readthedocs.io/en/stable/common_issues.html?highlight=platform#python-version-and-system-platform-checks
# Containment checks are too complex for mypy v1.5.0 and cause failure.
if sys.platform == "win32" or sys.platform == "emscripten":
# win32 does not have a getuid() function.
# Emscripten has a return 0 stub.
return None
# getuid shouldn't fail, but cpython defines such a case.
# Let's hope for the best.
uid = os.getuid()
return uid if uid != -1 else None
else:
uid = os.getuid()
return uid if uid != UNRELIABLE else None


# Perform exhaustiveness checking.
Expand Down
3 changes: 2 additions & 1 deletion testing/test_parseopt.py
Original file line number Diff line number Diff line change
Expand Up @@ -291,7 +291,8 @@ def test_multiple_metavar_help(self, parser: parseopt.Parser) -> None:

def test_argcomplete(pytester: Pytester, monkeypatch: MonkeyPatch) -> None:
try:
encoding = locale.getencoding() # New in Python 3.11, ignores utf-8 mode
# New in Python 3.11, ignores utf-8 mode
encoding = locale.getencoding() # type: ignore[attr-defined]
except AttributeError:
encoding = locale.getpreferredencoding(False)
try:
Expand Down