Git Product home page Git Product logo

dessert's Introduction

Build Status Version

Overview

Dessert is a utility library enabling Python code to introspect assertions raised via the assert statement.

It is a standalone version of the introspection code from pytest, and all credit is due to Holger Krekel and the pytest developers for this code.

Usage

Using dessert is fairly simple:

>>> with open(tmp_filename, "w") as f:
...     _ = f.write("""
... def func():
...     def x():
...         return 1
...     def y():
...         return -1
...     assert y() == x()
... """)

>>> import emport
>>> import dessert
>>> with dessert.rewrite_assertions_context():
...     module = emport.import_file(tmp_filename)
>>> module.func() # doctest: +IGNORE_EXCEPTION_DETAIL +ELLIPSIS
Traceback (most recent call last):
    ...
    assert y() == x()
AssertionError: assert -1 == 1
+  where -1 = <function y at ...>()
+  and   1 = <function x at ...>()

Licence

Dessert is released under the MIT license. It is 99% based on pytest, which is released under the MIT license.

dessert's People

Contributors

hpk42 avatar nicoddemus avatar ronnypfannschmidt avatar benjaminp avatar flub avatar the-compiler avatar bubenkoff avatar vmalloc avatar hackebrot avatar pfctdayelise avatar turbo87 avatar msabramo avatar jurko-gospodnetic avatar michaelaquilina avatar palaviv avatar tomviner avatar omarkohl avatar takluyver avatar blueyed avatar kalekundert avatar ayalash avatar avdn avatar carreau avatar kvas-it avatar hartym avatar sallner avatar pedronis avatar elizaveta239 avatar mbyt avatar schmir avatar

Stargazers

David Jeffrey Merwin avatar Jelle van Assema avatar  avatar Louis Maddox avatar Jeff Carpenter avatar Darren Burns avatar Augusto Hack avatar Minho Ryang avatar Heungsub Lee avatar Omer Katz avatar Jonathan Barratt avatar Erez Shinan avatar

Watchers

 avatar James Cloos avatar  avatar

dessert's Issues

ModuleNotFoundError: No module named 'attr'

Install dessert via pip3, then try to import it produces the following error ModuleNotFoundError: No module named 'attr'.

$ docker pull ubuntu:focal
$ docker run --rm -it --network host ubuntu:focal /bin/bash -l

## <inside docker container shell> ##

root@localhost:/# apt update -y \
    && apt install -y python3-pip \
    && pip3 install dessert \
    && python3 -V \
    && python3 -c "import dessert; print(dessert)"

<snip>
Collecting dessert
  Downloading dessert-1.4.0.tar.gz (33 kB)
Collecting atomicwrites>=1.0
  Downloading atomicwrites-1.4.0-py2.py3-none-any.whl (6.8 kB)
Collecting munch
  Downloading munch-2.5.0-py2.py3-none-any.whl (10 kB)
Collecting py
  Downloading py-1.8.1-py2.py3-none-any.whl (83 kB)
Collecting six
  Downloading six-1.14.0-py2.py3-none-any.whl (10 kB)
Building wheels for collected packages: dessert
  Building wheel for dessert (setup.py) ... done
  Created wheel for dessert: filename=dessert-1.4.0-py3-none-any.whl size=22531 sha256=50b715efe8d81bb74ae6dcbdfdf0d58cb138d13628cbd87cf3369d75d434ecdb
  Stored in directory: /root/.cache/pip/wheels/ae/00/d8/f8f14a753807f219cf3c14367eaf04dce5d9ba6498746b5ee6
Successfully built dessert
Installing collected packages: atomicwrites, six, munch, py, dessert
Successfully installed atomicwrites-1.4.0 dessert-1.4.0 munch-2.5.0 py-1.8.1 six-1.14.0

Python 3.8.2
Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "/usr/local/lib/python3.8/dist-packages/dessert/__init__.py", line 5, in <module>
    from .rewrite import AssertionRewritingHook
  File "/usr/local/lib/python3.8/dist-packages/dessert/rewrite.py", line 25, in <module>
    from . import util
  File "/usr/local/lib/python3.8/dist-packages/dessert/util.py", line 2, in <module>
    import attr
ModuleNotFoundError: No module named 'attr'

Occur 'Invalid python_requires' during installation via poetry

python version: 3.10.2
poetry version: 1.2.2

show >=3.5.* is invalid python_requires

pyproject.toml

[tool.poetry]
name = "xxx"
version = "0.1.0"
description = ""
authors = []

