feat(dml): add transparency support for solid fills and colors (closes #17)#30
Merged
MHoroszowski merged 1 commit intomasterfrom May 6, 2026
Merged
Conversation
Implements ColorFormat.transparency, FillFormat.transparency, and _SolidFill.transparency as a 0.0-1.0 float, backed by <a:alpha> in the underlying srgbClr/schemeClr/etc. element. - 0.0 = fully opaque (no <a:alpha> element written) - 1.0 = fully transparent (<a:alpha val="0"/>) - 0.5 = 50% transparent (<a:alpha val="50000"/>) Cherry-picked and adapted from upstream PR scanny#1090 (spandan-k, secondlayerco/python-pptx@feat/opacity-support), ported manually to keep the fork's ruff-formatted layout clean. Closes #17. Surface: - src/pptx/dml/color.py: ColorFormat.transparency, _Color.transparency, _validate_transparency_value (raises ValueError for out-of-range and for NoneColor) - src/pptx/dml/fill.py: FillFormat.transparency delegates to inner _Fill; base _Fill raises TypeError; _SolidFill delegates to fore_color - src/pptx/oxml/dml/color.py: alpha/alphaMod/alphaOff added as ZeroOrOne on _BaseColorElement with add_*/clear_alpha helpers; new CT_PositiveFixedPercentage element class - src/pptx/oxml/__init__.py: register a:alpha, a:alphaMod, a:alphaOff - tests/dml/test_transparency.py: 31 new tests across 4 describe classes (ColorFormat, FillFormat, _SolidFill, integration) - tests/oxml/unitdata/dml.py: a_alpha, a_alphaMod, a_alphaOff builders Tests: 3017 unit (+31 new) + 981 behave scenarios all passing. Lint: ruff check + ruff format clean. Out of scope (file as follow-ups): _GradientFill stop-level alpha, LineFormat.transparency, _BlipFill.transparency (Pictures epic), _PatternFill.transparency, alphaMod/alphaOff Python API surface.
MHoroszowski
added a commit
that referenced
this pull request
May 6, 2026
Documents project-level rules that apply to every contributor — human or
AI — working in this fork:
• Editable-install gotcha with git worktree (use PYTHONPATH=src or work
in the main checkout)
• Manual port over git cherry-pick for upstream PRs (this fork has a
repo-wide ruff format pass that upstream master lacks)
• Test discipline expectations (pytest + behave + ruff baselines and
TDD ordering)
• Branch / PR workflow with approval-gated UAT step
• Reporting contract for AI agents — verbatim verification output
required, no self-attestation
Claude Code auto-merges project-root CLAUDE.md into any session opened
in the repo, so the rules are enforced without any additional setup.
Refs PR #30 as canonical feature example, PR #31 as the run that
surfaced most of these rules in practice.
Co-authored-by: Matthew Horoszowski <mhoroszowski@Winton.lan>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #17
Implements transparency / opacity support across
ColorFormat,FillFormat, and_SolidFill— the longest-standing user request in upstream history (open since scanny/python-pptx#62, 2014).Surface
0.0= fully opaque (no<a:alpha>element written — optimal XML)1.0= fully transparent (<a:alpha val="0"/>)0.5= 50% transparent (<a:alpha val="50000"/>)Provenance
Cherry-picked from upstream PR scanny/python-pptx#1090 (spandan-k @ secondlayerco, last updated April 2026), ported manually to keep the fork's ruff-formatted layout clean.
Files touched
src/pptx/dml/color.pyColorFormat.transparency+_Color.transparency+_validate_transparency_valuesrc/pptx/dml/fill.pyFillFormat.transparency, base_FillraisesTypeError,_SolidFilldelegates to fore-colorsrc/pptx/oxml/dml/color.pyalpha/alphaMod/alphaOffas ZeroOrOne on_BaseColorElement;add_*andclear_alphahelpers; newCT_PositiveFixedPercentageelementsrc/pptx/oxml/__init__.pya:alpha,a:alphaMod,a:alphaOfftests/dml/test_transparency.pyDescribeclassestests/oxml/unitdata/dml.pya_alpha,a_alphaMod,a_alphaOffbuildersVerification
pytest tests/— 3017 passed (was 2986; +31 new transparency tests)behave features/— 981 scenarios passed, 0 failedruff check src tests— cleanruff format --check src tests— cleanErrors
Out of scope (filed as follow-ups)
_GradientFill.gradient_stops[i].transparency(per-stop alpha)LineFormat.transparency_BlipFill.transparency— coordinate with Pictures epic_PatternFill.transparencyalphaMod/alphaOffPython API (XML elements registered, no public surface yet)Round-trip safety
Existing
<a:alpha>elements in unrelated read paths (effects, theme.xml) are preserved — these were already serialized verbatim throughlxmlsince the elements weren't registered with custom classes; registering them withCT_PositiveFixedPercentagedoes not change the bytes written for unmodified parts.