Design-by-contract in Python3 with informative violation messages and inheritance

Overview

icontract

Continuous integration https://coveralls.io/repos/github/Parquery/icontract/badge.svg?branch=master PyPI - version

PyPI - Python Version

Documentation Gitter chat

icontract provides design-by-contract to Python3 with informative violation messages and inheritance.

It also gives a base for a flourishing of a wider ecosystem:

Related Projects

There exist a couple of contract libraries. However, at the time of this writing (September 2018), they all required the programmer either to learn a new syntax (PyContracts) or to write redundant condition descriptions ( e.g., contracts, covenant, deal, dpcontracts, pyadbc and pcd).

This library was strongly inspired by them, but we go two steps further.

First, our violation message on contract breach are much more informative. The message includes the source code of the contract condition as well as variable values at the time of the breach. This promotes don't-repeat-yourself principle (DRY) and spare the programmer the tedious task of repeating the message that was already written in code.

Second, icontract allows inheritance of the contracts and supports weakining of the preconditions as well as strengthening of the postconditions and invariants. Notably, weakining and strengthening of the contracts is a feature indispensable for modeling many non-trivial class hierarchies. Please see Section Inheritance. To the best of our knowledge, there is currently no other Python library that supports inheritance of the contracts in a correct way.

In the long run, we hope that design-by-contract will be adopted and integrated in the language. Consider this library a work-around till that happens. You might be also interested in the archived discussion on how to bring design-by-contract into Python language on python-ideas mailing list.

Teasers

We give a couple of teasers here to motivate the library. Please see the documentation available on icontract.readthedocs.io for a full scope of its capabilities.

The script is also available as a repl.it post.

None: ... pass ... >>> some_func(x=1) Traceback (most recent call last): ... icontract.errors.ViolationError: File , line 1 in : x must not be small: x > 3: x was 1 y was 5 # Pre-condition violation with more complex values >>> class B: ... def __init__(self) -> None: ... self.x = 7 ... ... def y(self) -> int: ... return 2 ... ... def __repr__(self) -> str: ... return "instance of B" ... >>> class A: ... def __init__(self) -> None: ... self.b = B() ... ... def __repr__(self) -> str: ... return "instance of A" ... >>> SOME_GLOBAL_VAR = 13 >>> @icontract.require(lambda a: a.b.x + a.b.y() > SOME_GLOBAL_VAR) ... def some_func(a: A) -> None: ... pass ... >>> an_a = A() >>> some_func(an_a) Traceback (most recent call last): ... icontract.errors.ViolationError: File , line 1 in : a.b.x + a.b.y() > SOME_GLOBAL_VAR: SOME_GLOBAL_VAR was 13 a was instance of A a.b was instance of B a.b.x was 7 a.b.y() was 2 # Post-condition >>> @icontract.ensure(lambda result, x: result > x) ... def some_func(x: int, y: int = 5) -> int: ... return x - y ... >>> some_func(x=10) Traceback (most recent call last): ... icontract.errors.ViolationError: File , line 1 in : result > x: result was 5 x was 10 y was 5 # Pre-conditions fail before post-conditions. >>> @icontract.ensure(lambda result, x: result > x) ... @icontract.require(lambda x: x > 3, "x must not be small") ... def some_func(x: int, y: int = 5) -> int: ... return x - y ... >>> some_func(x=3) Traceback (most recent call last): ... icontract.errors.ViolationError: File , line 2 in : x must not be small: x > 3: x was 3 y was 5 # Invariant >>> @icontract.invariant(lambda self: self.x > 0) ... class SomeClass: ... def __init__(self) -> None: ... self.x = -1 ... ... def __repr__(self) -> str: ... return "an instance of SomeClass" ... >>> some_instance = SomeClass() Traceback (most recent call last): ... icontract.errors.ViolationError: File , line 1 in : self.x > 0: self was an instance of SomeClass self.x was -1">
>>> import icontract

>>> @icontract.require(lambda x: x > 3)
... def some_func(x: int, y: int = 5) -> None:
...     pass
...

>>> some_func(x=5)

# Pre-condition violation
>>> some_func(x=1)
Traceback (most recent call last):
  ...
icontract.errors.ViolationError: File <doctest README.rst[1]>, line 1 in <module>:
x > 3:
x was 1
y was 5

# Pre-condition violation with a description
>>> @icontract.require(lambda x: x > 3, "x must not be small")
... def some_func(x: int, y: int = 5) -> None:
...     pass
...
>>> some_func(x=1)
Traceback (most recent call last):
  ...
icontract.errors.ViolationError: File <doctest README.rst[4]>, line 1 in <module>:
x must not be small: x > 3:
x was 1
y was 5

# Pre-condition violation with more complex values
>>> class B:
...     def __init__(self) -> None:
...         self.x = 7
...
...     def y(self) -> int:
...         return 2
...
...     def __repr__(self) -> str:
...         return "instance of B"
...
>>> class A:
...     def __init__(self) -> None:
...         self.b = B()
...
...     def __repr__(self) -> str:
...         return "instance of A"
...
>>> SOME_GLOBAL_VAR = 13
>>> @icontract.require(lambda a: a.b.x + a.b.y() > SOME_GLOBAL_VAR)
... def some_func(a: A) -> None:
...     pass
...
>>> an_a = A()
>>> some_func(an_a)
Traceback (most recent call last):
  ...
icontract.errors.ViolationError: File <doctest README.rst[9]>, line 1 in <module>:
a.b.x + a.b.y() > SOME_GLOBAL_VAR:
SOME_GLOBAL_VAR was 13
a was instance of A
a.b was instance of B
a.b.x was 7
a.b.y() was 2

# Post-condition
>>> @icontract.ensure(lambda result, x: result > x)
... def some_func(x: int, y: int = 5) -> int:
...     return x - y
...
>>> some_func(x=10)
Traceback (most recent call last):
  ...
icontract.errors.ViolationError: File <doctest README.rst[12]>, line 1 in <module>:
result > x:
result was 5
x was 10
y was 5


# Pre-conditions fail before post-conditions.
>>> @icontract.ensure(lambda result, x: result > x)
... @icontract.require(lambda x: x > 3, "x must not be small")
... def some_func(x: int, y: int = 5) -> int:
...    return x - y
...
>>> some_func(x=3)
Traceback (most recent call last):
  ...
