summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRonny Pfannschmidt <opensource@ronnypfannschmidt.de>2020-05-25 18:56:20 +0200
committerGitHub <noreply@github.com>2020-05-25 18:56:20 +0200
commit716511a39745827b37da8763097e42a1e0cdcd66 (patch)
tree394e39440c956eac3ba17a9a8195ece155327032
parent0dc3268c9ddfe01f10e4f2279c592b7d7b1de908 (diff)
parentc17e67f53860b26d265e55ded196be8495a99077 (diff)
downloadsetuptools-scm-716511a39745827b37da8763097e42a1e0cdcd66.tar.gz
Merge pull request #446 from henryiii/henryiii/win27
Python 2.7 fixes
-rw-r--r--.github/workflows/python-tests.yml8
-rw-r--r--setup.cfg1
-rw-r--r--src/setuptools_scm/git.py5
-rw-r--r--src/setuptools_scm/win_py31_compat.py214
-rw-r--r--testing/test_file_finder.py2
-rw-r--r--testing/test_git.py9
6 files changed, 232 insertions, 7 deletions
diff --git a/.github/workflows/python-tests.yml b/.github/workflows/python-tests.yml
index 9099eb2..ca8df3f 100644
--- a/.github/workflows/python-tests.yml
+++ b/.github/workflows/python-tests.yml
@@ -19,8 +19,6 @@ jobs:
os: [windows-latest, ubuntu-latest] #, macos-latest]
exclude:
- os: windows-latest
- python_version: "2.7"
- - os: windows-latest
python_version: "pypy2"
include:
- os: ubuntu-latest
@@ -61,7 +59,7 @@ jobs:
architecture: x64
# self install testing needs some clarity
# so its being executed without any other tools running
- - run: pip install -U setuptools jaraco.windows
+ - run: pip install -U setuptools
- run: python setup.py egg_info
- run: python setup.py sdist
- run: easy_install dist/*
@@ -93,7 +91,7 @@ jobs:
- name: Install dependencies
run: |
python -m pip install --upgrade pip
- pip install --upgrade wheel setuptools jaraco.windows
+ pip install --upgrade wheel setuptools
- run: python setup.py egg_info
- name: Build package
run: python setup.py bdist_egg
@@ -115,7 +113,7 @@ jobs:
- name: Install dependencies
run: |
python -m pip install --upgrade pip
- pip install --upgrade wheel setuptools jaraco.windows
+ pip install --upgrade wheel setuptools
- run: python setup.py egg_info
- name: Build package
run: python setup.py bdist_wheel sdist
diff --git a/setup.cfg b/setup.cfg
index b079bd8..c8f46a1 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -32,7 +32,6 @@ zip_safe = true
python_requires= >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*
install_requires=
setuptools
- jaraco.windows; python_version=="2.7"
packages=find:
package_dir=
=src
diff --git a/src/setuptools_scm/git.py b/src/setuptools_scm/git.py
index b717584..76be436 100644
--- a/src/setuptools_scm/git.py
+++ b/src/setuptools_scm/git.py
@@ -6,7 +6,10 @@ from os.path import isfile, join
import warnings
-from os.path import samefile
+try:
+ from os.path import samefile
+except ImportError:
+ from .win_py31_compat import samefile
DEFAULT_DESCRIBE = "git describe --dirty --tags --long --match *[0-9]*"
diff --git a/src/setuptools_scm/win_py31_compat.py b/src/setuptools_scm/win_py31_compat.py
new file mode 100644
index 0000000..82a11eb
--- /dev/null
+++ b/src/setuptools_scm/win_py31_compat.py
@@ -0,0 +1,214 @@
+"""
+Backport of os.path.samefile for Python prior to 3.2
+on Windows from jaraco.windows 3.8.
+
+DON'T EDIT THIS FILE!
+
+Instead, file tickets and PR's with `jaraco.windows
+<https://github.com/jaraco/jaraco.windows>`_ and request
+a port to setuptools_scm.
+"""
+
+import os
+import nt
+import posixpath
+import ctypes.wintypes
+import sys
+import __builtin__ as builtins
+
+
+##
+# From jaraco.windows.error
+
+def format_system_message(errno):
+ """
+ Call FormatMessage with a system error number to retrieve
+ the descriptive error message.
+ """
+ # first some flags used by FormatMessageW
+ ALLOCATE_BUFFER = 0x100
+ FROM_SYSTEM = 0x1000
+
+ # Let FormatMessageW allocate the buffer (we'll free it below)
+ # Also, let it know we want a system error message.
+ flags = ALLOCATE_BUFFER | FROM_SYSTEM
+ source = None
+ message_id = errno
+ language_id = 0
+ result_buffer = ctypes.wintypes.LPWSTR()
+ buffer_size = 0
+ arguments = None
+ bytes = ctypes.windll.kernel32.FormatMessageW(
+ flags,
+ source,
+ message_id,
+ language_id,
+ ctypes.byref(result_buffer),
+ buffer_size,
+ arguments,
+ )
+ # note the following will cause an infinite loop if GetLastError
+ # repeatedly returns an error that cannot be formatted, although
+ # this should not happen.
+ handle_nonzero_success(bytes)
+ message = result_buffer.value
+ ctypes.windll.kernel32.LocalFree(result_buffer)
+ return message
+
+
+class WindowsError(builtins.WindowsError):
+ """
+ More info about errors at
+ http://msdn.microsoft.com/en-us/library/ms681381(VS.85).aspx
+ """
+
+ def __init__(self, value=None):
+ if value is None:
+ value = ctypes.windll.kernel32.GetLastError()
+ strerror = format_system_message(value)
+ if sys.version_info > (3, 3):
+ args = 0, strerror, None, value
+ else:
+ args = value, strerror
+ super(WindowsError, self).__init__(*args)
+
+ @property
+ def message(self):
+ return self.strerror
+
+ @property
+ def code(self):
+ return self.winerror
+
+ def __str__(self):
+ return self.message
+
+ def __repr__(self):
+ return '{self.__class__.__name__}({self.winerror})'.format(**vars())
+
+
+def handle_nonzero_success(result):
+ if result == 0:
+ raise WindowsError()
+
+
+##
+# From jaraco.windows.api.filesystem
+
+FILE_FLAG_OPEN_REPARSE_POINT = 0x00200000
+FILE_FLAG_BACKUP_SEMANTICS = 0x2000000
+OPEN_EXISTING = 3
+FILE_ATTRIBUTE_NORMAL = 0x80
+FILE_READ_ATTRIBUTES = 0x80
+INVALID_HANDLE_VALUE = ctypes.wintypes.HANDLE(-1).value
+
+
+class BY_HANDLE_FILE_INFORMATION(ctypes.Structure):
+ _fields_ = [
+ ('file_attributes', ctypes.wintypes.DWORD),
+ ('creation_time', ctypes.wintypes.FILETIME),
+ ('last_access_time', ctypes.wintypes.FILETIME),
+ ('last_write_time', ctypes.wintypes.FILETIME),
+ ('volume_serial_number', ctypes.wintypes.DWORD),
+ ('file_size_high', ctypes.wintypes.DWORD),
+ ('file_size_low', ctypes.wintypes.DWORD),
+ ('number_of_links', ctypes.wintypes.DWORD),
+ ('file_index_high', ctypes.wintypes.DWORD),
+ ('file_index_low', ctypes.wintypes.DWORD),
+ ]
+
+ @property
+ def file_size(self):
+ return (self.file_size_high << 32) + self.file_size_low
+
+ @property
+ def file_index(self):
+ return (self.file_index_high << 32) + self.file_index_low
+
+
+class SECURITY_ATTRIBUTES(ctypes.Structure):
+ _fields_ = (
+ ('length', ctypes.wintypes.DWORD),
+ ('p_security_descriptor', ctypes.wintypes.LPVOID),
+ ('inherit_handle', ctypes.wintypes.BOOLEAN),
+ )
+
+
+LPSECURITY_ATTRIBUTES = ctypes.POINTER(SECURITY_ATTRIBUTES)
+
+
+CreateFile = ctypes.windll.kernel32.CreateFileW
+CreateFile.argtypes = (
+ ctypes.wintypes.LPWSTR,
+ ctypes.wintypes.DWORD,
+ ctypes.wintypes.DWORD,
+ LPSECURITY_ATTRIBUTES,
+ ctypes.wintypes.DWORD,
+ ctypes.wintypes.DWORD,
+ ctypes.wintypes.HANDLE,
+)
+CreateFile.restype = ctypes.wintypes.HANDLE
+
+GetFileInformationByHandle = ctypes.windll.kernel32.GetFileInformationByHandle
+GetFileInformationByHandle.restype = ctypes.wintypes.BOOL
+GetFileInformationByHandle.argtypes = (
+ ctypes.wintypes.HANDLE,
+ ctypes.POINTER(BY_HANDLE_FILE_INFORMATION),
+)
+
+
+##
+# From jaraco.windows.filesystem
+
+def compat_stat(path):
+ """
+ Generate stat as found on Python 3.2 and later.
+ """
+ stat = os.stat(path)
+ info = get_file_info(path)
+ # rewrite st_ino, st_dev, and st_nlink based on file info
+ return nt.stat_result(
+ (stat.st_mode,) +
+ (info.file_index, info.volume_serial_number, info.number_of_links) +
+ stat[4:]
+ )
+
+
+def samefile(f1, f2):
+ """
+ Backport of samefile from Python 3.2 with support for Windows.
+ """
+ return posixpath.samestat(compat_stat(f1), compat_stat(f2))
+
+
+def get_file_info(path):
+ # open the file the same way CPython does in posixmodule.c
+ desired_access = FILE_READ_ATTRIBUTES
+ share_mode = 0
+ security_attributes = None
+ creation_disposition = OPEN_EXISTING
+ flags_and_attributes = (
+ FILE_ATTRIBUTE_NORMAL |
+ FILE_FLAG_BACKUP_SEMANTICS |
+ FILE_FLAG_OPEN_REPARSE_POINT
+ )
+ template_file = None
+
+ handle = CreateFile(
+ path,
+ desired_access,
+ share_mode,
+ security_attributes,
+ creation_disposition,
+ flags_and_attributes,
+ template_file,
+ )
+
+ if handle == INVALID_HANDLE_VALUE:
+ raise WindowsError()
+
+ info = BY_HANDLE_FILE_INFORMATION()
+ res = GetFileInformationByHandle(handle, info)
+ handle_nonzero_success(res)
+
+ return info
diff --git a/testing/test_file_finder.py b/testing/test_file_finder.py
index a6e3d70..463d3d4 100644
--- a/testing/test_file_finder.py
+++ b/testing/test_file_finder.py
@@ -9,6 +9,8 @@ from setuptools_scm.integration import find_files
@pytest.fixture(params=["git", "hg"])
def inwd(request, wd, monkeypatch):
if request.param == "git":
+ if sys.platform == "win32" and sys.version_info[0] < 3:
+ pytest.skip("Long/short path names supported on Windows Python 2.7")
try:
wd("git init")
except OSError:
diff --git a/testing/test_git.py b/testing/test_git.py
index e485fc7..e92d19a 100644
--- a/testing/test_git.py
+++ b/testing/test_git.py
@@ -10,6 +10,12 @@ from setuptools_scm.file_finder_git import git_find_files
import warnings
+skip_if_win_27 = pytest.mark.skipif(
+ sys.platform == "win32" and sys.version_info[0] < 3,
+ reason="Not supported on Windows + Python 2.7",
+)
+
+
with warnings.catch_warnings():
warnings.filterwarnings("ignore")
if not has_command("git"):
@@ -186,6 +192,7 @@ def test_alphanumeric_tags_match(wd):
assert wd.version.startswith("0.1.dev1+g")
+@skip_if_win_27
def test_git_archive_export_ignore(wd, monkeypatch):
wd.write("test1.txt", "test")
wd.write("test2.txt", "test")
@@ -201,6 +208,7 @@ def test_git_archive_export_ignore(wd, monkeypatch):
assert integration.find_files(".") == [opj(".", "test1.txt")]
+@skip_if_win_27
@pytest.mark.issue(228)
def test_git_archive_subdirectory(wd, monkeypatch):
wd("mkdir foobar")
@@ -211,6 +219,7 @@ def test_git_archive_subdirectory(wd, monkeypatch):
assert integration.find_files(".") == [opj(".", "foobar", "test1.txt")]
+@skip_if_win_27
@pytest.mark.issue(251)
def test_git_archive_run_from_subdirectory(wd, monkeypatch):
wd("mkdir foobar")