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

conversion of exit codes to enum + exposure #5420

Merged
merged 7 commits into from
Jun 16, 2019

Conversation

RonnyPfannschmidt
Copy link
Member

fixes #5125

@nicoddemus
Copy link
Member

Howdy @RonnyPfannschmidt!

Are you back from your hiatus? 😁

@RonnyPfannschmidt
Copy link
Member Author

no, im currently on childcare leave since the rest of the family is sick and in bed, since they finally sleep i picked something easy that still allows me to retain my code-base familiarity

@codecov

This comment has been minimized.

@RonnyPfannschmidt
Copy link
Member Author

the last value failure is tricky, there is no simple way not to break the api wrt giving full allowance over the exit code anyway

@RonnyPfannschmidt
Copy link
Member Author

for now i do a unconditional warning, im wondering if that should be the case or if the code should be silent about it for now

in future i'd like to arrive at a stage where pytest return codes are well defined and enumerated

@RonnyPfannschmidt RonnyPfannschmidt changed the title WIP: conversion of exit codes to enum + exposure conversion of exit codes to enum + exposure Jun 9, 2019
@RonnyPfannschmidt
Copy link
Member Author

im not sure where to best document this

@nicoddemus
Copy link
Member

im not sure where to best document this

How about in reference.rst?

@nicoddemus
Copy link
Member

nicoddemus commented Jun 13, 2019

Thanks @RonnyPfannschmidt!

While the solution is clever, I'm a little concerned to introduce a exit_code public variable which is very similar to exitstatus, I'm sure it will bring confusion to users.

I've taken one of your earliest commits (b7cd089) and managed to fix the issue locally in xdist with this trivial change:

diff --git a/src/xdist/remote.py b/src/xdist/remote.py
index d87ff4c..1643a64 100644
--- a/src/xdist/remote.py
+++ b/src/xdist/remote.py
@@ -41,7 +41,7 @@ class WorkerInteractor(object):

     @pytest.hookimpl(hookwrapper=True)
     def pytest_sessionfinish(self, exitstatus):
-        self.config.workeroutput["exitstatus"] = exitstatus
+        self.config.workeroutput["exitstatus"] = int(exitstatus)
         yield
         self.sendevent("workerfinished", workeroutput=self.config.workeroutput)

So I think we are better off fixing this in pytest-xdist rather than introduce a new confusing public attribute. I volunteer to fix this in pytest-xdist and make a new release. What do you think?

@nicoddemus
Copy link
Member

docs note: there's a Possible exit codes section in usage.rst which should refer to the ExitCode enum in reference.rst.

@RonnyPfannschmidt
Copy link
Member Author

implementing it the proposed way is a breaking api change, i'd much rather introduce a new name for the new behavior and then deprecate the old before removing it later

while at it we also should introduce errro codes where plugins and test-suites can indicate errors within them and forbid free error codes

@nicoddemus
Copy link
Member

nicoddemus commented Jun 14, 2019

implementing it the proposed way is a breaking api change

The whole purpose of IntEnum is to change old constant-integers API we had to the new IntEnum in a backward compatible way. Can you provide a code sample of where changing exitstatus to an IntEnum breaks existing code, other than someone doing highly unlikely as expecting int(session.status) is int to be True?

Even if it is a breaking API change, we will be releasing it in 5.0, which is a major release and breaking changes are possible (not that I really thing this will break anything, mind you).

i'd much rather introduce a new name for the new behavior and then deprecate the old before removing it later

TBH I would rather then keep the old constants and publish them properly as attributes of sessionas suggested initially, rather than introducing a confusing new name just and deprecating the old existing name later.

@nicoddemus
Copy link
Member

nicoddemus commented Jun 14, 2019

Why closing @RonnyPfannschmidt? I think the change to IntEnum could go as a "breaking API change" into 5.0. I doubt it would bring any fallout TBH.

@RonnyPfannschmidt
Copy link
Member Author

i missunderstood then - but in that case i'd like to prohibit non-declared exit codes in general

@nicoddemus
Copy link
Member

i missunderstood then

Hmm sorry then, let me try to be clear about my point of view:

I think it is OK to introduce the ExitCode enum as the type of exitstatus in 5.0, noting that this might break esoteric cases but we don't expect major problems for users, as the IntEnum is highly compatible with ints.

The small xdist problem is trivially fixable and it is not a good example of problems that code out there can encounter caused by this change because xdist is really a special case because of execnet.

Having said that, if you agree, these changes are required before we can merge:

  1. Implement and release the small xdist change I posted before
  2. Remove the exit_code attribute
  3. Add docs: reference.rst and usage.rst

I'm happy to do 1).

What do you think?

@RonnyPfannschmidt
Copy link
Member Author

i'll pick the branch up later today, i just noted its on my desktop, and not the work laptop i have with me as im currently somewhere else - git branch sync is such a pain ^^

@nicoddemus
Copy link
Member

Sounds great. 👍

