Skip to content

Commit

Permalink
Fix basecenum not able to bind methods
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
eivindjahren authored and mortalisk committed Sep 19, 2022
1 parent d972469 commit 0aae058
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 16 deletions.
23 changes: 16 additions & 7 deletions cwrap/basecenum.py
Original file line number Diff line number Diff line change
Expand Up @@ -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 = {}
Expand Down Expand Up @@ -87,6 +89,9 @@ def __eq__(self, other):

return False

def is_initialized(self):
return True

def __hash__(self):
return hash(self.value)

Expand All @@ -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
Expand Down Expand Up @@ -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)]
Expand All @@ -174,4 +184,3 @@ def populateEnum(cls, library, enum_provider_function):
index += 1
else:
break

35 changes: 26 additions & 9 deletions tests/test_basecenum.py
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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

Expand All @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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

0 comments on commit 0aae058

Please sign in to comment.