icontract.errors.ViolationError: File <doctest README.rst[14]>, line 2 in <module>:
x must not be small: x > 3:
x was 3
y was 5

# Invariant
>>> @icontract.invariant(lambda self: self.x > 0)
... class SomeClass:
...     def __init__(self) -> None:
...         self.x = -1
...
...     def __repr__(self) -> str:
...         return "an instance of SomeClass"
...
>>> some_instance = SomeClass()
Traceback (most recent call last):
 ...
icontract.errors.ViolationError: File <doctest README.rst[16]>, line 1 in <module>:
self.x > 0:
self was an instance of SomeClass
self.x was -1

Installation

  • Install icontract with pip:
pip3 install icontract

Versioning

We follow Semantic Versioning. The version X.Y.Z indicates:

  • X is the major version (backward-incompatible),
  • Y is the minor version (backward-compatible), and
  • Z is the patch version (backward-compatible bug fix).
Comments
  • "Soft" contracts

    This is a proposal to introduce new functionality, "soft contracts".

    Problem

    Sometimes you want to track unwanted behaviour but instead of getting an exception, you want to log it.

    Say, your code is already in production and nothing fatal happens when this unwanted behaviour occurs. You want to track and eliminate it, but if you use the usual contracts, the users would suffer - the execution will stop at the contract point with an exception. Thus trying to catch a minor unwanted behaviour via introducing a contract would cause a bigger problem.

    So, you insert logging code into the body of your function. But now the code is less readable because of the "service code injections". The code would be cleaner if you used decorators similar to what icontract provides.

    Proposal

    Introduce a set of decorators named require_soft, ensure_soft, invariant_soft that would log an error (or a warning?) in case the condition is breached, but keep on running.

    This way the users are not harmed and the developer can track the bugs through inspecting the logs.

    opened by leshchenko1979 16
  • require decorator removes type annotations for mypy

    require decorator removes type annotations for mypy

    $ cat ic.py  
    from icontract import require
    
    @require(lambda x: x > 0)
    def f1(x: int): return x
    
    def f2(x: int): return 0
    
    f1("this is wrong")
    f2("this is too")
    
    $ mypy ic.py              
    ic.py:9: error: Argument 1 to "f2" has incompatible type "str"; expected "int"
    

    Both function calls are invalid types but mypy only sees the call as f2 as wrong. The decorator loses the type annotations?

    Related https://github.com/python/mypy/issues/3157

    opened by jamescasbon 12
  • AttributeError in contract caused by method call in constructor

    AttributeError in contract caused by method call in constructor

    When a method is called in the constructor, an AttributeError is raised in the contract. Here is a reproducer:

    from icontract import invariant
    
    
    @invariant(lambda self: all(" " not in part for part in self.parts))
    class ID:
        def __init__(self, identifier: str) -> None:
            self.parts = identifier.split(self.separator())
    
        def separator(self) -> str:
            return "."
    
    
    ID("A")
    
    $ python test.py  
    Traceback (most recent call last):
      File "test.py", line 14, in <module>
        ID("A")
      File "/home/tr/.local/lib/python3.8/site-packages/icontract/_checkers.py", line 461, in wrapper
        result = func(*args, **kwargs)
      File "test.py", line 7, in __init__
        self.parts = identifier.split(self.separator)
      File "/home/tr/.local/lib/python3.8/site-packages/icontract/_checkers.py", line 498, in wrapper
        _assert_invariant(contract=contract, instance=instance)
      File "/home/tr/.local/lib/python3.8/site-packages/icontract/_checkers.py", line 162, in _assert_invariant
        check = contract.condition(self=instance)
      File "test.py", line 4, in <lambda>
        @invariant(lambda self: all(" " not in part for part in self.parts))
    AttributeError: 'ID' object has no attribute 'parts'
    

    The contract works correctly when self.separator() is replaced by a string literal.

    Versions

    icontract 2.3.4 asttokens 2.0.4 Python 3.8.5

    opened by treiher 11
  • *args and **kwargs not supported

    *args and **kwargs not supported

    Given the following code snippet:

    from icontract import require
    
    
    def test_args():
        @require(lambda *args: args)
        def args(*args, **kwargs):
            pass
        args(0, x=0)
    
    
    def test_kwargs():
        @require(lambda **kwargs: kwargs)
        def args(*args, **kwargs):
            pass
        args(0, x=0)
    
    
    def test_both():
        @require(lambda *args, **kwargs: args and kwargs)
        def args(*args, **kwargs):
            pass
        args(0, x=0)
    

    I get errors saying that precondition arguments could not be set (from _checkers.py:114).

    Unless I've missed it, the README didn't explicitly state that * and ** aren't supported. My use case is a rather generic decorator applied to some endpoints. It shouldn't matter how these endpoints are called, but they must contain a request (for the decorator to do its magic), for which I want to create a contract.

    Some observations:

    • @require(lambda args: ...) without the asterisk only passes the first argument supplied to the function to the check (i.e. 0, not [0])
    • @require(lambda kwargs: ...) without the asterisks raises the same error

    I would gladly help with fixing/implementing this since I believe every language today should provide tools for DBC, and your library does a good job. Any thoughts on the feasibility of this? :)

    opened by ghost 11
  • Transpiler

    Transpiler

    (From python-ideas list in thread: "old" values in postconditions)

    What about a tool that converts contracts back and forth to readable form on IDE save/load with the following syntax:

    with contracts:
        with preconditions:
            assert arg1 < arg2
    
        with snapshot as S:
            S.var1 = some_func(arg1)
            with postconditions, \
                 resultie as result:
                     # result would be annotated with "# type:" 
                     # if return type is annotated.
                     assert arg1 < S.var1 < arg2, \
                         "Some contract description"
                      
                     # if not (...) followed by a raise statement 
                     # allows for custom exceptions
                     if not (arg1 > arg2):
                         "another contract description"
                         raise SomeException("some message", arg1)
                     
                     # if (..) followed by a list of asserts or if-not-raises 
                     # allows for toggling contracts
                     if some_enabled_flag:
                         assert arg1 + 10 < arg2
                         assert arg2 > 0
                         if not some_func(arg1, arg2):
                             raise AnotherException("some message", var1, arg1, arg2)
    

    For classes:

    class SomeClass:
        with invariants,
            selfie as self: # type: SomeClass
                 assert 0 < self.x < sqrt(self.x)
    

    icontract.dummies would provide these dummy context managers (all of them would raise exceptions on enter so that the code can not run by accident). The converter would add/remove these imports automatically.

    The advantage: no variable shadowing, valid python code, autocomplete works in Pycharm, even mypy could be made to work. with contracts makes it easier and less error prone to group preconditions and postconditions. The converter would check that there is no "with contracts" in the body of the function except in the first statement (and the same for class invariants).

    Descriptions in asserts and if-not-raise must be string literals (without format() etc.).

    wontfix 
    opened by mristin 11
  • Invariant on a class changes the type of the class

    Invariant on a class changes the type of the class

    from icontract import invariant
    
    class TestClass1():
        test_int: int = 1
    
    reveal_type(TestClass1)
    # Type[TestClass1]
    
    @invariant(lambda self: self.test_int == 1)
    class TestClass2():
        test_int: int = 1
    
    reveal_type(TestClass2)
    # type
    
    opened by ciresnave 10
  • convert readme example into a script that can be easily copy/pasted

    convert readme example into a script that can be easily copy/pasted

    this might just be my personal preference but i feel that it's easy to run and work with the example this way. direct copy and paste into a script would allow you to run the example and step through each piece without losing information. i also added an example showing that "Pre-conditions fail before Post-conditions". that wasn't immediately obvious to me. of course the big assumption is that people would know how to handle the python debugger. i'd guess that more people are familiar with the terminal session. so perhaps this won't be accepted. but with some simple instructions, literally just, type "c" and press enter, you'll walk through each example while being able to inspect either the result or the exception that was raised for each scenario. enjoying testing out the library, thanks :-)

    opened by wgwz 10
  • fixed performance regression due to state

    fixed performance regression due to state

    This commit makes a couple of fixes to improve the computational efficiency of the contracts. There was a performance regression when the state was introduced (notably, ExitStack caused a lot of overhead).

    This commit also introduces benchmarking into the continuous integration (as part of the precommit.py script) so that we can continously monitor the efficiency in the future.

    Fixes #142 .

    opened by mristin 10
  • Failed to recompute the values of the contract condition

    Failed to recompute the values of the contract condition

    I have the following code:

    @ensure(
        lambda result: len(result) > 30_000, "Too few lines"
    )
    @ensure(
        lambda result: all(
            result[col].notna().sum() / len(result) > 0.3 for col in FILTER_FEATURES
        ),
        "Filter features are not filled in properly",
    )
    def load_listings(regions=None) -> pd.DataFrame:
    ...
    

    If the first contract fails, I'm getting a RuntimeError instead of a ViolationError:

    Traceback (most recent call last):
      File "/layers/google.python.pip/pip/lib/python3.9/site-packages/flask/app.py", line 2070, in wsgi_app
        response = self.full_dispatch_request()
      File "/layers/google.python.pip/pip/lib/python3.9/site-packages/flask/app.py", line 1515, in full_dispatch_request
        rv = self.handle_user_exception(e)
      File "/layers/google.python.pip/pip/lib/python3.9/site-packages/flask/app.py", line 1513, in full_dispatch_request
        rv = self.dispatch_request()
      File "/layers/google.python.pip/pip/lib/python3.9/site-packages/flask/app.py", line 1499, in dispatch_request
        return self.ensure_sync(self.view_functions[rule.endpoint])(**req.view_args)
      File "/workspace/main.py", line 43, in main
        listings = load_listings()
      File "/layers/google.python.pip/pip/lib/python3.9/site-packages/icontract/_checkers.py", line 646, in wrapper
        violation_error = _assert_postconditions(
      File "/layers/google.python.pip/pip/lib/python3.9/site-packages/icontract/_checkers.py", line 396, in _assert_postconditions
        exception = _create_violation_error(contract=contract, resolved_kwargs=resolved_kwargs)
      File "/layers/google.python.pip/pip/lib/python3.9/site-packages/icontract/_checkers.py", line 192, in _create_violation_error
        raise RuntimeError(''.join(parts)) from err
    RuntimeError: Failed to recompute the values of the contract condition:
    File /workspace/main.py, line 65 in <module>:
    Too few lines: lambda result: len(result) > 30_000
    

    I also made the second one fail with pytest, and the test output was:

    ./test_minos.py::test_loading Failed: [undefined]RuntimeError: Failed to recompute the values of the contract condition:
    File c:\Users\leshc\flipio\minos\main.py, line 68 in <module>:
    Filter features are not filled in properly: lambda result: all(
            result[col].notna().sum() / len(result) > 0.3 for col in FILTER_FEATURES
        )
    contract = <icontract._types.Contract object at 0x000001C5B46DACA0>
    resolved_kwargs = {'_ARGS': (), '_KWARGS': {}, 'regions': None, 'result':        repair  house_material  windows_type  room_type
    0      ...         NaN           NaN        NaN
    39999     NaN             NaN           NaN        NaN
    
    [40000 rows x 4 columns]}
    
        def _create_violation_error(contract: Contract, resolved_kwargs: Mapping[str, Any]) -> BaseException:
            """Create the violation error based on the violated contract."""
            exception = None  # type: Optional[BaseException]
        
            if contract.error is None:
                try:
    >               msg = icontract._represent.generate_message(contract=contract, resolved_kwargs=resolved_kwargs)
    
    ..\..\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.9_qbz5n2kfra8p0\LocalCache\local-packages\Python39\site-packages\icontract\_checkers.py:181: 
    _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
    
    contract = <icontract._types.Contract object at 0x000001C5B46DACA0>
    resolved_kwargs = {'_ARGS': (), '_KWARGS': {}, 'regions': None, 'result':        repair  house_material  windows_type  room_type
    0      ...         NaN           NaN        NaN
    39999     NaN             NaN           NaN        NaN
    
    [40000 rows x 4 columns]}
    
        def generate_message(contract: Contract, resolved_kwargs: Mapping[str, Any]) -> str:
            """Generate the message upon contract violation."""
            parts = []  # type: List[str]
        
            if contract.location is not None:
                parts.append("{}:\n".format(contract.location))
        
            if contract.description is not None:
                parts.append("{}: ".format(contract.description))
        
            lambda_inspection = None  # type: Optional[ConditionLambdaInspection]
            if not is_lambda(a_function=contract.condition):
                condition_text = contract.condition.__name__
            else:
                # We need to extract the source code corresponding to the decorator since inspect.getsource() is broken with
                # lambdas.
                lambda_inspection = inspect_lambda_condition(condition=contract.condition)
                assert lambda_inspection is not None, \
                    "Unexpected no lambda inspection for condition: {}".format(contract.condition)
                condition_text = lambda_inspection.text
        
            parts.append(condition_text)
        
    >       repr_vals = repr_values(
                condition=contract.condition,
                lambda_inspection=lambda_inspection,
                resolved_kwargs=resolved_kwargs,
                a_repr=contract._a_repr)
    
    ..\..\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.9_qbz5n2kfra8p0\LocalCache\local-packages\Python39\site-packages\icontract\_represent.py:542: 
    _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
    
    condition = <function <lambda> at 0x000001C5B46E48B0>
    lambda_inspection = <icontract._represent.ConditionLambdaInspection object at 0x000001C5B484EF40>
    resolved_kwargs = {'_ARGS': (), '_KWARGS': {}, 'regions': None, 'result':        repair  house_material  windows_type  room_type
    0      ...         NaN           NaN        NaN
    39999     NaN             NaN           NaN        NaN
    
    [40000 rows x 4 columns]}
    a_repr = <reprlib.Repr object at 0x000001C5A34D9BB0>
    
        def repr_values(condition: Callable[..., bool], lambda_inspection: Optional[ConditionLambdaInspection],
                        resolved_kwargs: Mapping[str, Any], a_repr: reprlib.Repr) -> List[str]:
            """
            Represent function arguments and frame values in the error message on contract breach.
        
            :param condition: condition function of the contract
            :param lambda_inspection:
                inspected lambda AST node corresponding to the condition function (None if the condition was not given as a
                lambda function)
            :param resolved_kwargs: arguments put in the function call
            :param a_repr: representation instance that defines how the values are represented.
            :return: list of value representations
            """
            # Hide _ARGS and _KWARGS if they are not part of the condition for better readability
            if '_ARGS' in resolved_kwargs or '_KWARGS' in resolved_kwargs:
                parameters = inspect.signature(condition).parameters
                malleable_kwargs = cast(
                    MutableMapping[str, Any],
                    resolved_kwargs.copy()  # type: ignore
                )
        
                if '_ARGS' not in parameters:
                    malleable_kwargs.pop('_ARGS', None)
        
                if '_KWARGS' not in parameters:
                    malleable_kwargs.pop('_KWARGS', None)
        
                selected_kwargs = cast(Mapping[str, Any], malleable_kwargs)
            else:
                selected_kwargs = resolved_kwargs
        
            # Don't use ``resolved_kwargs`` from this point on.
            # ``selected_kwargs`` is meant to be used instead for better readability of error messages.
        
            if is_lambda(a_function=condition):
                assert lambda_inspection is not None, "Expected a lambda inspection when given a condition as a lambda function"
            else:
                assert lambda_inspection is None, "Expected no lambda inspection in a condition given as a non-lambda function"
        
            reprs = None  # type: Optional[MutableMapping[str, Any]]
        
            if lambda_inspection is not None:
                variable_lookup = collect_variable_lookup(condition=condition, resolved_kwargs=selected_kwargs)
        
                recompute_visitor = icontract._recompute.Visitor(variable_lookup=variable_lookup)
        
    >           recompute_visitor.visit(node=lambda_inspection.node.body)
    
    ..\..\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.9_qbz5n2kfra8p0\LocalCache\local-packages\Python39\site-packages\icontract\_represent.py:463: 
    _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
    
    self = <icontract._recompute.Visitor object at 0x000001C5B48575E0>
    node = <ast.Call object at 0x000001C5B486ABB0>
    
        def visit(self, node):
            """Visit a node."""
            method = 'visit_' + node.__class__.__name__
            visitor = getattr(self, method, self.generic_visit)
    >       return visitor(node)
    
    C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.9_3.9.2032.0_x64__qbz5n2kfra8p0\lib\ast.py:407: 
    _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
    
    self = <icontract._recompute.Visitor object at 0x000001C5B48575E0>
    node = <ast.Call object at 0x000001C5B486ABB0>
    
        def visit_Call(self, node: ast.Call) -> Any:
            """Visit the function and the arguments and finally make the function call with them."""
            func = self.visit(node=node.func)
        
            # Please see "NOTE ABOUT PLACEHOLDERS AND RE-COMPUTATION"
            if func == PLACEHOLDER:
                return PLACEHOLDER
        
            if not callable(func):
                raise ValueError("Unexpected call to a non-calllable during the re-computation: {}".format(func))
        
            if inspect.iscoroutinefunction(func):
                raise ValueError(
                    ("Unexpected coroutine function {} as a condition of a contract. "
                     "You must specify your own error if the condition of your contract is a coroutine function."
                     ).format(func))
        
            # Short-circuit tracing the all quantifier over a generator expression
            # yapf: disable
            if (
                    func == builtins.all  # pylint: disable=comparison-with-callable
                    and len(node.args) == 1
                    and isinstance(node.args[0], ast.GeneratorExp)
            ):
                # yapf: enable
    >           result = self._trace_all_with_generator(func=func, node=node)
    
    ..\..\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.9_qbz5n2kfra8p0\LocalCache\local-packages\Python39\site-packages\icontract\_recompute.py:567: 
    _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
    
    self = <icontract._recompute.Visitor object at 0x000001C5B48575E0>
    func = <built-in function all>, node = <ast.Call object at 0x000001C5B486ABB0>
    
        def _trace_all_with_generator(self, func: Callable[..., Any], node: ast.Call) -> Any:
            """Re-write the all call with for loops to trace the first offending item, if any."""
            assert func == builtins.all  # pylint: disable=comparison-with-callable
            assert len(node.args) == 1
            assert isinstance(node.args[0], ast.GeneratorExp)
        
            # Try the happy path first
        
            # Please see "NOTE ABOUT PLACEHOLDERS AND RE-COMPUTATION"
    >       recomputed_arg = self.visit(node=node.args[0])
    
    ..\..\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.9_qbz5n2kfra8p0\LocalCache\local-packages\Python39\site-packages\icontract\_recompute.py:733: 
    _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
    
    self = <icontract._recompute.Visitor object at 0x000001C5B48575E0>
    node = <ast.GeneratorExp object at 0x000001C5B486AAC0>
    
        def visit(self, node):
            """Visit a node."""
            method = 'visit_' + node.__class__.__name__
            visitor = getattr(self, method, self.generic_visit)
    >       return visitor(node)
    
    C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.9_3.9.2032.0_x64__qbz5n2kfra8p0\lib\ast.py:407: 
    _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
    
    self = <icontract._recompute.Visitor object at 0x000001C5B48575E0>
    node = <ast.GeneratorExp object at 0x000001C5B486AAC0>
    
        def visit_GeneratorExp(self, node: ast.GeneratorExp) -> Any:
            """Compile the generator expression as a function and call it."""
            # NOTE ABOUT PLACEHOLDERS AND RE-COMPUTATION:
            # Re-computing the comprehensions would be too slow. Therefore we re-compile the comprehension and call
            # the compiled code directly.
            #
            # However, we still want to report the values of the variables unrelated to the comprehension back
            # to the user. Therefore we introduce PLACEHOLDER's and propagate them through re-computation in all
            # the visit methods.
        
            # The following visits propagate the visitation to descendant nodes.
            # However, as we re-compute the comprehension *via* re-compilation & execution,
            # the results of the visits are all PLACEHOLDER's.
        
            # NOTE ABOUT NAME #x1F812 VALUE STACKING:
            # We need to make a copy of name #x1F812 value mapping since we need to add targets as placeholders
            # while we visit the comprehension. For example, as we compute comprehensions through re-compilation
            # and not through manual re-computation, we can not re-compute nested comprehensions.
            #
            # However, when our visit of comprehension is finished, the targets are not valid any more,
            # so we need to remove them from the mapping.
            #
            # Finally, we compute the comprehension with the original name #x1F812 value mapping by using
            # re-compilation. This final step is skipped if any of the names involved in the comprehension are
            # PLACEHOLDER's.
        
            old_name_to_value = copy.copy(self._name_to_value)
            for target_name in _collect_stored_names([generator.target for generator in node.generators]):
                self._name_to_value[target_name] = PLACEHOLDER
        
    >       self.visit(node.elt)
    
    ..\..\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.9_qbz5n2kfra8p0\LocalCache\local-packages\Python39\site-packages\icontract\_recompute.py:846: 
    _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
    
    self = <icontract._recompute.Visitor object at 0x000001C5B48575E0>
    node = <ast.Compare object at 0x000001C5B486AB20>
    
        def visit(self, node):
            """Visit a node."""
            method = 'visit_' + node.__class__.__name__
            visitor = getattr(self, method, self.generic_visit)
    >       return visitor(node)
    
    C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.9_3.9.2032.0_x64__qbz5n2kfra8p0\lib\ast.py:407: 
    _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
    
    self = <icontract._recompute.Visitor object at 0x000001C5B48575E0>
    node = <ast.Compare object at 0x000001C5B486AB20>
    
        def visit_Compare(self, node: ast.Compare) -> Any:
            """Recursively visit the comparators and apply the operations on them."""
    >       left = self.visit(node=node.left)
    
    ..\..\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.9_qbz5n2kfra8p0\LocalCache\local-packages\Python39\site-packages\icontract\_recompute.py:499: 
    _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
    
    self = <icontract._recompute.Visitor object at 0x000001C5B48575E0>
    node = <ast.BinOp object at 0x000001C5B486AA00>
    
        def visit(self, node):
            """Visit a node."""
            method = 'visit_' + node.__class__.__name__
            visitor = getattr(self, method, self.generic_visit)
    >       return visitor(node)
    
    C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.9_3.9.2032.0_x64__qbz5n2kfra8p0\lib\ast.py:407: 
    _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
    
    self = <icontract._recompute.Visitor object at 0x000001C5B48575E0>
    node = <ast.BinOp object at 0x000001C5B486AA00>
    
        def visit_BinOp(self, node: ast.BinOp) -> Any:
            """Recursively visit the left and right operand, respectively, and apply the operation on the results."""
            left = self.visit(node=node.left)
    >       right = self.visit(node=node.right)
    
    ..\..\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.9_qbz5n2kfra8p0\LocalCache\local-packages\Python39\site-packages\icontract\_recompute.py:441: 
    _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
    
    self = <icontract._recompute.Visitor object at 0x000001C5B48575E0>
    node = <ast.Call object at 0x000001C5B486A8B0>
    
        def visit(self, node):
            """Visit a node."""
            method = 'visit_' + node.__class__.__name__
            visitor = getattr(self, method, self.generic_visit)
    >       return visitor(node)
    
    C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.9_3.9.2032.0_x64__qbz5n2kfra8p0\lib\ast.py:407: 
    _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
    
    self = <icontract._recompute.Visitor object at 0x000001C5B48575E0>
    node = <ast.Call object at 0x000001C5B486A8B0>
    
        def visit_Call(self, node: ast.Call) -> Any:
            """Visit the function and the arguments and finally make the function call with them."""
            func = self.visit(node=node.func)
        
            # Please see "NOTE ABOUT PLACEHOLDERS AND RE-COMPUTATION"
            if func == PLACEHOLDER:
                return PLACEHOLDER
        
            if not callable(func):
                raise ValueError("Unexpected call to a non-calllable during the re-computation: {}".format(func))
        
            if inspect.iscoroutinefunction(func):
                raise ValueError(
                    ("Unexpected coroutine function {} as a condition of a contract. "
                     "You must specify your own error if the condition of your contract is a coroutine function."
                     ).format(func))
        
            # Short-circuit tracing the all quantifier over a generator expression
            # yapf: disable
            if (
                    func == builtins.all  # pylint: disable=comparison-with-callable
                    and len(node.args) == 1
                    and isinstance(node.args[0], ast.GeneratorExp)
            ):
                # yapf: enable
                result = self._trace_all_with_generator(func=func, node=node)
        
                if result is PLACEHOLDER:
                    return PLACEHOLDER
            else:
                args = []  # type: List[Any]
                for arg_node in node.args:
                    if isinstance(arg_node, ast.Starred):
                        args.extend(self.visit(node=arg_node))
                    else:
                        args.append(self.visit(node=arg_node))
        
                kwargs = dict()  # type: Dict[Union[str, Placeholder], Any]
                for keyword in node.keywords:
                    if keyword.arg is None:
                        kw = self.visit(node=keyword.value)
                        for key, val in kw.items():
                            kwargs[key] = val
        
                    else:
                        kwargs[keyword.arg] = self.visit(node=keyword.value)
        
                # Please see "NOTE ABOUT PLACEHOLDERS AND RE-COMPUTATION"
    >           if PLACEHOLDER in args or PLACEHOLDER in kwargs or PLACEHOLDER in kwargs.values():
    
    ..\..\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.9_qbz5n2kfra8p0\LocalCache\local-packages\Python39\site-packages\icontract\_recompute.py:590: 
    _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
    
    self =        repair  house_material  windows_type  room_type
    0       False           False         False      False
    1       ...        False         False      False
    39999   False           False         False      False
    
    [40000 rows x 4 columns]
    
        @final
        def __nonzero__(self):
    >       raise ValueError(
                f"The truth value of a {type(self).__name__} is ambiguous. "
                "Use a.empty, a.bool(), a.item(), a.any() or a.all()."
            )
    E       ValueError: The truth value of a DataFrame is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().
    
    ..\..\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.9_qbz5n2kfra8p0\LocalCache\local-packages\Python39\site-packages\pandas\core\generic.py:1537: ValueError
    
    The above exception was the direct cause of the following exception:
    
    monkeypatch = <_pytest.monkeypatch.MonkeyPatch object at 0x000001C5B46EC0D0>
    
        def test_loading(monkeypatch):
            def fake_load_psql(*args, **kwargs):
                return pd.DataFrame([{} for _ in range(40_000)], columns=FILTER_FEATURES)
        
            monkeypatch.setattr(main, "load_psql", fake_load_psql)
    >       load_listings()
    
    test_minos.py:22: 
    _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
    ..\..\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.9_qbz5n2kfra8p0\LocalCache\local-packages\Python39\site-packages\icontract\_checkers.py:646: in wrapper
        violation_error = _assert_postconditions(
    ..\..\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.9_qbz5n2kfra8p0\LocalCache\local-packages\Python39\site-packages\icontract\_checkers.py:396: in _assert_postconditions
        exception = _create_violation_error(contract=contract, resolved_kwargs=resolved_kwargs)
    _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
    
    contract = <icontract._types.Contract object at 0x000001C5B46DACA0>
    resolved_kwargs = {'_ARGS': (), '_KWARGS': {}, 'regions': None, 'result':        repair  house_material  windows_type  room_type
    0      ...         NaN           NaN        NaN
    39999     NaN             NaN           NaN        NaN
    
    [40000 rows x 4 columns]}
    
        def _create_violation_error(contract: Contract, resolved_kwargs: Mapping[str, Any]) -> BaseException:
            """Create the violation error based on the violated contract."""
            exception = None  # type: Optional[BaseException]
        
            if contract.error is None:
                try:
                    msg = icontract._represent.generate_message(contract=contract, resolved_kwargs=resolved_kwargs)
                except Exception as err:
                    parts = ["Failed to recompute the values of the contract condition:\n"]
                    if contract.location is not None:
                        parts.append("{}:\n".format(contract.location))
        
                    if contract.description is not None:
                        parts.append("{}: ".format(contract.description))
        
                    parts.append(icontract._represent.represent_condition(condition=contract.condition))
        
    >               raise RuntimeError(''.join(parts)) from err
    E               RuntimeError: Failed to recompute the values of the contract condition:
    E               File c:\Users\leshc\flipio\minos\main.py, line 68 in <module>:
    E               Filter features are not filled in properly: lambda result: all(
    E                       result[col].notna().sum() / len(result) > 0.3 for col in FILTER_FEATURES
    E                   )
    
    ..\..\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.9_qbz5n2kfra8p0\LocalCache\local-packages\Python39\site-packages\icontract\_checkers.py:192: RuntimeError
    
    opened by leshchenko1979 9
  • Runtime type validation?

    Runtime type validation?

    We are assessing a switch from typeguard to icontract for stricter runtime validation. However, I don't see anything akin to typeguard's @typechecked decorator. Correct me if I'm wrong, is the only way to do runtime type validation by making an @icontract.require(lambda arg: isinstance(arg, <type>) for all args?

    opened by crypdick 9
  • RecursionError due to contract checking during contract checking

    RecursionError due to contract checking during contract checking

    from typing import Any
    
    from icontract import DBC, ensure
    
    
    class Dimension(DBC):
        @ensure(lambda self, label, result: self.label(result) == label)
        def index(self, label: Any) -> int:
            return int(label)
    
        @ensure(lambda self, index, result: self.index(result) == index)
        def label(self, index: int) -> Any:
            return str(index)
    
    
    x = Dimension()
    print(x.label(0))
    

    This code results in a RecursionError, since while checking the postcondition for label the method index is invoked which triggers the check for the postcondition of index.

    It would be great if it were possible to suspend the checking of any other contracts while checking one contract, either by default or as a option when specifying the contract.

    opened by markusschmaus 9
  • License perms

    License perms

    When installing via pip. The license is placed in /usr/local

    ERROR: Could not install packages due to an OSError: [Errno 13] Permission denied: '/usr/local/LICENSE.txt'
    Consider using the `--user` option or check the permissions.
    

    Maybe consider rename for global installation too LICENSE.icontract.txt (or subdirectory). Just a suggestion, keep up the good work!

    opened by ronaldpetty 6
  • Question/Feature request: Iterable usage in `require` and `snapshot` decorators

    Question/Feature request: Iterable usage in `require` and `snapshot` decorators

    Question

    How do I use Iterable in a @snapshot or in a @require decorator? I didn't find any hints in the documentation so I assume I either used them wrong or didn't understand a core concept. Otherwise, I would like to propose a feature request 😀

    Examples for @ensure

    If I try to take a snapshot of an Iterable, it is not possible since snapshot consumes it. Using the file iter_in_ensure.py

    # ––– file iter_in_ensure.py
    from collections.abc import Iterable
    from icontract import ensure, snapshot
    from more_itertools import always_iterable
    
    
    @snapshot(lambda i: list(i))
    @ensure(lambda result, OLD: set(OLD.i) == set(result))
    def ensure_iter(i: Iterable[int]) -> list[int]:
        return list(i)
    
    
    assert 1 == len(ensure_iter(always_iterable(1)))
    

    in a python environment where icontract and more_itertools is included, the error message is:

    $ python iter_in_ensure.py
    Traceback (most recent call last):
      File "iter_in_ensure.py", line 13, in <module>
        assert 1 == len(ensure_iter(always_iterable(1)))
      File "/…/icontract/_checkers.py", line 649, in wrapper
        raise violation_error
    icontract.errors.ViolationError: File iter_in_ensure.py, line 8 in <module>:
    set(OLD.i) == set(result):
    OLD was a bunch of OLD values
    OLD.i was [1]
    i was <tuple_iterator object at 0x7fe0fe9afb20>
    result was []
    set(OLD.i) was {1}
    set(result) was set()
    

    showing that the @snapshot decorator already consumed the iterator, leaving an empty result back. A possible workaround is to use itertools.tee inside the function:

    # ––– file fixup_ensure.py
    from collections.abc import Iterable
    from icontract import ensure
    from itertools import tee
    from more_itertools import always_iterable
    
    
    @ensure(lambda result: set(result[0]) == set(result[1]))
    def ensure_iter(i: Iterable[int]) -> tuple[list[int], Iterable[int]]:
        tee0, tee1 = tee(i, 2)
        return list(tee0), tee1
    
    
    assert 1 == len(ensure_iter(always_iterable(1))[0])
    

    but that requires to change the functions's signature for usage in @ensure only which – at least in my opinion – contradicts icontract's philosophy.

    Examples for @require

    With the @require decorator, I even didn't find a workaround:

    # ––– file iter_in_require.py
    from collections.abc import Iterable
    from icontract import require
    from more_itertools import always_iterable
    
    
    @require(lambda i: 1 == len(list(i)))
    def require_iter(i: Iterable[int]) -> list[int]:
        return list(i)
    
    
    length = len(require_iter(always_iterable(1)))
    assert 1 == length, f"result length was {length}"
    

    results in

    $ python iter_in_require.py
    Traceback (most recent call last):
      File "iter_in_require.py", line 13, in <module>
        assert 1 == length, f"result length was {length}"
    AssertionError: result length was 0
    

    showing that @require already consumed the iterator and the function require_iter has no chance to access it again.

    Versions

    • Python: Python 3.10.4
    • more-itertools: 8.13.0
    • icontract: 2.6.1

    Feature pitch

    If I didn't miss anything, there are features missing for the @snapshot and the @require function decorators. I suggest to introduce additional arguments to disable iterator consumption.

    A possible example usage for @snapshot:

    from collections.abc import Iterable
    from icontract import ensure, snapshot
    from more_itertools import always_iterable
    
    
    @snapshot(lambda i: list(i), iter='i')  # <- new argument 'iter'
    @ensure(lambda result, OLD: set(OLD.i) == set(result))
    def ensure_iter(i: Iterable[int]) -> list[int]:
        return list(i)
    
    
    assert 1 == len(ensure_iter(always_iterable(1)))
    

    A possible example usage for @require:

    from collections.abc import Iterable
    from icontract import require
    from more_itertools import always_iterable
    
    
    @require(lambda i: 1 == len(list(i)), iter='i')  # <- new argument 'iter'
    def require_iter(i: Iterable[int]) -> list[int]:
        return list(i)
    
    
    length = len(require_iter(always_iterable(1)))
    assert 1 == length, f"result length was {length}"
    

    The new argument iter indicates to use an independent iterator. In @require's case, it forwards it to the decorated function.

    I'm aware that the proposed solution is not applicable to all iterables, but I'm still convinced it would pose an improvement.

    opened by claudio-ebel 4
  • icontract fails to restore class invariants at method exit

    icontract fails to restore class invariants at method exit

    icontract fails to restore class invariants at method exit:

    import icontract
    
    @icontract.invariant(lambda self: self.x > 0)
    class A:
        def __init__(self):
            self.x = 1
        def f(self):
            self.x = -1
            raise ValueError
    
    a = A()
    assert a.x > 0  # ok
    try:
        a.f()
    except ValueError:
        pass
    assert a.x > 0  # AssertionError
    

    This is contrary to what Bertrand Meyer prescribes in his 1992 seminal article Applying “Design by Contract”:

    Any exception handling, whether for resumption or for organized panic, should restore the invariant.

    Class invariants are the minimal guarantees in case of failure.

    opened by maggyero 3
  • Mypy fails to determine function's type in icontract.ensure()

    Mypy fails to determine function's type in icontract.ensure()

    Bug Report When a type-annotated function is (re-)used in its own postcondition icontract.ensure decorator, mypy is not able to determine its type. Since mypy does successfully infers the types of an annotated function before the function's actual definition, this bug is part of the icontract library and not mypy.

    To Reproduce

    1. Create a file “bug.py” with this content:
      # ––– file: bug.py –––
      from icontract import ensure
      
      
      @ensure(lambda a, b, result: result == myadd(b, a), "Commutativity violated!")
      def myadd(a: int, b: int) -> int:
          return a + b
      
    2. Use mypy on it
      $ mypy --config-file= bug.py 
      bug.py:5: error: Cannot determine type of "myadd"
      Found 1 error in 1 file (checked 1 source file)
      

    Expected Behavior In general, mypy does not have a problem with using an annotated function before its definition. To see this,

    1. Create a file “no_bug.py” with this content:
      # ––– file: no_bug.py –––
      
      
      def use_before() -> int:
          return myadd(1, 2)  # used before def; like in bug.py
      
      
      def myadd(a: int, b: int) -> int:
          return a + b
      
    2. Use mypy on it
      $ mypy --config-file= no_bug.py 
      Success: no issues found in 1 source file
      

    Failed solution attempts Using a forward declaration of myadd did not help:

    1. Create a file “forward_decl.py” with this content:
      # ––– file forward_decl.py ––
      from icontract import ensure
      from typing import Callable, cast
      
      MyaddType = Callable[[int, int], int]
      
      
      @ensure(lambda a, b, result: result == cast(MyaddType, myadd)(b, a),
              "Commutativity violated!")
      def myadd(a: int, b: int) -> int:
          return a + b
      
    2. Use mypy on it
      $ mypy --config-file= forward_decl.py
      forward_decl.py:8: error: Cannot determine type of "myadd"
      Found 1 error in 1 file (checked 1 source file)
      

    An alternative use of a cast of myadd's return type did not help either:

    1. Create a file “return_type.py” with this content:
      # ––– file: return_type.py –––
      from icontract import ensure
      from typing import cast
      
      
      @ensure(lambda a, b, result: result == cast(bool, myadd(b, a)),
              "Commutativity violated!")
      def myadd(a: int, b: int) -> int:
          return a + b
      
    2. Use mypy on it
      $ mypy --config-file= return_type.py
      return_type.py:6: error: Cannot determine type of "myadd"
      Found 1 error in 1 file (checked 1 source file)
      

    Your Environment

    • Mypy version used: mypy 0.950 (compiled: yes)
    • Mypy command-line flags: --config-file=
    • icontract version used: icontract==2.6.1
    • Python version used: Python 3.10.4
    opened by claudio-ebel 6
Releases(v2.6.2)
Controller state monitor plugin for EVA ICS

eva-plugin-cmon Controller status monitor plugin for EVA ICS Monitors connected controllers status in SFA and pushes measurements into an external Inf

Altertech 1 Nov 06, 2021
Todos os exercícios do Curso de Python, do canal Curso em Vídeo, resolvidos em Python, Javascript, Java, C++, C# e mais...

Exercícios - CeV Oferecido por Linguagens utilizadas atualmente O que vai encontrar aqui? 👀 Esse repositório é dedicado a armazenar todos os enunciad

Coding in Community 43 Nov 10, 2022
a sketch of what a zkvm could look like

We want to build a ZKP that validates an entire EVM block or as much of it as we can efficiently. Its okay to adjust the gas costs for every EVM opcode. Its also to exclude some opcodes for now if th

25 Dec 30, 2022
A maubot plugin to invite users to Matrix rooms according to LDAP groups

LDAP Inviter Bot This is a maubot plugin that invites users to Matrix rooms according to their membership in LDAP groups.

David Mehren 14 Dec 09, 2022
To lazy to read your homework ? Get it done with LOL

LOL To lazy to read your homework ? Get it done with LOL Needs python 3.x L:::::::::L OO:::::::::OO L:::::::::L L:::::::

KorryKatti 4 Dec 08, 2022
An example project which contains the Unity components necessary to complete Navigation2's SLAM tutorial with a Turtlebot3, using a custom Unity environment in place of Gazebo.

Navigation 2 SLAM Example This example provides a Unity Project and a colcon workspace that, when used together, allows a user to substitute Unity as

Unity Technologies 183 Jan 04, 2023
A browser login credentials thief for windows and Linux

Thief 🦹🏻 A browser login credentials thief for windows and Linux Python script to decrypt login credentials from browsers in windows or linux Decryp

Ash 1 Dec 13, 2021
A responsive package for Buttons, DropMenus and Combinations

A responsive package for Buttons, DropMenus and Combinations, This module makes the process a lot easier !

Skr Phoenix YT 0 Jan 30, 2022
It really seems like Trump is trying to get his own social media started. Not a huge fan tbh.

FuckTruthSocial It really seems like Trump is trying to get his own social media started. Not a huge fan tbh. (When TruthSocial actually releases, I'l

0 Jul 18, 2022
Research using python - Guide for development of research code (using Anaconda Python)

Guide for development of research code (using Anaconda Python) TL;DR: One time s

Ziv Yaniv 1 Feb 01, 2022
An open-source Python project series where beginners can contribute and practice coding.

Python Mini Projects A collection of easy Python small projects to help you improve your programming skills. Table Of Contents Aim Of The Project Cont

Leah Nguyen 491 Jan 04, 2023
A package with multiple bias correction methods for climatic variables, including the QM, DQM, QDM, UQM, and SDM methods

A package with multiple bias correction methods for climatic variables, including the QM, DQM, QDM, UQM, and SDM methods

Sebastián A. Aedo Quililongo 9 Nov 18, 2022
Stori QA Automation Challenge

Stori-QA-Automation-Challenge This is the repository is created for the Stori QA Intern Automation Engineer Challenge! In this you can find the Requir

Daniel Castañeda 0 Feb 20, 2022
Transform a Google Drive server into a VFX pipeline ready server

Google Drive VFX Server VFX Pipeline About The Project Quick tutorial to setup a Google Drive Server for multiple machines access, and VFX Pipeline on

Valentin Beaumont 17 Jun 27, 2022
This repository contains Python games that I've worked on. You'll learn how to create python games with AI. I try to focus on creating board games without GUI in Jupyter-notebook.

92_Python_Games 🎮 Introduction 👋 This repository contains Python games that I've worked on. You'll learn how to create python games with AI. I try t

Milaan Parmar / Милан пармар / _米兰 帕尔马 166 Jan 01, 2023
A simply program to find active jackbox.tv game codes

PeepingJack A simply program to find active jackbox.tv game codes How does this work? It uses a threadpool to loop through all possible codes in a ran

3 Mar 20, 2022
Use a real time weather API to apply wind to your mouse cursor.

wind-cursor Use a real time weather API to apply wind to your mouse cursor. Requirements PyAutoGUI pyowm Usage This program uses the OpenWeatherMap AP

Andreas Schmid 1 Feb 07, 2022
Spooky Castle Project

Spooky Castle Project Here is a repository where I have placed a few workflow scripts that could be used to automate the blender to godot sprite pipel

3 Jan 17, 2022
用于导出墨墨背单词的词库,并生成适用于 List 背单词,不背单词,欧陆词典等的自定义词库

maimemo-export 用于导出墨墨背单词的词库,并生成适用于 List 背单词,欧陆词典,不背单词等的自定义词库。 仓库内已经导出墨墨背单词所有自带词库(暂不包括云词库),多达 900 种词库,可以在仓库中选择需要的词库下载(下载单个文件的方法),也可以去 蓝奏云(密码:666) 下载打包好

ourongxing 293 Dec 29, 2022
A python based app to improve your presentation workflow

Presentation Remote A remote made for making presentations easier by enabling all the members to have access to change the slide and control the flow

Parnav 1 Oct 28, 2021