Skip to content

FIX: accept memoryview in Binary() - #741

Merged
Gaurav Sharma (bewithgaurav) merged 5 commits into
mainfrom
bewithgaurav/fix-739-binary-memoryview
Sep 3, 2026
Merged

FIX: accept memoryview in Binary()#741
Gaurav Sharma (bewithgaurav) merged 5 commits into
mainfrom
bewithgaurav/fix-739-binary-memoryview

Conversation

@bewithgaurav

Copy link
Copy Markdown
Collaborator

Work Item / Issue Reference

GitHub Issue: #739


Summary

Binary() rejected memoryview with a TypeError, so any DB-API caller that
passes a buffer-protocol value failed. Django's BinaryField hands the driver a
memoryview, which broke BinaryField writes and the serializer roundtrips.
Accept memoryview via tobytes(), matching pyodbc and the DB-API convention.

Binary() rejected memoryview with a TypeError, so any DB-API caller that hands the driver a buffer-protocol value failed. Django's BinaryField gives the driver a memoryview, so BinaryField writes and its serializer roundtrips all broke. Accept memoryview via tobytes(), matching pyodbc and the DB-API convention. (GH-739)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI lite review requested due to automatic review settings September 2, 2026 09:49
@github-actions github-actions Bot added the pr-size: small Minimal code update label Sep 2, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The runtime API change isn’t reflected in the public type stubs (mssql_python/mssql_python.pyi), which will cause type-checking inconsistencies for downstream users.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

This PR fixes DB-API compatibility for binary parameters by allowing mssql_python.Binary() to accept memoryview, which is commonly passed by Django’s BinaryField (GH-739), aligning behavior with pyodbc and typical buffer-protocol usage.

Changes:

  • Extend Binary() to accept memoryview via tobytes(), and update the error message and docstring accordingly.
  • Add unit coverage for memoryview inputs and update existing error-message assertions in type tests.
File summaries
File Description
mssql_python/type.py Accepts memoryview in Binary() and updates docs/error message to reflect the expanded supported input types.
tests/test_002_types.py Adds a memoryview test case for Binary() and updates TypeError message expectations for unsupported types.
Review details
  • Files reviewed: 2/2 changed files
  • Comments generated: 1
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread mssql_python/type.py Outdated
Match the runtime signature so type checkers accept Binary(memoryview(...)). (GH-739)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@github-actions

github-actions Bot commented Sep 2, 2026

Copy link
Copy Markdown

📊 Code Coverage Report

🔥 Diff Coverage

100%


🎯 Overall Coverage

82%


📈 Total Lines Covered: 7804 out of 9478
📁 Project: mssql-python


Diff Coverage

Diff: main...HEAD, staged and unstaged changes

  • mssql_python/type.py (100%)

Summary

  • Total: 4 lines
  • Missing: 0 lines
  • Coverage: 100%

📋 Files Needing Attention

📉 Files with overall lowest coverage (click to expand)
mssql_python.pybind.logger_bridge.cpp: 58.9%
mssql_python.pybind.ddbc_bindings.h: 61.5%
mssql_python.pybind.logger_bridge.hpp: 70.8%
mssql_python.pybind.ddbc_bindings.cpp: 75.5%
mssql_python.__init__.py: 77.6%
mssql_python.row.py: 77.6%
mssql_python.pybind.connection.connection_pool.cpp: 81.6%
mssql_python.pybind.connection.connection.cpp: 84.4%
mssql_python.logging.py: 85.5%
mssql_python.connection.py: 85.9%

🔗 Quick Links

⚙️ Build Summary 📋 Coverage Details

View Azure DevOps Build

Browse Full Coverage Report

Comment thread mssql_python/type.py Outdated
type.py ships py.typed, so annotate the runtime parameter directly (Union[str, bytes, bytearray, memoryview]) to make the accepted-input contract explicit at the source, matching the stub. (GH-739)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed the PR for correctness, security, reliability, performance, test coverage, repository conventions, and applicable architecture and design specifications. No actionable issues were identified. The implementation is consistent with repository standards and the applicable approved design requirements.

Details

  • Binary() normalizes memoryview to an exact bytes via .tobytes(), preserving the existing bytes return contract. This keeps the downstream binding path unchanged, since the binder already maps bytes to SQL_VARBINARY/SQL_C_BINARY (including large-value streaming).
  • .tobytes() produces an owned copy in logical C order, so non-contiguous, bytearray-backed, and empty memoryviews all round-trip correctly with no aliasing/lifetime concern.
  • Accepting memoryview aligns with pyodbc's acceptance of buffer-protocol values (pyodbc materializes to bytearray; this driver keeps its bytes contract) and resolves GH-739 (Django BinaryField hands the driver a memoryview).
  • Runtime signature and the PEP 561 .pyi stub are kept in sync; a focused regression test covers memoryview inputs and the updated error message; Black passes.

Recommendation: Approve

@bewithgaurav
Gaurav Sharma (bewithgaurav) merged commit 08cd24c into main Sep 3, 2026
29 checks passed
Gaurav Sharma (bewithgaurav) added a commit to microsoft/mssql-django that referenced this pull request Sep 3, 2026
Point the Windows PR-validation legs at the mssql-python wheel from
Build-Release-Package-Pipeline dev build 172271, which already carries the
two pyodbc-parity fixes (microsoft/mssql-python#741 Binary(memoryview) and
microsoft/mssql-python#742 Decimal SQL_NUMERIC) with the native core rebuilt.
The published PyPI 1.14.0 wheel does not have these yet, so the two Decimal
and BinaryField gaps would otherwise still fail.

- tox.ini: allow the mssql-python requirement to be overridden by
  MSSQL_PYTHON_WHEEL, defaulting to the PyPI requirement when unset.
- azure-pipelines-steps-windows.yml: download the matching per-Python wheel
  from build 172271 and hand its path to tox.
- azure-pipelines.yml: gate Linux_Core, Linux_Legacy and Windows_Legacy off
  for this run. Build 172271 produced no Linux wheels, and the EOL/py3.8-3.9
  legs have no wheel, so only the supported Windows matrix is validated here.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Gaurav Sharma (bewithgaurav) added a commit to microsoft/mssql-django that referenced this pull request Sep 3, 2026
Cross-project artifact download from the mssql-python project is blocked for
the public project's build identity (VS800075), so commit the Windows wheels
directly under ci/mssql-python-wheels/ and install the per-Python wheel from
there. Wheels are from Build-Release-Package-Pipeline dev build 172271 and
carry microsoft/mssql-python#741 (Binary(memoryview)) and
microsoft/mssql-python#742 (Decimal SQL_NUMERIC). Temporary: drop once
mssql-python 1.15.0 ships to PyPI with both fixes.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Gaurav Sharma (bewithgaurav) added a commit to microsoft/mssql-django that referenced this pull request Sep 8, 2026
The full Build-Release-Package-Pipeline run 173176 (main, commit b426da4e)
produced Linux wheels as well, so extend the wheel validation to the Linux
supported matrix:

- Refresh ci/mssql-python-wheels/ with the Windows and Linux x86_64 wheels
  from a single build (173176). Both still carry microsoft/mssql-python#741
  (Binary(memoryview)) and microsoft/mssql-python#742 (Decimal SQL_NUMERIC).
- azure-pipelines-steps-linux.yml: install the per-Python manylinux wheel from
  ci/mssql-python-wheels/ via MSSQL_PYTHON_WHEEL, mirroring the Windows steps.
- azure-pipelines.yml: re-enable Linux_Core and raise its timeout to 180 min
  to match Windows_Core (mssql-python runs the suite ~1.5-2x slower).

Windows_Legacy and Linux_Legacy stay gated off (no wheels for EOL py3.8/3.9).
Temporary: drop once mssql-python 1.15.0 ships to PyPI with both fixes.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

pr-size: small Minimal code update

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants