def test_union(self): self.assertEqual( mod.describe_type(objc._C_UNION_B + b"=" + objc._C_ID + objc._C_UNION_E), "union <?>", ) self.assertEqual( mod.describe_type(objc._C_UNION_B + objc._C_UNION_E), "union <?>" ) self.assertEqual( mod.describe_type( objc._C_UNION_B + b"name=" + objc._C_ID + objc._C_INT + objc._C_UNION_E ), "union name", ) self.assertEqual( mod.describe_type( objc._C_UNION_B + b'name="field"' + objc._C_ID + b'"field2"' + objc._C_INT + objc._C_UNION_E ), "union name", )
def test_struct(self): self.assertEqual( mod.describe_type(objc._C_STRUCT_B + b"=" + objc._C_ID + objc._C_STRUCT_E), "struct <?>", ) self.assertEqual( mod.describe_type(objc._C_STRUCT_B + objc._C_STRUCT_E), "struct <?>" ) self.assertEqual( mod.describe_type( objc._C_STRUCT_B + b"name=" + objc._C_ID + objc._C_INT + objc._C_STRUCT_E ), "struct name", ) self.assertEqual( mod.describe_type( objc._C_STRUCT_B + b'name="field"' + objc._C_ID + b'"field2"' + objc._C_INT + objc._C_STRUCT_E ), "struct name", ) _ = objc.createStructType( "NamedTestStruct", b'{NamedTestStruct1="a"i"b"i}', None ) self.assertEqual(mod.describe_type(b"{NamedTestStruct1=ii}"), "NamedTestStruct")
def test_inout(self): self.assertEqual(mod.describe_type(objc._C_IN + objc._C_PTR + objc._C_INT), "in int*") self.assertEqual(mod.describe_type(objc._C_OUT + objc._C_PTR + objc._C_INT), "out int*") self.assertEqual(mod.describe_type(objc._C_INOUT + objc._C_PTR + objc._C_INT), "inout int*") # Nonsense, but should give a sane result anway: self.assertEqual(mod.describe_type(objc._C_OUT + objc._C_IN + objc._C_PTR + objc._C_INT), "out in int*")
def test_array(self): self.assertEqual( mod.describe_type(objc._C_ARY_B + b"42" + objc._C_INT), "int[42]") self.assertEqual( mod.describe_type(objc._C_ARY_B + b"42" + objc._C_PTR + objc._C_INT), "int*[42]", )
def test_struct(self): self.assertEqual(mod.describe_type(objc._C_STRUCT_B + b"=" + objc._C_ID + objc._C_STRUCT_E), "struct <?>") self.assertEqual(mod.describe_type(objc._C_STRUCT_B + objc._C_STRUCT_E), "struct <?>") self.assertEqual(mod.describe_type(objc._C_STRUCT_B + b"name=" + objc._C_ID + objc._C_INT + objc._C_STRUCT_E), "struct name") self.assertEqual(mod.describe_type(objc._C_STRUCT_B + b"name=\"field\"" + objc._C_ID + b'"field2"' + objc._C_INT + objc._C_STRUCT_E), "struct name") strType = objc.createStructType("NamedTestStruct", b'{NamedTestStruct1="a"i"b"i}', None) self.assertEqual(mod.describe_type(b'{NamedTestStruct1=ii}'), "NamedTestStruct")
def test_pointers(self): self.assertEqual(mod.describe_type(objc._C_CHARPTR), "char*") self.assertEqual(mod.describe_type(objc._C_PTR + objc._C_CHR), "char*") self.assertEqual(mod.describe_type(objc._C_PTR + objc._C_PTR + objc._C_FLT), "float**") self.assertEqual(mod.describe_type(objc._C_PTR + objc._C_STRUCT_B + b'hello=' + objc._C_INT + objc._C_STRUCT_E), "struct hello*") handle = objc.createOpaquePointerType("NamedPointer", b"^{NamedTestPointer1=}") self.assertEqual(mod.describe_type(b"^{NamedTestPointer1=}"), "NamedPointer")
def test_callable(self): self.assertEqual(mod.describe_type(objc._C_ID + b"?"), "<BLOCK>") self.assertEqual(mod.describe_type(objc._C_PTR + b"?"), "<FUNCTION>")
def test_unknown(self): self.assertEqual(mod.describe_type(b"?"), "<?>") self.assertEqual(mod.describe_type(b"X"), "<?>")
def test_basic_types(self): self.assertEqual(mod.describe_type(objc._C_VOID), "void") self.assertEqual(mod.describe_type(objc._C_INT), "int") self.assertEqual(mod.describe_type(objc._C_UINT), "unsigned int") self.assertEqual(mod.describe_type(objc._C_CHR), "char") self.assertEqual(mod.describe_type(objc._C_UCHR), "unsigned char") self.assertEqual(mod.describe_type(objc._C_SHT), "short") self.assertEqual(mod.describe_type(objc._C_USHT), "unsigned short") self.assertEqual(mod.describe_type(objc._C_LNG), "long") self.assertEqual(mod.describe_type(objc._C_ULNG), "unsigned long") self.assertEqual(mod.describe_type(objc._C_LNG_LNG), "long long") self.assertEqual(mod.describe_type(objc._C_ULNG_LNG), "unsigned long long") self.assertEqual(mod.describe_type(objc._C_FLT), "float") self.assertEqual(mod.describe_type(objc._C_DBL), "double") self.assertEqual(mod.describe_type(objc._C_ID), "id") self.assertEqual(mod.describe_type(objc._C_CLASS), "Class") self.assertEqual(mod.describe_type(objc._C_SEL), "SEL") self.assertEqual(mod.describe_type(objc._C_CHARPTR), "char*") self.assertEqual(mod.describe_type(objc._C_BOOL), "bool") # PyObjC specials: self.assertEqual(mod.describe_type(objc._C_CHAR_AS_INT), "int8_t") self.assertEqual(mod.describe_type(objc._C_CHAR_AS_TEXT), "char") self.assertEqual(mod.describe_type(objc._C_UNICHAR), "UniChar") self.assertEqual(mod.describe_type(objc._C_NSBOOL), "BOOL")
def test_union(self): self.assertEqual(mod.describe_type(objc._C_UNION_B + b"=" + objc._C_ID + objc._C_UNION_E), "union <?>") self.assertEqual(mod.describe_type(objc._C_UNION_B + objc._C_UNION_E), "union <?>") self.assertEqual(mod.describe_type(objc._C_UNION_B + b"name=" + objc._C_ID + objc._C_INT + objc._C_UNION_E), "union name") self.assertEqual(mod.describe_type(objc._C_UNION_B + b"name=\"field\"" + objc._C_ID + b'"field2"' + objc._C_INT + objc._C_UNION_E), "union name")
def test_array(self): self.assertEqual(mod.describe_type(objc._C_ARY_B + b"42" + objc._C_INT), "int[42]") self.assertEqual(mod.describe_type(objc._C_ARY_B + b"42" + objc._C_PTR + objc._C_INT), "int*[42]")
def test_callable(self): self.assertEqual(mod.describe_type(objc._C_ID + b'?'), "<BLOCK>") self.assertEqual(mod.describe_type(objc._C_PTR + b'?'), "<FUNCTION>")
def test_unknown(self): self.assertEqual(mod.describe_type(b'?'), '<?>') self.assertEqual(mod.describe_type(b'X'), '<?>')
def document_callable( fp: IO[str], name: str, metadata: Union[FunctionInfo, MethodInfo], *, ismethod: bool, indent: str, native_name: Optional[str] = None, ) -> None: """ Generate documentation for a callable (function or method). """ # # This should be kept in sync with objc._callable_docstr, which # does something similar with more limited information. # # Note that the collected metadata does not include the implicit # arguments for selectors. # hdr_name = [] kind = "method" if ismethod else "function" hdr_name.append(f"{indent}.. {kind}:: {name}(") for info in metadata.args: hdr_name.append(f"{info.name}, ") if metadata.variadic: hdr_name.append("..., ") if metadata.args: hdr_name.append("/)") print("".join(hdr_name), file=fp) if isinstance(metadata, MethodInfo): if metadata.class_method: print(f"{indent} :classmethod:", file=fp) print("", file=fp) if native_name is not None: print(f"{indent} Binding for {native_name}", file=fp) print("", file=fp) for info in metadata.args: if info.type_name: type_name = info.type_name else: type_name = describe_type(info.typestr) print( f"{indent} :param {type_name} {info.name}: {describe_argument(info, metadata)}", # noqa: B950 file=fp, ) # This code is way to basic and doesn't handle pass-by-reference # output and input/output arguments, those are returned from the # callable. rv = metadata.retval if rv.type_name: type_name = rv.type_name else: type_name = describe_type(rv.typestr) if rv.typestr != objc._C_VOID: description = describe_returnvalue(rv) if description: print(f"{indent} :returns: {description}", file=fp) print(f"{indent} :rtype: {type_name}", file=fp) print("", file=fp) available(fp, metadata.availability, indent=indent + " ") print("", file=fp)