From 0aae0588eb52d2c75e2a32cfdc456f360e4de783 Mon Sep 17 00:00:00 2001 From: Eivind Jahren Date: Mon, 19 Sep 2022 13:31:19 +0200 Subject: [PATCH] Fix basecenum not able to bind methods Due to the newly added is_initialized, it was no longer possible to bind methods to a BaseCEnum this is fixed by adding a is_initialized method to BaseCEnum. --- cwrap/basecenum.py | 23 ++++++++++++++++------- tests/test_basecenum.py | 35 ++++++++++++++++++++++++++--------- 2 files changed, 42 insertions(+), 16 deletions(-) diff --git a/cwrap/basecenum.py b/cwrap/basecenum.py index 1d2a5d4..baa8701 100644 --- a/cwrap/basecenum.py +++ b/cwrap/basecenum.py @@ -16,11 +16,13 @@ from __future__ import absolute_import, division, print_function, unicode_literals +import ctypes + import six -import ctypes from .metacwrap import MetaCWrap + @six.add_metaclass(MetaCWrap) class BaseCEnum(object): enum_namespace = {} @@ -87,6 +89,9 @@ def __eq__(self, other): return False + def is_initialized(self): + return True + def __hash__(self): return hash(self.value) @@ -109,7 +114,6 @@ def __or__(self, other): value = self.value | other.value return self.__resolveOrCreateEnum(value) - def __xor__(self, other): self.__assertOtherIsSameType(other) value = self.value ^ other.value @@ -150,16 +154,22 @@ def __resolveEnum(cls, value): return None def __assertOtherIsSameType(self, other): - assert isinstance(other, self.__class__), "Can only operate on enums of same type: %s =! %s" % ( - self.__class__.__name__, other.__class__.__name__) - + assert isinstance( + other, self.__class__ + ), "Can only operate on enums of same type: %s =! %s" % ( + self.__class__.__name__, + other.__class__.__name__, + ) @classmethod def populateEnum(cls, library, enum_provider_function): try: func = getattr(library, enum_provider_function) except AttributeError: - raise ValueError("Could not find enum description function: %s - can not load enum: %s." % (enum_provider_function, cls.__name__)) + raise ValueError( + "Could not find enum description function: %s - can not load enum: %s." + % (enum_provider_function, cls.__name__) + ) func.restype = ctypes.c_char_p func.argtypes = [ctypes.c_int, ctypes.POINTER(ctypes.c_int)] @@ -174,4 +184,3 @@ def populateEnum(cls, library, enum_provider_function): index += 1 else: break - diff --git a/tests/test_basecenum.py b/tests/test_basecenum.py index 3d6651a..e5d5ec5 100644 --- a/tests/test_basecenum.py +++ b/tests/test_basecenum.py @@ -1,10 +1,10 @@ +import os import unittest -from cwrap import BaseCEnum +from cwrap import BaseCEnum, Prototype, load class BaseCEnumTest(unittest.TestCase): - def test_base_c_enum(self): class enum(BaseCEnum): pass @@ -33,19 +33,16 @@ class enum2(BaseCEnum): self.assertEqual(str(enum.ONE), "ONE") - self.assertEqual(enum.ONE + enum.TWO, enum.THREE) self.assertEqual(enum.ONE + enum.FOUR, 5) with self.assertRaises(ValueError): e = enum(5) - self.assertEqual(enum.THREE & enum.ONE, enum.ONE) self.assertEqual(enum.ONE | enum.TWO, enum.THREE) self.assertEqual(enum.THREE ^ enum.TWO, enum.ONE) - with self.assertRaises(AssertionError): e = enum.ONE + enum2.ONE @@ -58,7 +55,6 @@ class enum2(BaseCEnum): with self.assertRaises(AssertionError): e = enum.ONE ^ enum2.ONE - def test_in_operator(self): class PowerOf2(BaseCEnum): pass @@ -87,11 +83,10 @@ class MyLonelyEnum(BaseCEnum): tri = MyLonelyEnum.THREE self.assertEqual(repr(tri), 'MyLonelyEnum(name = "THREE", value = 3)') - self.assertEqual(str(tri), 'THREE') - self.assertEqual(tri.name, 'THREE') + self.assertEqual(str(tri), "THREE") + self.assertEqual(tri.name, "THREE") self.assertEqual(tri.value, 3) - def test_from_name(self): class EnumName(BaseCEnum): pass @@ -104,3 +99,25 @@ class EnumName(BaseCEnum): one = EnumName.from_string("ONE") self.assertEqual(one, EnumName.ONE) + + +def test_that_enum_can_be_bind_methods(): + class LibCPrototype(Prototype): + lib = load("msvcrt" if os.name == "nt" else None) + + def __init__(self, prototype, bind=False, allow_attribute_error=False): + super(LibCPrototype, self).__init__( + LibCPrototype.lib, + prototype, + bind=bind, + allow_attribute_error=allow_attribute_error, + ) + + class Endumb(BaseCEnum): + TYPE_NAME = "endumb" + SOME_VALUE = None + SOME_OTHER_VALUE = None + abs = LibCPrototype("int abs(endumb)", bind=True) + + Endumb.addEnum("SOME_VALUE", -1) + assert Endumb.SOME_VALUE.abs() == 1