diff --git a/comtypes/automation.py b/comtypes/automation.py index 26f84f47..f8bf6510 100644 --- a/comtypes/automation.py +++ b/comtypes/automation.py @@ -245,9 +245,6 @@ def _set_value(self, value): elif isinstance(value, bool): self.vt = VT_BOOL self._.VT_BOOL = value - elif isinstance(value, (int, c_int)): - self.vt = VT_I4 - self._.VT_I4 = value elif isinstance(value, int): u = self._ # try VT_I4 first. @@ -264,12 +261,11 @@ def _set_value(self, value): self.vt = VT_UI4 return # try VT_I8 next. - if value >= 0: - u.VT_I8 = value - if u.VT_I8 == value: - # did work. - self.vt = VT_I8 - return + u.VT_I8 = value + if u.VT_I8 == value: + # did work. + self.vt = VT_I8 + return # try VT_UI8 next. if value >= 0: u.VT_UI8 = value @@ -277,9 +273,7 @@ def _set_value(self, value): # did work. self.vt = VT_UI8 return - # VT_R8 is last resort. - self.vt = VT_R8 - u.VT_R8 = float(value) + raise TypeError(f"Cannot put {value!r} in VARIANT") elif isinstance(value, (float, c_double)): self.vt = VT_R8 self._.VT_R8 = value @@ -364,6 +358,9 @@ def _set_value(self, value): elif isinstance(value, c_uint): self.vt = VT_UI4 self._.VT_UI4 = value + elif isinstance(value, c_int): + self.vt = VT_I4 + self._.VT_I4 = value elif isinstance(value, c_float): self.vt = VT_R4 self._.VT_R4 = value diff --git a/comtypes/test/test_variant.py b/comtypes/test/test_variant.py index dc1d5094..599cbf49 100644 --- a/comtypes/test/test_variant.py +++ b/comtypes/test/test_variant.py @@ -129,6 +129,39 @@ def test_integers(self): self.assertEqual(v.value, 1) self.assertIsInstance(v.value, int) + def test_vt_uix_range_boundaries(self): + MIN_VT_I4 = -(2**31) + MAX_VT_I4 = 2**31 - 1 + MAX_VT_UI4 = 2**32 - 1 + MIN_VT_I8 = -(2**63) + MAX_VT_I8 = 2**63 - 1 + MAX_VT_UI8 = 2**64 - 1 + for val, vt in [ + (MIN_VT_I8, VT_I8), + (MIN_VT_I4 - 1, VT_I8), + (MIN_VT_I4, VT_I4), + (0, VT_I4), + (MAX_VT_I4, VT_I4), + (MAX_VT_I4 + 1, VT_UI4), + (MAX_VT_UI4, VT_UI4), + (MAX_VT_UI4 + 1, VT_I8), + (MAX_VT_I8, VT_I8), + (MAX_VT_I8 + 1, VT_UI8), + (MAX_VT_UI8, VT_UI8), + ]: + with self.subTest(val=val, vt=vt): + v = VARIANT() + v.value = val + self.assertEqual(v.value, val) + self.assertEqual(v.vt, vt) + + def test_out_of_vt_uix_range(self): + MIN_VT_I8 = -(2**63) + MAX_VT_UI8 = 2**64 - 1 + for val in [MIN_VT_I8 - 1, MAX_VT_UI8 + 1]: + with self.subTest(val=val), self.assertRaises(TypeError): + VARIANT().value = val + def test_datetime(self): now = datetime.datetime.now()