Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

remove sys.version_info bridges from the production codebase #449

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 7 additions & 20 deletions comtypes/GUID.py
Original file line number Diff line number Diff line change
@@ -1,23 +1,10 @@
from ctypes import *
import sys

if sys.version_info >= (2, 6):

def binary(obj):
return bytes(obj)
def binary(obj):
return bytes(obj)

else:

def binary(obj):
return buffer(obj)


if sys.version_info >= (3, 0):
text_type = str
base_text_type = str
else:
text_type = unicode
base_text_type = basestring

BYTE = c_byte
WORD = c_ushort
Expand All @@ -41,10 +28,10 @@ class GUID(Structure):

def __init__(self, name=None):
if name is not None:
_CLSIDFromString(text_type(name), byref(self))
_CLSIDFromString(str(name), byref(self))

def __repr__(self):
return 'GUID("%s")' % text_type(self)
return 'GUID("%s")' % str(self)

def __unicode__(self):
p = c_wchar_p()
Expand All @@ -71,7 +58,7 @@ def __hash__(self):
return hash(binary(self))

def copy(self):
return GUID(text_type(self))
return GUID(str(self))

@classmethod
def from_progid(cls, progid):
Expand All @@ -80,11 +67,11 @@ def from_progid(cls, progid):
progid = progid._reg_clsid_
if isinstance(progid, cls):
return progid
elif isinstance(progid, base_text_type):
elif isinstance(progid, str):
if progid.startswith("{"):
return cls(progid)
inst = cls()
_CLSIDFromProgID(text_type(progid), byref(inst))
_CLSIDFromProgID(str(progid), byref(inst))
return inst
else:
raise TypeError("Cannot construct guid from %r" % progid)
Expand Down
87 changes: 15 additions & 72 deletions comtypes/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,53 +52,6 @@
)


################################################################

# fmt: off
def add_metaclass(metaclass):
"""Class decorator from six.py for creating a class with a metaclass.

Copyright (c) 2010-2020 Benjamin Peterson

Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
"""
def wrapper(cls):
orig_vars = cls.__dict__.copy()
slots = orig_vars.get('__slots__')
if slots is not None:
if isinstance(slots, text_type):
slots = [slots]
for slots_var in slots:
orig_vars.pop(slots_var)
orig_vars.pop('__dict__', None)
orig_vars.pop('__weakref__', None)
if hasattr(cls, '__qualname__'):
orig_vars['__qualname__'] = cls.__qualname__
return metaclass(cls.__name__, cls.__bases__, orig_vars)
return wrapper
# fmt: on


################################################################
if sys.version_info >= (3, 0):
text_type = str
else:
text_type = unicode
_all_slice = slice(None, None, None)


Expand Down Expand Up @@ -134,21 +87,16 @@ def _check_version(actual, tlib_cached_mtime=None):
raise ImportError("Typelib different than module")


if sys.version_info >= (3, 0):
pythonapi.PyInstanceMethod_New.argtypes = [py_object]
pythonapi.PyInstanceMethod_New.restype = py_object
PyInstanceMethod_Type = type(pythonapi.PyInstanceMethod_New(id))
pythonapi.PyInstanceMethod_New.argtypes = [py_object]
pythonapi.PyInstanceMethod_New.restype = py_object
PyInstanceMethod_Type = type(pythonapi.PyInstanceMethod_New(id))

def instancemethod(func, inst, cls):
mth = PyInstanceMethod_Type(func)
if inst is None:
return mth
return mth.__get__(inst)

else:

def instancemethod(func, inst, cls):
return types.MethodType(func, inst, cls)
def instancemethod(func, inst, cls):
mth = PyInstanceMethod_Type(func)
if inst is None:
return mth
return mth.__get__(inst)


class ReturnHRESULT(Exception):
Expand Down Expand Up @@ -587,7 +535,7 @@ def _make_methods(self, methods):
except KeyError:
raise AttributeError("this class must define an _iid_")
else:
com_interface_registry[text_type(iid)] = self
com_interface_registry[str(iid)] = self
# create members
vtbl_offset = self.__get_baseinterface_methodcount()
member_gen = ComMemberGenerator(self.__name__, vtbl_offset, self._iid_)
Expand Down Expand Up @@ -627,8 +575,7 @@ class _compointer_meta(type(c_void_p), _cominterface_meta):
# no functionality, but needed to avoid a metaclass conflict


