athena-python-pptx 0.14.0__tar.gz → 0.14.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (90) hide show
  1. {athena_python_pptx-0.14.0 → athena_python_pptx-0.14.1}/CHANGELOG.md +12 -0
  2. {athena_python_pptx-0.14.0 → athena_python_pptx-0.14.1}/PKG-INFO +1 -1
  3. {athena_python_pptx-0.14.0 → athena_python_pptx-0.14.1}/pptx/__init__.py +1 -1
  4. {athena_python_pptx-0.14.0 → athena_python_pptx-0.14.1}/pptx/presentation.py +26 -13
  5. {athena_python_pptx-0.14.0 → athena_python_pptx-0.14.1}/pyproject.toml +1 -1
  6. {athena_python_pptx-0.14.0 → athena_python_pptx-0.14.1}/.gitignore +0 -0
  7. {athena_python_pptx-0.14.0 → athena_python_pptx-0.14.1}/AGENTS.md +0 -0
  8. {athena_python_pptx-0.14.0 → athena_python_pptx-0.14.1}/API_PARITY_REPORT.md +0 -0
  9. {athena_python_pptx-0.14.0 → athena_python_pptx-0.14.1}/CLAUDE.md +0 -0
  10. {athena_python_pptx-0.14.0 → athena_python_pptx-0.14.1}/DEV-GUIDE.md +0 -0
  11. {athena_python_pptx-0.14.0 → athena_python_pptx-0.14.1}/PARITY_QUESTIONS.md +0 -0
  12. {athena_python_pptx-0.14.0 → athena_python_pptx-0.14.1}/PUBLISHING.md +0 -0
  13. {athena_python_pptx-0.14.0 → athena_python_pptx-0.14.1}/README.md +0 -0
  14. {athena_python_pptx-0.14.0 → athena_python_pptx-0.14.1}/docs/API_PARITY_EXCEPTIONS.md +0 -0
  15. {athena_python_pptx-0.14.0 → athena_python_pptx-0.14.1}/docs/athena-api.json +0 -0
  16. {athena_python_pptx-0.14.0 → athena_python_pptx-0.14.1}/docs/athena-api.md +0 -0
  17. {athena_python_pptx-0.14.0 → athena_python_pptx-0.14.1}/pptx/_athena_extension.py +0 -0
  18. {athena_python_pptx-0.14.0 → athena_python_pptx-0.14.1}/pptx/_citations.py +0 -0
  19. {athena_python_pptx-0.14.0 → athena_python_pptx-0.14.1}/pptx/_ptc.py +0 -0
  20. {athena_python_pptx-0.14.0 → athena_python_pptx-0.14.1}/pptx/_references.py +0 -0
  21. {athena_python_pptx-0.14.0 → athena_python_pptx-0.14.1}/pptx/action.py +0 -0
  22. {athena_python_pptx-0.14.0 → athena_python_pptx-0.14.1}/pptx/batching.py +0 -0
  23. {athena_python_pptx-0.14.0 → athena_python_pptx-0.14.1}/pptx/chart/__init__.py +0 -0
  24. {athena_python_pptx-0.14.0 → athena_python_pptx-0.14.1}/pptx/chart/axis.py +0 -0
  25. {athena_python_pptx-0.14.0 → athena_python_pptx-0.14.1}/pptx/chart/category.py +0 -0
  26. {athena_python_pptx-0.14.0 → athena_python_pptx-0.14.1}/pptx/chart/chart.py +0 -0
  27. {athena_python_pptx-0.14.0 → athena_python_pptx-0.14.1}/pptx/chart/data.py +0 -0
  28. {athena_python_pptx-0.14.0 → athena_python_pptx-0.14.1}/pptx/chart/datalabel.py +0 -0
  29. {athena_python_pptx-0.14.0 → athena_python_pptx-0.14.1}/pptx/chart/legend.py +0 -0
  30. {athena_python_pptx-0.14.0 → athena_python_pptx-0.14.1}/pptx/chart/marker.py +0 -0
  31. {athena_python_pptx-0.14.0 → athena_python_pptx-0.14.1}/pptx/chart/plot.py +0 -0
  32. {athena_python_pptx-0.14.0 → athena_python_pptx-0.14.1}/pptx/chart/point.py +0 -0
  33. {athena_python_pptx-0.14.0 → athena_python_pptx-0.14.1}/pptx/chart/series.py +0 -0
  34. {athena_python_pptx-0.14.0 → athena_python_pptx-0.14.1}/pptx/chart/xlsx.py +0 -0
  35. {athena_python_pptx-0.14.0 → athena_python_pptx-0.14.1}/pptx/client.py +0 -0
  36. {athena_python_pptx-0.14.0 → athena_python_pptx-0.14.1}/pptx/commands.py +0 -0
  37. {athena_python_pptx-0.14.0 → athena_python_pptx-0.14.1}/pptx/decorators.py +0 -0
  38. {athena_python_pptx-0.14.0 → athena_python_pptx-0.14.1}/pptx/dml/__init__.py +0 -0
  39. {athena_python_pptx-0.14.0 → athena_python_pptx-0.14.1}/pptx/dml/chtfmt.py +0 -0
  40. {athena_python_pptx-0.14.0 → athena_python_pptx-0.14.1}/pptx/dml/color.py +0 -0
  41. {athena_python_pptx-0.14.0 → athena_python_pptx-0.14.1}/pptx/dml/effect.py +0 -0
  42. {athena_python_pptx-0.14.0 → athena_python_pptx-0.14.1}/pptx/dml/fill.py +0 -0
  43. {athena_python_pptx-0.14.0 → athena_python_pptx-0.14.1}/pptx/dml/line.py +0 -0
  44. {athena_python_pptx-0.14.0 → athena_python_pptx-0.14.1}/pptx/docgen.py +0 -0
  45. {athena_python_pptx-0.14.0 → athena_python_pptx-0.14.1}/pptx/enum/__init__.py +0 -0
  46. {athena_python_pptx-0.14.0 → athena_python_pptx-0.14.1}/pptx/enum/action.py +0 -0
  47. {athena_python_pptx-0.14.0 → athena_python_pptx-0.14.1}/pptx/enum/chart.py +0 -0
  48. {athena_python_pptx-0.14.0 → athena_python_pptx-0.14.1}/pptx/enum/dml.py +0 -0
  49. {athena_python_pptx-0.14.0 → athena_python_pptx-0.14.1}/pptx/enum/lang.py +0 -0
  50. {athena_python_pptx-0.14.0 → athena_python_pptx-0.14.1}/pptx/enum/shapes.py +0 -0
  51. {athena_python_pptx-0.14.0 → athena_python_pptx-0.14.1}/pptx/enum/text.py +0 -0
  52. {athena_python_pptx-0.14.0 → athena_python_pptx-0.14.1}/pptx/errors.py +0 -0
  53. {athena_python_pptx-0.14.0 → athena_python_pptx-0.14.1}/pptx/exc.py +0 -0
  54. {athena_python_pptx-0.14.0 → athena_python_pptx-0.14.1}/pptx/kit.py +0 -0
  55. {athena_python_pptx-0.14.0 → athena_python_pptx-0.14.1}/pptx/media.py +0 -0
  56. {athena_python_pptx-0.14.0 → athena_python_pptx-0.14.1}/pptx/oxml/__init__.py +0 -0
  57. {athena_python_pptx-0.14.0 → athena_python_pptx-0.14.1}/pptx/oxml/ns.py +0 -0
  58. {athena_python_pptx-0.14.0 → athena_python_pptx-0.14.1}/pptx/package.py +0 -0
  59. {athena_python_pptx-0.14.0 → athena_python_pptx-0.14.1}/pptx/parts/__init__.py +0 -0
  60. {athena_python_pptx-0.14.0 → athena_python_pptx-0.14.1}/pptx/parts/_base.py +0 -0
  61. {athena_python_pptx-0.14.0 → athena_python_pptx-0.14.1}/pptx/parts/chart.py +0 -0
  62. {athena_python_pptx-0.14.0 → athena_python_pptx-0.14.1}/pptx/parts/coreprops.py +0 -0
  63. {athena_python_pptx-0.14.0 → athena_python_pptx-0.14.1}/pptx/parts/embeddedpackage.py +0 -0
  64. {athena_python_pptx-0.14.0 → athena_python_pptx-0.14.1}/pptx/parts/image.py +0 -0
  65. {athena_python_pptx-0.14.0 → athena_python_pptx-0.14.1}/pptx/parts/media.py +0 -0
  66. {athena_python_pptx-0.14.0 → athena_python_pptx-0.14.1}/pptx/parts/presentation.py +0 -0
  67. {athena_python_pptx-0.14.0 → athena_python_pptx-0.14.1}/pptx/parts/slide.py +0 -0
  68. {athena_python_pptx-0.14.0 → athena_python_pptx-0.14.1}/pptx/shapes/__init__.py +0 -0
  69. {athena_python_pptx-0.14.0 → athena_python_pptx-0.14.1}/pptx/shapes/autoshape.py +0 -0
  70. {athena_python_pptx-0.14.0 → athena_python_pptx-0.14.1}/pptx/shapes/base.py +0 -0
  71. {athena_python_pptx-0.14.0 → athena_python_pptx-0.14.1}/pptx/shapes/connector.py +0 -0
  72. {athena_python_pptx-0.14.0 → athena_python_pptx-0.14.1}/pptx/shapes/freeform.py +0 -0
  73. {athena_python_pptx-0.14.0 → athena_python_pptx-0.14.1}/pptx/shapes/graphfrm.py +0 -0
  74. {athena_python_pptx-0.14.0 → athena_python_pptx-0.14.1}/pptx/shapes/group.py +0 -0
  75. {athena_python_pptx-0.14.0 → athena_python_pptx-0.14.1}/pptx/shapes/picture.py +0 -0
  76. {athena_python_pptx-0.14.0 → athena_python_pptx-0.14.1}/pptx/shapes/placeholder.py +0 -0
  77. {athena_python_pptx-0.14.0 → athena_python_pptx-0.14.1}/pptx/shapes/shapetree.py +0 -0
  78. {athena_python_pptx-0.14.0 → athena_python_pptx-0.14.1}/pptx/shared.py +0 -0
  79. {athena_python_pptx-0.14.0 → athena_python_pptx-0.14.1}/pptx/slide.py +0 -0
  80. {athena_python_pptx-0.14.0 → athena_python_pptx-0.14.1}/pptx/slides.py +0 -0
  81. {athena_python_pptx-0.14.0 → athena_python_pptx-0.14.1}/pptx/spec.py +0 -0
  82. {athena_python_pptx-0.14.0 → athena_python_pptx-0.14.1}/pptx/table.py +0 -0
  83. {athena_python_pptx-0.14.0 → athena_python_pptx-0.14.1}/pptx/text/__init__.py +0 -0
  84. {athena_python_pptx-0.14.0 → athena_python_pptx-0.14.1}/pptx/text/fonts.py +0 -0
  85. {athena_python_pptx-0.14.0 → athena_python_pptx-0.14.1}/pptx/text/layout.py +0 -0
  86. {athena_python_pptx-0.14.0 → athena_python_pptx-0.14.1}/pptx/text/text.py +0 -0
  87. {athena_python_pptx-0.14.0 → athena_python_pptx-0.14.1}/pptx/types.py +0 -0
  88. {athena_python_pptx-0.14.0 → athena_python_pptx-0.14.1}/pptx/typing.py +0 -0
  89. {athena_python_pptx-0.14.0 → athena_python_pptx-0.14.1}/pptx/units.py +0 -0
  90. {athena_python_pptx-0.14.0 → athena_python_pptx-0.14.1}/pptx/util.py +0 -0
