better docstrings
you now see: class_method(cls, *args, **kwargs) method of gi.types.GObjectMeta instance make a black image usage: out = Vips.Image.black(width, height, bands = gint) where: out - Output image, VipsImage required parameters: width - Image width in pixels, gint height - Image height in pixels, gint optional parameters: bands - Number of bands in image, gint
This commit is contained in:
parent
f8200d67a8
commit
6a25b04974
82
TODO
82
TODO
@ -29,86 +29,16 @@
|
||||
op = Vips.Operation.new("black")
|
||||
help(op)
|
||||
|
||||
- want to get the description for an operation
|
||||
but does not include our docstring, strange
|
||||
|
||||
op = Vips.Operation.new("black")
|
||||
this has stuff from comments in Vips.py
|
||||
|
||||
can't look at op.description, since that's not set until build(), we need to
|
||||
get the class and walk that
|
||||
|
||||
help(Vips.Image)
|
||||
|
||||
try:
|
||||
we should trim and rewrite comments
|
||||
|
||||
GType a = Vips.type_find("VipsObject", "black")
|
||||
|
||||
in C, use this to get the class from a gtype:
|
||||
|
||||
g_type_class_ref(gtype)
|
||||
|
||||
from gi.repository import GObject
|
||||
dir(GObject.GType)
|
||||
['__class__', '__delattr__', '__doc__', '__eq__', '__format__',
|
||||
'__ge__', '__getattribute__', '__gt__', '__hash__', '__init__',
|
||||
'__le__', '__lt__', '__ne__', '__new__', '__reduce__',
|
||||
'__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__',
|
||||
'__subclasshook__', 'children', 'depth', 'from_name', 'fundamental',
|
||||
'has_value_table', 'interfaces', 'is_a', 'is_abstract', 'is_classed',
|
||||
'is_deep_derivable', 'is_derivable', 'is_instantiatable',
|
||||
'is_interface', 'is_value_abstract', 'is_value_type', 'name',
|
||||
'parent', 'pytype']
|
||||
|
||||
a = Vips.type_find("VipsObject", "black")
|
||||
dir(a)
|
||||
['__class__', '__delattr__', '__doc__', '__eq__', '__format__',
|
||||
'__ge__', '__getattribute__', '__gt__', '__hash__', '__init__',
|
||||
'__le__', '__lt__', '__ne__', '__new__', '__reduce__',
|
||||
'__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__',
|
||||
'__subclasshook__', 'children', 'depth', 'from_name', 'fundamental',
|
||||
'has_value_table', 'interfaces', 'is_a', 'is_abstract', 'is_classed',
|
||||
'is_deep_derivable', 'is_derivable', 'is_instantiatable',
|
||||
'is_interface', 'is_value_abstract', 'is_value_type', 'name',
|
||||
'parent', 'pytype']
|
||||
|
||||
>>> op = Vips.Operation.new("black")
|
||||
>>> dir(op)
|
||||
['__class__', '__copy__', '__deepcopy__', '__delattr__', '__dict__',
|
||||
'__doc__', '__eq__', '__format__', '__gdoc__', '__ge__',
|
||||
'__getattribute__', '__gpointer__', '__grefcount__', '__gsignals__',
|
||||
'__gt__', '__gtype__', '__hash__', '__info__', '__init__', '__le__',
|
||||
'__lt__', '__module__', '__ne__', '__new__', '__reduce__',
|
||||
'__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__',
|
||||
'__subclasshook__', '_force_floating', '_ref', '_ref_sink', '_unref',
|
||||
'_unsupported_data_method', '_unsupported_method', 'argument_isset',
|
||||
'argument_needsstring', 'argument_table', 'bind_property',
|
||||
'bind_property_full', 'build', 'chain', 'close', 'compat_control',
|
||||
'connect', 'connect_after', 'connect_object', 'connect_object_after',
|
||||
'constructed', 'description', 'disconnect', 'disconnect_by_func',
|
||||
'do_build', 'do_close', 'do_get_flags', 'do_invalidate',
|
||||
'do_output_to_arg', 'do_postbuild', 'do_postclose', 'do_preclose',
|
||||
'do_rewind', 'emit', 'emit_stop_by_name', 'force_floating',
|
||||
'found_hash', 'freeze_notify', 'g_type_instance',
|
||||
'get_argument_flags', 'get_argument_priority',
|
||||
'get_argument_to_string', 'get_data', 'get_flags', 'get_properties',
|
||||
'get_property', 'get_qdata', 'handler_block', 'handler_block_by_func',
|
||||
'handler_disconnect', 'handler_is_connected', 'handler_unblock',
|
||||
'handler_unblock_by_func', 'hash', 'interface_find_property',
|
||||
'interface_install_property', 'interface_list_properties',
|
||||
'invalidate', 'is_floating', 'local_cb', 'local_memory', 'new',
|
||||
'new_from_string', 'nickname', 'notify', 'notify_by_pspec',
|
||||
'parent_instance', 'parent_object', 'pixels', 'postclose', 'preclose',
|
||||
'print_all', 'print_dump', 'print_name', 'print_summary',
|
||||
'print_summary_class', 'props', 'qdata', 'ref', 'ref_count',
|
||||
'ref_sink', 'replace_data', 'replace_qdata', 'rewind', 'run_dispose',
|
||||
'sanity', 'sanity_all', 'set_argument_from_string', 'set_data',
|
||||
'set_from_string', 'set_properties', 'set_property', 'set_required',
|
||||
'set_static', 'static_object', 'steal_data', 'steal_qdata',
|
||||
'stop_emission', 'stop_emission_by_name', 'thaw_notify', 'unref',
|
||||
'unref_outputs', 'watch_closure', 'weak_ref']
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
- python fitsload has both "access" and "sequential" as kwargs, is this right?
|
||||
why do we need both?
|
||||
|
||||
- test other arg types
|
||||
|
||||
|
@ -639,6 +639,8 @@ void vips_object_rewind( VipsObject *object );
|
||||
|
||||
void vips_object_unref_outputs( VipsObject *object );
|
||||
|
||||
const char *vips_object_get_description( VipsObject *object );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /*__cplusplus*/
|
||||
|
@ -2974,3 +2974,26 @@ vips_object_unref_outputs( VipsObject *object )
|
||||
(void) vips_argument_map( object,
|
||||
vips_object_unref_outputs_sub, NULL, NULL );
|
||||
}
|
||||
|
||||
/**
|
||||
* vips_object_get_description:
|
||||
* @object: object to fetch description from
|
||||
*
|
||||
* Fetch the object description. Useful for language bindings.
|
||||
*
|
||||
* @object.description is only avaliable after _build(), which can be too
|
||||
* late. This function fetches from the instance, if possible, but falls back
|
||||
* to the class description if we are too early.
|
||||
*
|
||||
* Returns: the object description
|
||||
*/
|
||||
const char *
|
||||
vips_object_get_description( VipsObject *object )
|
||||
{
|
||||
VipsObjectClass *class = VIPS_OBJECT_GET_CLASS( object );
|
||||
|
||||
if( object->description )
|
||||
return( object->description ) ;
|
||||
else
|
||||
return( class->description ) ;
|
||||
}
|
||||
|
@ -157,6 +157,13 @@ class Argument:
|
||||
|
||||
return value
|
||||
|
||||
def description(self):
|
||||
result = self.name
|
||||
result += " " * (10 - len(self.name)) + " - " + self.prop.blurb
|
||||
result += ", " + self.prop.value_type.name
|
||||
|
||||
return result
|
||||
|
||||
Vips.Argument = Argument
|
||||
|
||||
# search a list recursively for a Vips.Image object
|
||||
@ -391,15 +398,61 @@ def generate_docstring(name):
|
||||
not x.isset]
|
||||
|
||||
required_output = [x for x in args if x.flags & enm.OUTPUT and
|
||||
not x.flags & enm.REQUIRED]
|
||||
x.flags & enm.REQUIRED]
|
||||
|
||||
optional_output = [x for x in args if x.flags & enm.OUTPUT and
|
||||
not x.flags & enm.REQUIRED]
|
||||
|
||||
result = "usage:\n"
|
||||
# find the first required input image, if any ... we will be a member
|
||||
# function of this instance
|
||||
member_x = None
|
||||
for i in range(0, len(required_input)):
|
||||
x = required_input[i]
|
||||
if GObject.type_is_a(vips_type_image, x.prop.value_type):
|
||||
member_x = x
|
||||
break
|
||||
|
||||
result = op.get_description() + "\n"
|
||||
result += "usage:\n"
|
||||
|
||||
result += " " + ", ".join([x.name for x in required_output]) + " = "
|
||||
if member_x:
|
||||
result += member_x.name + "." + name + "("
|
||||
else:
|
||||
result += "Vips.Image." + name + "("
|
||||
result += ", ".join([x.name for x in required_input
|
||||
if x != member_x])
|
||||
if len(optional_input) > 0:
|
||||
result += ", "
|
||||
result += ", ".join([x.name + " = " + x.prop.value_type.name
|
||||
for x in optional_input])
|
||||
result += ")\n"
|
||||
|
||||
result += "\n"
|
||||
|
||||
result += "where:\n"
|
||||
for x in required_output:
|
||||
result += " " + x.description() + "\n"
|
||||
|
||||
result += "\n"
|
||||
|
||||
result += "required parameters:\n"
|
||||
for x in required_input:
|
||||
result += x.name + "\n"
|
||||
result += " " + x.description() + "\n"
|
||||
|
||||
if len(optional_input) > 0:
|
||||
result += "\n"
|
||||
|
||||
result += "optional parameters:\n"
|
||||
for x in optional_input:
|
||||
result += " " + x.description() + "\n"
|
||||
|
||||
if len(optional_output) > 0:
|
||||
result += "\n"
|
||||
|
||||
result += "extra output options:\n"
|
||||
for x in optional_output:
|
||||
result += " " + x.description() + "\n"
|
||||
|
||||
return result
|
||||
|
||||
@ -412,6 +465,13 @@ def smap(func, x):
|
||||
else:
|
||||
return func(x)
|
||||
|
||||
# decorator to set docstring
|
||||
def add_doc(value):
|
||||
def _doc(func):
|
||||
func.__doc__ = value
|
||||
return func
|
||||
return _doc
|
||||
|
||||
class Image(Vips.Image):
|
||||
"""This is a test docstring in Vips.py ... does this get attached to the
|
||||
class we are overriding?
|
||||
@ -455,9 +515,9 @@ class Image(Vips.Image):
|
||||
if name in dir(self.props):
|
||||
return getattr(self.props, name)
|
||||
|
||||
@add_doc(generate_docstring(name))
|
||||
def call_function(*args, **kwargs):
|
||||
return _call_instance(self, name, args, kwargs)
|
||||
call_function.__doc__ = generate_docstring(name)
|
||||
|
||||
return call_function
|
||||
|
||||
@ -788,12 +848,6 @@ class_methods = [
|
||||
"fitsload",
|
||||
"openexrload"]
|
||||
|
||||
def add_doc(value):
|
||||
def _doc(func):
|
||||
func.__doc__ = value
|
||||
return func
|
||||
return _doc
|
||||
|
||||
def generate_class_method(name):
|
||||
@classmethod
|
||||
@add_doc(generate_docstring(name))
|
||||
|
Loading…
x
Reference in New Issue
Block a user