@add_metaclass(_compointer_meta)
class _compointer_base(c_void_p):
class _compointer_base(c_void_p, metaclass=_compointer_meta):
"base class for COM interface pointer classes"

def __del__(self, _debug=logger.debug):
Expand Down Expand Up @@ -757,7 +704,7 @@ def from_param(cls, value):
# IDL stuff


class helpstring(text_type):
class helpstring(str):
"Specifies the helpstring for a COM method or property."


Expand Down Expand Up @@ -830,7 +777,7 @@ def COMMETHOD(idlflags, restype, methodname, *argspec):

if TYPE_CHECKING:

class _IUnknown_Base(c_void_p):
class _IUnknown_Base(c_void_p, metaclass=_cominterface_meta):
"""This is workaround to avoid false-positive of static type checking.

`IUnknown` behaves as a ctypes type, and `POINTER` can take it.
Expand All @@ -848,8 +795,7 @@ class _IUnknown_Base(c_void_p):
_IUnknown_Base = object


@add_metaclass(_cominterface_meta)
class IUnknown(_IUnknown_Base):
class IUnknown(_IUnknown_Base, metaclass=_cominterface_meta):
"""The most basic COM interface.

Each subclasses of IUnknown must define these class attributes:
Expand Down Expand Up @@ -963,9 +909,7 @@ def CoGetObject(displayname, interface):
interface = IUnknown
punk = POINTER(interface)()
# Do we need a way to specify the BIND_OPTS parameter?
_ole32.CoGetObject(
text_type(displayname), None, byref(interface._iid_), byref(punk)
)
_ole32.CoGetObject(str(displayname), None, byref(interface._iid_), byref(punk))
return punk # type: ignore