[tool.poetry.dependencies]
python = "~3.10"
dessert = "1.4.4"

[build-system]
requires = ["poetry-core>=1.0.0"]
build-backend = "poetry.core.masonry.api"

Error message:

  Command ['/Users/tabi/Documents/gf-qa/.venv/bin/python', '-m', 'pip', 'install', '--use-pep517', '--disable-pip-version-check', '--prefix', '/Users/tabi/Documents/gf-qa/.venv', '--no-deps', '/Users/tabi/Library/Caches/pypoetry/artifacts/a5/24/6d/3eb6c7f669e521658694300384b6ef03c4ff58aeb3728892047ae7d7c0/dessert-1.4.4.tar.gz'] errored with the following return code 1, and output: 
  Processing /Users/tabi/Library/Caches/pypoetry/artifacts/a5/24/6d/3eb6c7f669e521658694300384b6ef03c4ff58aeb3728892047ae7d7c0/dessert-1.4.4.tar.gz
    Installing build dependencies: started
    Installing build dependencies: finished with status 'done'
    Getting requirements to build wheel: started
    Getting requirements to build wheel: finished with status 'done'
    Installing backend dependencies: started
    Installing backend dependencies: finished with status 'done'
    Preparing metadata (pyproject.toml): started
    Preparing metadata (pyproject.toml): finished with status 'error'
    error: subprocess-exited-with-error
    
    × Preparing metadata (pyproject.toml) did not run successfully.
    │ exit code: 1
    ╰─> [1 lines of output]
        error in setup command: 'python_requires' must be a string containing valid version specifiers; Invalid specifier: '>=3.5.*'
        [end of output]
    
    note: This error originates from a subprocess, and is likely not a problem with pip.
  error: metadata-generation-failed
  
  × Encountered error while generating package metadata.
  ╰─> See above for output.
  
  note: This is an issue with the package mentioned above, not pip.
  hint: See above for details.

Support python 3.11

All unittests fails when running with python 3.11 on ValueError:

ValueError: AST node line range (7, 1) is not valid

(some tests fails on range (12,1)).

It might be related to: python/cpython#93351

Dessert fails when importing pendulum 3.0.0

When attempting the following:

with dessert.rewrite_assertions_context():
    emport.import_file("path/to/pendulum/date.py")

dessert fails with:

  File "/Users/loz/terrible/python_ten/ten_env/lib/python3.10/site-packages/pendulum/helpers.py", line 51, in <module>
    difference_formatter = DifferenceFormatter()
  File "/Users/loz/terrible/python_ten/ten_env/lib/python3.10/site-packages/pendulum/formatting/difference_formatter.py", line 18, in __init__
    self._locale = Locale.load(locale)
  File "/Users/loz/terrible/python_ten/ten_env/lib/python3.10/site-packages/pendulum/locales/locale.py", line 41, in load
    raise ValueError(f"Locale [{locale}] does not exist.")

I bet it's related to the following code that did not exist in the previous pendulum version:

        locale_path = cast(Path, resources.files(__package__).joinpath(actual_locale))

Full context:

class Locale:

   ...

    @classmethod
    def load(cls, locale: str | Locale) -> Locale:
        if isinstance(locale, Locale):
            return locale

        locale = cls.normalize_locale(locale)
        if locale in cls._cache:
            return cls._cache[locale]

        # Checking locale existence
        actual_locale = locale
        locale_path = cast(Path, resources.files(__package__).joinpath(actual_locale))
        while not locale_path.exists():
            if actual_locale == locale:
                raise ValueError(f"Locale [{locale}] does not exist.")

EDIT: It seems that it works for python3.9 but fails in 3.10

Inconsistency of behavior using absolute and relative imports

Hi @vmalloc !

