ESSS / pytest-regressions

Pytest plugin for regression testing: https://pytest-regressions.readthedocs.io
MIT License
183 stars 36 forks source link

2.2.0: pytest is failing #61

Closed kloczek closed 2 years ago

kloczek commented 3 years ago

Please ignore that unit which is failing because missing matplotlib Just normal build, install and test cycle used on building package from non-root account:

tests/test_grids.py .. [ 4%] tests/test_image_regression.py F. [ 9%] tests/test_num_regression.py ................ [ 45%] tests/test_file_regression.py .... [ 54%] . F [ 56%] tests/test_data_regression.py ....... [ 72%] tests/test_dataframe_regression.py ......F...FF [100%]

================================================================================= FAILURES ================================================================================= __ test_image_regression ___

image_regression = <pytest_regressions.image_regression.ImageRegressionFixture object at 0x7f78e2fd5880> datadir = PosixPath('/tmp/pytest-of-tkloczko/pytest-204/test_image_regression0/test_image_regression')

def test_image_regression(image_regression, datadir):
  import matplotlib

E ModuleNotFoundError: No module named 'matplotlib'

tests/test_image_regression.py:9: ModuleNotFoundError test session

cls = <class '_pytest.runner.CallInfo'>, func = <function call_runtest_hook.. at 0x7f78e28fd940>, when = 'call' reraise = (<class '_pytest.outcomes.Exit'>, <class 'KeyboardInterrupt'>)

@classmethod
def from_call(
    cls,
    func: "Callable[[], TResult]",
    when: "Literal['collect', 'setup', 'call', 'teardown']",
    reraise: Optional[
        Union[Type[BaseException], Tuple[Type[BaseException], ...]]
    ] = None,
) -> "CallInfo[TResult]":
    excinfo = None
    start = timing.time()
    precise_start = timing.perf_counter()
    try:
      result: Optional[TResult] = func()

/usr/lib/python3.8/site-packages/_pytest/runner.py:311:


  lambda: ihook(item=item, **kwds), when=when, reraise=reraise

)

/usr/lib/python3.8/site-packages/_pytest/runner.py:255:


self = <_HookCaller 'pytest_runtest_call'>, args = (), kwargs = {'item': }, notincall = set()

def __call__(self, *args, **kwargs):
    if args:
        raise TypeError("hook calling supports only keyword arguments")
    assert not self.is_historic()
    if self.spec and self.spec.argnames:
        notincall = (
            set(self.spec.argnames) - set(["__multicall__"]) - set(kwargs.keys())
        )
        if notincall:
            warnings.warn(
                "Argument(s) {} which are declared in the hookspec "
                "can not be found in this hook call".format(tuple(notincall)),
                stacklevel=2,
            )
  return self._hookexec(self, self.get_hookimpls(), kwargs)

/usr/lib/python3.8/site-packages/pluggy/hooks.py:286:


