diff options
author | da-woods <dw-git@d-woods.co.uk> | 2022-07-20 09:11:15 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-07-20 09:11:15 +0100 |
commit | 15819719f4ae804df92cf58bbb744ccd079e04e4 (patch) | |
tree | c2652f37966d679d851a391686cb1b530324f52a | |
parent | c01c6d508339587935ef4c101663dd2803c70e9e (diff) | |
download | cython-15819719f4ae804df92cf58bbb744ccd079e04e4.tar.gz |
Improve test coverage of special methods with type conversions (#4900)
https://github.com/cython/cython/issues/4163
```
if old_type.is_pyobject:
if arg.default: # 4325 ↛ 4326
code.putln("if (%s) {" % arg.hdr_cname)
else:
code.putln("assert(%s); {" % arg.hdr_cname)
self.generate_arg_conversion_from_pyobject(arg, code)
code.putln("}")
elif new_type.is_pyobject: # 4331 ↛ 4334
self.generate_arg_conversion_to_pyobject(arg, code)
else:
if new_type.assignable_from(old_type):
code.putln("%s = %s;" % (arg.entry.cname, arg.hdr_cname))
else:
error(arg.pos, "Cannot convert 1 argument from '%s' to '%s'" % (old_type, new_type))
```
It doesn't cover the arg.default case (since I don't think any
of these methods accept a default argument, or the failed conversion
case. But does cover the pyobject->C, C->pyobject and C->C cases
-rw-r--r-- | tests/run/special_methods_T561.pyx | 41 |
1 files changed, 41 insertions, 0 deletions
diff --git a/tests/run/special_methods_T561.pyx b/tests/run/special_methods_T561.pyx index 5eb9dddfc..79de744b3 100644 --- a/tests/run/special_methods_T561.pyx +++ b/tests/run/special_methods_T561.pyx @@ -956,3 +956,44 @@ cdef class ReverseMethodsExist: return "radd" def __rsub__(self, other): return "rsub" + + +cdef class ArgumentTypeConversions: + """ + The user can set the signature of special method arguments so that + it doesn't match the C signature. This just tests that a few work + (and fills in a hole in coverage of the Cython source) + + >>> obj = ArgumentTypeConversions() + >>> obj[1] + 1 + >>> obj["not a number!"] + Traceback (most recent call last): + ... + TypeError: an integer is required + >>> obj < obj + In comparison 0 + True + >>> obj == obj + In comparison 2 + False + + Here I'm not sure how reproducible the flags are between Python versions. + Therefore I'm just checking that they end with ".0" + >>> memoryview(obj) # doctest:+ELLIPSIS + Traceback (most recent call last): + ... + RuntimeError: From __getbuffer__ with flags ....0 + """ + # force conversion of object to int + def __getitem__(self, int x): + return x + + # force conversion of comparison (int) to object + def __richcmp__(self, other, object comparison): + print "In comparison", comparison + return not bool(comparison) + + # force conversion of flags (int) to double + def __getbuffer__(self, Py_buffer *buffer, double flags): + raise RuntimeError("From __getbuffer__ with flags {}".format(flags)) |