diff --git a/CHANGELOG.rst b/CHANGELOG.rst index b72ee8d..82ceb36 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,6 +1,8 @@ # master - ensure compatibility with a single shared libvips library [kleisauke] +- add flags_dict(), enum_dict() for better flags introspection +- improve generation of enums.py ## Version 2.2.2 (released 4 Jan 2023) diff --git a/examples/gen-enums.py b/examples/gen-enums.py index b6e2675..3e61f06 100755 --- a/examples/gen-enums.py +++ b/examples/gen-enums.py @@ -3,7 +3,7 @@ import sys import xml.etree.ElementTree as ET -from pyvips import ffi, values_for_enum, values_for_flag, \ +from pyvips import ffi, enum_dict, flags_dict, \ vips_lib, type_map, type_name, type_from_name # This file generates enums.py -- the set of classes giving the permissible @@ -50,6 +50,10 @@ def add_nickname(gtype, a, b): type_map(type_from_name('GEnum'), add_nickname) + # Filter internal enums + blacklist = ['VipsImageType', 'VipsToken'] + all_nicknames = [name for name in all_nicknames if name not in blacklist] + for name in all_nicknames: gtype = type_from_name(name) python_name = remove_prefix(name) @@ -57,7 +61,7 @@ def add_nickname(gtype, a, b): continue node = xml_enums[python_name] - values = values_for_enum(gtype) + values = enum_dict(gtype) enum_doc = node.find("goi:doc", namespace) print('') @@ -70,8 +74,8 @@ def add_nickname(gtype, a, b): print('') print('Attributes:') print('') - for value in values: - python_name = value.replace('-', '_') + for key, value in values.items(): + python_name = key.replace('-', '_') member = node.find(f"goi:member[@name='{python_name}']", namespace) member_doc = member.find("goi:doc", namespace) if member_doc is not None: @@ -81,9 +85,9 @@ def add_nickname(gtype, a, b): print(' """') print('') - for value in values: - python_name = value.replace('-', '_').upper() - print(f' {python_name} = \'{value}\'') + for key, value in values.items(): + python_name = key.replace('-', '_').upper() + print(f' {python_name} = \'{key}\'') def generate_flags(): @@ -100,8 +104,8 @@ def add_nickname(gtype, a, b): type_map(type_from_name('GFlags'), add_nickname) # Filter internal flags - filter = ['VipsForeignFlags'] - all_nicknames = [name for name in all_nicknames if name not in filter] + blacklist = ['VipsForeignFlags'] + all_nicknames = [name for name in all_nicknames if name not in blacklist] for name in all_nicknames: gtype = type_from_name(name) @@ -110,7 +114,7 @@ def add_nickname(gtype, a, b): continue node = xml_flags[python_name] - values = values_for_flag(gtype) + values = flags_dict(gtype) enum_doc = node.find("goi:doc", namespace) print('') @@ -123,8 +127,8 @@ def add_nickname(gtype, a, b): print('') print('Attributes:') print('') - for value in values: - python_name = value.replace('-', '_') + for key, value in values.items(): + python_name = key.replace('-', '_') member = node.find(f"goi:member[@name='{python_name}']", namespace) member_doc = member.find("goi:doc", namespace) if member_doc is not None: @@ -134,10 +138,9 @@ def add_nickname(gtype, a, b): print(' """') print('') - for value in values: - python_name = value.replace('-', '_') - member = node.find(f"goi:member[@name='{python_name}']", namespace) - print(f' {python_name.upper()} = {member.get("value")}') + for key, value in values.items(): + python_name = key.replace('-', '_').upper() + print(f' {python_name} = {value}') if __name__ == "__main__": diff --git a/pyvips/base.py b/pyvips/base.py index 6bd581f..b80bdaa 100644 --- a/pyvips/base.py +++ b/pyvips/base.py @@ -107,7 +107,7 @@ def type_map(gtype, fn): def values_for_enum(gtype): - """Get all values for a enum (gtype).""" + """Deprecated.""" g_type_class = gobject_lib.g_type_class_ref(gtype) g_enum_class = ffi.cast('GEnumClass *', g_type_class) @@ -118,7 +118,7 @@ def values_for_enum(gtype): def values_for_flag(gtype): - """Get all values for a flag (gtype).""" + """Deprecated.""" g_type_class = gobject_lib.g_type_class_ref(gtype) g_flags_class = ffi.cast('GFlagsClass *', g_type_class) @@ -127,6 +127,29 @@ def values_for_flag(gtype): for i in range(g_flags_class.n_values)] +def enum_dict(gtype): + """Get name -> value dict for a enum (gtype).""" + + g_type_class = gobject_lib.g_type_class_ref(gtype) + g_enum_class = ffi.cast('GEnumClass *', g_type_class) + + # -1 since we always have a "last" member. + return {_to_string(g_enum_class.values[i].value_nick): + g_enum_class.values[i].value + for i in range(g_enum_class.n_values - 1)} + + +def flags_dict(gtype): + """Get name -> value dict for a flags (gtype).""" + + g_type_class = gobject_lib.g_type_class_ref(gtype) + g_flags_class = ffi.cast('GFlagsClass *', g_type_class) + + return {_to_string(g_flags_class.values[i].value_nick): + g_flags_class.values[i].value + for i in range(g_flags_class.n_values)} + + __all__ = [ 'leak_set', 'version', @@ -138,5 +161,7 @@ def values_for_flag(gtype): 'type_map', 'type_from_name', 'values_for_enum', - 'values_for_flag' + 'values_for_flag', + 'enum_dict', + 'flags_dict' ] diff --git a/pyvips/enums.py b/pyvips/enums.py index 904eb02..66bf25e 100644 --- a/pyvips/enums.py +++ b/pyvips/enums.py @@ -1317,19 +1317,6 @@ class CombineMode(object): ADD = 'add' -class Token(object): - """Token. - -Attributes: - - """ - - LEFT = 'left' - RIGHT = 'right' - STRING = 'string' - EQUALS = 'equals' - - class Saveable(object): """Saveable. @@ -1359,23 +1346,6 @@ class Saveable(object): ANY = 'any' -class ImageType(object): - """ImageType. - -Attributes: - - """ - - ERROR = 'error' - NONE = 'none' - SETBUF = 'setbuf' - SETBUF_FOREIGN = 'setbuf-foreign' - OPENIN = 'openin' - MMAPIN = 'mmapin' - MMAPINRW = 'mmapinrw' - OPENOUT = 'openout' - - class ForeignKeep(object): """ForeignKeep.