self = <_pytest.config.PytestPluginManager object at 0x7f78eab62f70>, hook = <_HookCaller 'pytest_runtest_call'> methods = [<HookImpl plugin_name='runner', plugin=<module '_pytest.runner' from '/usr/lib/python3.8/site-packages/_pytest/runner...pper name='/dev/null' mode='r' encoding='UTF-8'>> _state='suspended' _in_suspended=False> _capture_fixture=None>>, ...] kwargs = {'item': }

def _hookexec(self, hook, methods, kwargs):
    # called from all hookcaller instances.
    # enable_tracing will set its own wrapping function at self._inner_hookexec
  return self._inner_hookexec(hook, methods, kwargs)

/usr/lib/python3.8/site-packages/pluggy/manager.py:93:


hook = <_HookCaller 'pytest_runtest_call'> methods = [<HookImpl plugin_name='runner', plugin=<module '_pytest.runner' from '/usr/lib/python3.8/site-packages/_pytest/runner...pper name='/dev/null' mode='r' encoding='UTF-8'>> _state='suspended' _in_suspended=False> _capture_fixture=None>>, ...] kwargs = {'item': }

self._inner_hookexec = lambda hook, methods, kwargs: hook.multicall( methods, kwargs, firstresult=hook.spec.opts.get("firstresult") if hook.spec else False, )

/usr/lib/python3.8/site-packages/pluggy/manager.py:84:


hook_impls = [<HookImpl plugin_name='runner', plugin=<module '_pytest.runner' from '/usr/lib/python3.8/site-packages/_pytest/runner...pper name='/dev/null' mode='r' encoding='UTF-8'>> _state='suspended' _in_suspended=False> _capture_fixture=None>>, ...] caller_kwargs = {'item': }, firstresult = False

def _multicall(hook_impls, caller_kwargs, firstresult=False):
    """Execute a call into multiple python functions/methods and return the
    result(s).

    ``caller_kwargs`` comes from _HookCaller.__call__().
    """
    __tracebackhide__ = True
    results = []
    excinfo = None
    try:  # run impl and wrapper setup functions in a loop
        teardowns = []
        try:
            for hook_impl in reversed(hook_impls):
                try:
                    args = [caller_kwargs[argname] for argname in hook_impl.argnames]
                except KeyError:
                    for argname in hook_impl.argnames:
                        if argname not in caller_kwargs:
                            raise HookCallError(
                                "hook call must provide argument %r" % (argname,)
                            )

                if hook_impl.hookwrapper:
                    try:
                        gen = hook_impl.function(*args)
                        next(gen)  # first yield
                        teardowns.append(gen)
                    except StopIteration:
                        _raise_wrapfail(gen, "did not yield")
                else:
                    res = hook_impl.function(*args)
                    if res is not None:
                        results.append(res)
                        if firstresult:  # halt further impl calls
                            break
        except BaseException:
            excinfo = sys.exc_info()
    finally:
        if firstresult:  # first result hooks return a single value
            outcome = _Result(results[0] if results else None, excinfo)
        else:
            outcome = _Result(results, excinfo)

        # run all wrapper post-yield blocks
        for gen in reversed(teardowns):
            try:
                gen.send(outcome)
                _raise_wrapfail(gen, "has second yield")
            except StopIteration:
                pass
      return outcome.get_result()

/usr/lib/python3.8/site-packages/pluggy/callers.py:208:


self = <pluggy.callers._Result object at 0x7f78e263f730>

def get_result(self):
    """Get the result(s) for this hook call.

    If the hook was marked as a ``firstresult`` only a single value
    will be returned otherwise a list of results.
    """
    __tracebackhide__ = True
    if self._excinfo is None:
        return self._result
    else:
        ex = self._excinfo
        if _py3:
          raise ex[1].with_traceback(ex[2])

/usr/lib/python3.8/site-packages/pluggy/callers.py:80:


hook_impls = [<HookImpl plugin_name='runner', plugin=<module '_pytest.runner' from '/usr/lib/python3.8/site-packages/_pytest/runner...pper name='/dev/null' mode='r' encoding='UTF-8'>> _state='suspended' _in_suspended=False> _capture_fixture=None>>, ...] caller_kwargs = {'item': }, firstresult = False

def _multicall(hook_impls, caller_kwargs, firstresult=False):
    """Execute a call into multiple python functions/methods and return the
    result(s).

    ``caller_kwargs`` comes from _HookCaller.__call__().
    """
    __tracebackhide__ = True
    results = []
    excinfo = None
    try:  # run impl and wrapper setup functions in a loop
        teardowns = []
        try:
            for hook_impl in reversed(hook_impls):
                try:
                    args = [caller_kwargs[argname] for argname in hook_impl.argnames]
                except KeyError:
                    for argname in hook_impl.argnames:
                        if argname not in caller_kwargs:
                            raise HookCallError(
                                "hook call must provide argument %r" % (argname,)
                            )

                if hook_impl.hookwrapper:
                    try:
                        gen = hook_impl.function(*args)
                        next(gen)  # first yield
                        teardowns.append(gen)
                    except StopIteration:
                        _raise_wrapfail(gen, "did not yield")
                else:
                  res = hook_impl.function(*args)

/usr/lib/python3.8/site-packages/pluggy/callers.py:187:


item =

def pytest_runtest_call(item: Item) -> None:
    _update_current_test_var(item, "call")
    try:
        del sys.last_type
        del sys.last_value
        del sys.last_traceback
    except AttributeError:
        pass
    try:
        item.runtest()
    except Exception as e:
        # Store trace info to allow postmortem debugging
        sys.last_type = type(e)
        sys.last_value = e
        assert e.__traceback__ is not None
        # Skip *this* frame
        sys.last_traceback = e.__traceback__.tb_next
      raise e

/usr/lib/python3.8/site-packages/_pytest/runner.py:170:


item =

def pytest_runtest_call(item: Item) -> None:
    _update_current_test_var(item, "call")
    try:
        del sys.last_type
        del sys.last_value
        del sys.last_traceback
    except AttributeError:
        pass
    try:
      item.runtest()

/usr/lib/python3.8/site-packages/_pytest/runner.py:162:


self =

def runtest(self):
  desc = self.get_long_description()

/usr/lib/python3.8/site-packages/pytest_checkdocs/init.py:29:


self =

def get_long_description(self):
  return Description.from_md(ensure_clean(pep517.meta.load('.').metadata))

/usr/lib/python3.8/site-packages/pytest_checkdocs/init.py:60:


root = '.'

def load(root):
    """
    Given a source directory (root) of a package,
    return an importlib.metadata.Distribution object
    with metadata build from that package.
    """
    root = os.path.expanduser(root)
    system = compat_system(root)
    builder = functools.partial(build, source_dir=root, system=system)
  path = Path(build_as_zip(builder))

/usr/lib/python3.8/site-packages/pep517/meta.py:71:


builder = functools.partial(<function build at 0x7f78e7a0adc0>, source_dir='.', system={'build-backend': 'setuptools.build_meta:legacy', 'requires': ['setuptools', 'wheel']})

def build_as_zip(builder=build):
    with tempdir() as out_dir:
      builder(dest=out_dir)

/usr/lib/python3.8/site-packages/pep517/meta.py:58:


source_dir = '.', dest = '/tmp/tmppqylg39m', system = {'build-backend': 'setuptools.build_meta:legacy', 'requires': ['setuptools', 'wheel']}

def build(source_dir='.', dest=None, system=None):
    system = system or load_system(source_dir)
    dest = os.path.join(source_dir, dest or 'dist')
    mkdir_p(dest)
    validate_system(system)
    hooks = Pep517HookCaller(
        source_dir, system['build-backend'], system.get('backend-path')
    )

    with hooks.subprocess_runner(quiet_subprocess_runner):
        with BuildEnvironment() as env:
            env.pip_install(system['requires'])
          _prep_meta(hooks, env, dest)

/usr/lib/python3.8/site-packages/pep517/meta.py:53:


hooks = <pep517.wrappers.Pep517HookCaller object at 0x7f78e263f7f0>, env = <pep517.envbuild.BuildEnvironment object at 0x7f78e263f610>, dest = '/tmp/tmppqylg39m'

def _prep_meta(hooks, env, dest):
    reqs = hooks.get_requires_for_build_wheel({})
    log.info('Got build requires: %s', reqs)

    env.pip_install(reqs)
    log.info('Installed dynamic build dependencies')

    with tempdir() as td:
        log.info('Trying to build metadata in %s', td)
      filename = hooks.prepare_metadata_for_build_wheel(td, {})

/usr/lib/python3.8/site-packages/pep517/meta.py:36:


self = <pep517.wrappers.Pep517HookCaller object at 0x7f78e263f7f0>, metadata_directory = '/tmp/tmpruv20d3u', config_settings = {}, _allow_fallback = True

def prepare_metadata_for_build_wheel(
        self, metadata_directory, config_settings=None,
        _allow_fallback=True):
    """Prepare a ``*.dist-info`` folder with metadata for this project.

    Returns the name of the newly created folder.

    If the build backend defines a hook with this name, it will be called
    in a subprocess. If not, the backend will be asked to build a wheel,
    and the dist-info extracted from that (unless _allow_fallback is
    False).
    """
  return self._call_hook('prepare_metadata_for_build_wheel', {

'metadata_directory': abspath(metadata_directory), 'config_settings': config_settings, '_allow_fallback': _allow_fallback, })

/usr/lib/python3.8/site-packages/pep517/wrappers.py:184:


self = <pep517.wrappers.Pep517HookCaller object at 0x7f78e263f7f0>, hook_name = 'prepare_metadata_for_build_wheel' kwargs = {'_allow_fallback': True, 'config_settings': {}, 'metadata_directory': '/tmp/tmpruv20d3u'}

def _call_hook(self, hook_name, kwargs):
    # On Python 2, pytoml returns Unicode values (which is correct) but the
    # environment passed to check_call needs to contain string values. We
    # convert here by encoding using ASCII (the backend can only contain
    # letters, digits and _, . and : characters, and will be used as a
    # Python identifier, so non-ASCII content is wrong on Python 2 in
    # any case).
    # For backend_path, we use sys.getfilesystemencoding.
    if sys.version_info[0] == 2:
        build_backend = self.build_backend.encode('ASCII')
    else:
        build_backend = self.build_backend
    extra_environ = {'PEP517_BUILD_BACKEND': build_backend}

    if self.backend_path:
        backend_path = os.pathsep.join(self.backend_path)
        if sys.version_info[0] == 2:
            backend_path = backend_path.encode(sys.getfilesystemencoding())
        extra_environ['PEP517_BACKEND_PATH'] = backend_path

    with tempdir() as td:
        hook_input = {'kwargs': kwargs}
        compat.write_json(hook_input, pjoin(td, 'input.json'),
                          indent=2)

        # Run the hook in a subprocess
        with _in_proc_script_path() as script:
            python = self.python_executable
          self._subprocess_runner(

[python, abspath(str(script)), hook_name, td], cwd=self.source_dir, extra_environ=extra_environ )

/usr/lib/python3.8/site-packages/pep517/wrappers.py:265:


cmd = ['/usr/bin/python3', '/usr/lib/python3.8/site-packages/pep517/in_process/_in_process.py', 'prepare_metadata_for_build_wheel', '/tmp/tmps1lr660y'] cwd = '/home/tkloczko/rpmbuild/BUILD/pytest-regressions-2.2.0', extra_environ = {'PEP517_BUILD_BACKEND': 'setuptools.build_meta:legacy'}

def quiet_subprocess_runner(cmd, cwd=None, extra_environ=None):
    """A method of calling the wrapper subprocess while suppressing output."""
    env = os.environ.copy()
    if extra_environ:
        env.update(extra_environ)
  check_output(cmd, cwd=cwd, env=env, stderr=STDOUT)

/usr/lib/python3.8/site-packages/pep517/wrappers.py:75:


timeout = None popenargs = (['/usr/bin/python3', '/usr/lib/python3.8/site-packages/pep517/in_process/_in_process.py', 'prepare_metadata_for_build_wheel', '/tmp/tmps1lr660y'],) kwargs = {'cwd': '/home/tkloczko/rpmbuild/BUILD/pytest-regressions-2.2.0', 'env': {'AR': '/usr/bin/gcc-ar', 'BASH_FUNC_which%%'...sh-protection -fcf-protection -fdata-sections -ffunction-sections -flto=auto -flto-partition=none', ...}, 'stderr': -2}

def check_output(*popenargs, timeout=None, **kwargs):
    r"""Run command with arguments and return its output.

    If the exit code was non-zero it raises a CalledProcessError.  The
    CalledProcessError object will have the return code in the returncode
    attribute and output in the output attribute.

    The arguments are the same as for the Popen constructor.  Example:

    >>> check_output(["ls", "-l", "/dev/null"])
    b'crw-rw-rw- 1 root root 1, 3 Oct 18  2007 /dev/null\n'

    The stdout argument is not allowed as it is used internally.
    To capture standard error in the result, use stderr=STDOUT.

    >>> check_output(["/bin/sh", "-c",
    ...               "ls -l non_existent_file ; exit 0"],
    ...              stderr=STDOUT)
    b'ls: non_existent_file: No such file or directory\n'

    There is an additional optional argument, "input", allowing you to
    pass a string to the subprocess's stdin.  If you use this argument
    you may not also use the Popen constructor's "stdin" argument, as
    it too will be used internally.  Example:

    >>> check_output(["sed", "-e", "s/foo/bar/"],
    ...              input=b"when in the course of fooman events\n")
    b'when in the course of barman events\n'

    By default, all communication is in bytes, and therefore any "input"
    should be bytes, and the return value will be bytes.  If in text mode,
    any "input" should be a string, and the return value will be a string
    decoded according to locale encoding, or by "encoding" if set. Text mode
    is triggered by setting any of text, encoding, errors or universal_newlines.
    """
    if 'stdout' in kwargs:
        raise ValueError('stdout argument not allowed, it will be overridden.')

    if 'input' in kwargs and kwargs['input'] is None:
        # Explicitly passing input=None was previously equivalent to passing an
        # empty string. That is maintained here for backwards compatibility.
        if kwargs.get('universal_newlines') or kwargs.get('text'):
            empty = ''
        else:
            empty = b''
        kwargs['input'] = empty
  return run(*popenargs, stdout=PIPE, timeout=timeout, check=True,

**kwargs).stdout

/usr/lib64/python3.8/subprocess.py:415:


input = None, capture_output = False, timeout = None, check = True popenargs = (['/usr/bin/python3', '/usr/lib/python3.8/site-packages/pep517/in_process/_in_process.py', 'prepare_metadata_for_build_wheel', '/tmp/tmps1lr660y'],) kwargs = {'cwd': '/home/tkloczko/rpmbuild/BUILD/pytest-regressions-2.2.0', 'env': {'AR': '/usr/bin/gcc-ar', 'BASH_FUNC_which%%'...-fcf-protection -fdata-sections -ffunction-sections -flto=auto -flto-partition=none', ...}, 'stderr': -2, 'stdout': -1} process = <subprocess.Popen object at 0x7f78e2554c10> stdout = b'Traceback (most recent call last):\n File "/usr/lib/python3.8/site-packages/pep517/in_process/_in_process.py", line...ng pip, instead of https://github.com/user/proj/archive/master.zip use git+https://github.com/user/proj.git#egg=proj\n' stderr = None, retcode = 1

def run(*popenargs,
        input=None, capture_output=False, timeout=None, check=False, **kwargs):
    """Run command with arguments and return a CompletedProcess instance.

    The returned instance will have attributes args, returncode, stdout and
    stderr. By default, stdout and stderr are not captured, and those attributes
    will be None. Pass stdout=PIPE and/or stderr=PIPE in order to capture them.

    If check is True and the exit code was non-zero, it raises a
    CalledProcessError. The CalledProcessError object will have the return code
    in the returncode attribute, and output & stderr attributes if those streams
    were captured.

    If timeout is given, and the process takes too long, a TimeoutExpired
    exception will be raised.

    There is an optional argument "input", allowing you to
    pass bytes or a string to the subprocess's stdin.  If you use this argument
    you may not also use the Popen constructor's "stdin" argument, as
    it will be used internally.

    By default, all communication is in bytes, and therefore any "input" should
    be bytes, and the stdout and stderr will be bytes. If in text mode, any
    "input" should be a string, and stdout and stderr will be strings decoded
    according to locale encoding, or by "encoding" if set. Text mode is
    triggered by setting any of text, encoding, errors or universal_newlines.

    The other arguments are the same as for the Popen constructor.
    """
    if input is not None:
        if kwargs.get('stdin') is not None:
            raise ValueError('stdin and input arguments may not both be used.')
        kwargs['stdin'] = PIPE

    if capture_output:
        if kwargs.get('stdout') is not None or kwargs.get('stderr') is not None:
            raise ValueError('stdout and stderr arguments may not be used '
                             'with capture_output.')
        kwargs['stdout'] = PIPE
        kwargs['stderr'] = PIPE

    with Popen(*popenargs, **kwargs) as process:
        try:
            stdout, stderr = process.communicate(input, timeout=timeout)
        except TimeoutExpired as exc:
            process.kill()
            if _mswindows:
                # Windows accumulates the output in a single blocking
                # read() call run on child threads, with the timeout
                # being done in a join() on those threads.  communicate()
                # _after_ kill() is required to collect that and add it
                # to the exception.
                exc.stdout, exc.stderr = process.communicate()
            else:
                # POSIX _communicate already populated the output so
                # far into the TimeoutExpired exception.
                process.wait()
            raise
        except:  # Including KeyboardInterrupt, communicate handled that.
            process.kill()
            # We don't call process.wait() as .__exit__ does that for us.
            raise
        retcode = process.poll()
        if check and retcode:
          raise CalledProcessError(retcode, process.args,

output=stdout, stderr=stderr) E subprocess.CalledProcessError: Command '['/usr/bin/python3', '/usr/lib/python3.8/site-packages/pep517/in_process/_in_process.py', 'prepare_metadata_for_build_wheel', '/tmp/tmps1lr660y']' returned non-zero exit status 1.

/usr/lib64/python3.8/subprocess.py:516: CalledProcessError __ test_non_numeric_data[array1] ___

dataframe_regression = <pytest_regressions.dataframe_regression.DataFrameRegressionFixture object at 0x7f78c97d2ee0> array = [<test_dataframe_regression.Foo object at 0x7f78e354b520>, <test_dataframe_regression.Foo object at 0x7f78e3547100>, <test_dataframe_regression.Foo object at 0x7f78e35474f0>, <test_dataframe_regression.Foo object at 0x7f78e3547880>] no_regen = None

@pytest.mark.parametrize(
    "array", [[np.random.randint(10, 99, 6)] * 6, [Foo(i) for i in range(4)]]
)
def test_non_numeric_data(dataframe_regression, array, no_regen):
    data1 = pd.DataFrame()
    data1["data1"] = array
    with pytest.raises(
        AssertionError,
        match="Only numeric data is supported on dataframe_regression fixture.\n"
        "  Array with type '%s' was given." % (str(data1["data1"].dtype),),
    ):
      dataframe_regression.check(data1)

tests/test_dataframe_regression.py:184:


self = <pytest_regressions.dataframe_regression.DataFrameRegressionFixture object at 0x7f78c97d2ee0> data_frame = data1 0 <test_dataframe_regression.Foo object at 0x7f7... 1 <test_dat...t at 0x7f7... 2 <test_dataframe_regression.Foo object at 0x7f7... 3 <test_dataframe_regression.Foo object at 0x7f7... basename = None, fullpath = None, tolerances = None, default_tolerance = None

def check(
    self,
    data_frame,
    basename=None,
    fullpath=None,
    tolerances=None,
    default_tolerance=None,
):
    """
    Checks the given pandas dataframe against a previously recorded version, or generate a new file.

    Example::

        data_frame = pandas.DataFrame.from_dict({
            'U_gas': U[0][positions],
            'U_liquid': U[1][positions],
            'gas_vol_frac [-]': vol_frac[0][positions],
            'liquid_vol_frac [-]': vol_frac[1][positions],
            'P': Pa_to_bar(P)[positions],
        })
        dataframe_regression.check(data_frame)

    :param pandas.DataFrame data_frame: pandas DataFrame containing data for regression check.

    :param str basename: basename of the file to test/record. If not given the name
        of the test is used.

    :param str fullpath: complete path to use as a reference file. This option
        will ignore embed_data completely, being useful if a reference file is located
        in the session data dir for example.

    :param dict tolerances: dict mapping keys from the data_dict to tolerance settings for the
        given data. Example::

            tolerances={'U': Tolerance(atol=1e-2)}

    :param dict default_tolerance: dict mapping the default tolerance for the current check
        call. Example::

            default_tolerance=dict(atol=1e-7, rtol=1e-18).

        If not provided, will use defaults from numpy's ``isclose`` function.

    ``basename`` and ``fullpath`` are exclusive.
    """
    try:
        import pandas as pd
    except ModuleNotFoundError:
        raise ModuleNotFoundError(import_error_message("Pandas"))

    import functools

    __tracebackhide__ = True

    assert type(data_frame) is pd.DataFrame, (
        "Only pandas DataFrames are supported on on dataframe_regression fixture.\n"
        "Object with type '%s' was given." % (str(type(data_frame)),)
    )

    for column in data_frame.columns:
        array = data_frame[column]
        # Skip assertion if an array of strings
        if (array.dtype == "O") and (type(array[0]) is str):
            continue
        # Rejected: timedelta, datetime, objects, zero-terminated bytes, unicode strings and raw data
      assert array.dtype not in ["m", "M", "O", "S", "a", "U", "V"], (

"Only numeric data is supported on dataframe_regression fixture.\n" "Array with type '%s' was given.\n" % (str(array.dtype),) ) E AssertionError: Only numeric data is supported on dataframe_regression fixture. E Array with type 'object' was given.

../../BUILDROOT/python-pytest-regressions-2.2.0-2.fc35.x86_64/usr/lib/python3.8/site-packages/pytest_regressions/dataframe_regression.py:235: AssertionError

During handling of the above exception, another exception occurred:

dataframe_regression = <pytest_regressions.dataframe_regression.DataFrameRegressionFixture object at 0x7f78c97d2ee0> array = [<test_dataframe_regression.Foo object at 0x7f78e354b520>, <test_dataframe_regression.Foo object at 0x7f78e3547100>, <test_dataframe_regression.Foo object at 0x7f78e35474f0>, <test_dataframe_regression.Foo object at 0x7f78e3547880>] no_regen = None

@pytest.mark.parametrize(
    "array", [[np.random.randint(10, 99, 6)] * 6, [Foo(i) for i in range(4)]]
)
def test_non_numeric_data(dataframe_regression, array, no_regen):
    data1 = pd.DataFrame()
    data1["data1"] = array
    with pytest.raises(
        AssertionError,
        match="Only numeric data is supported on dataframe_regression fixture.\n"
        "  Array with type '%s' was given." % (str(data1["data1"].dtype),),
    ):
      dataframe_regression.check(data1)

E AssertionError: Regex pattern "Only numeric data is supported on dataframe_regression fixture.\n Array with type 'object' was given." does not match "Only numeric data is supported on dataframe_regression fixture.\nArray with type 'object' was given.\n".

tests/test_dataframe_regression.py:184: AssertionError __ test_non_numeric_data[array0] ___

dataframe_regression = <pytest_regressions.dataframe_regression.DataFrameRegressionFixture object at 0x7f78c971b850> array = [array([20, 18, 37, 32, 74, 91]), array([20, 18, 37, 32, 74, 91]), array([20, 18, 37, 32, 74, 91]), array([20, 18, 37, 32, 74, 91]), array([20, 18, 37, 32, 74, 91]), array([20, 18, 37, 32, 74, 91])] no_regen = None

@pytest.mark.parametrize(
    "array", [[np.random.randint(10, 99, 6)] * 6, [Foo(i) for i in range(4)]]
)
def test_non_numeric_data(dataframe_regression, array, no_regen):
    data1 = pd.DataFrame()
    data1["data1"] = array
    with pytest.raises(
        AssertionError,
        match="Only numeric data is supported on dataframe_regression fixture.\n"
        "  Array with type '%s' was given." % (str(data1["data1"].dtype),),
    ):
      dataframe_regression.check(data1)

tests/test_dataframe_regression.py:184:


self = <pytest_regressions.dataframe_regression.DataFrameRegressionFixture object at 0x7f78c971b850> data_frame = data1 0 [20, 18, 37, 32, 74, 91] 1 [20, 18, 37, 32, 74, 91] 2 [20, 18, 37, 32, 74, 91] 3 [20, 18, 37, 32, 74, 91] 4 [20, 18, 37, 32, 74, 91] 5 [20, 18, 37, 32, 74, 91] basename = None, fullpath = None, tolerances = None, default_tolerance = None

def check(
    self,
    data_frame,
    basename=None,
    fullpath=None,
    tolerances=None,
    default_tolerance=None,
):
    """
    Checks the given pandas dataframe against a previously recorded version, or generate a new file.

    Example::

        data_frame = pandas.DataFrame.from_dict({
            'U_gas': U[0][positions],
            'U_liquid': U[1][positions],
            'gas_vol_frac [-]': vol_frac[0][positions],
            'liquid_vol_frac [-]': vol_frac[1][positions],
            'P': Pa_to_bar(P)[positions],
        })
        dataframe_regression.check(data_frame)

    :param pandas.DataFrame data_frame: pandas DataFrame containing data for regression check.

    :param str basename: basename of the file to test/record. If not given the name
        of the test is used.

    :param str fullpath: complete path to use as a reference file. This option
        will ignore embed_data completely, being useful if a reference file is located
        in the session data dir for example.

    :param dict tolerances: dict mapping keys from the data_dict to tolerance settings for the
        given data. Example::

            tolerances={'U': Tolerance(atol=1e-2)}

    :param dict default_tolerance: dict mapping the default tolerance for the current check
        call. Example::

            default_tolerance=dict(atol=1e-7, rtol=1e-18).

        If not provided, will use defaults from numpy's ``isclose`` function.

    ``basename`` and ``fullpath`` are exclusive.
    """
    try:
        import pandas as pd
    except ModuleNotFoundError:
        raise ModuleNotFoundError(import_error_message("Pandas"))

    import functools

    __tracebackhide__ = True

    assert type(data_frame) is pd.DataFrame, (
        "Only pandas DataFrames are supported on on dataframe_regression fixture.\n"
        "Object with type '%s' was given." % (str(type(data_frame)),)
    )

    for column in data_frame.columns:
        array = data_frame[column]
        # Skip assertion if an array of strings
        if (array.dtype == "O") and (type(array[0]) is str):
            continue
        # Rejected: timedelta, datetime, objects, zero-terminated bytes, unicode strings and raw data
      assert array.dtype not in ["m", "M", "O", "S", "a", "U", "V"], (

"Only numeric data is supported on dataframe_regression fixture.\n" "Array with type '%s' was given.\n" % (str(array.dtype),) ) E AssertionError: Only numeric data is supported on dataframe_regression fixture. E Array with type 'object' was given.

../../BUILDROOT/python-pytest-regressions-2.2.0-2.fc35.x86_64/usr/lib/python3.8/site-packages/pytest_regressions/dataframe_regression.py:235: AssertionError

During handling of the above exception, another exception occurred:

dataframe_regression = <pytest_regressions.dataframe_regression.DataFrameRegressionFixture object at 0x7f78c971b850> array = [array([20, 18, 37, 32, 74, 91]), array([20, 18, 37, 32, 74, 91]), array([20, 18, 37, 32, 74, 91]), array([20, 18, 37, 32, 74, 91]), array([20, 18, 37, 32, 74, 91]), array([20, 18, 37, 32, 74, 91])] no_regen = None

@pytest.mark.parametrize(
    "array", [[np.random.randint(10, 99, 6)] * 6, [Foo(i) for i in range(4)]]
)
def test_non_numeric_data(dataframe_regression, array, no_regen):
    data1 = pd.DataFrame()
    data1["data1"] = array
    with pytest.raises(
        AssertionError,
        match="Only numeric data is supported on dataframe_regression fixture.\n"
        "  Array with type '%s' was given." % (str(data1["data1"].dtype),),
    ):
      dataframe_regression.check(data1)

E AssertionError: Regex pattern "Only numeric data is supported on dataframe_regression fixture.\n Array with type 'object' was given." does not match "Only numeric data is supported on dataframe_regression fixture.\nArray with type 'object' was given.\n".

tests/test_dataframe_regression.py:184: AssertionError ____ test_non_pandasdataframe ____

dataframe_regression = <pytest_regressions.dataframe_regression.DataFrameRegressionFixture object at 0x7f78c970f880>

def test_non_pandas_dataframe(dataframe_regression):
    data = np.ones(shape=(10, 10))
    with pytest.raises(
        AssertionError,
        match="Only pandas DataFrames are supported on on dataframe_regression fixture.\n"
        "  Object with type '%s' was given." % (str(type(data)),),
    ):
      dataframe_regression.check(data)

tests/test_dataframe_regression.py:249:


self = <pytest_regressions.dataframe_regression.DataFrameRegressionFixture object at 0x7f78c970f880> data_frame = array([[1., 1., 1., 1., 1., 1., 1., 1., 1., 1.], [1., 1., 1., 1., 1., 1., 1., 1., 1., 1.], [1., 1., 1., ...1., 1., 1., 1., 1.], [1., 1., 1., 1., 1., 1., 1., 1., 1., 1.], [1., 1., 1., 1., 1., 1., 1., 1., 1., 1.]]) basename = None, fullpath = None, tolerances = None, default_tolerance = None

def check(
    self,
    data_frame,
    basename=None,
    fullpath=None,
    tolerances=None,
    default_tolerance=None,
):
    """
    Checks the given pandas dataframe against a previously recorded version, or generate a new file.

    Example::

        data_frame = pandas.DataFrame.from_dict({
            'U_gas': U[0][positions],
            'U_liquid': U[1][positions],
            'gas_vol_frac [-]': vol_frac[0][positions],
            'liquid_vol_frac [-]': vol_frac[1][positions],
            'P': Pa_to_bar(P)[positions],
        })
        dataframe_regression.check(data_frame)

    :param pandas.DataFrame data_frame: pandas DataFrame containing data for regression check.

    :param str basename: basename of the file to test/record. If not given the name
        of the test is used.

    :param str fullpath: complete path to use as a reference file. This option
        will ignore embed_data completely, being useful if a reference file is located
        in the session data dir for example.

    :param dict tolerances: dict mapping keys from the data_dict to tolerance settings for the
        given data. Example::

            tolerances={'U': Tolerance(atol=1e-2)}

    :param dict default_tolerance: dict mapping the default tolerance for the current check
        call. Example::

            default_tolerance=dict(atol=1e-7, rtol=1e-18).

        If not provided, will use defaults from numpy's ``isclose`` function.

    ``basename`` and ``fullpath`` are exclusive.
    """
    try:
        import pandas as pd
    except ModuleNotFoundError:
        raise ModuleNotFoundError(import_error_message("Pandas"))

    import functools

    __tracebackhide__ = True
  assert type(data_frame) is pd.DataFrame, (

"Only pandas DataFrames are supported on on dataframe_regression fixture.\n" "Object with type '%s' was given." % (str(type(data_frame)),) ) E AssertionError: Only pandas DataFrames are supported on on dataframe_regression fixture. E Object with type '<class 'numpy.ndarray'>' was given.

../../BUILDROOT/python-pytest-regressions-2.2.0-2.fc35.x86_64/usr/lib/python3.8/site-packages/pytest_regressions/dataframe_regression.py:224: AssertionError

During handling of the above exception, another exception occurred:

dataframe_regression = <pytest_regressions.dataframe_regression.DataFrameRegressionFixture object at 0x7f78c970f880>

def test_non_pandas_dataframe(dataframe_regression):
    data = np.ones(shape=(10, 10))
    with pytest.raises(
        AssertionError,
        match="Only pandas DataFrames are supported on on dataframe_regression fixture.\n"
        "  Object with type '%s' was given." % (str(type(data)),),
    ):
      dataframe_regression.check(data)

E AssertionError: Regex pattern "Only pandas DataFrames are supported on on dataframe_regression fixture.\n Object with type '<class 'numpy.ndarray'>' was given." does not match "Only pandas DataFrames are supported on on dataframe_regression fixture.\nObject with type '<class 'numpy.ndarray'>' was given.".

tests/test_dataframe_regression.py:249: AssertionError ========================================================================= short test summary info ========================================================================== FAILED tests/test_image_regression.py::test_image_regression - ModuleNotFoundError: No module named 'matplotlib' FAILED ::project - subprocess.CalledProcessError: Command '['/usr/bin/python3', '/usr/lib/python3.8/site-packages/pep517/in_process/_in_process.py', 'prepare_metadata_fo... FAILED tests/test_dataframe_regression.py::test_non_numeric_data[array1] - AssertionError: Regex pattern "Only numeric data is supported on dataframe_regression fixture.... FAILED tests/test_dataframe_regression.py::test_non_numeric_data[array0] - AssertionError: Regex pattern "Only numeric data is supported on dataframe_regression fixture.... FAILED tests/test_dataframe_regression.py::test_non_pandas_dataframe - AssertionError: Regex pattern "Only pandas DataFrames are supported on on dataframe_regression fix... ====================================================================== 5 failed, 39 passed in 18.00s =======================================================================

tovrstra commented 3 years ago

This should be fixed in #72. @kloczek Could you check?

kloczek commented 3 years ago

Sure :) Will back shortly with redults.

kloczek commented 2 years ago

Just checked that and looks like it works. I've added few other commits to my build procedure. I think that it would be good to make new release :)

nicoddemus commented 2 years ago

2.3.0 released! Thanks everyone.

kloczek commented 2 years ago

Just tested 2.3.0. Small correction for some warning on rendering documentation:

+ /usr/bin/python3 setup.py build_sphinx -b man --build-dir build/sphinx
/usr/lib/python3.8/site-packages/pkg_resources/__init__.py:116: PkgResourcesDeprecationWarning: 1.16.0-unknown is an invalid version and will not be supported in a future release
  warnings.warn(
/usr/lib/python3.8/site-packages/setuptools/installer.py:27: SetuptoolsDeprecationWarning: setuptools.installer is deprecated. Requirements should be satisfied by a PEP 517 installer.
  warnings.warn(
WARNING: The wheel package is not available.
running build_sphinx
Running Sphinx v4.3.2
making output directory... done
building [mo]: targets for 0 po files that are out of date
building [man]: all manpages
updating environment: [new config] 5 added, 0 changed, 0 removed
reading sources... [100%] overview
WARNING: autodoc: failed to import method 'data_regression.DataRegressionFixture.check' from module 'pytest_regressions'; the following exception was raised:
No module named 'pytest_regressions'
WARNING: autodoc: failed to import method 'dataframe_regression.DataFrameRegressionFixture.check' from module 'pytest_regressions'; the following exception was raised:
No module named 'pytest_regressions'
WARNING: autodoc: failed to import method 'file_regression.FileRegressionFixture.check' from module 'pytest_regressions'; the following exception was raised:
No module named 'pytest_regressions'
WARNING: autodoc: failed to import method 'num_regression.NumericRegressionFixture.check' from module 'pytest_regressions'; the following exception was raised:
No module named 'pytest_regressions'
WARNING: autodoc: failed to import method 'image_regression.ImageRegressionFixture.check' from module 'pytest_regressions'; the following exception was raised:
No module named 'pytest_regressions'
looking for now-outdated files... none found
pickling environment... done
checking consistency... done
writing... python-pytest-regressions.3 { installation overview api license } done
build succeeded, 5 warnings.

And fix:

--- a/doc/conf.py~      2022-01-04 12:08:13.000000000 +0000
+++ b/doc/conf.py       2022-01-04 12:40:46.506675951 +0000
@@ -10,9 +10,9 @@
 # add these directories to sys.path here. If the directory is relative to the
 # documentation root, use os.path.abspath to make it absolute, like shown here.
 #
-# import os
-# import sys
-# sys.path.insert(0, os.path.abspath('.'))
+import os
+import sys
+sys.path.append(os.path.abspath('../src'))
 # -- Project information -----------------------------------------------------

 project = "pytest-regressions"

With that patch:

+ /usr/bin/python3 setup.py build_sphinx -b man --build-dir build/sphinx
/usr/lib/python3.8/site-packages/pkg_resources/__init__.py:116: PkgResourcesDeprecationWarning: 1.16.0-unknown is an invalid version and will not be supported in a future release
  warnings.warn(
/usr/lib/python3.8/site-packages/setuptools/installer.py:27: SetuptoolsDeprecationWarning: setuptools.installer is deprecated. Requirements should be satisfied by a PEP 517 installer.
  warnings.warn(
WARNING: The wheel package is not available.
running build_sphinx
Running Sphinx v4.3.2
making output directory... done
building [mo]: targets for 0 po files that are out of date
building [man]: all manpages
updating environment: [new config] 5 added, 0 changed, 0 removed
reading sources... [100%] overview
looking for now-outdated files... none found
pickling environment... done
checking consistency... done
writing... python-pytest-regressions.3 { installation overview api license } done
build succeeded.

I'm not sure how to correct other warnings.