diff --git a/.travis.yml b/.travis.yml index 303bfa7..dab9b93 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,6 +2,8 @@ language: python python: - "2.7" + - "3.2" + - "3.3" before_install: - sudo add-apt-repository ppa:ubuntu-wine/ppa -y diff --git a/scripts/run_tests_wine.sh b/scripts/run_tests_wine.sh index a83c5df..19a76a9 100644 --- a/scripts/run_tests_wine.sh +++ b/scripts/run_tests_wine.sh @@ -3,10 +3,16 @@ set -e export DISPLAY=:99.0 -PYTHON="c:/Python27/python.exe" -COVERAGE="c:/Python27/Scripts/coverage.exe" +if [ "${TRAVIS_PYTHON_VERSION}" = "2.7" ]; then + COVERAGE="c:/Python27/Scripts/coverage.exe" +elif [ "${TRAVIS_PYTHON_VERSION}" = "3.2" ]; then + COVERAGE="c:/Python32/Scripts/coverage.exe" +elif [ "${TRAVIS_PYTHON_VERSION}" = "3.3" ]; then + COVERAGE="c:/Python33/Scripts/coverage.exe" +else + exit 1; +fi -wine ${PYTHON} -m nose.core win32ctypes wine ${COVERAGE} erase wine ${COVERAGE} run -m nose.core win32ctypes wine ${COVERAGE} report --include=win32ctypes* diff --git a/scripts/setup_tests_wine.sh b/scripts/setup_tests_wine.sh index 8a1b8d8..504c1a8 100644 --- a/scripts/setup_tests_wine.sh +++ b/scripts/setup_tests_wine.sh @@ -3,12 +3,34 @@ set -e export DISPLAY=:99.0 -PYTHON="c:/Python27/python.exe" -EASY_INSTALL="c:/Python27/Scripts/easy_install.exe" -PIP="c:/Python27/Scripts/pip.exe" +if [ "${TRAVIS_PYTHON_VERSION}" = "2.7" ]; then + PYTHON_MSI="python-2.7.6.msi" + PYTHON_URL="http://www.python.org/ftp/python/2.7.6/${PYTHON_MSI}" + PYTHON="c:/Python27/python.exe" + EASY_INSTALL="c:/Python27/Scripts/easy_install.exe" + PIP="c:/Python27/Scripts/pip.exe" +elif [ "${TRAVIS_PYTHON_VERSION}" = "3.2" ]; then + PYTHON_MSI="python-3.2.5.msi" + PYTHON_URL="http://www.python.org/ftp/python/3.2.5/${PYTHON_MSI}" + PYTHON="c:/Python32/python.exe" + EASY_INSTALL="c:/Python32/Scripts/easy_install.exe" + PIP="c:/Python32/Scripts/pip.exe" +elif [ "${TRAVIS_PYTHON_VERSION}" = "3.3" ]; then + PYTHON_MSI="python-3.3.4.msi" + PYTHON_URL="http://www.python.org/ftp/python/3.3.4/${PYTHON_MSI}" + PYTHON="c:/Python33/python.exe" + EASY_INSTALL="c:/Python33/Scripts/easy_install.exe" + PIP="c:/Python33/Scripts/pip.exe" +else + echo "Python ${TRAVIS_PYTHON_VERSION} not supported." + exit 1; +fi -wget http://www.python.org/ftp/python/2.7.6/python-2.7.6.msi -wine msiexec /i python-2.7.6.msi /qn +PYWIN32_EXE="pywin32-218.win32-py${TRAVIS_PYTHON_VERSION}.exe" +PYWIN32_URL="http://sourceforge.net/projects/pywin32/files/pywin32/Build%20218/pywin32-218.win32-py${TRAVIS_PYTHON_VERSION}.exe/download" + +wget ${PYTHON_URL} +wine msiexec /i ${PYTHON_MSI} /qn wget https://pypi.python.org/packages/source/s/setuptools/setuptools-2.2.tar.gz tar xf setuptools-2.2.tar.gz @@ -16,6 +38,6 @@ tar xf setuptools-2.2.tar.gz wine ${EASY_INSTALL} nose coverage -wget http://sourceforge.net/projects/pywin32/files/pywin32/Build%20218/pywin32-218.win32-py2.7.exe/download -O pywin32-218.win32-py2.7.exe +wget ${PYWIN32_URL} -O ${PYWIN32_EXE} -wine ${EASY_INSTALL} pywin32-218.win32-py2.7.exe +wine ${EASY_INSTALL} ${PYWIN32_EXE} diff --git a/win32ctypes/_common.py b/win32ctypes/_common.py index ed97a85..3e39dbc 100644 --- a/win32ctypes/_common.py +++ b/win32ctypes/_common.py @@ -14,6 +14,7 @@ from ctypes import pythonapi, POINTER, c_void_p, py_object from ctypes.wintypes import BYTE, UINT +from .compat import PY3 from ._util import function_factory PPy_UNICODE = c_void_p @@ -29,9 +30,14 @@ LPBYTE = POINTER(BYTE) -_PyString_FromStringAndSize = function_factory( - pythonapi.PyString_FromStringAndSize, - return_type=py_object) +if PY3: + _PyBytes_FromStringAndSize = function_factory( + pythonapi.PyBytes_FromStringAndSize, + return_type=py_object) +else: + _PyBytes_FromStringAndSize = function_factory( + pythonapi.PyString_FromStringAndSize, + return_type=py_object) _GetACP = function_factory( kernel32.GetACP, diff --git a/win32ctypes/_win32cred.py b/win32ctypes/_win32cred.py index 237e4a0..e78e21e 100644 --- a/win32ctypes/_win32cred.py +++ b/win32ctypes/_win32cred.py @@ -13,9 +13,9 @@ from __future__ import absolute_import import ctypes -from ctypes import POINTER, Structure +from ctypes import POINTER, Structure, c_void_p, c_wchar_p from ctypes.wintypes import ( - BOOL, DWORD, FILETIME, c_void_p, c_wchar_p, LPCWSTR) + BOOL, DWORD, FILETIME, LPCWSTR) from ._common import LPBYTE from ._util import function_factory, check_zero, check_zero_factory diff --git a/win32ctypes/compat.py b/win32ctypes/compat.py new file mode 100644 index 0000000..07cc4ca --- /dev/null +++ b/win32ctypes/compat.py @@ -0,0 +1,19 @@ +import sys + +if sys.version_info[0] >= 3: + PY3 = True + PY2 = False +else: + PY3 = False + PY2 = True + +if PY3: + def is_unicode(s): + return isinstance(s, str) + + unicode = str +else: + def is_unicode(s): + return isinstance(s, unicode) + + unicode = unicode diff --git a/win32ctypes/tests/test_win32cred.py b/win32ctypes/tests/test_win32cred.py index 0a75c1f..570f218 100644 --- a/win32ctypes/tests/test_win32cred.py +++ b/win32ctypes/tests/test_win32cred.py @@ -41,7 +41,7 @@ def test_write_simple(self): self.assertEqual(res["Type"], CRED_TYPE_GENERIC) self.assertEqual( - unicode(res["CredentialBlob"], encoding='utf-16'), + res["CredentialBlob"].decode(encoding='utf-16'), password) self.assertEqual(res["UserName"], username) self.assertEqual(res["TargetName"], target) diff --git a/win32ctypes/win32api.py b/win32ctypes/win32api.py index 06dd532..10ccc15 100644 --- a/win32ctypes/win32api.py +++ b/win32ctypes/win32api.py @@ -8,7 +8,7 @@ from __future__ import absolute_import -from ._common import _PyString_FromStringAndSize +from ._common import _PyBytes_FromStringAndSize from . import _win32api LOAD_LIBRARY_AS_DATAFILE = 0x2 @@ -61,7 +61,7 @@ def LoadResource(hModule, type_, name, language): size = _win32api._SizeofResource(hModule, hrsrc) hglob = _win32api._LoadResource(hModule, hrsrc) pointer = _win32api._LockResource(hglob) - return _PyString_FromStringAndSize(pointer, size) + return _PyBytes_FromStringAndSize(pointer, size) def FreeLibrary(hModule): diff --git a/win32ctypes/win32cred.py b/win32ctypes/win32cred.py index b79757e..ce515c4 100644 --- a/win32ctypes/win32cred.py +++ b/win32ctypes/win32cred.py @@ -11,7 +11,8 @@ import ctypes -from ._common import _PyString_FromStringAndSize, _GetACP +from ._common import _PyBytes_FromStringAndSize, _GetACP +from .compat import is_unicode, unicode from . import _win32cred CRED_TYPE_GENERIC = 0x1 @@ -103,7 +104,7 @@ def CredRead(TargetName, Type): if key != 'CredentialBlob': credential[key] = getattr(c_creds, key) else: - blob = _PyString_FromStringAndSize( + blob = _PyBytes_FromStringAndSize( c_creds.CredentialBlob, c_creds.CredentialBlobSize) credential['CredentialBlob'] = blob return credential @@ -132,7 +133,7 @@ def _make_blob(password): Credentials. """ - if isinstance(password, unicode): + if is_unicode(password): return password else: code_page = _GetACP()