Skip to content

Change how nodeids are created in relation to rootdir #11245

@bluetech

Description

@bluetech

This issue is about the path part of the nodeid (the part before the ::).

Problem

Generally, the path part of a nodeid is created by taking the node's path relative to the rootdir.
But, if the node's path is not below the rootdir ("out of tree"), then we create its nodeid relative to the initial paths (= paths given in the command line), specifically the first one which contains the path. This was added in 14b6380 as a fix for an issue with out-of-tree --pyargs (2775) which would result in an empty nodeid path.

This change broke an important property of the nodeid, that it is always relative to the rootdir, or said differently, that the nodeid cannot be relied upon to be the root of all nodeids. This causes various issues that crop up when such invariants are broken:

  • ambiguous nodeids
  • duplicate nodeids
  • incorrect printing of nodeids

See #11186, #6605, #3714.

The issues mostly stem from the fact that a nodeid does not carry around the context of which path it it relative to, so the context is lost and becomes ambiguous.

Proposed solution

Perhaps the simplest fix is to change back to always using the rootdir, but now allowing .. (parent directory) segments in the nodeid path. This is kind of ugly, but running tests outside the rootdir is discouraged anyway, so I'm not too worried about it, in fact it might encourage settings the rootdir correctly...

I have an initial implementation here: https://github.com/bluetech/pytest/commits/rootdir-rel

Other solutions?

Another solution might be to change nodeids to be structured and maintain the context. However, users still interact with nodeids as strings so I don't think this can go very far.

And another solution can be that out-of-tree nodeids just always use absolute paths e.g. /my/out/of/tree/test.py::test_it instead of ../../of/tree/test.py::test_it. Maybe it's better?

Metadata

Metadata

Assignees

No one assigned

    Labels

    topic: collectionrelated to the collection phasetype: 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