Fix performance regression from version 4.0.0 (#386)

* Fix performance issue when collecting tests.

* Add changelog entry
This commit is contained in:
Alessio Bogon 2020-09-08 11:59:01 +02:00 committed by GitHub
parent 6ca1df907b
commit a8c1ff4ff3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 42 additions and 19 deletions

View File

@ -1,6 +1,11 @@
Changelog
=========
Unreleased
----------
- Fixed performance regression introduced in 4.0.0 where collection time of tests would take way longer than before. (youtux)
4.0.0
-----

View File

@ -1,29 +1,39 @@
"""Various utility functions."""
import inspect
from sys import _getframe
from inspect import getframeinfo
import six
CONFIG_STACK = []
if six.PY2:
from inspect import getargspec as _getargspec
def get_args(func):
"""Get a list of argument names for a function.
def get_args(func):
"""Get a list of argument names for a function.
This is a wrapper around inspect.getargspec/inspect.signature because
getargspec got deprecated in Python 3.5 and signature isn't available on
Python 2.
:param func: The function to inspect.
:param func: The function to inspect.
:return: A list of argument names.
:rtype: list
"""
return _getargspec(func).args
:return: A list of argument names.
:rtype: list
"""
if six.PY2:
return inspect.getargspec(func).args
params = inspect.signature(func).parameters.values()
return [param.name for param in params if param.kind == param.POSITIONAL_OR_KEYWORD]
else:
from inspect import signature as _signature
def get_args(func):
"""Get a list of argument names for a function.
:param func: The function to inspect.
:return: A list of argument names.
:rtype: list
"""
params = _signature(func).parameters.values()
return [param.name for param in params if param.kind == param.POSITIONAL_OR_KEYWORD]
def get_parametrize_markers_args(node):
@ -36,11 +46,19 @@ def get_parametrize_markers_args(node):
def get_caller_module_locals(depth=2):
frame_info = inspect.stack()[depth]
frame = frame_info[0] # frame_info.frame
return frame.f_locals
"""Get the caller module locals dictionary.
We use sys._getframe instead of inspect.stack(0) because the latter is way slower, since it iterates over
all the frames in the stack.
"""
return _getframe(depth).f_locals
def get_caller_module_path(depth=2):
frame_info = inspect.stack()[depth]
return frame_info[1] # frame_info.filename
"""Get the caller module path.
We use sys._getframe instead of inspect.stack(0) because the latter is way slower, since it iterates over
all the frames in the stack.
"""
frame = _getframe(depth)
return getframeinfo(frame, context=0).filename