From 6a9d9e45f90703ad3b7eb2e6f9c7a2e5c2be18b1 Mon Sep 17 00:00:00 2001 From: Avasam Date: Sun, 22 Dec 2024 21:23:31 -0500 Subject: [PATCH] adodbapi: Drop Python 3.8 support (#2430) --- .github/workflows/main.yml | 5 +-- adodbapi/adodbapi.py | 2 +- adodbapi/apibase.py | 3 +- adodbapi/test/adodbapitest.py | 60 +++-------------------------------- adodbapi/test/dbapi20.py | 12 ++----- pyrightconfig.json | 2 +- 6 files changed, 13 insertions(+), 71 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index ee088ea638..a335225c22 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -126,7 +126,8 @@ jobs: with: version: "0.4.9" args: "format --check" - - run: | # Too many files to fit in a single command, also exclude vendored Scintilla and MAPIStubLibrary + - run: + | # Too many files to fit in a single command, also exclude vendored Scintilla and MAPIStubLibrary clang-format --Werror --dry-run $(git ls-files '*.cpp' ':!:com/win32comext/mapi/src/MAPIStubLibrary/') if ($LastExitCode -ne 0) { exit $LastExitCode } clang-format --Werror --dry-run $(git ls-files '*.h' ':!:Pythonwin/Scintilla/' ':!:com/win32comext/mapi/src/MAPIStubLibrary/') @@ -156,7 +157,7 @@ jobs: strategy: fail-fast: false matrix: - python-version: ["3.8", "3.9", "3.10", "3.11", "3.12", "3.13"] + python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"] steps: - uses: actions/checkout@v4 - uses: actions/setup-python@v5 diff --git a/adodbapi/adodbapi.py b/adodbapi/adodbapi.py index 19adbfb30c..80ffdee36b 100644 --- a/adodbapi/adodbapi.py +++ b/adodbapi/adodbapi.py @@ -234,7 +234,7 @@ def __init__(self): # now define the instance attributes self.paramstyle = api.paramstyle self.supportsTransactions = False self.connection_string = "" - self.cursors = weakref.WeakValueDictionary() + self.cursors = weakref.WeakValueDictionary[int, Cursor]() self.dbms_name = "" self.dbms_version = "" self.errorhandler = None # use the standard error handler for this instance diff --git a/adodbapi/apibase.py b/adodbapi/apibase.py index 749c378d38..0c09ef98e0 100644 --- a/adodbapi/apibase.py +++ b/adodbapi/apibase.py @@ -13,7 +13,6 @@ import sys import time from collections.abc import Callable, Iterable, Mapping -from typing import Dict # noinspection PyUnresolvedReferences from . import ado_consts as adc @@ -465,7 +464,7 @@ def convert_to_python(variant, func): # convert DB value into Python value return func(variant) # call the appropriate conversion function -class MultiMap(Dict[int, Callable[[object], object]]): +class MultiMap(dict[int, Callable[[object], object]]): # builds a dictionary from {(iterable,of,keys) : function} """A dictionary of ado.type : function -- but you can set multiple items by passing an iterable of keys""" diff --git a/adodbapi/test/adodbapitest.py b/adodbapi/test/adodbapitest.py index 88dab12671..6cd9abf488 100644 --- a/adodbapi/test/adodbapitest.py +++ b/adodbapi/test/adodbapitest.py @@ -27,7 +27,6 @@ import decimal import random import string -import sys import time import unittest @@ -37,14 +36,6 @@ import adodbapi import adodbapi.apibase as api -try: - import adodbapi.ado_consts as ado_consts -except ImportError: # we are doing a shortcut import as a module -- so - try: - import ado_consts - except ImportError: - from adodbapi import ado_consts - def randomstring(length): return "".join([random.choice(string.ascii_letters) for n in range(32)]) @@ -188,49 +179,6 @@ def testUserDefinedConversions(self): pass self.helpRollbackTblTemp() - def testUserDefinedConversionForExactNumericTypes(self): - # variantConversions is a dictionary of conversion functions - # held internally in adodbapi.apibase - # - # !!! this test intentionally alters the value of what should be constant in the module - # !!! no new code should use this example, to is only a test to see that the - # !!! deprecated way of doing this still works. (use connection.variantConversions) - # - if sys.version_info < (3, 0): ### Py3 need different test - oldconverter = adodbapi.variantConversions[ - ado_consts.adNumeric - ] # keep old function to restore later - # By default decimal and "numbers" are returned as decimals. - # Instead, make numbers return as floats - try: - adodbapi.variantConversions[ado_consts.adNumeric] = adodbapi.cvtFloat - self.helpTestDataType( - "decimal(18,2)", "NUMBER", 3.45, compareAlmostEqual=1 - ) - self.helpTestDataType( - "numeric(18,2)", "NUMBER", 3.45, compareAlmostEqual=1 - ) - # now return strings - adodbapi.variantConversions[ado_consts.adNumeric] = adodbapi.cvtString - self.helpTestDataType("numeric(18,2)", "NUMBER", "3.45") - # now a completely weird user defined conversion - adodbapi.variantConversions[ado_consts.adNumeric] = ( - lambda x: "!!This function returns a funny unicode string %s!!" % x - ) - self.helpTestDataType( - "numeric(18,2)", - "NUMBER", - "3.45", - allowedReturnValues=[ - "!!This function returns a funny unicode string 3.45!!" - ], - ) - finally: - # now reset the converter to its original function - adodbapi.variantConversions[ado_consts.adNumeric] = ( - oldconverter # Restore the original conversion function - ) - def helpTestDataType( self, sqlDataTypeString, @@ -432,7 +380,7 @@ def testDataTypeInt(self): "bigint", "NUMBER", 3000000000, - allowedReturnValues=[3000000000, int(3000000000)], + allowedReturnValues=[3000000000, 3000000000], ) self.helpTestDataType("int", "NUMBER", 2147483647) @@ -1136,7 +1084,7 @@ def getConnection(self): return self.conn def getAnotherConnection(self, addkeys=None): - keys = dict(config.connStrSQLServer[1]) + keys = config.connStrSQLServer[1].copy() if addkeys: keys.update(addkeys) return config.dbSqlServerconnect(*config.connStrSQLServer[0], **keys) @@ -1316,7 +1264,7 @@ def getConnection(self): return self.conn def getAnotherConnection(self, addkeys=None): - keys = dict(config.connStrMySql[1]) + keys = config.connStrMySql[1].copy() if addkeys: keys.update(addkeys) return config.dbMySqlconnect(*config.connStrMySql[0], **keys) @@ -1382,7 +1330,7 @@ def getConnection(self): return self.conn def getAnotherConnection(self, addkeys=None): - keys = dict(config.connStrPostgres[1]) + keys = config.connStrPostgres[1].copy() if addkeys: keys.update(addkeys) return config.dbPostgresConnect(*config.connStrPostgres[0], **keys) diff --git a/adodbapi/test/dbapi20.py b/adodbapi/test/dbapi20.py index ea920d42b2..fa0c7063c3 100644 --- a/adodbapi/test/dbapi20.py +++ b/adodbapi/test/dbapi20.py @@ -14,7 +14,6 @@ __version__ = "$Revision: 1.15.0 $"[11:-2] __author__ = "Stuart Bishop " -import sys import time import unittest @@ -197,14 +196,9 @@ def test_paramstyle(self): self.fail("Driver doesn't define paramstyle") def test_Exceptions(self): - # Make sure required exceptions exist, and are in the - # defined hierarchy. - if sys.version[0] == "3": # under Python 3 StardardError no longer exists - self.assertTrue(issubclass(self.driver.Warning, Exception)) - self.assertTrue(issubclass(self.driver.Error, Exception)) - else: - self.failUnless(issubclass(self.driver.Warning, Exception)) - self.failUnless(issubclass(self.driver.Error, Exception)) + # Make sure required exceptions exist, and are in the defined hierarchy. + self.assertTrue(issubclass(self.driver.Warning, Exception)) + self.assertTrue(issubclass(self.driver.Error, Exception)) self.assertTrue(issubclass(self.driver.InterfaceError, self.driver.Error)) self.assertTrue(issubclass(self.driver.DatabaseError, self.driver.Error)) diff --git a/pyrightconfig.json b/pyrightconfig.json index c35e4a565b..6b631cdfeb 100644 --- a/pyrightconfig.json +++ b/pyrightconfig.json @@ -1,7 +1,7 @@ { "typeCheckingMode": "basic", // Target the oldest supported version in editors and default CLI - "pythonVersion": "3.8", + "pythonVersion": "3.9", // Keep it simple for now by allowing both mypy and pyright to use `type: ignore` "enableTypeIgnoreComments": true, // Exclude from scanning when running pyright