Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 21 additions & 4 deletions PyPI_Description.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,29 @@ PyBind11 provides:
- Memory-safe bindings
- Clean and Pythonic API, while performance-critical logic remains in robust, maintainable C++.

## What's new in v1.0.0
## What's new in v1.1.0

### New Features
### Enhancements

- *Python 3.14 support* - ensuring compatibility with the latest Python ecosystem.
- *GA stability* - hardened release engineering, expanded test coverage, and compliance checks for enterprise readiness.
- **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.

### Critical Bug Fixes

- **Linux Stability** - Fixed critical double-free issue causing segmentation faults during Python garbage collection, significantly improving stability on Linux platforms.

- **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.

- **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.

- **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.

- **NULL Parameter Arrays** - Added support for arrays containing only NULL values in `executemany()`, improving batch operation reliability.

- **Query Timeout Consistency** - Refactored timeout handling to set query timeout during cursor initialization, reducing overhead and ensuring consistent timeout application.

- **IntegrityError Detection** - Fixed error handling in `fetchall()` for INSERT statements with OUTPUT clause and multiple VALUES entries.

- **Sensitive Parameter Filtering** - Corrected authentication parameter filtering to properly exclude Trusted_Connection while preserving encryption settings.

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

Expand Down
2 changes: 1 addition & 1 deletion mssql_python/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
from .helpers import Settings, get_settings, _settings, _settings_lock

# Driver version
__version__ = "1.0.0"
__version__ = "1.1.0"

# Exceptions
# https://www.python.org/dev/peps/pep-0249/#exceptions
Expand Down
132 changes: 73 additions & 59 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,60 +4,67 @@
from setuptools.dist import Distribution
from wheel.bdist_wheel import bdist_wheel


# Custom distribution to force platform-specific wheel
class BinaryDistribution(Distribution):
def has_ext_modules(self):
return True


def get_platform_info():
"""Get platform-specific architecture and platform tag information."""
if sys.platform.startswith('win'):
if sys.platform.startswith("win"):
# Get architecture from environment variable or default to x64
arch = os.environ.get('ARCHITECTURE', 'x64')
arch = os.environ.get("ARCHITECTURE", "x64")
# Strip quotes if present
if isinstance(arch, str):
arch = arch.strip('"\'')
arch = arch.strip("\"'")

# Normalize architecture values
if arch in ['x86', 'win32']:
return 'x86', 'win32'
elif arch == 'arm64':
return 'arm64', 'win_arm64'
if arch in ["x86", "win32"]:
return "x86", "win32"
elif arch == "arm64":
return "arm64", "win_arm64"
else: # Default to x64/amd64
return 'x64', 'win_amd64'
elif sys.platform.startswith('darwin'):
return "x64", "win_amd64"

elif sys.platform.startswith("darwin"):
# macOS platform - always use universal2
return 'universal2', 'macosx_15_0_universal2'
elif sys.platform.startswith('linux'):
return "universal2", "macosx_15_0_universal2"

elif sys.platform.startswith("linux"):
# Linux platform - use musllinux or manylinux tags based on architecture
# Get target architecture from environment variable or default to platform machine type
import platform
target_arch = os.environ.get('targetArch', platform.machine())

target_arch = os.environ.get("targetArch", platform.machine())

# Detect libc type
libc_name, _ = platform.libc_ver()
is_musl = libc_name == '' or 'musl' in libc_name.lower()
if target_arch == 'x86_64':
return 'x86_64', 'musllinux_1_2_x86_64' if is_musl else 'manylinux_2_28_x86_64'
elif target_arch in ['aarch64', 'arm64']:
return 'aarch64', 'musllinux_1_2_aarch64' if is_musl else 'manylinux_2_28_aarch64'
is_musl = libc_name == "" or "musl" in libc_name.lower()

if target_arch == "x86_64":
return "x86_64", "musllinux_1_2_x86_64" if is_musl else "manylinux_2_28_x86_64"
elif target_arch in ["aarch64", "arm64"]:
return "aarch64", "musllinux_1_2_aarch64" if is_musl else "manylinux_2_28_aarch64"
else:
raise OSError(f"Unsupported architecture '{target_arch}' for Linux; expected 'x86_64' or 'aarch64'.")
raise OSError(
f"Unsupported architecture '{target_arch}' for Linux; expected 'x86_64' or 'aarch64'."
)


# Custom bdist_wheel command to override platform tag
class CustomBdistWheel(bdist_wheel):
def finalize_options(self):
# Call the original finalize_options first to initialize self.bdist_dir
bdist_wheel.finalize_options(self)

# Get platform info using consolidated function
arch, platform_tag = get_platform_info()
self.plat_name = platform_tag
print(f"Setting wheel platform tag to: {self.plat_name} (arch: {arch})")


# Find all packages in the current directory
packages = find_packages()

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

# Add platform-specific packages
if sys.platform.startswith('win'):
packages.extend([
f'mssql_python.libs.windows.{arch}',
f'mssql_python.libs.windows.{arch}.1033',
f'mssql_python.libs.windows.{arch}.vcredist'
])
elif sys.platform.startswith('darwin'):
packages.extend([
f'mssql_python.libs.macos',
])
elif sys.platform.startswith('linux'):
packages.extend([
f'mssql_python.libs.linux',
])
if sys.platform.startswith("win"):
packages.extend(
[
f"mssql_python.libs.windows.{arch}",
f"mssql_python.libs.windows.{arch}.1033",
f"mssql_python.libs.windows.{arch}.vcredist",
]
)
elif sys.platform.startswith("darwin"):
packages.extend(
[
f"mssql_python.libs.macos",
]
)
elif sys.platform.startswith("linux"):
packages.extend(
[
f"mssql_python.libs.linux",
]
)

setup(
name='mssql-python',
version='1.0.0',
description='A Python library for interacting with Microsoft SQL Server',
long_description=open('PyPI_Description.md', encoding='utf-8').read(),
long_description_content_type='text/markdown',
author='Microsoft Corporation',
author_email='[email protected]',
url='https://github.com/microsoft/mssql-python',
name="mssql-python",
version="1.1.0",
description="A Python library for interacting with Microsoft SQL Server",
long_description=open("PyPI_Description.md", encoding="utf-8").read(),
long_description_content_type="text/markdown",
author="Microsoft Corporation",
author_email="[email protected]",
url="https://github.com/microsoft/mssql-python",
packages=packages,
package_data={
# Include PYD and DLL files inside mssql_python, exclude YML files
'mssql_python': [
'ddbc_bindings.cp*.pyd', # Include all PYD files
'ddbc_bindings.cp*.so', # Include all SO files
'libs/*',
'libs/**/*',
'*.dll'
"mssql_python": [
"ddbc_bindings.cp*.pyd", # Include all PYD files
"ddbc_bindings.cp*.so", # Include all SO files
"libs/*",
"libs/**/*",
"*.dll",
]
},
include_package_data=True,
# Requires >= Python 3.10
python_requires='>=3.10',
python_requires=">=3.10",
# Add dependencies
install_requires=[
'azure-identity>=1.12.0', # Azure authentication library
"azure-identity>=1.12.0", # Azure authentication library
],
classifiers=[
'Operating System :: Microsoft :: Windows',
'Operating System :: MacOS',
'Operating System :: POSIX :: Linux',
"Operating System :: Microsoft :: Windows",
"Operating System :: MacOS",
"Operating System :: POSIX :: Linux",
],
zip_safe=False,
# Force binary distribution
distclass=BinaryDistribution,
exclude_package_data={
'': ['*.yml', '*.yaml'], # Exclude YML files
'mssql_python': [
'libs/*/vcredist/*', 'libs/*/vcredist/**/*', # Exclude vcredist directories, added here since `'libs/*' is already included`
"": ["*.yml", "*.yaml"], # Exclude YML files
"mssql_python": [
"libs/*/vcredist/*",
"libs/*/vcredist/**/*", # Exclude vcredist directories, added here since `'libs/*' is already included`
],
},
# Register custom commands
cmdclass={
'bdist_wheel': CustomBdistWheel,
"bdist_wheel": CustomBdistWheel,
},
)
Loading