<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class=""><br class=""><div><br class=""><blockquote type="cite" class=""><div class="">On 5 Aug 2018, at 18:14, Nick Coghlan <<a href="mailto:ncoghlan@gmail.com" class="">ncoghlan@gmail.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div class="">On 5 August 2018 at 18:06, Ronald Oussoren <<a href="mailto:ronaldoussoren@mac.com" class="">ronaldoussoren@mac.com</a>> wrote:<br class=""><blockquote type="cite" class="">I’m not sure if I understand this, ctypes and cffi are used to access C APIs<br class="">without writing C code including the CPython API (see for example<br class=""><<a href="https://github.com/abarnert/superhackyinternals/blob/master/internals.py" class="">https://github.com/abarnert/superhackyinternals/blob/master/internals.py</a>>).<br class=""><br class="">The code code below should be mostly equivalent to the Cython example posted<br class="">earlier:<br class=""><br class="">import unittest<br class="">import ctypes<br class="">from ctypes import pythonapi<br class=""><br class="">class PyObject(ctypes.Structure):<br class="">    _fields_ = (<br class="">        ('ob_refcnt', ctypes.c_ssize_t),<br class="">    )<br class=""><br class="">pythonapi.PyList_Append.argtypes = [ctypes.py_object, ctypes.py_object]<br class=""><br class="">def refcount(v):<br class="">    return PyObject.from_address(id(v)).ob_refcnt<br class=""></blockquote><br class="">The quoted code is what I was referring to in:<br class="">====<br class="">ctypes & cffi likely wouldn't help as much in the case, since they<br class="">don't eliminate the need to come up with custom code for parts 3 & 4,<br class="">they just let you write that logic in Python rather than C.<br class="">====</div></div></blockquote><div><br class=""></div>And earlier Nick wrote:</div><div></div><blockquote type="cite" class=""><div><span style="font-family: Menlo-Regular; font-size: 11px;" class="">1. The test case itself (what action to take, which assertions to make about it)</span><br style="font-family: Menlo-Regular; font-size: 11px;" class=""><span style="font-family: Menlo-Regular; font-size: 11px;" class="">2. The C code to make the API call you want to test</span><br style="font-family: Menlo-Regular; font-size: 11px;" class=""><span style="font-family: Menlo-Regular; font-size: 11px;" class="">3. The Python->C interface for the test case from 1 to pass test</span><br style="font-family: Menlo-Regular; font-size: 11px;" class=""><span style="font-family: Menlo-Regular; font-size: 11px;" class="">values in to the code from 2</span><br style="font-family: Menlo-Regular; font-size: 11px;" class=""><span style="font-family: Menlo-Regular; font-size: 11px;" class="">4. The C->Python interface to get state of interest from 2 back to the</span><br style="font-family: Menlo-Regular; font-size: 11px;" class=""><span style="font-family: Menlo-Regular; font-size: 11px;" class="">test case from 1</span></div></blockquote><div class=""><br class=""></div>For all of Cython, ctypes and cffi you almost never have to write (2), and hence (3) and (4), but can write that code in Python. This is at the code of making it harder to know which bits of the CPython API are used in step (2), which makes it harder to review a testcase. <div class=""><br class=""></div><div class="">BTW. In other projects I use tests there almost all of the test code is in C, the unittest runner only calls a C function and uses the result of that function to deduce if the test passed or failed. This only works nicely for fairly simple tests (such as the example test in this thread), not for more complicated and interesting tests due to having to write more C code.</div><div class=""><br class=""></div><div class="">Ronald</div><div class=""><br class=""></div></body></html>