Expand Down Expand Up @@ -1236,8 +1180,7 @@ def CoCreateInstanceEx(
from comtypes._meta import _coclass_meta


@add_metaclass(_coclass_meta)
class CoClass(COMObject):
class CoClass(COMObject, metaclass=_coclass_meta):
pass


Expand Down
12 changes: 2 additions & 10 deletions comtypes/_comobject.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
from _ctypes import CopyComPointer
import logging
import os
import queue
import sys

from comtypes import COMError, ReturnHRESULT, instancemethod, _encode_idl
Expand All @@ -37,11 +38,6 @@
_warning = logger.warning
_error = logger.error

if sys.version_info >= (3, 0):
int_types = (int,)
else:
int_types = (int, long)

################################################################
# COM object implementation

Expand Down Expand Up @@ -72,7 +68,7 @@ def winerror(exc):
return exc.hresult
elif isinstance(exc, WindowsError):
code = exc.winerror
if isinstance(code, int_types):
if isinstance(code, int):
return code
# Sometimes, a WindowsError instance has no error code. An access
# violation raised by ctypes has only text, for example. In this
Expand Down Expand Up @@ -381,10 +377,6 @@ def run_sta(self):
messageloop.run()

def run_mta(self):
if sys.version_info >= (3, 0):
import queue
else:
import Queue as queue
self._queue = queue.Queue()
self._queue.get()

Expand Down
37 changes: 8 additions & 29 deletions comtypes/automation.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,15 +34,6 @@ class _safearray(object):
tagSAFEARRAY = None


if sys.version_info >= (3, 0):
int_types = (int,)
str_types = (str,)
base_text_type = str
else:
int_types = (int, long)
str_types = (unicode, str)
base_text_type = basestring

LCID = DWORD
DISPID = LONG
SCODE = LONG
Expand Down Expand Up @@ -262,9 +253,7 @@ def _set_value(self, value):
if value is None:
self.vt = VT_NULL
elif (
hasattr(value, "__len__")
and len(value) == 0
and not isinstance(value, base_text_type)
hasattr(value, "__len__") and len(value) == 0 and not isinstance(value, str)
):
self.vt = VT_NULL
# since bool is a subclass of int, this check must come before
Expand All @@ -275,7 +264,7 @@ def _set_value(self, value):
elif isinstance(value, (int, c_int)):
self.vt = VT_I4
self._.VT_I4 = value
elif isinstance(value, int_types):
elif isinstance(value, int):
u = self._
# try VT_I4 first.
u.VT_I4 = value
Expand Down Expand Up @@ -310,7 +299,7 @@ def _set_value(self, value):
elif isinstance(value, (float, c_double)):
self.vt = VT_R8
self._.VT_R8 = value
elif isinstance(value, str_types):
elif isinstance(value, str):
self.vt = VT_BSTR
# do the c_wchar_p auto unicode conversion
self._.c_void_p = _SysAllocStringLen(value, len(value))
Expand Down Expand Up @@ -633,21 +622,11 @@ class IEnumVARIANT(IUnknown):
def __iter__(self):
return self

if sys.version_info >= (3, 0):

def __next__(self):
item, fetched = self.Next(1)
if fetched:
return item
raise StopIteration

else:

def next(self):
item, fetched = self.Next(1)
if fetched:
return item
raise StopIteration
def __next__(self):
item, fetched = self.Next(1)
if fetched:
return item
raise StopIteration

def __getitem__(self, index):
self.Reset()
Expand Down
7 changes: 1 addition & 6 deletions comtypes/client/_constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,6 @@
import comtypes.automation
import comtypes.typeinfo

if sys.version_info >= (3, 0):
base_text_type = str
else:
base_text_type = basestring


class _frozen_attr_dict(dict):
__slots__ = ()
Expand Down Expand Up @@ -78,7 +73,7 @@ class Constants(object):
__slots__ = ("alias", "consts", "enums", "tcomp")

def __init__(self, obj):
if isinstance(obj, base_text_type):
if isinstance(obj, str):
tlib = comtypes.typeinfo.LoadTypeLibEx(obj)
else:
obj = obj.QueryInterface(comtypes.automation.IDispatch)
Expand Down
16 changes: 4 additions & 12 deletions comtypes/client/_generate.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,7 @@
import sys
import types
from typing import Any, Tuple, List, Optional, Dict, Union as _UnionT

if sys.version_info >= (3, 0):
base_text_type = str
import winreg
else:
base_text_type = basestring
import _winreg as winreg
import winreg

from comtypes import GUID, typeinfo
import comtypes.client
Expand Down Expand Up @@ -46,7 +40,7 @@ def _resolve_filename(tlib_string, dirpath):
(abspath, True) or (relpath, False):
where relpath is an unresolved path.
"""
assert isinstance(tlib_string, base_text_type)
assert isinstance(tlib_string, str)
# pathname of type library
if os.path.isabs(tlib_string):
# a specific location
Expand Down Expand Up @@ -107,7 +101,7 @@ def GetModule(tlib):
UIAutomation. The former module contains all the code, the
latter is a short stub loading the former.
"""
if isinstance(tlib, base_text_type):
if isinstance(tlib, str):
tlib_string = tlib
# if a relative pathname is used, we try to interpret it relative to
# the directory of the calling module (if not from command line)
Expand Down Expand Up @@ -136,8 +130,6 @@ def GetModule(tlib):
modulename = codegenerator.name_friendly_module(tlib)
if modulename is None:
return mod
if sys.version_info < (3, 0):
modulename = modulename.encode("mbcs")
# create and import the friendly-named module
return _create_friendly_module(tlib, modulename)

Expand All @@ -146,7 +138,7 @@ def _load_tlib(obj):
# type: (Any) -> typeinfo.ITypeLib
"""Load a pointer of ITypeLib on demand."""
# obj is a filepath or a ProgID
if isinstance(obj, base_text_type):
if isinstance(obj, str):
# in any case, attempt to load and if tlib_string is not valid, then raise
# as "OSError: [WinError -2147312566] Error loading type library/DLL"
return typeinfo.LoadTypeLibEx(obj)
Expand Down
Loading