Skip to content

FixtureRequest.node should be typed to return a Node #13888

Open

Description

@sk-

Currently the property node of FixtureRequest is defined as

    @property
    @abc.abstractmethod
    def node(self):
         """Underlying collection node (depends on current request scope)."""
         raise NotImplementedError()

which implicitly types the return type as Any. However, based on the name of the function and the underlying implementations it should return a nodes.Node.

Unfortunately, when I tried this on a fork, I got the following error:

mypy............................................................................Failed
- hook id: mypy
- exit code: 1

src/_pytest/junitxml.py:294: error: "Node" has no attribute "user_properties"  [attr-defined]
Found 1 error in 1 file (checked 239 source files)

This happens because junitxml actually expects to receive a nodes.NodeItem instead of a plain nodes.Node.

One quick fix for this would be to put a type assertion in junitxml, but I'm not sure if that's the preferred approach. I'd be happy to send a PR if someone could give ve some guidance on how to best resolve this.

Activity

  1. bluetech commented on Nov 10, 2025

    @bluetech
    Member

    We actually don't expose Node, but it's mostly equivalent to Item | Collector.

    However, the reason we don't type request.node is that returning a general Item | Collector would often be annoying, since the user knows that it's a more specific node type (e.g. Function) but the typing cannot know that. So we opt for less type safety over forcing users to do assert isinstance or casts.

  2. added
    type: proposalproposal for a new feature, often to gather opinions or design the API around the new feature
    topic: fixturesanything involving fixtures directly or indirectly
    on Nov 10, 2025
  3. sk- commented on Nov 10, 2025

    @sk-
    Author

    Thanks Ran for the response, I had not noticed that nodes.Node is not exported.

    Typing it as Item | Collector would work for our use case as we are accessing nodeid (request.node.nodeid). Having types is important as without the type annotations we need to type the result explicitly.

    I understand that adding types in the presence of subclass may become annoying specially when one knows the type must be of certain class. However, I would argue that these assumptions could be error prone as those assumptions may change, specially for users of pytest (inside pytest assumptions should be safer). In fact, in the particular case of pytest, the proposed change would only require an instance check in junitxml.

    Note also that given that Node is not exported, if we wanted to type request.node on the consumer side, we would need to somehow know that this is equivalent to Item | Collector. Maybe a reference could be added to the docs.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    topic: fixturesanything involving fixtures directly or indirectlytopic: typingtype-annotation issuetype: proposalproposal for a new feature, often to gather opinions or design the API around the new feature

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions