Skip to content
Open
Show file tree
Hide file tree
Changes from 5 commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions AUTHORS
Original file line number Diff line number Diff line change
Expand Up @@ -440,6 +440,7 @@ Sylvain Marié
Tadek Teleżyński
Takafumi Arakaki
Takumi Otani
Tammy Hartline
Taneli Hukkinen
Tanvi Mehta
Tanya Agarwal
Expand Down
1 change: 1 addition & 0 deletions changelog/13817.bugfix.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fixed ``AttributeError`` in ``Argument.__repr__`` when ``dest`` attribute is not set, which occurred when displaying error messages for invalid option names. The error now shows a helpful message instead of masking the original validation error.
5 changes: 4 additions & 1 deletion src/_pytest/config/argparsing.py
Original file line number Diff line number Diff line change
Expand Up @@ -359,7 +359,10 @@ def __repr__(self) -> str:
args += ["_short_opts: " + repr(self._short_opts)]
if self._long_opts:
args += ["_long_opts: " + repr(self._long_opts)]
args += ["dest: " + repr(self.dest)]
if hasattr(self, "dest"):
args += ["dest: " + repr(self.dest)]
else:
args += ["dest: <not set>"]
if hasattr(self, "type"):
args += ["type: " + repr(self.type)]
if hasattr(self, "default"):
Expand Down
54 changes: 54 additions & 0 deletions testing/test_argparsing_repr_fix.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
"""
Test case for issue #13817: AttributeError with invalid flag in pytest_addoption
"""

from __future__ import annotations

from _pytest.config.argparsing import ArgumentError
from _pytest.config.argparsing import Parser
import pytest


# Suppress warning about using private pytest API (we're testing pytest itself)
@pytest.mark.filterwarnings("ignore::pytest.PytestDeprecationWarning")
class TestArgumentReprFix:
"""Test that Argument.__repr__ handles missing dest attribute."""

def test_invalid_option_without_dashes(self) -> None:
"""Test that invalid option names produce helpful error messages."""
parser = Parser()

with pytest.raises(ArgumentError) as exc_info:
parser.addoption("shuffle") # Missing required -- prefix

error_message = str(exc_info.value)
assert "invalid long option string" in error_message
assert "shuffle" in error_message
assert "must start with --" in error_message

# Ensure no AttributeError is mentioned
assert "AttributeError" not in error_message
assert "has no attribute 'dest'" not in error_message

def test_invalid_short_option(self) -> None:
"""Test that invalid short option names produce helpful error messages."""
parser = Parser()

with pytest.raises(ArgumentError) as exc_info:
parser.addoption("-ab") # 3 chars, treated as invalid long option

error_message = str(exc_info.value)
# -ab is treated as invalid long option (3+ chars)
assert (
"invalid long option string" in error_message
or "invalid short option string" in error_message
)

def test_valid_option_works(self) -> None:
"""Test that valid options still work correctly."""
parser = Parser()
parser.addoption("--shuffle", action="store_true", help="Shuffle tests")

options = parser._anonymous.options
assert len(options) > 0
assert "--shuffle" in options[0].names()