Skip to content

fix(step): support attribute access in step title placeholders#910

Open
golikovichev wants to merge 1 commit intoallure-framework:masterfrom
golikovichev:fix-step-placeholder-attribute-access
Open

fix(step): support attribute access in step title placeholders#910
golikovichev wants to merge 1 commit intoallure-framework:masterfrom
golikovichev:fix-step-placeholder-attribute-access

Conversation

@golikovichev
Copy link
Copy Markdown

Closes #896.

Problem

@allure.step("Process: {data.name}") raises AttributeError when data is an object with a name attribute (for example a dataclass), because func_parameters() converts every parameter value to its string representation before str.format() runs. By the time the title is being formatted, the values are already strings, so attribute access on {data.name} fails.

Root cause

In allure-python-commons/src/allure_commons/utils.py, func_parameters() applies represent() to every value at the moment it builds the parameter mapping:

sorted_items = sorted(
    map(
        lambda kv: (kv[0], represent(kv[1])),  # values become strings here
        items
    ),
    ...
)

In _allure.py, the step decorator passed that already-stringified mapping to self.title.format(*args, **params), so {data.name} tried to access .name on a string and raised.

Fix

Introduce _StepTitleFormatter, a subclass of string.Formatter, that defers represent() to format_field, applied after attribute traversal. The decorator now hands the formatter the raw arguments (with defaults filled in from the function signature), so attribute traversal operates on the original objects. Leaf values are still wrapped via represent(), which preserves the existing repr-style display for plain positional and keyword placeholders.

Behaviour

  • Existing positional and keyword placeholders unchanged.
  • Object attribute placeholders work: {data.name} traverses to the attribute and then applies represent() on the leaf value.
  • Nested attribute access works: {user.address.city}.
  • Method calls (self and cls first arg) continue to work.
  • Default values for arguments are honoured, matching func_parameters().

Tests

Added a new regression test file tests/allure_pytest/acceptance/step/step_attribute_placeholder_test.py covering:

  1. Dataclass attribute access in a step title.
  2. Plain object (non-dataclass) attribute access.
  3. Nested attribute access (user.address.city).

All existing step tests continue to pass:

tests/allure_pytest/acceptance/step/ ... 14 passed
tests/allure_pytest/ (excluding pre-existing externals failures) ... 265 passed

The 6 failures in tests/allure_pytest/externals/ reproduce on master without my changes (missing optional plugins such as pytest-check in the dev environment) and are unrelated to this PR.

Closes allure-framework#896.

@allure.step("Process: {data.name}") used to raise AttributeError when
data was an object such as a dataclass. The reason was that
func_parameters() called represent() on every parameter value before
str.format() ran, so by the time the title was being formatted all
arguments were already strings and {data.name} tried attribute access
on a string.

Fix: introduce _StepTitleFormatter, a subclass of string.Formatter, that
applies represent() in format_field instead of at parameter binding
time. The formatter is given the raw arguments (with defaults filled in
from the function signature), so attribute traversal works on the
original objects. The leaf value is then wrapped via represent(),
preserving the existing repr-style display for plain positional and
keyword placeholders.

Added regression tests covering dataclass attribute access, plain
object attribute access, and nested attribute access (user.address.city).
@CLAassistant
Copy link
Copy Markdown

CLAassistant commented May 3, 2026

CLA assistant check
All committers have signed the CLA.

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.

Allure step placeholder fails when accessing dataclass attribute data.name

2 participants