GitXplorerGitXplorer
b

dissert

public
4 stars
0 forks
0 issues

Commits

List of commits on branch main.
Unverified
b11726384caa4d82062659a2cf7f14fb34bc54b1

added MANIFEST.in; renamed readme.md to README.md

bboothby committed 5 years ago
Unverified
01f07c9a02f6cc22a799f6520f162a9fba77fd2a

massaged tests up to 100% coverage; remediated dissert_selector

bboothby committed 5 years ago
Unverified
d9f60340cc809a843d02a41ec676e9ed14fae5db

added tests of bypass asserts and select_dissert

bboothby committed 5 years ago
Unverified
b9a5bf8c6f068f777c418b6d34d881ebaa6e498d

added unparse requirement

bboothby committed 5 years ago
Unverified
c33fcd9fcdeb4d60378b13e2edca50b173c7376b

added unit tests and fixed several bugs

bboothby committed 5 years ago
Unverified
a2b911b71487c64ee0b7ca47d359af8b15fe112a

added setup.py

bboothby committed 5 years ago

README

The README file for this repository.

Dissert

Dissert is a granular assertion disabler. Lets you write all the inline assertions you want for development and testing, but puts the fast version into the hands of your users. All the code lives in a happy little file with an MIT license and everything, so feel free to grab it and put it wherever.

There was a long-lost feature of Python, where you could disable asserts in a file. It was cool, if before my time. I use like using asserts as in-line unit tests in C++, and ship with them disabled. A coworker asked how to do the same in Python. I'd recently seen some fun projects abusing source code encodings to fill weird niches, and this project was born that very night.

We want to litter our code with assertions, and write "always-on" unit tests. But then your code is sluggish! Many say to use python -O, but your user might want asserts for something they're using your module for! Well good news, we can eat cake and also have cake. As long as we're all good at cleaning up our rooms (or __pycache__ or whatever).

Absolute file-level dissertion

To disable all asserts in a file, simply set its source encoding to dissert.

> source = b"""# encoding: dissert
assert False
print("okay")"""
> exec(source)
okay

Selectable file-level dissertion

We also provide a toggle mechanism for somewhat granular control.

File "fail.py":

# encoding: dissert-select
def foo(x):
    print("oh no, I got called")
    assert x is not x

if foo is not None:
    assert foo() is not None

print("okay")

Include it without asserts (delete your __pycache__!):

> from dissert import dissert_selector
> with dissert_selector(True):
>     import fail.py
okay

Include it with asserts (delete your __pycache__!):

> from dissert import dissert_selector
> with dissert_selector(False):
>     import fail.py
oh no, I got called
AssertionError: ...

Selectable module-level dissertion

Dissert your module for release builds by renaming your __init__.py to _init_.py and replacing it with a shim. Of course, it will only remove asserts from dissert and dissert-select-encoded files, but that's more of a feature than a drawback.

from dissert import dissert
from mymodule.__package_info__ import __release__
with dissert_selector(__release__):
    from mymodule._init_ import *

Note that this uses a global variable under the hood, so you might want to clear the __pycache__ of dependent projects which also use dissert. It can be a bit of a rabbit-hole if you want very granular selectivity, as you'll have to be extremely careful about import order.

Bypass Assert and ASSERT

The module also defines an Assert function that works even in affected files (but also goes away with -O). Additionally, we provide an ASSERT function that emulates assertions with if...raise and doesn't go away under -O. In a future version, these may be accomplished through mangling the AST rather than imports. Make a PR or open a discussion ticket if you think this is a good/bad idea.

> source = b'''
> # encoding: dissert
> from dissert import Assert
> assert(False, "wrong failure!")
> Assert(False, "successfully failed!")
> raise RuntimeError("bad success")
> '''
> exec(source)
...
AssertionError: successfully failed!