Skip to content

Commit

Permalink
Update supported Python versions (#174)
Browse files Browse the repository at this point in the history
* Update supported versions to reflect current state
* Update tests to use Python 3.12
* Update to newer instance type for testing
* Don't use editable installation
* Add setuptools to test requirements
* Make version conformant with PEP-0440
* Split test_invalid_parameters into individual tests
* Uninstall pytds as part of test run, since it is installed by dependency on sqlalchemy-pytds
* Add src to PYTHONPATH
* Disable NTLM tests when running on Python version which does not support MD4
* Disable test for recordtype row strategy when Python version does not define collection.Mapping class, which is deprecated
  • Loading branch information
denisenkom authored Oct 2, 2024
1 parent 8085713 commit 18e6427
Show file tree
Hide file tree
Showing 8 changed files with 66 additions and 26 deletions.
20 changes: 9 additions & 11 deletions appveyor.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
version: 1.0.{build}

os: Windows Server 2012 R2
os: Visual Studio 2019

environment:
INAPPVEYOR: 1
Expand All @@ -9,23 +9,20 @@ environment:
SQLPASSWORD: Password12!
DATABASE: test
matrix:
- PYTHON: "C:\\Python38"
SQLINSTANCE: SQL2016
- PYTHON: "C:\\Python312"
SQLINSTANCE: SQL2019
- PYTHON: "C:\\Python312-x64"
SQLINSTANCE: SQL2019
- PYTHON: "C:\\Python38-x64"
SQLINSTANCE: SQL2016
- PYTHON: "C:\\Python38-x64"
SQLINSTANCE: SQL2014
- PYTHON: "C:\\Python38-x64"
SQLINSTANCE: SQL2012SP1
- PYTHON: "C:\\Python38-x64"
SQLINSTANCE: SQL2008R2SP2
SQLINSTANCE: SQL2017

install:
- "SET PATH=%PYTHON%;%PYTHON%\\Scripts;%PATH%"
- python --version
- "python -c \"import struct; print(struct.calcsize('P') * 8)\""
- pip install -e .
- pip install -r requirements.txt
- pip install -r test_requirements.txt
- pip uninstall -y python-tds

build_script:
- python setup.py sdist
Expand All @@ -43,6 +40,7 @@ before_test:
test_script:
- mypy src
- ruff check src
- set PYTHONPATH=src
- pytest -v --junitxml=junit-results.xml --cov=./
- ps: |
$wc = New-Object 'System.Net.WebClient'
Expand Down
9 changes: 5 additions & 4 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,11 @@
classifiers=[
"Development Status :: 4 - Beta",
"Programming Language :: Python",
"Programming Language :: Python :: 2.7",
"Programming Language :: Python :: 3.3",
"Programming Language :: Python :: 3.4",
"Programming Language :: Python :: 3.5",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
],
zip_safe=True,
install_requires=requirements,
Expand Down
3 changes: 2 additions & 1 deletion test_requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,5 @@ sqlalchemy-pytds
SQLAlchemy==2.0.34
mypy==1.7.1
pytest-mypy==0.10.3
ruff==0.6.3
ruff==0.6.3
setuptools==75.1.0
25 changes: 21 additions & 4 deletions tests/all_test.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# vim: set fileencoding=utf8 :
from __future__ import with_statement
from __future__ import unicode_literals
import collections
import os
import random
import string
Expand Down Expand Up @@ -211,7 +212,7 @@ def test_connection_timeout_no_mars():


@unittest.skipUnless(LIVE_TEST, "requires HOST variable to be set")
def test_row_strategies():
def test_list_row_strategy():
kwargs = settings.CONNECT_KWARGS.copy()
kwargs.update(
{
Expand All @@ -222,17 +223,29 @@ def test_row_strategies():
with conn.cursor() as cur:
cur.execute("select 1")
assert cur.fetchall() == [[1]]


@unittest.skipUnless(LIVE_TEST, "requires HOST variable to be set")
def test_namedtuple_row_strategy():
kwargs = settings.CONNECT_KWARGS.copy()
kwargs.update(
{
"row_strategy": pytds.namedtuple_row_strategy,
}
)
import collections

with connect(**kwargs) as conn:
with conn.cursor() as cur:
cur.execute("select 1 as f")
assert cur.fetchall() == [collections.namedtuple("Row", ["f"])(1)]


@unittest.skipUnless(LIVE_TEST, "requires HOST variable to be set")
@pytest.mark.skipif(
not hasattr(collections, "Mapping"),
reason="Skip this test if current version of Python does not define Mapping class"
)
def test_recordtype_row_strategy():
kwargs = settings.CONNECT_KWARGS.copy()
kwargs.update(
{
"row_strategy": pytds.recordtype_row_strategy,
Expand Down Expand Up @@ -308,7 +321,7 @@ def test_new_datetime(self):

@unittest.skipUnless(LIVE_TEST, "requires HOST variable to be set")
class BadConnection(unittest.TestCase):
def test_invalid_parameters(self):
def test_bad_host(self):
with self.assertRaises(socket.gaierror):
with connect(
server="badhost",
Expand All @@ -319,6 +332,8 @@ def test_invalid_parameters(self):
) as conn:
with conn.cursor() as cur:
cur.execute("select 1")

def test_bad_database(self):
with self.assertRaises(Error):
with connect(
server=settings.HOST,
Expand All @@ -328,6 +343,8 @@ def test_invalid_parameters(self):
) as conn:
with conn.cursor() as cur:
cur.execute("select 1")

def test_bad_user(self):
with self.assertRaises(Error):
with connect(
server=settings.HOST, database="master", user="baduser", password=None
Expand Down
4 changes: 4 additions & 0 deletions tests/connected_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -577,6 +577,10 @@ def test_cursor_connection_property(db_connection):
assert cur.connection is db_connection


@pytest.mark.skipif(
not utils.hashlib_supports_md4(),
reason="Current python version does not support MD4 which is needed for NTLM"
)
def test_invalid_ntlm_creds():
if not LIVE_TEST:
pytest.skip("LIVE_TEST is not set")
Expand Down
5 changes: 5 additions & 0 deletions tests/unit_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@
VarBinarySerializer72,
)
import pytds.login
import utils

tzoffset = pytds.tz.FixedOffsetTimezone
logger = logging.getLogger(__name__)
Expand Down Expand Up @@ -1536,6 +1537,10 @@ def test_cert_with_san(test_ca, server_key, address, root_ca_path):
pass


@pytest.mark.skipif(
not utils.hashlib_supports_md4(),
reason="Current python version does not support MD4 which is needed for NTLM"
)
def test_ntlm():
# test NTLM packet generation without actual server
auth = pytds.login.NtlmAuth(user_name="testuser", password="password")
Expand Down
10 changes: 10 additions & 0 deletions tests/utils.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import hashlib
import sys
import unittest
from io import BytesIO
Expand Down Expand Up @@ -197,3 +198,12 @@ def create_test_database(connection: pytds.Connection):

def tran_count(cursor: pytds.Cursor) -> int:
return cursor.execute_scalar("select @@trancount")


def hashlib_supports_md4() -> bool:
try:
hashlib.new('md4', b'test').digest()
except ValueError as e:
return False
else:
return True
16 changes: 10 additions & 6 deletions version.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,15 +36,16 @@
from subprocess import Popen, PIPE


def call_git_describe(abbrev=4):
def git_describe(abbrev=4):
try:
p = Popen(["git", "describe", "--abbrev=%d" % abbrev], stdout=PIPE, stderr=PIPE)
p = Popen(["git", "describe", "--long", "--abbrev=%d" % abbrev], stdout=PIPE, stderr=PIPE)
p.stderr.close()
line = p.stdout.readlines()[0]
return line.strip().decode("utf8")

version_str = line.strip().decode("utf8")
version, changes, commit_hash = version_str.split("-")
return version, int(changes), commit_hash
except:
return None
return None, None, None


def read_release_version():
Expand Down Expand Up @@ -75,7 +76,7 @@ def get_git_version(abbrev=4):

# First try to get the current version using “git describe”.

version = call_git_describe(abbrev)
version, changes, commit_hash = git_describe(abbrev)

# If that doesn't work, fall back on the value that's in
# RELEASE-VERSION.
Expand All @@ -88,6 +89,9 @@ def get_git_version(abbrev=4):
if version is None:
return "unknown"

if changes is not None and changes != 0:
version += f".dev{changes}"

# If the current version is different from what's in the
# RELEASE-VERSION file, update the file to be current.

Expand Down

0 comments on commit 18e6427

Please sign in to comment.