CConvert.pyx 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. #################### FromPyStructUtility ####################
  2. cdef extern from *:
  3. ctypedef struct PyTypeObject:
  4. char* tp_name
  5. PyTypeObject *Py_TYPE(obj)
  6. bint PyMapping_Check(obj)
  7. object PyErr_Format(exc, const char *format, ...)
  8. @cname("{{funcname}}")
  9. cdef {{struct_type}} {{funcname}}(obj) except *:
  10. cdef {{struct_type}} result
  11. if not PyMapping_Check(obj):
  12. PyErr_Format(TypeError, b"Expected %.16s, got %.200s", b"a mapping", Py_TYPE(obj).tp_name)
  13. {{for member in var_entries:}}
  14. try:
  15. value = obj['{{member.name}}']
  16. except KeyError:
  17. raise ValueError("No value specified for struct attribute '{{member.name}}'")
  18. result.{{member.cname}} = value
  19. {{endfor}}
  20. return result
  21. #################### FromPyUnionUtility ####################
  22. cdef extern from *:
  23. ctypedef struct PyTypeObject:
  24. char* tp_name
  25. PyTypeObject *Py_TYPE(obj)
  26. bint PyMapping_Check(obj)
  27. object PyErr_Format(exc, const char *format, ...)
  28. @cname("{{funcname}}")
  29. cdef {{struct_type}} {{funcname}}(obj) except *:
  30. cdef {{struct_type}} result
  31. cdef Py_ssize_t length
  32. if not PyMapping_Check(obj):
  33. PyErr_Format(TypeError, b"Expected %.16s, got %.200s", b"a mapping", Py_TYPE(obj).tp_name)
  34. last_found = None
  35. length = len(obj)
  36. if length:
  37. {{for member in var_entries:}}
  38. if '{{member.name}}' in obj:
  39. if last_found is not None:
  40. raise ValueError("More than one union attribute passed: '%s' and '%s'" % (last_found, '{{member.name}}'))
  41. last_found = '{{member.name}}'
  42. result.{{member.cname}} = obj['{{member.name}}']
  43. length -= 1
  44. if not length:
  45. return result
  46. {{endfor}}
  47. if last_found is None:
  48. raise ValueError("No value specified for any of the union attributes (%s)" %
  49. '{{", ".join(member.name for member in var_entries)}}')
  50. return result
  51. #################### cfunc.to_py ####################
  52. @cname("{{cname}}")
  53. cdef object {{cname}}({{return_type.ctype}} (*f)({{ ', '.join(arg.type_cname for arg in args) }}) {{except_clause}}):
  54. def wrap({{ ', '.join('{arg.ctype} {arg.name}'.format(arg=arg) for arg in args) }}):
  55. """wrap({{', '.join(('{arg.name}: {arg.type_displayname}'.format(arg=arg) if arg.type_displayname else arg.name) for arg in args)}}){{if return_type.type_displayname}} -> {{return_type.type_displayname}}{{endif}}"""
  56. {{'' if return_type.type.is_void else 'return '}}f({{ ', '.join(arg.name for arg in args) }})
  57. return wrap
  58. #################### carray.from_py ####################
  59. cdef extern from *:
  60. object PyErr_Format(exc, const char *format, ...)
  61. @cname("{{cname}}")
  62. cdef int {{cname}}(object o, {{base_type}} *v, Py_ssize_t length) except -1:
  63. cdef Py_ssize_t i = length
  64. try:
  65. i = len(o)
  66. except (TypeError, OverflowError):
  67. pass
  68. if i == length:
  69. for i, item in enumerate(o):
  70. if i >= length:
  71. break
  72. v[i] = item
  73. else:
  74. i += 1 # convert index to length
  75. if i == length:
  76. return 0
  77. PyErr_Format(
  78. IndexError,
  79. ("too many values found during array assignment, expected %zd"
  80. if i >= length else
  81. "not enough values found during array assignment, expected %zd, got %zd"),
  82. length, i)
  83. #################### carray.to_py ####################
  84. cdef extern from *:
  85. void Py_INCREF(object o)
  86. tuple PyTuple_New(Py_ssize_t size)
  87. list PyList_New(Py_ssize_t size)
  88. void PyTuple_SET_ITEM(object p, Py_ssize_t pos, object o)
  89. void PyList_SET_ITEM(object p, Py_ssize_t pos, object o)
  90. @cname("{{cname}}")
  91. cdef inline list {{cname}}({{base_type}} *v, Py_ssize_t length):
  92. cdef size_t i
  93. cdef object value
  94. l = PyList_New(length)
  95. for i in range(<size_t>length):
  96. value = v[i]
  97. Py_INCREF(value)
  98. PyList_SET_ITEM(l, i, value)
  99. return l
  100. @cname("{{to_tuple_cname}}")
  101. cdef inline tuple {{to_tuple_cname}}({{base_type}} *v, Py_ssize_t length):
  102. cdef size_t i
  103. cdef object value
  104. t = PyTuple_New(length)
  105. for i in range(<size_t>length):
  106. value = v[i]
  107. Py_INCREF(value)
  108. PyTuple_SET_ITEM(t, i, value)
  109. return t