Commit Graph

358 Commits

Author SHA1 Message Date
Ran Benita baaa67dfb9 python: simplify code in Package.collect()
The path of Package is already the `__init__.py` file, and we're already
assured it's a file.
2023-05-20 21:14:29 +03:00
Ran Benita fcada1ea47 nodes: change _prunetraceback to return the new traceback instead of modifying excinfo
This makes it usable as a general function, and just more understandable
in general.
2023-04-28 11:47:45 +03:00
Ran Benita 6f7f89f3c4 code: make TracebackEntry immutable
TracebackEntry being mutable caught me by surprise and makes reasoning
about the exception formatting code harder. Make it a proper value.
2023-04-28 11:47:45 +03:00
Ran Benita cc23ec91d0 code: stop storing weakref to ExceptionInfo on Traceback and TracebackEntry
TracebackEntry needs the excinfo for the `__tracebackhide__ = callback`
functionality, where `callback` accepts the excinfo.

Currently it achieves this by storing a weakref to the excinfo which
created it. I think this is not great, mixing layers and bloating the
objects.

Instead, have `ishidden` (and transitively, `Traceback.filter()`) take
the excinfo as a parameter.
2023-04-28 11:47:45 +03:00
pre-commit-ci[bot] 59e7d2bbc9
[pre-commit.ci] pre-commit autoupdate (#10712)
* [pre-commit.ci] pre-commit autoupdate

updates:
- [github.com/psf/black: 22.12.0 → 23.1.0](https://github.com/psf/black/compare/22.12.0...23.1.0)
- [github.com/PyCQA/autoflake: v2.0.0 → v2.0.1](https://github.com/PyCQA/autoflake/compare/v2.0.0...v2.0.1)

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Update .pre-commit-config.yaml

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Bruno Oliveira <nicoddemus@gmail.com>
2023-02-07 19:30:33 -03:00
Teejay 5dbfb8e108
Fix fixtures named teardown being considered by nose (#10696)
Closes #10597
2023-01-27 14:33:46 -03:00
Ran Benita 310b67b227
Drop attrs dependency, use dataclasses instead (#10669)
Since pytest now requires Python>=3.7, we can use the stdlib attrs
clone, dataclasses, instead of the OG package.

attrs is still somewhat nicer than dataclasses and has some extra
functionality, but for pytest usage there's not really a justification
IMO to impose the extra dependency on users when a standard alternative
exists.
2023-01-20 11:13:36 +02:00
Marko Pacak 9fbd67dd4b
Class methods can now be discovered as tests (#10552)
Fix #10525
2022-12-02 15:53:04 +00:00
Simon K 3bf2bc55b1
Add deprecations for tests written for `nose` (#9907)
Fixes #9886
2022-10-09 17:16:33 -03:00
Ran Benita 67e29d2548 mark: allow any Sequence[str] for parametrize(argnames), not just list/tuple
The main motivation for this change is to simplify the type shown in
code editors -- `Sequence[str]` is easier to follow than
`Union[list[str], tuple[str, ...]]`.

It also permits using other types if desired. It might lead to problems
if someone uses some oddball sequence type, but hopefully they won't do
that.
2022-08-15 19:38:09 +03:00
Hugo van Kemenade e54c6a1362
Document the --code-highlight default (#9883)
Also normalized all help text using the patterns:

* `One sentence help text`
* `First sentence of help. Second sentence of help.`
2022-05-31 16:32:51 -03:00
Cheuk Ting Ho c988e49af6
Warn when test functions return other than None (#9956)
Closes #7337
2022-05-25 09:48:02 -03:00
Ran Benita c3aa4647c7 python: unify code to generate ID from value
In the following

    @pytest.mark.parametrize(..., ids=[val])

the ID values are only allowed to be `str`, `float`, `int` or `bool`.

In the following

    @pytest.mark.parametrize(..., [val])

    @pytest.mark.parametrize(..., [pytest.param(..., id=val])

a different code path is used, which also allows `bytes`, `complex`,
`re.Pattern`, `Enum` and anything with a `__name__`.

In the interest of consistency, use the latter code path for all cases.
2022-02-12 19:22:37 +02:00
Bruno Oliveira 8afec9a64d
Add autoflake to pre-commit configuration (#9666) 2022-02-11 14:34:02 -03:00
Tobias Deiminger b21b008118 Refactor idmaker functions into class IdMaker
This commit only refactors, it does not change or add functionality yet. Public
API is retained. Reason or refactoring:

User provided parameter IDs (e.g. Metafunc.parametrize(ids=...)) had so far
only been used to calculate a unique test ID for each test invocation. That
test ID was a joined string where each parameter contributed some partial ID.

We're soon going to reuse functionality to generate parameter keys for
reorder_items and FixtureDef cache. We will be interested in the partial
IDs, and only if they originate from explicit user information. Refactoring
makes logic and data accessible for reuse, and increases cohesion in general.
2022-01-26 15:42:34 +02:00
Ran Benita bb5a4e2d63
Merge pull request #9531 from bluetech/misc
python: fix confused docstring of `Metafunc._resolve_arg_ids`
2022-01-21 17:24:56 +02:00
Ran Benita 471634d6bd python: fix confused docstring of `Metafunc._resolve_arg_ids`
The docstring (and function name itself) described things as if IDs are
being assigned to the argnames, but actually they're assigned to the
parameter sets.
2022-01-21 16:18:44 +02:00
Ran Benita 6d128cd52e python: use a more memory-friendly generator 2022-01-21 14:35:25 +02:00
Ran Benita 74571ba55f Add missing `keywords` type annotations 2022-01-21 14:35:25 +02:00
Ran Benita 456a2538ac python: optimize node keywords initialization
If we do the `update`s in the right order, we can avoid the `mark.name
not in self.keywords` check, since `self.keywords` starts out clean and
`update` will override previously set keywords.
2022-01-21 14:35:25 +02:00
Ran Benita 3c69bc919c python: remove broken/ineffectual keywords marks initialization
By my analysis, this deleted code block has no effect:

1. `self.keywords` is `update`d with `callspec.marks`.
2. `self.own_markers` is `update`d with `callspec.marks`.
3. `self.keywords` is `update`d with `self.own_markers`.

So together steps 2+3 completely undo step 1.
2022-01-21 14:35:24 +02:00
Ran Benita d9bcfa0c2b python: don't redundantly duplicate parent markers to own keywords
This does have a slight semantic change: in a node hierarchy parent ->
child, if parent has a marker applied, then child is constructed, then
`parent.themarker = "overridden"`, previously
`child.keywords['themarker']` would return `True`, now it returns
`"overridden"`. But that's actually what I would have expected so I see
it as more of a bugfix.
2022-01-21 14:34:27 +02:00
Ran Benita 8713c32462 python: unpacked marks need to be added to keywords on all node types
(except `Instance`)

Currently, `Function` does this manually, but other node types don't get
their markers added to their `keywords`, but they should, if only for
consistency.
2022-01-21 14:34:27 +02:00
Ran Benita e9bb1aa233 python: be consistent with what value marks have in keywords
Marks are added to keywords in three places:

- `Node.add_marker`: name -> `Mark`
- `Function.__init__(callspec)`: name -> `Mark`
- `Function.__init__ iter_markers`: name -> True

I think it should be consistent, which will also help with some upcoming
code cleaning. The `Mark` seems more useful than just a `True`, so
switch to that.
2022-01-21 14:34:27 +02:00
Ran Benita 4e5fb520b6 python: remove an unneeded normalize_mark_list call
`callspec.mark` is already `List[Mark]` so no need to normalize it.
2022-01-21 14:34:27 +02:00
Ran Benita f08a77de77 python: add back `instance` accessor to all python nodes, not just Function
Regressed in 062d91ab4 (pytest 7.0.0rc1 only).

Fix #9486.
2022-01-09 12:14:46 +02:00
Anthony Sottile b0aabe4081 fix mypy 0.930 errors 2021-12-30 06:19:29 -08:00
Hugo van Kemenade 1fd3601caa Drop support for EOL Python 3.6 2021-12-30 12:37:18 +02:00
Kian Meng, Ang 55debfad1f
Fix typos (#9424) 2021-12-27 09:23:15 -03:00
Ran Benita 10e21dadee python: skip nose setup/teardown fixtures if non-callable
Since commit 89f0b5b5a2 cases as in the
added test started to fail, like they do for the standard pytest names
(`setup_module` etc). But the name `setup` in particular is way too
common for us to start taking it over more aggressively, so restore the
previous behavior which required the object to be callable.

Fix #9391.
2021-12-25 12:09:11 +02:00
Ran Benita 0e69c62ece doc: add a `hook` crossref type
Allow writing

    🪝`pytest_cmdline_main`

instead of

    :func:`pytest_cmdline_main <_pytest.hookspec.pytest_cmdline_main>`
2021-12-12 16:29:30 +02:00
Ran Benita e05e696fda Make PyCollector an implementation detail - don't use in hook type annotation
The `pytest_pycollector_makeitem` argument `collector` is currently
annotated with type `PyCollector`. As part of #7469, that would have
required us to expose it in the public API. But really it's an
implementation detail, not something we want to expose. So replace the
annotation with the concrete python collector types that are passed.

Strictly speaking, `pytest_pycollector_makeitem` is called from
`PyCollector.collect()`, so the new type annotation is incorrect if
another type subclasses `PyCollector`. But the set of python collectors
is closed (mapping to language constructs), and the type is private, so
there shouldn't be any other deriving classes, and we can consider it
effectively sealed (unfortunately Python does not provide a way to
express this - yet?).
2021-12-08 15:20:23 +02:00
Florian Bruhin 663be09723
Improve reference and path/fspath docs (#9341)
* Improve reference and path/fspath docs

Closes #9283

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* fixups

* Add explanation

* Update wording after #9363

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2021-12-06 11:25:05 +01:00
Bruno Oliveira a335ade1f5
Rename pathlib hook parameters (#9363)
* Rename pytest_ignore_collect fspath parameter to collection_path

* Rename pytest_collect_file fspath parameter to file_path

* Rename pytest_pycollect_makemodule fspath parameter to module_path

* Rename pytest_report_header startpath parameter to start_path

* Rename pytest_report_collectionfinish startpath parameter to start_path

* Update docs with the renamed parameters

* Use pytest-flakes fork temporarily to prove it works

* Use pytest-flakes 4.0.5
2021-12-03 13:14:09 +01:00
Ran Benita 062d91ab47
python: remove the `Instance` collector node 2021-11-13 14:03:44 +02:00
Florian Bruhin 5d87a27434
Elide pytest-internal paths for --fixtures (#9281)
* Elide pytest-internal paths for --fixtures

Fixes #8822

* Make flake8 happy
2021-11-10 15:16:41 +01:00
Simon K eb6c4493b2
Deprecation of `msg=` for both `pytest.skip()` and `pytest.fail()`. (#8950)
* porting pytest.skip() to use reason=, adding tests

* avoid adding **kwargs, it breaks other functionality, use optional msg= instead

* deprecation of `pytest.fail(msg=...)`

* fix bug with not capturing the returned reason value

* pass reason= in acceptance async tests instead of msg=

* finalising deprecations of `msg` in `pytest.skip()` and `pytest.fail()`

* Update doc/en/deprecations.rst

Co-authored-by: Bruno Oliveira <nicoddemus@gmail.com>

* Update doc/en/deprecations.rst

Co-authored-by: Bruno Oliveira <nicoddemus@gmail.com>

* fix failing test after upstream merge

* adding deprecation to `pytest.exit(msg=...)`

* add docs for pytest.exit deprecations

* finalising deprecation of msg for pytest.skip, pytest.exit and pytest.fail

* hold a reference to the Scope instance to please mypy

Co-authored-by: Bruno Oliveira <nicoddemus@gmail.com>
2021-11-08 15:31:14 +01:00
Ran Benita 89f0b5b5a2 nose: fix class- and module-level fixture behavior
Fixes #9272.

Fixing the issue directly in the plugin is somewhat hard, so do it in
core. Since the plugin is going to be deprecated, I figure it's OK to
cheat a bit.
2021-11-06 14:45:24 +02:00
Ran Benita 7eee5c1634 Change `Node.reportinfo()` return value from `py.path` to `str|os.PathLike[str]`
`reportinfo()` is the last remaining py.path-only code path in pytest,
i.e. the last piece holding back py.path deprecation. The problem with
it is that plugins/users use it from both sides -- implementing it
(returning the value) and using it (using the return value). Dealing
with implementers is easy enough -- allow to return `os.PathLike[str]`.
But for callers who expect strictly `py.path` this will break and
there's not really a good way to provide backward compat for this.

From analyzing a corpus of 680 pytest plugins, the vast majority of
`reportinfo` appearances are implementations, and the few callers don't
actually access the path part of the return tuple.

As for test suites that might access `reportinfo` (e.g. using
`request.node.reportinfo()` or other ways), that is much harder to
survey, but from the ones I searched, I only found case
(`pytest_teamcity`, but even then it uses `str(fspath)` so is unlikely
to be affected in practice). They are better served with using
`node.location` or `node.path` directly.

Therefore, just break it and change the return type to
`str|os.PathLike[str]`.

Refs #7259.
2021-10-09 15:02:03 +03:00
Ran Benita 076ac901bb nodes: micro-optimize _imply_path 2021-10-06 10:29:52 +03:00
Ran Benita 570b1facb7 python: refactor CallSpec2
This type is semi-private; not documented but many plugins access it
through `item.callspec`. However, plugins access the public fields and
almost none try to construct or monkeypatch it. So we should be allowed
to clean it up some.

- Convert to attrs, add slots and frozen

- Instead of doing `new = old.copy(); new.setmulti2()`, do `new =
  old.setmulti()`. This is cleaner and faster.

- Remove the `metafunc` attribute. This causes a reference cycle
  (multifunc._calls -> callspec -> multifunc) for no good reason --
  neither pytest itself or plugins access this attribute, so let's not
  keep the Metafunc objects alive past their due.

- Some comments.

I would have also like to make the dicts and lists themselves immutable,
however some plugins mess with those so that should be done separately,
if at all.
2021-10-04 17:33:52 +03:00
Ran Benita 5fc3e35afb
Merge pull request #9144 from bluetech/py36_order_by_definition
py36+ tests are definition ordered [v2]
2021-10-01 16:17:37 +03:00
Ran Benita 1f938e3ef5 compat: replace REGEX_TYPE with typing.Pattern
Since Python 3.7, there is `re.Pattern` for this, but since we need to
support Python 3.6, can use `typing.Pattern` which works as well.
2021-10-01 14:00:15 +03:00
Bruno Oliveira a83b359cf0
Refactor internal scope handling by introducing Scope enum
PR #8913
2021-08-01 06:11:56 -03:00
Naveen-Pratap febb978651
Update error message for module level skip to include 'allow_module_level' (#8906)
Co-authored-by: Naveen <NaveenPr1@microland.com>
Co-authored-by: Bruno Oliveira <nicoddemus@gmail.com>
2021-07-14 14:27:26 +00:00
Bruno Oliveira 828fde1156
Merge pull request #8858 from The-Compiler/update-doc-urls 2021-07-14 09:28:46 -03:00
Graeme Smecher 5c04674e96 Generate useful parameterization IDs for complex() numbers. 2021-07-12 12:27:24 -07:00
Florian Bruhin 953fdabaf0 Adjust doc links for new scheme
Closes #8831
2021-07-06 09:11:35 +02:00
Ran Benita 88d84a5791 config: expose Config for typing purposes
This type is used in hooks and fixtures.

The constructor is publicly documented so is not marked private.
2021-05-24 12:26:22 +03:00
Rahul Kumaresan c516dba69a
add feature to view fixture source location in invocations with --fixtures-per-test option (#8626)
* add feature to view fixture source location in invocations with --fixtures-per-test option

* remove unrelated changes to show_fixtures_per_test::test_doctest_items

* eshew the extraneous else in _show_fixtures_per_test.write_fixture

* enable the accommodation of multi-line docstring with --fixtures-per-test option

* add feature to view fixture source location in invocations with --fixtures

* add colour encoding to fixture location paths

* add changelog for #8606 fixing

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2021-05-14 14:38:55 +02:00
pre-commit-ci[bot] d200598de9
[pre-commit.ci] pre-commit autoupdate (#8547)
* [pre-commit.ci] pre-commit autoupdate

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Ran Benita <ran@unusedvar.com>
2021-04-14 12:49:09 +03:00
Ronny Pfannschmidt 41a90cd9fe
Merge pull request #8463 from RonnyPfannschmidt/workaround-8361
address #8361 - introduce hook caller wrappers that enable backward compat
2021-04-05 22:50:31 +02:00
Tadeu Manoel b706a2c048
Fix error with --import-mode=importlib and modules containing dataclasses or pickle (#7870)
Co-authored-by: Bruno Oliveira <nicoddemus@gmail.com>

Fixes #7856, fixes #7859
2021-04-05 17:10:03 -03:00
Ronny Pfannschmidt a550db4b6c drop internal py.path.local objects from hook calls 2021-03-20 21:50:40 +01:00
Ran Benita e515264eb1 Remove yet more unnecessary py.path uses 2021-03-18 10:23:48 +02:00
Ran Benita f0c7043138 Remove/replace some more unnecessary uses of py.path 2021-03-15 10:39:44 +02:00
Ronny Pfannschmidt 77cb110258 drop usage of py.path.local calls
Co-authored-by: Bruno Oliveira <nicoddemus@gmail.com>
2021-03-06 21:32:03 +01:00
Ronny Pfannschmidt 22dad53a24 implement Node.path as pathlib.Path
* reorganize lastfailed node sort

Co-authored-by: Bruno Oliveira <nicoddemus@gmail.com>
2021-03-06 21:32:03 +01:00
Alexandros Tzannes 19a2f7425d
Merge pull request #8399 from atzannes/master
closes #8394

Generated fixture names for unittest/xunit/nose should start with underscore
2021-03-04 22:45:57 +02:00
Simon K 22c0dace3b
change istestfunction to callable() (#8374) 2021-02-25 20:32:27 +00:00
Florian Bruhin 54a154c86f Allow Class.from_parent to forward custom parameters to the constructor
Similarly to #7143, at work we have a project with a custom pytest.Class
subclass, adding an additional argument to the constructor.

All from_parent implementations in pytest accept and forward *kw, except
Class (before this change) and DoctestItem - since I'm not familiar with
doctest support, I've left the latter as-is.
2021-02-23 18:00:56 +01:00
Ronny Pfannschmidt 325d701f6e
Merge pull request #8248 from RonnyPfannschmidt/mixin-mro-position
alter the PyObjMixin to carry over typing information from Node
2021-02-07 18:44:44 +01:00
Ran Benita afea190797 Remove some no longer needed type-ignores 2021-01-29 20:40:43 +02:00
Ronny Pfannschmidt a9e43152bc alter the PyObjMixin to carry over typing information from Node
as PyObjMixin is always supposed to be mixed in the mro
before nodes.Node the behavior doesn't change,
but all the typing information carry over to help mypy.

extracted from #8037
2021-01-17 14:36:28 +01:00
Ran Benita 2ff88098a7 python: inline a simple method
I don't think it adds much value!
2021-01-01 23:23:08 +02:00
pre-commit-ci[bot] ee03e31831
[pre-commit.ci] pre-commit autoupdate (#8201)
* [pre-commit.ci] pre-commit autoupdate

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* manual fixes after configuration update

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Anthony Sottile <asottile@umich.edu>
2020-12-30 11:56:09 +02:00
Ran Benita bd76042344 python: export pytest.Metafunc for typing purposes
The type cannot be constructed directly, but is exported for use in type
annotations, since it is reachable through existing public API.
2020-12-26 21:05:02 +02:00
Ran Benita ca4effc822 Convert most of the collection code from py.path to pathlib 2020-12-22 21:09:36 +02:00
Ran Benita 92ba96b061 code: convert from py.path to pathlib 2020-12-22 21:08:25 +02:00
antonblr 196b173c8a address comments 2020-12-18 12:36:20 -08:00
antonblr 15156e94c4 tests: Migrate to pytester - final update 2020-12-18 11:02:38 -08:00
Ran Benita 592b32bd69 hookspec: add pathlib.Path alternatives to py.path.local parameters in hooks
As part of the ongoing migration for py.path to pathlib, make sure all
hooks which take a py.path.local also take an equivalent pathlib.Path.
2020-12-15 00:34:23 +02:00
Ran Benita ed658d6829 Some py.path.local -> pathlib.Path
- Some conftest related functions
- _confcutdir
- Allow arbitrary os.PathLike[str] in gethookproxy.
2020-12-12 17:33:28 +02:00
Ran Benita f1e6fdcddb Export types of builtin fixture for type annotations
In order to allow users to type annotate fixtures they request, the
types need to be imported from the `pytest` namespace. They are/were
always available to import from the `_pytest` namespace, but that is
not guaranteed to be stable.

These types are only exported for the purpose of typing. Specifically,
the following are *not* public:

- Construction (`__init__`)
- Subclassing
- staticmethods and classmethods

We try to combat them being used anyway by:

- Marking the classes as `@final` when possible (already done).

- Not documenting private stuff in the API Reference.

- Using `_`-prefixed names or marking as `:meta private:` for private
  stuff.

- Adding a keyword-only `_ispytest=False` to private constructors,
  warning if False, and changing pytest itself to pass True. In the
  future it will (hopefully) become a hard error.

Hopefully that will be enough.
2020-11-13 11:25:09 +02:00
Ran Benita a95da7a425
Merge pull request #7980 from bluetech/code-changes
code: a few minor improvements
2020-11-01 09:51:39 +02:00
Bruno Oliveira 569c091769 Add FunctionDefinition to the reference docs
Fix #7968
2020-10-31 08:45:34 -03:00
Ran Benita 531416cc5a code: simplify Code construction 2020-10-31 12:40:25 +02:00
Ran Benita 50114d4731 python: fix quadratic behavior in collection of items using xunit fixtures
Since commit 0f918b1a9d pytest uses auto-generated autouse
pytest fixtures for the xunit fixtures
{setup,teardown}_{module,class,method,function}. All of these fixtures
were given the same name.

Unfortunately, pytest fixture lookup for a name works by grabbing all of
the fixtures globally declared with a name and filtering to only those
which match the specific node. So each xunit-using item iterates over a
list (of fixturedefs) of a size of all previous same-xunit-using items,
i.e. quadratic.

Fixing this properly to use a better data structure is likely to take
some effort, but we can avoid the immediate problem by just using
a different name for each item's autouse fixture, so it only matches
itself.

A benchmark is added to demonstrate the issue. It is still way too slow
after the fix and possibly still quadratic, but for a different reason
which is another matter.

Running --collect-only, before (snipped):

         202533232 function calls (201902604 primitive calls) in 86.379 seconds

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
        1    0.000    0.000   85.688   85.688 main.py:320(pytest_collection)
        1    0.000    0.000   85.688   85.688 main.py:567(perform_collect)
80557/556    0.021    0.000   85.050    0.153 {method 'extend' of 'list' objects}
85001/15001  0.166    0.000   85.045    0.006 main.py:785(genitems)
    10002    0.050    0.000   84.219    0.008 runner.py:455(collect_one_node)
    10002    0.049    0.000   83.763    0.008 runner.py:340(pytest_make_collect_report)
    10002    0.079    0.000   83.668    0.008 runner.py:298(from_call)
    10002    0.019    0.000   83.541    0.008 runner.py:341(<lambda>)
     5001    0.184    0.000   81.922    0.016 python.py:412(collect)
     5000    0.020    0.000   81.072    0.016 python.py:842(collect)
    30003    0.118    0.000   78.478    0.003 python.py:218(pytest_pycollect_makeitem)
    30000    0.190    0.000   77.957    0.003 python.py:450(_genfunctions)
    40001    0.081    0.000   76.664    0.002 nodes.py:183(from_parent)
    30000    0.087    0.000   76.629    0.003 python.py:1595(from_parent)
    40002    0.092    0.000   76.583    0.002 nodes.py:102(_create)
    30000    0.305    0.000   76.404    0.003 python.py:1533(__init__)
    15000    0.132    0.000   74.765    0.005 fixtures.py:1439(getfixtureinfo)
    15000    0.165    0.000   73.664    0.005 fixtures.py:1492(getfixtureclosure)
    15000    0.044    0.000   57.584    0.004 fixtures.py:1653(getfixturedefs)
    30000   18.840    0.001   57.540    0.002 fixtures.py:1668(_matchfactories)
 37507500   31.352    0.000   38.700    0.000 nodes.py:76(ischildnode)
    15000   10.464    0.001   15.806    0.001 fixtures.py:1479(_getautousenames)
112930587/112910019   7.333    0.000    7.339    0.000 {built-in method builtins.len}

After:

         51890333 function calls (51259706 primitive calls) in 27.306 seconds

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
        1    0.000    0.000   26.783   26.783 main.py:320(pytest_collection)
        1    0.000    0.000   26.783   26.783 main.py:567(perform_collect)
80557/556    0.020    0.000   26.108    0.047 {method 'extend' of 'list' objects}
85001/15001  0.151    0.000   26.103    0.002 main.py:785(genitems)
    10002    0.047    0.000   25.324    0.003 runner.py:455(collect_one_node)
    10002    0.045    0.000   24.888    0.002 runner.py:340(pytest_make_collect_report)
    10002    0.069    0.000   24.805    0.002 runner.py:298(from_call)
    10002    0.017    0.000   24.690    0.002 runner.py:341(<lambda>)
     5001    0.168    0.000   23.150    0.005 python.py:412(collect)
     5000    0.019    0.000   22.223    0.004 python.py:858(collect)
    30003    0.101    0.000   19.818    0.001 python.py:218(pytest_pycollect_makeitem)
    30000    0.161    0.000   19.368    0.001 python.py:450(_genfunctions)
    30000    0.302    0.000   18.236    0.001 python.py:1611(from_parent)
    40001    0.084    0.000   18.051    0.000 nodes.py:183(from_parent)
    40002    0.116    0.000   17.967    0.000 nodes.py:102(_create)
    30000    0.308    0.000   17.770    0.001 python.py:1549(__init__)
    15000    0.117    0.000   16.111    0.001 fixtures.py:1439(getfixtureinfo)
    15000    0.134    0.000   15.135    0.001 fixtures.py:1492(getfixtureclosure)
    15000    9.320    0.001   14.738    0.001 fixtures.py:1479(_getautousenames)
2020-10-23 22:36:23 +03:00
Anthony Sottile 33d119f71a py36+: com2ann 2020-10-05 18:33:17 -07:00
Anthony Sottile 66bd44c13a py36+: pyupgrade: py36+ 2020-10-03 12:46:54 -07:00
Anthony Sottile f295b0267d py36+: update the target version of black to py36 2020-10-03 08:17:22 -07:00
Anthony Sottile bfadd4060e py36+: from typing import Type: no longer need guard 2020-10-02 19:50:10 -07:00
Anthony Sottile 2c7b7d8f66
Merge pull request #7836 from asottile/py36_typing_X
py36+: replace typing.X with X
2020-10-02 19:47:42 -07:00
Anthony Sottile cf220b92a2 py36+: replace typing.X with X 2020-10-02 15:05:13 -07:00
Anthony Sottile a238d1f37d py36+: remove TYPE_CHECKING from _pytest.compat
automated with:

```bash
git grep -l 'from .* import TYPE_CHECKING' |
    xargs reorder-python-imports \
        --application-directories .:src \
        --remove-import 'from _pytest.compat import TYPE_CHECKING' \
        --add-import 'from typing import TYPE_CHECKING'
```
2020-10-02 15:03:24 -07:00
Ran Benita a99ca879e7 Mark some public and to-be-public classes as `@final`
This indicates at least for people using type checkers that these
classes are not designed for inheritance and we make no stability
guarantees regarding inheritance of them.

Currently this doesn't show up in the docs. Sphinx does actually support
`@final`, however it only works when imported directly from `typing`,
while we import from `_pytest.compat`.

In the future there might also be a `@sealed` decorator which would
cover some more cases.
2020-09-22 12:40:40 +03:00
Sorin Sbarnea b031a7cecf
Smoke tests for assorted plugins (#7721)
Co-authored-by: Bruno Oliveira <nicoddemus@gmail.com>
Co-authored-by: Thomas Grainger <tagrain@gmail.com>
Co-authored-by: Kyle Altendorf <sda@fstab.net>
2020-09-19 15:56:52 -03:00
Ran Benita daca174c98 python: small optimization in PyCollector.collect()
Inline `_makeitem()` so that `self.ihook` (which is moderately
expensive) can be called only once.

Note: the removed test "test_makeitem_non_underscore" comes from an old
behavior of skipping names that start with `_` which has since been
generalized, making the test no longer relevant.
2020-08-27 10:18:37 +03:00
Ran Benita 98891a5947 python: skip pytest_pycollect_makeitem work on certain names
When a Python object (module/class/instance) is collected, for each name
in `obj.__dict__` (and up its MRO) the pytest_pycollect_makeitem hook is
called for potentially creating a node for it.

These Python objects have a bunch of builtin attributes that are
extremely unlikely to be collected. But due to their pervasiveness,
dispatching the hook for them ends up being mildly expensive and also
pollutes PYTEST_DEBUG=1 output and such.

Let's just ignore these attributes.

On the pandas test suite commit 04e9e0afd476b1b8bed930e47bf60e,
collect only, irrelevant lines snipped, about 5% improvement:

Before:

```
         51195095 function calls (48844352 primitive calls) in 39.089 seconds

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
226602/54    0.145    0.000   38.940    0.721 manager.py:90(_hookexec)
    72227    0.285    0.000   20.146    0.000 python.py:424(_makeitem)
    72227    0.171    0.000   16.678    0.000 python.py:218(pytest_pycollect_makeitem)
```

After:

```
          48410921 function calls (46240870 primitive calls) in 36.950 seconds

    ncalls  tottime  percall  cumtime  percall filename:lineno(function)
 181429/54    0.113    0.000   36.777    0.681 manager.py:90(_hookexec)
     27054    0.130    0.000   17.755    0.001 python.py:465(_makeitem)
     27054    0.121    0.000   16.219    0.001 python.py:218(pytest_pycollect_makeitem)
```
2020-08-26 17:43:57 +03:00
Ran Benita a267a622eb python: fix empty parametrize() leading to "NotSetType.token" id
In ff8b7884e8 NOTSET was changed to a
singleton enum, which ended up unexpectedly triggering a code path in ID
generation which checks for `isinstance(Enum)`.

Add an explicit case for it, which is not too bad anyway.
2020-08-25 22:01:43 +03:00
Ran Benita c1f975668e main: couple of code simplifications 2020-08-24 18:15:11 +03:00
Ran Benita 57aca11d4a hookspec: type annotate parent argument to pytest_collect_file 2020-08-24 18:15:11 +03:00
Ran Benita 4b8e1a1771 Revert "Move common code between Session and Package to FSCollector"
This reverts commit f10ab021e2.

The commit was good in that it removed a non-trivial amount of code
duplication. However it was done in the wrong layer (nodes.py) and split
up a major part of the collection (the filesystem traversal) to a
separate class making it harder to understand.

We should try to reduce the duplication, but in a more appropriate
manner.
2020-08-24 18:15:11 +03:00
Bruno Oliveira 98530184a5 Remove funcargnames compatibility property 2020-08-19 08:11:39 -03:00
Ran Benita eddd993cf4 Only define gethookproxy, isinitpath on Session
This fixes an issue where pylint complains about missing implementations
of abstract methods in subclasses of `File` which only override
`collect()` (as they should).

It is also cleaner and makes sense, these methods really don't need to
be overridden.

The previous methods defined directly on `FSCollector` and `Package` are
deprecated, to be removed in pytest 7.

See commits e2934c3f8c and
f10ab021e2 for reference.
2020-08-15 13:40:16 +03:00
Ran Benita f8c4e038fd Replace some usages of py.path.local 2020-08-06 18:46:17 +03:00
Ran Benita 9ab14c6d9c typing: set warn_unreachable
This makes mypy raise an error whenever it detects code which is
statically unreachable, e.g.

    x: int
    if isinstance(x, str):
        ... # Statement is unreachable  [unreachable]

This is really neat and finds quite a few logic and typing bugs.

Sometimes the code is intentionally unreachable in terms of types, e.g.
raising TypeError when a function is given an argument with a wrong
type. In these cases a `type: ignore[unreachable]` is needed, but I
think it's a nice code hint.
2020-08-04 09:59:46 +03:00
Ran Benita be656dd4e4 typing: set disallow_any_generics
This prevents referring to a generic type without filling in its generic
type parameters.

The FixtureDef typing might need some more refining in the future.
2020-08-01 20:39:15 +03:00
Ran Benita 0242de4f56 Format docstrings in a consistent style 2020-08-01 17:14:37 +03:00
Ran Benita 8d98de8f8a typing: set no_implicit_reexport
In Python, if module A defines a name `name`, and module B does `import
name from A`, then another module C can `import name from B`.

Sometimes it is intentional -- module B is meant to "reexport" `name`.
But sometimes it is just confusion/inconsistency on where `name` should
be imported from.

mypy has a flag `--no-implicit-reexport` which puts some order into
this. A name can only be imported from a module if

1. The module defines the name
2. The module's `__all__` includes the name
3. The module imports the name as `from ... import .. as name`.

This flag is included in mypy's `--strict` flag.

I like this flag, but I realize it is a bit controversial, and in
particular item 3 above is a bit unfriendly to contributors who don't
know about it. So I didn't intend to add it to pytest.

But while investigating issue 7589 I came upon mypy issue 8754 which
causes `--no-implicit-reexport` to leak into installed libraries and
causes some unexpected typing differences *in pytest* if the user uses
this flag.

Since the diff mostly makes sense, let's just conform to it.
2020-07-31 10:09:11 +03:00