fix: preserve hand-written Python package initializers - #2590
fix: preserve hand-written Python package initializers#2590ranadeepsingh wants to merge 3 commits into
Conversation
## Summary Generate deterministic UTF-8 Python package import headers while preserving hand-written __init__.py source overrides, namespace roots, and the cognitive compatibility package. Add regression coverage for nested packages, manual and absent initializers, OpenAI extras, and repeat-run idempotency. ## Prompting Intent Recreate the intent of stale PR microsoft#2286 on current master without editing generated outputs, account for the OpenAI init hook added by microsoft#2560, and validate the change through TDD, compilation, codegen, style, and generated-output assertions. ## Linked Sources - Original fix proposal: microsoft#2286 - OpenAI codegen change: microsoft#2560 ## Rationale Read manual initializer content from the source override tree rather than prepending to generated output. This keeps source authoritative and prevents duplicate generated blocks on repeated codegen. Generated imports remain sorted, the microsoft#2560 hook stays between generated imports and manual content, non-empty manual namespace roots are retained, and empty roots remain namespace packages. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
Azure Pipelines: There may be pipelines that require an authorized user to comment /azp run to run. |
|
Hey @ranadeepsingh 👋! We use semantic commit messages to streamline the release process. Examples of commit messages with semantic prefixes:
To test your commit locally, please follow our guild on building from source. |
|
/azp run |
|
Azure Pipelines: Successfully started running 1 pipeline(s). |
There was a problem hiding this comment.
Pull request overview
This PR updates SynapseML’s Python code generation (PyCodegen) to preserve hand-written __init__.py content (including UTF-8 text) while still emitting deterministic generated imports and required OpenAI compatibility glue. It also adds targeted regression tests to validate manual-content retention, namespace-root behavior, ordering, and idempotency across repeated runs.
Changes:
- Refactors
PyCodegen.makeInitFilesto read manual initializer content from the source override tree (src/main/python) and compose it after generated metadata/imports (and anyinitFileExtra). - Makes generated import emission deterministic (sorted) and explicitly UTF-8 encoded for init-file writes/reads.
- Adds
PyCodegenSuitecovering UTF-8 preservation, namespace-root deletion/retention rules, OpenAI hook ordering, cognitive manual-only behavior, and repeat-run byte idempotency.
Show a summary per file
| File | Description |
|---|---|
| core/src/main/scala/com/microsoft/azure/synapse/ml/codegen/PyCodegen.scala | Refactors init-file generation to preserve manual content from the override tree, enforce deterministic ordering, and use explicit UTF-8. |
| core/src/test/scala/com/microsoft/azure/synapse/ml/codegen/PyCodegenSuite.scala | Adds focused regression tests for manual __init__.py preservation, namespace-root handling, UTF-8, OpenAI hook behavior, and idempotency. |
Review details
- Files reviewed: 2/2 changed files
- Comments generated: 0
- Review effort level: Lite
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #2590 +/- ##
==========================================
+ Coverage 84.79% 84.80% +0.01%
==========================================
Files 334 334
Lines 17806 17826 +20
Branches 1623 1643 +20
==========================================
+ Hits 15099 15118 +19
- Misses 2707 2708 +1 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
## Summary Remove the obsolete automl initializer override that imports the nonexistent _FindBestModel module. With manual initializer preservation enabled, that previously hidden dead code broke AutoML imports in website and Databricks checks. ## Prompting Intent Iterate on every PR check until green without editing generated output. Diagnose the failures caused by preserving current source overrides and fix the source-level defect exposed by the codegen change. ## Linked Sources - Current PR: microsoft#2590 - Original init preservation proposal: microsoft#2286 - Failing Azure Pipelines build: https://msdata.visualstudio.com/b9b2accc-2d1c-45b3-9d24-0eb5d78cc47f/_build/results?buildId=229204431 - Prior stale-file analysis: microsoft@0b07808 ## Rationale Delete the override instead of replacing it with another manual import. PyCodegen already generates the valid FindBestModel wildcard import from FindBestModel.py, while _FindBestModel.py has never existed on this branch. Removing dead source keeps generated imports authoritative and avoids preserving a broken compatibility symbol. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
/azp run |
|
Azure Pipelines: Successfully started running 1 pipeline(s). |
## Summary Include both synapse.ml and synapse.ml.* in component and aggregate setuptools namespace discovery so a preserved non-empty synapse/ml/__init__.py is shipped in wheels. Add component and aggregate wheel-content regression fixtures. ## Prompting Intent Address the independent PR review finding that init preservation was incomplete at the packaging boundary, validate actual wheel contents, push the existing PR, and rerun all checks to green. ## Linked Sources - Current PR: microsoft#2590 - Original init preservation proposal: microsoft#2286 - OpenAI codegen compatibility change: microsoft#2560 ## Rationale Setuptools include patterns do not make synapse.ml.* match the synapse.ml package itself. Listing the exact namespace root alongside the descendant wildcard preserves namespace behavior when no root initializer exists while packaging the root whenever codegen retains a non-empty manual initializer. Building and inspecting real fixture wheels guards both setup templates. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
/azp run |
|
@imatiach-msft Re-review requested after addressing the namespace-root wheel packaging finding. Commit Local validation: 7/7 targeted PyCodegen tests passed, component/test scalastyle passed with zero findings, Black passed, and canonical core codegen emitted the corrected discovery expression. |
|
Azure Pipelines: Successfully started running 1 pipeline(s). |
Related PRs
master.Problem
PyCodegen copies hand-written Python overrides and then rewrites nested
__init__.pyfiles, discarding required manual content. It also deletes every namespace-root initializer and the prepend approach proposed in #2286 would duplicate generated headers when init generation is repeated.Before the fix, targeted regression tests reproduced three failures: nested manual UTF-8 content was missing, a non-empty manual namespace root was deleted, and OpenAI manual content was lost around the #2560 hook.
Changes
initFileExtra, then manual content.No files under
target/or other generated output are committed.Validation
core/testOnly com.microsoft.azure.synapse.ml.codegen.PyCodegenSuite: 5 passed.core/Test/compileandcognitive/Test/compile: passed.core/codegen,cognitive/codegen, anddeepLearning/codegen: passed.core/scalastyleandcore/Test/scalastyle: passed with zero findings.black==22.3.0 --check --extend-exclude docs/ .: 179 files unchanged.core/codegenwas byte-idempotent across all 30 generated__init__.pyfiles.Review
The repository
code-reviewchecklist was run before commit; no concrete findings remained.CI iteration
The first Azure Pipelines run exposed a stale source override at
core/src/main/python/synapse/ml/automl/__init__.py: it imported_FindBestModel, but that generated module does not exist. The file had previously been harmless only because PyCodegen overwrote it. The override is now removed so deterministic codegen supplies the validFindBestModelimport. Local targeted tests and canonical core codegen passed after the fix.Packaging review follow-up
Independent review found that
find_namespace_packages(include=["synapse.ml.*"])omitted a preservedsynapse/ml/__init__.pyfrom wheels. Component and aggregate setup templates now include both the exactsynapse.mlpackage andsynapse.ml.*. Regression tests build and inspect real fixture wheels for both templates, including UTF-8 root initializer content.