We've notice strange behavior using dessert (via slash) with absolute imports (i.e. by changing sys.path or PYTHONPATH). using absolute imports the loaded module is not the one from dessert's rewrite (with starts with _0. namespace, but the original module. this does not happen when using relative imports.

In the example below, there are 2 variables on a "global" module. each fixture loads the module in different way, and each test (with use different fixture) results different (it rather complicated, so I can share an archive with all the files)

.
├── config.py
├── fix
│   ├── __init__.py
│   ├── my_fix_absolute.py
│   ├── my_fix_relative.py
├── __init__.py
├── slashconf.py
└── test.py

$ tail ./*.py fix/*.py                                                                                     [10/798]
==> ./config.py <==
my_var_abs = True
my_var_rel = True


==> ./__init__.py <==

==> ./slashconf.py <==
import os, sys
sys.path.append(os.getcwd())

from fix.my_fix_absolute import my_fix
from fix.my_fix_relative import my_fix_rel

==> ./test.py <==
print __file__, config

def test_absolute_import(my_fix):
    print __file__, config.my_var_abs
    assert config.my_var_abs is False

def test_relative_import(my_fix_rel):
    print __file__, config.my_var_rel
    assert config.my_var_rel is False


==> fix/__init__.py <==

==> fix/my_fix_absolute.py <==
import slash
import config

print __file__, config

@slash.fixture
def my_fix():
    config.my_var_abs = False
    print __file__, config.my_var_abs
    return 'my_fix'

==> fix/my_fix_relative.py <==
import slash
from .. import config

print __file__, config

@slash.fixture
def my_fix_rel():
    config.my_var_rel = False
    print __file__, config.my_var_rel
    return 'my_fix'

$ slash run -v test.py
0 tests collected.../home/eli/dessert_test/test.py <module '_0.dessert_test.config' from '/home/eli/dessert_test/config.py'>
/home/eli/dessert_test/fix/my_fix_absolute.py <module 'config' from '/home/eli/dessert_test/config.py'>
/home/eli/dessert_test/fix/my_fix_relative.py <module '_0.dessert_test.config' from '/home/eli/dessert_test/config.py'>
2 tests collected
[2017-02-28 21:41:27] test.py:test_absolute_import
/home/eli/dessert_test/fix/my_fix_absolute.py False
/home/eli/dessert_test/test.py True
F: AssertionError: assert True is False
 +  where True = config.my_var_abs
[2017-02-28 21:41:27] test.py:test_relative_import
/home/eli/dessert_test/fix/my_fix_relative.py False
/home/eli/dessert_test/test.py False
==== Session Summary ====
== #1: test.py:test_absolute_import ====
 - 1/1 F (2017-02-28 23:41:27 +02:00):   - - - - - - - - - - - - - 
 /home/eli/dessert_test/test.py:6
>    assert config.my_var_abs is False
F    AssertionError: assert True is False
     +  where True = config.my_var_abs
==== Session ended. 1 successful, 0 skipped, 1 failures, 0 errors. Total duration: 00:00:00 ====

DeprecationWarning on using imp, please switch to importlib

../.env/lib/python3.7/site-packages/dessert/__init__.py:5: in <module>
    from .rewrite import AssertionRewritingHook
../.env/lib/python3.7/site-packages/dessert/rewrite.py:5: in <module>
    import imp
/usr/lib/python3.7/imp.py:33: in <module>
    DeprecationWarning, stacklevel=2)
E   DeprecationWarning: the imp module is deprecated in favour of importlib; see the module's documentation for alternative uses

Dessert rewrite emits deprecation warnings

From python documentation:

Deprecated since version 3.8: Old classes ast.Num, ast.Str, ast.Bytes, ast.NameConstant and ast.Ellipsis are still available, but they will be removed in future Python releases. In the meantime, instantiating them will return an instance of a different class.

https://docs.python.org/3/library/ast.html#node-classes

Emitted warnings:

ast.NameConstant is deprecated and will be removed in Python 3.14; use ast.Constant instead
ast.NameConstant is deprecated and will be removed in Python 3.14; use ast.Constant instead
ast.Str is deprecated and will be removed in Python 3.14; use ast.Constant instead
ast.Str is deprecated and will be removed in Python 3.14; use ast.Constant instead
ast.NameConstant is deprecated and will be removed in Python 3.14; use ast.Constant instead
ast.Str is deprecated and will be removed in Python 3.14; use ast.Constant instead
ast.Num is deprecated and will be removed in Python 3.14; use ast.Constant instead
ast.Num is deprecated and will be removed in Python 3.14; use ast.Constant instead
ast.Str is deprecated and will be removed in Python 3.14; use ast.Constant instead
ast.Str is deprecated and will be removed in Python 3.14; use ast.Constant instead
ast.Str is deprecated and will be removed in Python 3.14; use ast.Constant instead
ast.NameConstant is deprecated and will be removed in Python 3.14; use ast.Constant instead

Release of the package version 1.4.5

I can't install the package:
error in setup command: 'python_requires' must be a string containing valid version specifiers; Invalid specifier: '>=3.5.*'

I see that the fix has already been made, but a new version of the package has not yet been released. Please release a new version with a fix

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.