@@ -2,6 +2,18 @@
2
2
 
3
3
  All notable changes to `athena-python-pptx` are documented in this file.
4
4
 
5
+ ## 0.14.1 — no shutdown error from `Presentation.__del__`
6
+
7
+ - A `Presentation` still alive when the script's interpreter exits no longer
8
+ prints `Exception ignored in: <function Presentation.__del__>` /
9
+ `ImportError: sys.meta_path is None, Python is likely shutting down` to
10
+ stderr. `__del__` now does nothing once the interpreter is finalizing (the
11
+ atexit hook has already flushed pending commands by then), `atexit` is
12
+ imported at module level instead of inside `_release()`, and a finalizer
13
+ error is swallowed instead of printed. Garbage collection during normal
14
+ execution still flushes pending commands, unregisters the atexit hook and
15
+ closes the HTTP session.
16
+
5
17
  ## 0.14.0 — waterfall charts render and export as waterfalls
6
18
 
7
19
  Requires a studio that authors `AddChart2016` waterfalls and accepts the
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: athena-python-pptx
3
- Version: 0.14.0
3
+ Version: 0.14.1
4
4
  Summary: Drop-in replacement for python-pptx that connects to PPTX Studio for real-time collaboration
5
5
  Project-URL: Homepage, https://github.com/pptx-studio/python-sdk
