This release has been yanked by its maintainers, and will be ignored by installers, except when explicitly specified.
Reason given by maintainers: Renamed to pqtools - run: pip install pqtools
mquery-toolkit
Offline command-line and Python tooling for Power Query M source: parse, format,
lint (check), and safely rename a let binding.
Unofficial. Not affiliated with or endorsed by Microsoft. Not an M runtime - it parses and formats M source text; it does not evaluate queries.
Install
pip install mquery-toolkit
Requires Node.js 22 or newer on PATH, or point MQUERY_NODE at a Node
binary. The Microsoft parser and formatter packages are bundled inside the
wheel (_bridge.cjs) - no npm install needed.
Quick start
# Parse to deterministic JSON (tokens, root kind, bindings/references)
mquery parse query.pq
# Format - dry run prints a unified diff, nothing is written
mquery format query.pq
# Format and write in place (atomic replace, preserves mode/newline/encoding)
mquery format query.pq --write
# Lint, machine-readable output; exit code 2 if any diagnostic is severity=error
mquery check query.pq --json
# Rename one top-level let binding - dry run first
mquery rename query.pq --old OldName --new NewName
Python API
from mquery_toolkit import check, format_source, parse, rename, update_file
parsed = parse(source_text) # dict: tokens, rootKind, analysis
formatted = format_source(source_text) # formatted M source, same encoding
diagnostics = check(source_text, "query.pq") # list[Diagnostic]
renamed = rename(source_text, "OldName", "NewName")
# File-level edit with the same dry-run/--write safety model as the CLI
diff = update_file(path, format_source) # dry run: unified diff
diff = update_file(path, format_source, write=True) # atomic write
Diagnostics
| Code | Severity | Meaning |
|---|---|---|
M_PARSE_ERROR |
error | source does not parse |
M001 |
error | duplicate let binding name |
M002 |
warning | Web.Contents called with a non-literal (dynamic) URL |
M003 |
warning | credential-like literal (password/token/secret = "...") |
M004 |
warning | let binding unreachable from the result |
M005 |
warning | unresolved unqualified reference |
M006 |
info | source-function inventory (*.Contents dependency) |
M002 and M003 are conservative text-pattern checks on the raw source, not
AST checks; expect occasional false positives inside comments or strings.
Every matching occurrence is reported, one diagnostic per call site or
literal.
check --json emits stable objects; check without --json prints
file:line:column: severity code: message per diagnostic. The CLI exits 2
when any diagnostic has severity error, 0 otherwise.
Safety model
- Dry-run by default. Every edit command (
format,rename,replace-source) prints a unified diff and touches nothing unless--writeis passed. --writeis an atomic replace: the file is written to a sibling temp file,fsync'd,chmod'd to match the original, then moved into place withos.replace.- Layout is preserved: UTF-8 encoding, a leading BOM (present in every
Power Query SDK connector file), newline convention (
\nvs\r\n), final-newline state, and file mode all round-trip unchanged. - Refuses symlinks and hardlinks - writes require a regular, single-link file.
- Detects concurrent change: the source is snapshotted before the
transform and re-checked immediately before the atomic replace - this final
snapshot check, not the lock, is the guarantee against lost updates; a
change in that microsecond window raises
SafeWriteError. - Advisory lock while writing only - a
--writecall takes a cross-process advisory lock (fcntl/msvcrt) for the duration of the write and removes the lock file afterward, best-effort. It only serialises cooperatingmqueryprocesses and is not a correctness guarantee: because the lock file is removed after use, a waiting process and a freshly started one can end up locking different inodes. Dry-run calls take no lock and create no lock file. - This is not mandatory locking - no OS provides a portable mandatory lock, and the advisory lock is not itself the correctness guard. Use source control or external exclusive ownership for concurrent editors.
Limits
- Input and output are capped at 10 MiB.
- The Node subprocess is bounded to a 30 second timeout.
- Supported extensions:
.pq,.m,.pqm, and any*.query.pqfile. renamescope: exactly one unquoted top-levelletbinding. It refuses quoted identifiers (#"..."), record literals, lambda expressions, and non-ASCII source.Retry-Afteron the Fabric adapter must be whole seconds; HTTP-date values are rejected.
Optional adapters
fabricextra (pip install "mquery-toolkit[fabric]") - a Fabric Execute Query client that takes a caller-provided bearer token and an injected HTTP transport. It never manages credentials itself and is fully mocked in tests (no network access in the test suite).pqtest- a bounded wrapper around a user-installed Microsoft PQTest executable, Windows-only, pinned to version2.155.2. It never downloads a binary; it only validates and runs one already on disk.
What it is not
- Not an M language runtime or evaluator.
- Not a Power BI or Fabric client, and it does not manage credentials.
- Not a general-purpose file editor - it only touches files with a supported extension and only through the safety model above.
- Not a replacement for Microsoft's own parser/formatter - it vendors and calls them directly rather than reimplementing M syntax.
Development
git clone https://github.com/GopalGB/mquery-toolkit
cd mquery-toolkit
python -m venv .venv && source .venv/bin/activate
pip install -e ".[dev,fabric]"
npm ci --ignore-scripts
pytest -q --cov=mquery_toolkit --cov-fail-under=80
mypy src
ruff check .
ruff format --check .
npm test
python -m build
License
MIT - see LICENSE. Bundled Microsoft packages
(@microsoft/powerquery-parser, @microsoft/powerquery-formatter) and their
dependencies are also MIT; see THIRD_PARTY_NOTICES.txt and NOTICE.
Metadata
Release files for mquery-toolkit 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| mquery_toolkit-0.1.0.tar.gz | 347.8 kB | With provenance | Details for mquery_toolkit-0.1.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| mquery_toolkit-0.1.0-py3-none-any.whl | Python 3 | none | any | Details for mquery_toolkit-0.1.0-py3-none-any.whl |
Total release size: 693.9 kB
Release files / mquery_toolkit-0.1.0.tar.gz
| Download URL | mquery_toolkit-0.1.0.tar.gz |
|---|---|
| Size | 347.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
3345e1569c5a364ce74edff3416c4eeae89bae08fd3075e9bb46afe244ba72b2
|
|
BLAKE2b-256 checksum How to use checksums |
a62a9a18015e9958fbb09042a523095f3ac1338a68e7ba41465b4c03606f958f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 3, 2026.
Transparency logRelease files / mquery_toolkit-0.1.0-py3-none-any.whl
| Download URL | mquery_toolkit-0.1.0-py3-none-any.whl |
|---|---|
| Size | 346.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
f6c0aa7c73c75e1aacec1c0e640b9264e1b259bd43c4b18d7a9251cd3c5442f7
|
|
BLAKE2b-256 checksum How to use checksums |
48f6023d49cd894dfc8e9e635f433252d96325e09ec1f8cacffc71004000e55f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 3, 2026.
Transparency logSecurity for mquery-toolkit 0.1.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
Both files in this release have been uploaded with provenance metadata.
Attestation for mquery_toolkit-0.1.0.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 3, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.