Skip to content

Commit f875072

Browse files
authored
RELEASE: v1.1.0 (#382)
### Work Item / Issue Reference <!-- IMPORTANT: Please follow the PR template guidelines below. For mssql-python maintainers: Insert your ADO Work Item ID below (e.g. AB#37452) For external contributors: Insert Github Issue number below (e.g. #149) Only one reference is required - either GitHub issue OR ADO Work Item. --> <!-- mssql-python maintainers: ADO Work Item --> > [AB#41191](https://sqlclientdrivers.visualstudio.com/c6d89619-62de-46a0-8b46-70b92a84d85e/_workitems/edit/41191) <!-- External contributors: GitHub Issue --> > GitHub Issue: #<ISSUE_NUMBER> ------------------------------------------------------------------- ### Summary This pull request updates the `mssql-python` package to version 1.1.0, introducing several critical bug fixes, enhancements, and improvements to platform-specific packaging and metadata. The update also removes unused global connection cleanup logic from the package initialization. Below are the most important changes: ## Major Enhancements and Bug Fixes - **Critical Stability and Security Fixes:** - Introduced thread-safe encoding/decoding with mutex-based protection and strict validation for SQL_WCHAR types. - Fixed a critical double-free issue on Linux, improved UTF-16 string decoding, ensured connection pooling isolation resets, corrected connection string escaping, improved NULL parameter array handling, ensured consistent query timeout, fixed IntegrityError detection, and improved sensitive parameter filtering. - **Documentation Update:** - Updated the `PyPI_Description.md` to reflect new features, enhancements, and bug fixes for version 1.1.0. ## Package Initialization and Versioning - **Version Bump:** - Updated the package version from `1.0.0` to `1.1.0` in both `mssql_python/__init__.py` and `setup.py`. - **Removed Connection Cleanup Logic:** - Eliminated global weakref-based connection tracking and atexit cleanup logic from `mssql_python/__init__.py`, as it is no longer needed. ## Packaging and Distribution Improvements - **Platform-Specific Packaging:** - Refactored `setup.py` to use consistent double quotes, improved architecture and platform tag detection, and expanded logic for adding platform-specific package data for Windows, macOS, and Linux. - **Metadata Consistency:** - Updated all metadata fields (e.g., author, description, classifiers) and ensured consistent formatting and requirements in `setup.py`. These changes collectively improve package stability, security, and cross-platform compatibility, while also ensuring accurate documentation and streamlined packaging.
1 parent 0db1ec9 commit f875072

File tree

3 files changed

+95
-64
lines changed

3 files changed

+95
-64
lines changed

PyPI_Description.md

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,29 @@ PyBind11 provides:
3535
- Memory-safe bindings
3636
- Clean and Pythonic API, while performance-critical logic remains in robust, maintainable C++.
3737

38-
## What's new in v1.0.0
38+
## What's new in v1.1.0
3939

40-
### New Features
40+
### Enhancements
4141

42-
- *Python 3.14 support* - ensuring compatibility with the latest Python ecosystem.
43-
- *GA stability* - hardened release engineering, expanded test coverage, and compliance checks for enterprise readiness.
42+
- **Thread-Safe Encoding/Decoding** - Mutex-based lock protection prevents race conditions in multi-threaded applications with concurrent connections. Strict validation for SQL_WCHAR types and security measures against encoding-based attacks ensure data integrity and application security.
43+
44+
### Critical Bug Fixes
45+
46+
- **Linux Stability** - Fixed critical double-free issue causing segmentation faults during Python garbage collection, significantly improving stability on Linux platforms.
47+
48+
- **Connection Pooling Isolation Level** - Transaction isolation level now explicitly resets to READ COMMITTED when pooled connections are reused, preventing unexpected transaction behavior and isolation level conflicts.
49+
50+
- **Connection String Escaping** - Fixed parser and builder to correctly handle ODBC curly brace escaping rules, enabling proper handling of special characters in passwords and connection values.
51+
52+
- **UTF-16 String Decoding** - Enhanced `connection.getinfo()` to properly decode UTF-16LE strings from SQL Server, eliminating data corruption when retrieving metadata with non-ASCII characters.
53+
54+
- **NULL Parameter Arrays** - Added support for arrays containing only NULL values in `executemany()`, improving batch operation reliability.
55+
56+
- **Query Timeout Consistency** - Refactored timeout handling to set query timeout during cursor initialization, reducing overhead and ensuring consistent timeout application.
57+
58+
- **IntegrityError Detection** - Fixed error handling in `fetchall()` for INSERT statements with OUTPUT clause and multiple VALUES entries.
59+
60+
- **Sensitive Parameter Filtering** - Corrected authentication parameter filtering to properly exclude Trusted_Connection while preserving encryption settings.
4461

4562
For more information, please visit the project link on Github: https://github.com/microsoft/mssql-python
4663

mssql_python/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
from .helpers import Settings, get_settings, _settings, _settings_lock
1616

1717
# Driver version
18-
__version__ = "1.0.0"
18+
__version__ = "1.1.0"
1919

2020
# Exceptions
2121
# https://www.python.org/dev/peps/pep-0249/#exceptions

setup.py

Lines changed: 73 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -4,60 +4,67 @@
44
from setuptools.dist import Distribution
55
from wheel.bdist_wheel import bdist_wheel
66

7+
78
# Custom distribution to force platform-specific wheel
89
class BinaryDistribution(Distribution):
910
def has_ext_modules(self):
1011
return True
1112

13+
1214
def get_platform_info():
1315
"""Get platform-specific architecture and platform tag information."""
14-
if sys.platform.startswith('win'):
16+
if sys.platform.startswith("win"):
1517
# Get architecture from environment variable or default to x64
16-
arch = os.environ.get('ARCHITECTURE', 'x64')
18+
arch = os.environ.get("ARCHITECTURE", "x64")
1719
# Strip quotes if present
1820
if isinstance(arch, str):
19-
arch = arch.strip('"\'')
21+
arch = arch.strip("\"'")
2022

2123
# Normalize architecture values
22-
if arch in ['x86', 'win32']:
23-
return 'x86', 'win32'
24-
elif arch == 'arm64':
25-
return 'arm64', 'win_arm64'
24+
if arch in ["x86", "win32"]:
25+
return "x86", "win32"
26+
elif arch == "arm64":
27+
return "arm64", "win_arm64"
2628
else: # Default to x64/amd64
27-
return 'x64', 'win_amd64'
28-
29-
elif sys.platform.startswith('darwin'):
29+
return "x64", "win_amd64"
30+
31+
elif sys.platform.startswith("darwin"):
3032
# macOS platform - always use universal2
31-
return 'universal2', 'macosx_15_0_universal2'
32-
33-
elif sys.platform.startswith('linux'):
33+
return "universal2", "macosx_15_0_universal2"
34+
35+
elif sys.platform.startswith("linux"):
3436
# Linux platform - use musllinux or manylinux tags based on architecture
3537
# Get target architecture from environment variable or default to platform machine type
3638
import platform
37-
target_arch = os.environ.get('targetArch', platform.machine())
39+
40+
target_arch = os.environ.get("targetArch", platform.machine())
3841

3942
# Detect libc type
4043
libc_name, _ = platform.libc_ver()
41-
is_musl = libc_name == '' or 'musl' in libc_name.lower()
42-
43-
if target_arch == 'x86_64':
44-
return 'x86_64', 'musllinux_1_2_x86_64' if is_musl else 'manylinux_2_28_x86_64'
45-
elif target_arch in ['aarch64', 'arm64']:
46-
return 'aarch64', 'musllinux_1_2_aarch64' if is_musl else 'manylinux_2_28_aarch64'
44+
is_musl = libc_name == "" or "musl" in libc_name.lower()
45+
46+
if target_arch == "x86_64":
47+
return "x86_64", "musllinux_1_2_x86_64" if is_musl else "manylinux_2_28_x86_64"
48+
elif target_arch in ["aarch64", "arm64"]:
49+
return "aarch64", "musllinux_1_2_aarch64" if is_musl else "manylinux_2_28_aarch64"
4750
else:
48-
raise OSError(f"Unsupported architecture '{target_arch}' for Linux; expected 'x86_64' or 'aarch64'.")
51+
raise OSError(
52+
f"Unsupported architecture '{target_arch}' for Linux; expected 'x86_64' or 'aarch64'."
53+
)
54+
4955

5056
# Custom bdist_wheel command to override platform tag
5157
class CustomBdistWheel(bdist_wheel):
5258
def finalize_options(self):
5359
# Call the original finalize_options first to initialize self.bdist_dir
5460
bdist_wheel.finalize_options(self)
55-
61+
5662
# Get platform info using consolidated function
5763
arch, platform_tag = get_platform_info()
5864
self.plat_name = platform_tag
5965
print(f"Setting wheel platform tag to: {self.plat_name} (arch: {arch})")
6066

67+
6168
# Find all packages in the current directory
6269
packages = find_packages()
6370

@@ -66,64 +73,71 @@ def finalize_options(self):
6673
print(f"Detected architecture: {arch} (platform tag: {platform_tag})")
6774

6875
# Add platform-specific packages
69-
if sys.platform.startswith('win'):
70-
packages.extend([
71-
f'mssql_python.libs.windows.{arch}',
72-
f'mssql_python.libs.windows.{arch}.1033',
73-
f'mssql_python.libs.windows.{arch}.vcredist'
74-
])
75-
elif sys.platform.startswith('darwin'):
76-
packages.extend([
77-
f'mssql_python.libs.macos',
78-
])
79-
elif sys.platform.startswith('linux'):
80-
packages.extend([
81-
f'mssql_python.libs.linux',
82-
])
76+
if sys.platform.startswith("win"):
77+
packages.extend(
78+
[
79+
f"mssql_python.libs.windows.{arch}",
80+
f"mssql_python.libs.windows.{arch}.1033",
81+
f"mssql_python.libs.windows.{arch}.vcredist",
82+
]
83+
)
84+
elif sys.platform.startswith("darwin"):
85+
packages.extend(
86+
[
87+
f"mssql_python.libs.macos",
88+
]
89+
)
90+
elif sys.platform.startswith("linux"):
91+
packages.extend(
92+
[
93+
f"mssql_python.libs.linux",
94+
]
95+
)
8396

8497
setup(
85-
name='mssql-python',
86-
version='1.0.0',
87-
description='A Python library for interacting with Microsoft SQL Server',
88-
long_description=open('PyPI_Description.md', encoding='utf-8').read(),
89-
long_description_content_type='text/markdown',
90-
author='Microsoft Corporation',
91-
author_email='[email protected]',
92-
url='https://github.com/microsoft/mssql-python',
98+
name="mssql-python",
99+
version="1.1.0",
100+
description="A Python library for interacting with Microsoft SQL Server",
101+
long_description=open("PyPI_Description.md", encoding="utf-8").read(),
102+
long_description_content_type="text/markdown",
103+
author="Microsoft Corporation",
104+
author_email="[email protected]",
105+
url="https://github.com/microsoft/mssql-python",
93106
packages=packages,
94107
package_data={
95108
# Include PYD and DLL files inside mssql_python, exclude YML files
96-
'mssql_python': [
97-
'ddbc_bindings.cp*.pyd', # Include all PYD files
98-
'ddbc_bindings.cp*.so', # Include all SO files
99-
'libs/*',
100-
'libs/**/*',
101-
'*.dll'
109+
"mssql_python": [
110+
"ddbc_bindings.cp*.pyd", # Include all PYD files
111+
"ddbc_bindings.cp*.so", # Include all SO files
112+
"libs/*",
113+
"libs/**/*",
114+
"*.dll",
102115
]
103116
},
104117
include_package_data=True,
105118
# Requires >= Python 3.10
106-
python_requires='>=3.10',
119+
python_requires=">=3.10",
107120
# Add dependencies
108121
install_requires=[
109-
'azure-identity>=1.12.0', # Azure authentication library
122+
"azure-identity>=1.12.0", # Azure authentication library
110123
],
111124
classifiers=[
112-
'Operating System :: Microsoft :: Windows',
113-
'Operating System :: MacOS',
114-
'Operating System :: POSIX :: Linux',
125+
"Operating System :: Microsoft :: Windows",
126+
"Operating System :: MacOS",
127+
"Operating System :: POSIX :: Linux",
115128
],
116129
zip_safe=False,
117130
# Force binary distribution
118131
distclass=BinaryDistribution,
119132
exclude_package_data={
120-
'': ['*.yml', '*.yaml'], # Exclude YML files
121-
'mssql_python': [
122-
'libs/*/vcredist/*', 'libs/*/vcredist/**/*', # Exclude vcredist directories, added here since `'libs/*' is already included`
133+
"": ["*.yml", "*.yaml"], # Exclude YML files
134+
"mssql_python": [
135+
"libs/*/vcredist/*",
136+
"libs/*/vcredist/**/*", # Exclude vcredist directories, added here since `'libs/*' is already included`
123137
],
124138
},
125139
# Register custom commands
126140
cmdclass={
127-
'bdist_wheel': CustomBdistWheel,
141+
"bdist_wheel": CustomBdistWheel,
128142
},
129143
)

0 commit comments

Comments
 (0)