6
6
  Project-URL: Documentation, https://docs.pptx-studio.com/sdk/python
@@ -265,7 +265,7 @@ def validate_all_touched() -> dict[int, list[str]]:
265
265
  return results
266
266
 
267
267
 
268
- __version__ = "0.14.0"
268
+ __version__ = "0.14.1"
269
269
 
270
270
  __all__ = [
271
271
  # Main entry point
@@ -6,7 +6,9 @@ on remote decks via the PPTX Studio API.
6
6
  """
7
7
 
8
8
  from __future__ import annotations
9
+ import atexit
9
10
  import re
11
+ import sys
10
12
  from contextlib import contextmanager
11
13
  from pathlib import Path
12
14
  from typing import Any, Generator, Optional, Union
@@ -182,6 +184,11 @@ class CoreProperties:
182
184
  return f"<CoreProperties title={self._title!r} author={self._author!r}>"
183
185
 
184
186
 
187
+ def _interpreter_is_finalizing() -> bool:
188
+ """True while Python is shutting down and module state may be half torn down."""
189
+ return sys.is_finalizing()
190
+
191
+
185
192
  class Presentation:
186
193
  """
187
194
  Presentation proxy - the main entry point for working with a deck.
@@ -292,8 +299,6 @@ class Presentation:
292
299
  # Register atexit handler so buffered commands flush on process exit.
293
300
  # This is critical for auto_batch mode — without it, commands are lost
294
301
  # if the caller doesn't explicitly call flush()/save()/batch().
295
- import atexit
296
-
297
302
  # Weakref (not a strong capture) so the atexit registry doesn't pin the
298
303
  # buffer -> client -> requests.Session for the whole process lifetime.
299
304
  _buf_ref = _weakref.ref(self._buffer)
@@ -385,15 +390,25 @@ class Presentation:
385
390
  self._closed = True
386
391
 
387
392
  def __del__(self) -> None:
388
- """Best-effort flush on garbage collection."""
389
- if not getattr(self, "_closed", True):
390
- if self._buffer.pending_count > 0:
391
- try:
392
- self._buffer.flush()
393
- except Exception:
394
- pass
395
- self._closed = True
396
- self._release()
393
+ """Best-effort flush on garbage collection.
394
+
395
+ Does nothing once the interpreter is shutting down: the atexit hook has
396
+ already flushed by then, and imports or network calls made during
397
+ finalization fail and print "Exception ignored in ... __del__".
398
+ """
399
+ try:
400
+ if _interpreter_is_finalizing():
401
+ return
402
+ if not getattr(self, "_closed", True):
403
+ if self._buffer.pending_count > 0:
404
+ try:
405
+ self._buffer.flush()
406
+ except Exception:
407
+ pass
408
+ self._closed = True
409
+ self._release()
410
+ except Exception:
411
+ pass
397
412
 
398
413
  def _release(self) -> None:
399
414
  """Unregister the atexit flush hook and close the HTTP session.
@@ -402,8 +417,6 @@ class Presentation:
402
417
  """
403
418
  handler = getattr(self, "_atexit_flush", None)
404
419
  if handler is not None:
405
- import atexit
406
-
407
420
  atexit.unregister(handler)
408
421
  self._atexit_flush = None
409
422
  client = getattr(self, "_client", None)
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "athena-python-pptx"
7
- version = "0.14.0"
7
+ version = "0.14.1"
8
8
  description = "Drop-in replacement for python-pptx that connects to PPTX Studio for real-time collaboration"
9
9
  readme = "README.md"
10
10
  license = "MIT"