--- a/contrib/python-zstandard/tests/common.py Thu Feb 09 21:44:32 2017 -0500
+++ b/contrib/python-zstandard/tests/common.py Tue Feb 07 23:24:47 2017 -0800
@@ -1,4 +1,50 @@
+import inspect
import io
+import types
+
+
+def make_cffi(cls):
+ """Decorator to add CFFI versions of each test method."""
+
+ try:
+ import zstd_cffi
+ except ImportError:
+ return cls
+
+ # If CFFI version is available, dynamically construct test methods
+ # that use it.
+
+ for attr in dir(cls):
+ fn = getattr(cls, attr)
+ if not inspect.ismethod(fn) and not inspect.isfunction(fn):
+ continue
+
+ if not fn.__name__.startswith('test_'):
+ continue
+
+ name = '%s_cffi' % fn.__name__
+
+ # Replace the "zstd" symbol with the CFFI module instance. Then copy
+ # the function object and install it in a new attribute.
+ if isinstance(fn, types.FunctionType):
+ globs = dict(fn.__globals__)
+ globs['zstd'] = zstd_cffi
+ new_fn = types.FunctionType(fn.__code__, globs, name,
+ fn.__defaults__, fn.__closure__)
+ new_method = new_fn
+ else:
+ globs = dict(fn.__func__.func_globals)
+ globs['zstd'] = zstd_cffi
+ new_fn = types.FunctionType(fn.__func__.func_code, globs, name,
+ fn.__func__.func_defaults,
+ fn.__func__.func_closure)
+ new_method = types.UnboundMethodType(new_fn, fn.im_self,
+ fn.im_class)
+
+ setattr(cls, name, new_method)
+
+ return cls
+
class OpCountingBytesIO(io.BytesIO):
def __init__(self, *args, **kwargs):