Commit Graph

1921 Commits

Author SHA1 Message Date
Daniel Hahler
691a7fceea Revisit some help texts with regard to newlines 2020-05-19 19:34:08 -03:00
Daniel Hahler
87423d3cc8 Keep explicit newlines with help texts
This makes a difference for e.g. pytest-xdist:

Before:
```
  --dist=distmode       set mode for distributing tests to exec environments. each: …
                        available environment. loadscope: …
                        grouped by file to any available environment. (default) no: …
```

After:
```
  --dist=distmode       set mode for distributing tests to exec environments.
                        each: send each test to all available environments.
                        load: load balance by sending any pending test to any available environment.
                        …
                        (default) no: run tests inprocess, don't distribute.
```

This might also result in unexpected changes (hard wrapping), when line
endings where used unintentionally, e.g. with:

```
help="""
    some long
    help text
    """
```

But the benefits from that are worth it, and it is easy to fix, as will
be done for the internal `assertmode` option.
2020-05-19 19:34:08 -03:00
Bruno Oliveira
5a6296a2d7 Merge pull request #7226 from nicoddemus/remove-function-args 2020-05-19 18:53:23 -03:00
Ran Benita
85a06cfafb Merge pull request #7227 from bluetech/logging-reuse-handler
logging: reuse LoggingCaptureHandler instance since it's expensive to create
2020-05-18 23:16:51 +03:00
Ran Benita
fe2febfff2 Merge pull request #7019 from bluetech/rm-pyobj_property
Remove pyobj_property helper, inline it instead
2020-05-18 23:13:52 +03:00
Ran Benita
694fdc6554 Remove pyobj_property helper, inline it instead
It doesn't save much code but adds indirection which makes it a bit
harder to follow and to type.
2020-05-18 20:54:11 +03:00
Bruno Oliveira
ad3169428b Remove unused Function.__init__ 'args' parameter 2020-05-18 14:30:48 -03:00
Daniel Hahler
8b9b81c3c0 Function: use originalname in _getobj and make it default to name (#7035) 2020-05-18 14:08:47 -03:00
Ran Benita
d2d11a8bdc logging: reuse LoggingCaptureHandler instance since it's expensive to create
Previously, a LoggingCaptureHandler was instantiated for each test's
setup/call/teardown which turns out to be expensive.

Instead, only keep one instance and reset it between runs.
2020-05-18 11:27:50 +03:00
Ran Benita
e27228a4e4 Merge pull request #7224 from bluetech/logging-simplifications
logging: some simplifications/cleanups
2020-05-18 00:15:59 +03:00
Ran Benita
f71ec8cc90 logging: order hookimpl's in chronological order
Makes it easier to understand what's going on.
2020-05-17 21:41:38 +03:00
Ran Benita
3f8200676f logging: remove deprecated --no-print-logs option/ini
This option was deprecated in 5.4.0 and was marked for removal in 6.0.0.
2020-05-17 21:41:38 +03:00
Ran Benita
bd5e3f042d logging: move log_file_handler cleanup from sessionend to unconfigure
It is set-up in configure, so match it.
2020-05-17 21:41:38 +03:00
Ran Benita
43c465c9bf logging: use dummy handler when CLI logging is disabled instead of None
This makes the code cleaner by removing conditionals and making the CLI
and file logging completely analogous.

Doesn't affect performance.
2020-05-17 21:41:38 +03:00
Ran Benita
bd657bab3f logging: don't use _runtest_for for the pytest_log* hooks
The logstart/logreport/logfinish hooks don't need the stuff in
_runtest_for. The test capturing catching_logs call is irrelevant for
them, and the item-conditional sections are gone.
2020-05-17 21:41:38 +03:00
Ran Benita
b13af52bbe logging: call set_when() in a consistent manner 2020-05-17 21:41:38 +03:00
Ran Benita
075903dafa logging: simplify log-file handling
- Instead of making it optional, always set up a handler, but possibly
  going to /dev/null. This simplifies the code by removing a lot of
  conditionals. It also can replace the NullHandler() we already add.

- Change `set_log_path` to just change the stream, instead of recreating
  one. Besides plugging a resource leak, it enables the next item.

- Remove the capturing_logs from _runtest_for, since it sufficiently
  covered by the one in pytest_runtestloop now, which wraps all other
  _runtest_for calls.

The first item alone would have had an adverse performance impact, but
the last item removes it.
2020-05-17 21:41:37 +03:00
Ran Benita
e48ac692de logging: optimize catching_logs slightly
Remove usage of `@contextmanager` as it is a bit slower than
hand-rolling, and also disallows re-entry which we want to use.

Removing protections around addHandler()/removeHandler(), because
logging already checks that internally.
2020-05-17 20:42:06 +03:00
Ran Benita
eceb28e4be logging: set formatter on handler creation, not in catching_logs
Conceptually it doesn't check per catching_logs (and catching_logs
doesn't restore the older one either). It is just something that is
defined for each handler once.
2020-05-17 20:42:06 +03:00
Ran Benita
ce0f218793 logging: yield from _runtest_for instead of contextmanager
Avoid the slight overhead of contextmanager.
2020-05-17 20:42:06 +03:00
Ran Benita
9effbe7425 logging: inline _runtest_for_main into _runtest_for
This avoids a little bit of overhead, and makes the code a bit clearer
too.
2020-05-17 20:42:06 +03:00
Ran Benita
ac6c02f1e2 logging: use item's store for private attributes
This makes things type-safe and properly private.
2020-05-17 20:42:05 +03:00
Bruno Oliveira
c26f389c09 Refactor handling of non-top-level pytest_plugins handling
Decided to move the 'if' logic together with the error message, as this leaves
the _importconftest method cleaner.
2020-05-17 11:26:30 -03:00
Bruno Oliveira
9e1e7fcabe Use a nice string repr for ConftestImportFailure
The default message is often hard to read:

    E   _pytest.config.ConftestImportFailure: (local('D:\\projects\\pytest\\.tmp\\root\\foo\\conftest.py'), (<class 'RuntimeError'>, RuntimeError('some error',), <traceback object at 0x000001CCC3E39348>))

Using a shorter message is better:

    E   _pytest.config.ConftestImportFailure: RuntimeError: some error (from D:\projects\pytest\.tmp\root\foo\conftest.py)

And we don't really lose any information due to exception chaining.
2020-05-17 11:26:30 -03:00
Bruno Oliveira
5eaebc1900 Remove one of the tracebacks from conftest import failures
This removes the KeyError from the traceback chain when an
conftest fails to import:

    return self._conftestpath2mod[key]
    E   KeyError: WindowsPath('D:/projects/pytest/.tmp/root/foo/conftest.py')

    During handling of the above exception, another exception occurred:
    ...
        raise RuntimeError("some error")
    E   RuntimeError: some error

    During handling of the above exception, another exception occurred:
    ...
    E   _pytest.config.ConftestImportFailure: (...)

By slightly changing the code, we can remove the first chain, which is often
very confusing to users and doesn't help with anything.

Fix #7223
2020-05-17 11:26:02 -03:00
Bruno Oliveira
f506682abe Merge pull request #6919 from nicoddemus/backport-6914 2020-05-16 12:42:15 -03:00
Daniel Hahler
d530d70128 Fix regressions with --lf plugin
Only filter with known failures, and explicitly keep paths of passed
arguments.

This also displays the "run-last-failure" status before collected files,
and does not update the cache with "--collect-only".

Fixes https://github.com/pytest-dev/pytest/issues/6968.
2020-05-15 18:35:38 -03:00
Ran Benita
f0f552d60c Merge pull request #6283 from felixn/master
Create LogCaptureHandler if necessary (closes #6240)
2020-05-15 09:13:57 +03:00
Ran Benita
2ac28f6c65 Merge pull request #7205 from lancelote/7126
Issue 7126 - "saferepr" to avoid BytesWarning when using --setup-show
2020-05-14 16:04:22 +03:00
Felix Nieuwenhuizen
4dfc461036 Create LogCaptureHandler if necessary (closes #6240) 2020-05-13 20:38:14 +02:00
Ran Benita
c714f05ad7 mark: reuse compiled expression for all items in -k/-m
The previous commit made this possible, so utilize it.

Since legacy.py becomes pretty bare, I inlined it into __init__.py. I'm
not sure it's really "legacy" anyway!

Using a simple 50000 items benchmark with `--collect-only -k nomatch`:

Before (two commits ago):

   ======================== 50000 deselected in 10.31s =====================
         19129345 function calls (18275596 primitive calls) in 10.634 seconds

   Ordered by: cumulative time

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
        1    0.001    0.001    2.270    2.270 __init__.py:149(pytest_collection_modifyitems)
        1    0.036    0.036    2.270    2.270 __init__.py:104(deselect_by_keyword)
    50000    0.055    0.000    2.226    0.000 legacy.py:87(matchkeyword)

After:

   ======================== 50000 deselected in 9.37s =========================
         18029363 function calls (17175972 primitive calls) in 9.701 seconds

   Ordered by: cumulative time

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
        1    0.000    0.000    1.394    1.394 __init__.py:239(pytest_collection_modifyitems)
        1    0.057    0.057    1.393    1.393 __init__.py:162(deselect_by_keyword)

The matching itself can be optimized more but that's a different story.
2020-05-12 12:55:37 +03:00
Ran Benita
622c4ce02e mark/expression: support compiling once and reusing for multiple evaluations
In current pytest, the same expression is matched against all items. But
it is re-parsed for every match.

Add support for "compiling" an expression and reusing the result. Errors
may only occur during compilation.

This is done by parsing the expression into a Python `ast.Expression`,
then `compile()`ing it into a code object. Evaluation is then done using
`eval()`.

Note: historically we used to use `eval` directly on the user input --
this is not the case here, the expression is entirely under our control
according to our grammar, we just JIT-compile it to Python as a
(completely safe) optimization.
2020-05-12 12:53:12 +03:00
Ran Benita
645aaa728d python_api: reduce scope of a except BaseException in ApproxNumpy
I'm not sure if it can even raise at all, but catching BaseException
would swallow ctrl-C and such and is definitely inappropriate here.
2020-05-12 12:07:56 +03:00
Ran Benita
23c9856857 Remove no longer needed noqa's 2020-05-12 09:29:47 +03:00
Ran Benita
59a12e9ab3 Replace bare excepts with except BaseException
Mostly I wanted to remove uses of `noqa`.

In Python 3 the two are the same.
2020-05-12 09:29:47 +03:00
Ran Benita
c4f9eaa5de mark: deprecate a couple undocumented -k syntaxes
The `-k '-expr'` syntax is an old alias to `-k 'not expr'`. It's also
not a very convenient to have syntax that start with `-` on the CLI.
Deprecate it and suggest replacing with `not`.

---

The `-k 'expr:'` syntax discards all items until the first match and
keeps all subsequent, e.g. `-k foo` with

    test_bar
    test_foo
    test_baz

results in `test_foo`, `test_baz`. That's a bit weird, so deprecate it
without a replacement. If someone complains we can reconsider or devise
a better alternative.
2020-05-11 16:07:52 +03:00
Pavel Karateev
7b196747dd Use saferepr for all types 2020-05-10 12:47:26 +03:00
Pavel Karateev
903e2ab6ee Fix #7126 - saferepr for bytes params
bytes parametrize parameters cause error when --setup-show is used
and Python is called with -bb flag
2020-05-09 13:57:17 +03:00
Bruno Oliveira
5dd987e10f Merge pull request #6999 from bluetech/simplify-fixture-compat 2020-05-08 08:06:35 -03:00
Bruno Oliveira
9657798c12 Merge pull request #7158 from CarycaKatarzyna/issue_7076 2020-05-08 07:56:03 -03:00
Ran Benita
857b5c9ccd Merge pull request #7185 from bluetech/sigpipe
Handle SIGPIPE/BrokenPipeError in pytest's CLI
2020-05-08 13:32:34 +03:00
Ran Benita
73448f265d Handle EPIPE/BrokenPipeError in pytest's CLI
Running `pytest | head -1` and similar causes an annoying error to be
printed to stderr:

    Exception ignored in: <_io.TextIOWrapper name='<stdout>' mode='w' encoding='utf-8'>
    BrokenPipeError: [Errno 32] Broken pipe

(or possibly even a propagating exception in older/other Python versions).

The standard UNIX behavior is to handle the EPIPE silently. To
recommended method to do this in Python is described here:
https://docs.python.org/3/library/signal.html#note-on-sigpipe

It is not appropriate to apply this recommendation to `pytest.main()`,
which is used programmatically for in-process runs. Hence, change
pytest's entrypoint to a new `pytest.console_main()` function, to be
used exclusively by pytest's CLI, and add the SIGPIPE code there.

Fixes #4375.
2020-05-08 12:51:02 +03:00
Anthony Sottile
b238845d0f Fix _is_setup_py for files encoded differently than locale 2020-05-07 13:14:58 -07:00
Ran Benita
65963d2066 warnings: speed up work done in catch_warnings_for_item()
When setting up the warnings capture, filter strings (with the general
form `action:message:category:module:line`) are collected from the
cmdline, ini and item and applied. This happens for every test and other
cases.

To apply a string it needs to be parsed into a tuple, and it turns out
this is slow. Since we already vendor the parsing code from Python's
warnings.py, we can speed it up by caching the result. After splitting
the parsing part from the applying part, the parsing is pure and is
straightforward to cache.

An alternative is to parse ahead of time and reuse the result, however
the caching solution turns out cleaner and more general in this case.

On this benchmark:

    import pytest
    @pytest.mark.parametrize("x", range(5000))
    def test_foo(x): pass

Before:

============================ 5000 passed in 14.11s =============================
         14365646 function calls (13450775 primitive calls) in 14.536 seconds

After:

============================ 5000 passed in 13.61s =============================
         13290372 function calls (12375498 primitive calls) in 14.034 seconds
2020-05-07 12:19:13 +03:00
Ran Benita
81da5dac48 Merge pull request #7122 from bluetech/matcher-parser
Stop using Python's eval() for -m and -k
2020-05-07 09:23:29 +03:00
Bruno Oliveira
6c2d358918 Merge pull request #7135 from pytest-dev/terminalwriter 2020-05-06 18:26:44 -03:00
Bruno Oliveira
4d439760ad Merge pull request #7168 from nicoddemus/saferepr-getattr-fail-7145 2020-05-06 17:57:38 -03:00
Ran Benita
d16ae0bbdc Merge pull request #7171 from bluetech/code-import-cycles
code: fix import cycles between code.py and source.py
2020-05-06 18:15:32 +03:00
Ran Benita
89eee90b5f python: optimize PythonCollector.collect 2020-05-06 12:05:04 +03:00
Ran Benita
b90f34569f nodes: micro-optimize Node attribute access 2020-05-06 11:58:30 +03:00