tinkering with pyvips8 docs

This commit is contained in:
John Cupitt 2014-11-11 14:59:06 +00:00
parent 8a545ab6c4
commit 326854843a
3 changed files with 122 additions and 5 deletions

95
TODO
View File

@ -1,9 +1,18 @@
- why don't we get gtk-doc expansions in the leading chapters? we turn them on
- try:
$ cd vips-x.x.x/libvips
$ g-ir-doc-tool --language=Python -o /tmp/vips-doc Vips-8.0.gir
$ yelp /tmp/vips-doc
shows gir contents
- can we generate python docstrings?
this works
from gi.repository import Vips
help(Vips.Image.black)
but this does not
@ -15,7 +24,91 @@
a = Vips.Image.black(10, 10)
help(a.add)
do we need to override __getattribute__ as well?
this has loads of stuff from gi!!
op = Vips.Operation.new("black")
help(op)
- want to get the description for an operation
op = Vips.Operation.new("black")
can't look at op.description, since that's not set until build(), we need to
get the class and walk that
try:
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']
- test other arg types

View File

@ -118,12 +118,12 @@ vips_get_argv0( void )
/**
* VIPS_INIT:
* @argv0: name of application
* @ARGV0: name of application
*
* VIPS_INIT() starts up the world of VIPS. You should call this on
* program startup before using any other VIPS operations. If you do not call
* VIPS_INIT(), VIPS will call it for you when you use your first VIPS
* operation, but it may not be able to get hold of @argv0 and VIPS may
* operation, but it may not be able to get hold of @ARGV0 and VIPS may
* therefore be unable to find its data files. It is much better to call
* this macro yourself.
*

View File

@ -369,6 +369,30 @@ def vips_image_new_from_array(cls, array, scale = 1, offset = 0):
setattr(Vips.Image, 'new_from_array', vips_image_new_from_array)
def generate_docstring(name):
try:
op = Vips.Operation.new(name)
except TypeError, e:
return 'No such operator ' + name
# find all the args for this op, sort into priority order
args = [Argument(op, x) for x in op.props]
args.sort(lambda a, b: a.priority - b.priority)
enm = Vips.ArgumentFlags
# find all required, unassigned input args
required_input = [x for x in args if x.flags & enm.INPUT and
x.flags & enm.REQUIRED and
not x.isset]
result = ""
for x in required_input:
result += x.name + "\n"
return result
# apply a function to a thing, or map over a list
# we often need to do something like (1.0 / other) and need to work for lists
# as well as scalars
@ -420,7 +444,7 @@ class Image(Vips.Image):
def call_function(*args, **kwargs):
return _call_instance(self, name, args, kwargs)
call_function.__doc__ = "hello world, from " + name
call_function.__doc__ = generate_docstring(name)
return call_function
@ -759,7 +783,7 @@ def add_doc(value):
def generate_class_method(name):
@classmethod
@add_doc('hello, world!')
@add_doc(generate_docstring(name))
def class_method(cls, *args, **kwargs):
return _call_base(name, args, kwargs)