nicoddemus added a commit to nicoddemus/pytest-xdist that referenced this pull request Jun 14, 2019
nicoddemus added a commit to nicoddemus/pytest-xdist that referenced this pull request Jun 14, 2019
@nicoddemus
Copy link
Member

Done: pytest-dev/pytest-xdist#442 👍

@blueyed

This comment has been minimized.

@RonnyPfannschmidt

This comment has been minimized.

@RonnyPfannschmidt
Copy link
Member Author

i returned back to the state where passing a integer is still valid, but the type is now primaryly the enum, that gives some wiggle room until we deprecate user defined random values for real

@RonnyPfannschmidt
Copy link
Member Author

passes with new xdist t seems :) 👍 @nicoddemus

Copy link
Member

@nicoddemus nicoddemus left a comment

Choose a reason for hiding this comment

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

Looks great, thanks!

I think we are only missing docs now:

  • Add ExitCode to reference.rst
  • Link ExitCode in the "Possible exit codes" section in usage.rst

src/_pytest/main.py Show resolved Hide resolved
@@ -0,0 +1,2 @@
Introduce the ``pytest.ExitCode`` Enum and make session.exitcode an instance of it.
User defined exit codes are still valid, but consumers need to take the enum into account.
Copy link
Member

Choose a reason for hiding this comment

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

"but consumers need to take the enum into account."

Not clear to me what this means, what consumers would need to do specifically?

Copy link
Member Author

Choose a reason for hiding this comment

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

users of that api, like the xdist release you just made to support it

Copy link
Member

Choose a reason for hiding this comment

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

Ahh OK, I got confused because I thought the first and second sentence were related, but the "but consumers take the enum into account" phrase was actually referring to the "Introduce the pytestExitCode" phase.

Copy link
Member

Choose a reason for hiding this comment

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

How about:

``Session.exitcode`` values are now coded in ``pytest.ExitCode``, an ``IntEnum``. This makes the exit code available for consumer code and are more explicit other than just documentation. User defined exit codes are still valid, but should be used with caution.

The team doesn't expect this change to break test suites or plugins in general, except in esoteric/specific scenarios.

**pytest-xdist** users should upgrade to ``1.29.0`` or later, as ``pytest-xdist`` required a compatibility fix because of this change.

(can't use the "suggestion" feature as this spams multiple lines)

@nicoddemus nicoddemus added this to the 5.0 milestone Jun 15, 2019
class ExitCode(enum.IntEnum):
OK = 0
TESTS_FAILED = 1
INTERRUPTED = 2
Copy link
Member

Choose a reason for hiding this comment

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

Just occurred to me: is there a consensus about how to name the enumerate members? test_failed, TestsFailed or TESTS_FAILED? I've not seen many enums in the wild so I'm not sure. 🤔

Copy link
Member

Choose a reason for hiding this comment

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

Hmm all examples in the enum docs show ALL_CAPS, so I think we are fine. 👍

Copy link
Member Author

Choose a reason for hiding this comment

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

using PEP8 for constants

Copy link
Member Author

Choose a reason for hiding this comment

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

basically enum members are constants, thus follow the same rules as constants ^^


class ExitCode(enum.IntEnum):
"""
encodes the valid exit codes of pytest
Copy link
Member

Choose a reason for hiding this comment

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

This paragraph is not looking too good:

image

Suggestion:

Encodes the valid exit codes by pytest.

Currently users and plugins may supply other exit codes as well.

Copy link
Member

@nicoddemus nicoddemus left a comment

Choose a reason for hiding this comment

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

Also please add a link to usage.rst. 😁

Copy link
Member

@nicoddemus nicoddemus left a comment

Choose a reason for hiding this comment

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

Thanks!

@nicoddemus nicoddemus merged commit bbfc8d1 into pytest-dev:master Jun 16, 2019
@@ -33,6 +33,8 @@ Running ``pytest`` can result in six different exit codes:
:Exit code 4: pytest command line usage error
:Exit code 5: No tests were collected

They are repressended by the :class:`_pytest.main.ExitCode` enum.
Copy link
Contributor

Choose a reason for hiding this comment

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

*represented

INTERRUPTED = 2
#: an internal error got in the way
INTERNAL_ERROR = 3
#: pytest was missused
Copy link
Contributor

Choose a reason for hiding this comment

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

*misused

INTERNAL_ERROR = 3
#: pytest was missused
USAGE_ERROR = 4
#: pytest couldnt find tests
Copy link
Contributor

Choose a reason for hiding this comment

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

*couldn't

return res

def genitems(self, colitems):
"""Generate all test items from a collection node.
"""Generate all test items from a collection node.src/_pytest/main.py
Copy link
Contributor

Choose a reason for hiding this comment

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

paste error?

@RonnyPfannschmidt
Copy link
Member Author

yikes, good finds

@blueyed
Copy link
Contributor

blueyed commented Jun 17, 2019

yikes, good finds

Will you fix them?

@RonnyPfannschmidt
Copy link
Member Author

i can get around it mid week

@Zac-HD
Copy link
Member

Zac-HD commented Jun 22, 2019

#3144 might also be related?

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.

Make exit statuses public API
4 participants