Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package python-structlog for 
openSUSE:Factory checked in at 2025-03-12 15:24:24
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-structlog (Old)
 and      /work/SRC/openSUSE:Factory/.python-structlog.new.19136 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-structlog"

Wed Mar 12 15:24:24 2025 rev:15 rq:1252316 version:25.2.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-structlog/python-structlog.changes        
2025-02-05 12:43:01.502986711 +0100
+++ 
/work/SRC/openSUSE:Factory/.python-structlog.new.19136/python-structlog.changes 
    2025-03-12 15:25:07.448910106 +0100
@@ -1,0 +2,15 @@
+Wed Mar 12 08:14:09 UTC 2025 - Michael Vetter <mvet...@suse.com>
+
+- Update to 25.2.0:
+  Added:
+  * structlog.tracebacks.Stack now includes an exc_notes field reflecting
+    the notes attached to the exception. #684
+  Changed:
+  * structlog.stdlib.BoundLogger's binding-related methods now also return 
Self. #694
+  * structlog.processors.TimeStamper now produces internally timezone-aware
+    datetime objects. Default output hasn't changed, but you can now use %z in 
your fmt string. #709
+  Fixed:
+  * Expose structlog.dev.RichTracebackFormatter for imports. #699
+  * Expose structlog.processors.LogfmtRenderer for imports. #701
+
+-------------------------------------------------------------------

Old:
----
  25.1.0.tar.gz

New:
----
  25.2.0.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-structlog.spec ++++++
--- /var/tmp/diff_new_pack.oN3Jt2/_old  2025-03-12 15:25:07.868927696 +0100
+++ /var/tmp/diff_new_pack.oN3Jt2/_new  2025-03-12 15:25:07.872927865 +0100
@@ -18,7 +18,7 @@
 
 %{?sle15_python_module_pythons}
 Name:           python-structlog
-Version:        25.1.0
+Version:        25.2.0
 Release:        0
 Summary:        Structured Logging for Python
 License:        Apache-2.0 OR MIT

++++++ 25.1.0.tar.gz -> 25.2.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/structlog-25.1.0/.git_archival.txt 
new/structlog-25.2.0/.git_archival.txt
--- old/structlog-25.1.0/.git_archival.txt      2025-01-16 11:09:21.000000000 
+0100
+++ new/structlog-25.2.0/.git_archival.txt      2025-03-11 18:32:04.000000000 
+0100
@@ -1,3 +1,3 @@
-node: a38a5ac5d6e7a461b0c304294b7446a2bf674410
-node-date: 2025-01-16T11:09:21+01:00
-describe-name: 25.1.0
+node: e948850c1bd20334247ce5d8228eab6549ab94a6
+node-date: 2025-03-11T18:32:04+01:00
+describe-name: 25.2.0
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/structlog-25.1.0/.pre-commit-config.yaml 
new/structlog-25.2.0/.pre-commit-config.yaml
--- old/structlog-25.1.0/.pre-commit-config.yaml        2025-01-16 
11:09:21.000000000 +0100
+++ new/structlog-25.2.0/.pre-commit-config.yaml        2025-03-11 
18:32:04.000000000 +0100
@@ -4,7 +4,7 @@
 
 repos:
   - repo: https://github.com/astral-sh/ruff-pre-commit
-    rev: v0.9.1
+    rev: v0.9.10
     hooks:
       - id: ruff
         args: [--fix, --exit-non-zero-on-fix]
@@ -17,10 +17,10 @@
         args: [tests]
 
   - repo: https://github.com/codespell-project/codespell
-    rev: v2.3.0
+    rev: v2.4.1
     hooks:
       - id: codespell
-        args: [-L, alog]
+        args: [-L, alog, -L, abl]
 
   - repo: https://github.com/pre-commit/pre-commit-hooks
     rev: v5.0.0
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/structlog-25.1.0/CHANGELOG.md 
new/structlog-25.2.0/CHANGELOG.md
--- old/structlog-25.1.0/CHANGELOG.md   2025-01-16 11:09:21.000000000 +0100
+++ new/structlog-25.2.0/CHANGELOG.md   2025-03-11 18:32:04.000000000 +0100
@@ -13,6 +13,31 @@
 <!-- changelog follows -->
 
 
+## [25.2.0](https://github.com/hynek/structlog/compare/25.1.0...25.2.0) - 
2025-03-11
+
+### Added
+
+- `structlog.tracebacks.Stack` now includes an `exc_notes` field reflecting 
the notes attached to the exception.
+  [#684](https://github.com/hynek/structlog/pull/684)
+
+
+### Changed
+
+- `structlog.stdlib.BoundLogger`'s binding-related methods now also return 
`Self`.
+  [#694](https://github.com/hynek/structlog/pull/694)
+
+- `structlog.processors.TimeStamper` now produces internally timezone-aware 
`datetime` objects.
+  Default output hasn't changed, but you can now use `%z` in your *fmt* string.
+  [#709](https://github.com/hynek/structlog/pull/709)
+
+
+### Fixed
+
+-  Expose `structlog.dev.RichTracebackFormatter` for imports.
+   [#699](https://github.com/hynek/structlog/pull/699)
+-  Expose `structlog.processors.LogfmtRenderer` for imports.
+   [#701](https://github.com/hynek/structlog/pull/701)
+
 ## [25.1.0](https://github.com/hynek/structlog/compare/24.4.0...25.1.0) - 
2025-01-16
 
 ### Added
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/structlog-25.1.0/README.md 
new/structlog-25.2.0/README.md
--- old/structlog-25.1.0/README.md      2025-01-16 11:09:21.000000000 +0100
+++ new/structlog-25.2.0/README.md      2025-03-11 18:32:04.000000000 +0100
@@ -52,6 +52,7 @@
 <a href="https://www.variomedia.de/";><img title="Variomedia AG" 
src="docs/_static/sponsors/Variomedia.svg" width="190" /></a>
 <a 
href="https://tidelift.com/?utm_source=lifter&utm_medium=referral&utm_campaign=hynek";><img
 title="Tidelift" src="docs/_static/sponsors/Tidelift.svg" width="190" /></a>
 <a href="https://klaviyo.com/";><img title="Klaviyo" 
src="docs/_static/sponsors/Klaviyo.svg" width="190" /></a>
+<a href="https://privacy-solutions.org/";><img title="Privacy Solutions" 
src="docs/_static/sponsors/Privacy-Solutions.svg" width="190" /></a>
 <a href="https://www.emsys-renewables.com/";><img title="emsys renewables" 
src="docs/_static/sponsors/emsys-renewables.svg" width="190" /></a>
 <a href="https://filepreviews.io/";><img title="FilePreviews" 
src="docs/_static/sponsors/FilePreviews.svg" width="190" /></a>
 <a href="https://polar.sh/";><img title="Polar" 
src="docs/_static/sponsors/Polar.svg" width="190" /></a>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/structlog-25.1.0/docs/_static/sponsors/Privacy-Solutions.svg 
new/structlog-25.2.0/docs/_static/sponsors/Privacy-Solutions.svg
--- old/structlog-25.1.0/docs/_static/sponsors/Privacy-Solutions.svg    
1970-01-01 01:00:00.000000000 +0100
+++ new/structlog-25.2.0/docs/_static/sponsors/Privacy-Solutions.svg    
2025-03-11 18:32:04.000000000 +0100
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg"; xml:space="preserve" 
style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2"
 viewBox="0 0 9000 3000"><path d="M0 0h9000v3000H0z" style="fill:#fff" 
transform="translate(0 -5.502)"/><path d="M378 148.8h2.4v-2.3H378zm-4.1 
0h2.1v-5.5c0-2-.9-2.9-2.7-2.9-1.4 0-2.2.7-2.7 1.6v-1.4h-2v8.3h2.1V144c0-1.3.6-2 
1.9-2 .5 0 .9.2 1.1.5s.3.9.3 1.5v4.8zm-7.3-2.3h-2c-.1.5-.5 1.1-1.6 1.1-1.2 
0-1.8-.8-1.9-2.4h5.6v-.7c0-2.3-1.1-4.2-3.8-4.2-2.5 0-3.9 1.8-3.9 4.3 0 2.6 1.3 
4.3 3.9 4.3 2.2.1 3.5-.8 3.7-2.4m-2-2.6h-3.5c.1-1.3.7-2.2 1.8-2.2s1.6.8 1.7 
2.2m-15 7.8h2.1v-4c.3.7 1.2 1.3 2.4 1.3 2 0 3.5-1.5 3.5-4.4 
0-3.1-1.5-4.3-3.3-4.3-1.3 0-2.2.8-2.6 1.5v-1.4h-2v11.3zm2.1-6.6v-.9c0-1.4.8-2.3 
1.9-2.3 1.4 0 1.9 1 1.9 2.8 0 1.9-.7 2.9-1.9 2.9-1.3-.1-1.9-1.1-1.9-2.5m-11.7 
6.6h2.1v-4c.3.7 1.2 1.3 2.4 1.3 2 0 3.5-1.5 3.5-4.4 0-3.1-1.5-4.3-3.3-4.3-1.3 
0-2.2.8-2.6 1.5v-1.4h-2v11.3zm2-6.6v-.9c0-1.4.8-2.3 1.9-2.3 1.4 0 1.9 1 1.9 2.8 
0 1.9-.7 2.9-1.9 2.9-1
 .2-.1-1.9-1.1-1.9-2.5m-9.2-2.2c0-.7.4-1.2 1.4-1.2.9 0 1.4.5 1.4 
1.6v.4c-1.8.1-3 .2-3.9.6q-1.2.6-1.2 2.1c0 1.5 1 2.4 2.7 2.4 1.2 0 2.1-.5 
2.5-1.3.2.9.7 1.3 2 1.3h.6v-1.5c-.5 0-.7-.2-.7-.7v-3c0-2.2-.9-3.2-3.4-3.2-2.1 
0-3.3 1-3.4 2.6h2zm.9 4.6c-.8 0-1.2-.4-1.2-1.1 0-.4.1-.7.4-.9.4-.3 1.2-.4 
2.7-.5v.2c0 1.6-1 2.3-1.9 2.3m-7 1.3h2.1v-5.5c0-2-.9-2.9-2.7-2.9-1.4 
0-2.2.8-2.6 1.5v-5.3h-2.1v12.2h2.1V144c0-1.3.6-2 1.9-2 .5 0 .9.2 1.1.5s.3.9.3 
1.5v4.8zm-15.5 0-.1.3c-.3.9-.7 1.2-1.6 1.2-.3 0-.6 0-.8-.1v1.6c.1 0 .5.1 1.1.1 
2 0 2.7-.8 3.4-2.7l2.9-8.6h-2l-1.4 4.6c-.3.9-.4 1.5-.4 
1.5s-.1-.6-.4-1.5l-1.5-4.6h-2.1zm-3.9-5.5c-.1-2-1.6-3-3.6-3-2.5 0-4 1.7-4 4.3 0 
2.7 1.4 4.3 4 4.3 2 0 3.6-1.1 3.7-3.1h-2c0 .7-.4 1.7-1.7 1.7-1.5 
0-1.9-1.4-1.9-2.9 0-1.6.5-2.9 1.9-2.9 1 0 1.5.7 1.6 1.6zm-14.2-.4c0-.7.4-1.2 
1.4-1.2.9 0 1.4.5 1.4 1.6v.4c-1.8.1-3 .2-3.9.6q-1.2.6-1.2 2.1c0 1.5 1 2.4 2.7 
2.4 1.2 0 2.1-.5 2.5-1.3.2.9.7 1.3 2 1.3h.6v-1.5c-.5 
0-.7-.2-.7-.7v-3c0-2.2-.9-3.2-3.4-3.2-2.1 0-3.3 1-3.4 2.6h2zm.9 4.6c-.8 0-
 1.2-.4-1.2-1.1 0-.4.1-.7.4-.9.4-.3 1.2-.4 2.7-.5v.2c0 1.6-1 2.3-1.9 2.3m-8.9 
1.3h2.2l2.9-8.3h-2l-1.5 4.6c-.3.8-.4 1.7-.4 
1.7s-.2-.8-.4-1.7l-1.5-4.6h-2.1zm-6.3 0h2.1v-8.3h-2.1zm0-9.8h2.1v-2h-2.1zm-6.5 
9.8h2.1v-4.2c0-1.6.9-2.2 2.4-2.2h.4v-1.9h-.2c-1.1 0-2.3.7-2.7 1.8v-1.7h-2zm-9.8 
2.9h2.1v-4c.3.7 1.2 1.3 2.4 1.3 2 0 3.5-1.5 3.5-4.4 0-3.1-1.5-4.3-3.3-4.3-1.3 
0-2.2.8-2.6 1.5v-1.4h-2v11.3zm2.1-6.6v-.9c0-1.4.8-2.3 1.9-2.3 1.4 0 1.9 1 1.9 
2.8 0 1.9-.7 2.9-1.9 2.9-1.3-.1-1.9-1.1-1.9-2.5m-7.8 1.4h-2c-.1.5-.5 1.1-1.6 
1.1-1.2 0-1.8-.8-1.9-2.4h5.6v-.7c0-2.3-1.1-4.2-3.8-4.2-2.5 0-3.9 1.8-3.9 4.3 0 
2.6 1.3 4.3 3.9 4.3 2.1.1 3.4-.8 3.7-2.4m-2-2.6h-3.5c.1-1.3.7-2.2 1.8-2.2s1.6.8 
1.7 2.2m-11.8 2.6 1.1-1.3 2.1 3.6h2.3l-3-5.1 2.8-3.2H246l-3 
3.6v-7.6h-2.1v12.2h2.1zm-9.3-3.6c0-.7.4-1.2 1.4-1.2.9 0 1.4.5 1.4 
1.6v.4c-1.8.1-3 .2-3.9.6q-1.2.6-1.2 2.1c0 1.5 1 2.4 2.7 2.4 1.2 0 2.1-.5 
2.5-1.3.2.9.7 1.3 2 1.3h.6v-1.5c-.5 0-.7-.2-.7-.7v-3c0-2.2-.9-3.2-3.4-3.2-2.1 
0-3.3 1-3.4 2.6h2zm1 4.6c-.8 0-1.2-.4-1.2-1.1 0-
 .4.1-.7.4-.9.4-.3 1.2-.4 2.7-.5v.2c-.1 1.6-1 2.3-1.9 2.3m-17.6 
1.3h2.1V144c0-1.2.6-2 1.8-2 .5 0 .9.2 1.1.5s.3.9.3 1.5v4.9h2.1V144c0-1.3.6-2 
1.8-2 .5 0 .9.1 1.1.5q.3.6.3 1.5v4.9h2.1v-5.5c0-2-.9-2.9-2.7-2.9-1.5 
0-2.4.9-2.7 1.7-.3-1.1-1.1-1.7-2.5-1.7-1.3 0-2.2.7-2.6 
1.6v-1.4h-2v8.1zm-5.8-2.3h-2c-.1.5-.5 1.1-1.6 1.1-1.2 
0-1.8-.8-1.9-2.4h5.6v-.7c0-2.3-1.1-4.2-3.8-4.2-2.5 0-3.9 1.8-3.9 4.3 0 2.6 1.3 
4.3 3.9 4.3 2.2.1 3.5-.8 3.7-2.4m-2-2.6h-3.5c.1-1.3.7-2.2 1.8-2.2 1.2 0 1.6.8 
1.7 2.2m-16.1 4.9 2-7.5c.3-1.2.4-1.9.4-1.9s.1.7.4 1.9l2.1 
7.5h2.2l3.2-11.8h-2l-1.9 7.3c-.3 1.2-.4 1.9-.4 1.9s-.1-.8-.4-2l-2-7.3h-2.1l-2 
7.3c-.3 1.2-.4 1.9-.4 1.9s-.1-.8-.4-2l-1.9-7.3h-2.2l3.2 
11.8h2.2zm250.4-41.3c-.2-2.9-2.3-4.8-6.4-4.8-4.3 0-6.5 2.4-6.5 5.3s1.7 4.4 4.7 
4.8l2.6.3c1.8.2 2.2.8 2.2 2 0 1.4-1.2 2.2-3 2.2-2.3 0-3-1.2-3.1-2.4h-3.9c.2 3.3 
2.6 5.2 7 5.2 4 0 6.9-1.9 6.9-5.5 
0-2.9-1.5-4.4-4.7-4.8l-2.7-.4c-1.5-.2-2.1-.8-2.1-1.9 0-1.2 1-2 2.6-2 1.7 0 
2.6.9 2.7 2zm-20.8 12.1h4.3v-11c0-4-1.8-5.9-5.5-5.9-2.8 0-4.5 
 1.5-5.4 3.1h-.1V103h-4v16.5h4.2v-9.7c0-2.5 1.2-4.1 3.7-4.1 1 0 1.8.3 2.3 1s.5 
1.8.5 2.9zm-21.9-14c2.7 0 3.7 2.3 3.7 5.8 0 3.4-1 5.8-3.7 
5.8s-3.7-2.3-3.7-5.8c0-3.4 1.1-5.8 3.7-5.8m0 14.4c4.8 0 8-3.3 8-8.7 
0-5.3-3-8.6-8-8.6s-8.1 3.3-8.1 8.6c.1 5.4 3 8.7 8.1 
8.7m-15.4-.4h4.2v-16.5h-4.2zm-.1-19.7h4.2V96h-4.2zm-10.9-1.5v1.2c0 3.1-.4 
3.5-2.5 3.5h-.6v2.9h2.7v8.9c0 3.4 1.7 4.9 5 4.9 1.4 0 2.6-.2 
3-.2v-3.1s-.8.1-1.5.1c-1.7 0-2.3-.7-2.3-2.4v-8.1h3.8v-3h-3.8v-4.7zm-16.6 
4.7h-4.1v11.2c0 3.9 1.8 5.7 5.5 5.7 2.7 0 4.4-1.4 
5.2-3.1h.1v2.7h4v-16.5h-4.2v9c0 3.1-1.2 4.7-3.7 4.7-1 
0-1.8-.3-2.2-1-.5-.7-.6-1.8-.6-2.9zm-12.5 16.5h4.2V95.2h-4.2zm-11.5-14c2.7 0 
3.7 2.3 3.7 5.8 0 3.4-1 5.8-3.7 5.8s-3.7-2.3-3.7-5.8c0-3.4 1-5.8 3.7-5.8m0 
14.4c4.8 0 8-3.3 8-8.7 0-5.3-3-8.6-8-8.6s-8.1 3.3-8.1 8.6c0 5.4 3 8.7 8.1 
8.7m-11.6-17.7c-.2-4-2.7-6.8-8.4-6.8-5.4 0-8.6 3-8.6 7 0 3.5 2.1 5.9 6.1 
6.6l3.5.7c2.6.5 3.6 1.5 3.6 3.3 0 2-1.3 3.7-4.6 3.7-3 0-4.6-1.8-4.9-4h-4.5c.2 
4.6 3.5 7.2 9.3 7.2 5.9 0 9.2-2.8 9.2-7.6 0-3.5-1.9-
 5.7-6.2-6.5l-3.5-.6c-2.4-.5-3.4-1.5-3.4-3.3 0-1.9 1.5-3.3 4-3.3 2.7 0 3.9 1.7 
4.1 3.6zm-37.4 17.4-.2.6c-.7 1.7-1.3 2.4-3.3 2.4-.6 
0-1.2-.1-1.6-.2v3.1c.2.1.9.2 2.2.2 4.1 0 5.5-1.6 6.8-5.5l5.9-17.2h-4.1l-2.9 
9.3c-.5 1.7-.8 3-.8 
3h-.1s-.2-1.3-.8-3l-3-9.3h-4.2zm-7.9-11c-.2-4.1-3.2-6-7.2-6-5 0-8 3.4-8 8.7 0 
5.4 2.9 8.6 8 8.6 4.1 0 7.2-2.1 7.4-6.3h-4c-.1 1.5-.9 3.3-3.3 3.3-3 
0-3.7-2.8-3.7-5.8 0-3.2 1.1-5.7 3.7-5.7 2 0 3 1.4 3.2 
3.1h3.9zm-28.6-.8c.1-1.3.9-2.4 2.8-2.4s2.8 1 2.8 3.3v.8c-3.6.2-6.1.4-7.8 
1.3s-2.5 2.3-2.5 4.2c0 3 2.1 4.8 5.5 4.8 2.4 0 4.1-1 5.1-2.7h.1c.4 1.9 1.5 2.5 
3.9 2.5h1.2v-3c-1.1 0-1.4-.4-1.4-1.5v-6.1c0-4.4-1.9-6.4-6.8-6.4-4.2 0-6.7 2-6.8 
5.1h3.9zm1.8 9.1c-1.5 0-2.4-.9-2.4-2.2 0-.8.2-1.4.8-1.8.9-.6 2.4-.9 5.3-1v.5c0 
3.2-1.9 4.5-3.7 4.5m-18.2 2.6h4.3l5.8-16.5h-4l-3 9.1c-.5 1.7-.9 3.3-.9 
3.3h-.1s-.3-1.6-.9-3.3l-2.9-9.1h-4.2zm-12.8 
0h4.2v-16.5h-4.2zm0-19.7h4.2V96h-4.2zm-12.4 19.7h4.2v-8.5c0-3.2 1.8-4.4 
4.7-4.4h.8v-3.9h-.3c-2.3 0-4.5 1.4-5.4 3.6h-.1v-3.3h-3.9zM192 108v-8.9h3.
 4c2.8 0 4.5 1.2 4.5 4.4 0 3-1.7 4.5-4.6 4.5zm3.2 3.1c5.1 0 9.1-2.2 9.1-7.7 
0-5.4-3.8-7.5-8.7-7.5h-7.9v23.7h4.3v-8.5z" 
style="fill:#717074;fill-rule:nonzero" transform="translate(-489.672 
-353.755)scale(19.9587)"/><path d="M82.3 52.3c5.5-2.5 11.7-3.9 18.1-3.9 24.3 0 
44 19.6 44 43.7 0 8.6-2.5 16.7-6.9 23.5 15.4-6.8 26.2-22.1 26.2-40 
0-24.2-19.7-43.7-44-43.7-15.5 0-29.2 8-37 20.1" 
style="fill:#0079c1;fill-rule:nonzero" transform="translate(-489.672 
-353.755)scale(19.9587)"/><path d="M75.7 75.7V137c0 2.5 0 5-2.4 7.2l-10.6 
10.3c-3.4 3.3-6.3.7-6.3-2.9V92.2c0-17.7 10.6-33 26-40-4.1 6.7-6.7 14.8-6.7 
23.5m61.8 39.9c-7.8 12.2-21.5 20.3-37.1 20.3-2.6 0-3.1 
0-6.4-.5-3-.4-4.2-2.4-1.7-4.7l10.8-10.6c1.7-1.6 3.5-1.7 6.3-1.3s6.4.7 
10.3.7c6.3-.1 12.3-1.4 17.8-3.9" style="fill:#00457c;fill-rule:nonzero" 
transform="translate(-489.672 -353.755)scale(19.9587)"/><path d="M0 
0h500v212H0z" style="fill:none;fill-rule:nonzero" transform="translate(-489.672 
-353.755)scale(19.9587)"/></svg>
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/structlog-25.1.0/docs/api.rst 
new/structlog-25.2.0/docs/api.rst
--- old/structlog-25.1.0/docs/api.rst   2025-01-16 11:09:21.000000000 +0100
+++ new/structlog-25.2.0/docs/api.rst   2025-03-11 18:32:04.000000000 +0100
@@ -197,7 +197,7 @@
          ...     1 / 0
          ... except ZeroDivisionError:
          ...     log.exception("Cannot compute!")
-         {"event": "Cannot compute!", "exception": [{"exc_type": 
"ZeroDivisionError", "exc_value": "division by zero", "syntax_error": null, 
"is_cause": false, "frames": [{"filename": "<doctest default[3]>", "lineno": 2, 
"name": "<module>", "locals": {..., "var": "'spam'"}}]}]}
+         {"event": "Cannot compute!", "exception": [{"exc_type": 
"ZeroDivisionError", "exc_value": "division by zero", "exc_notes": [], 
"syntax_error": null, "is_cause": false, "frames": [{"filename": "<doctest 
default[3]>", "lineno": 2, "name": "<module>", "locals": {..., "var": 
"'spam'"}}]}]}
 
 .. autoclass:: KeyValueRenderer
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/structlog-25.1.0/docs/configuration.md 
new/structlog-25.2.0/docs/configuration.md
--- old/structlog-25.1.0/docs/configuration.md  2025-01-16 11:09:21.000000000 
+0100
+++ new/structlog-25.2.0/docs/configuration.md  2025-03-11 18:32:04.000000000 
+0100
@@ -75,7 +75,7 @@
 In the simplest case, it's a function that returns a logger -- or just a class.
 But you can also pass in an instance of a class with a `__call__` method for 
more complicated setups.
 
-These will be passed to the logger factories.
+The arguments you pass to `structlog.get_logger()` will be passed to the 
logger factory.
 For example, if you use `structlog.get_logger("a name")` and configure 
*structlog* to use the standard library 
{class}`~structlog.stdlib.LoggerFactory`, which has support for positional 
parameters, the returned logger will have the name `"a name"`.
 
 For the common cases of standard library logging and Twisted logging, 
*structlog* comes with two factories built right in:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/structlog-25.1.0/docs/index.md 
new/structlog-25.2.0/docs/index.md
--- old/structlog-25.1.0/docs/index.md  2025-01-16 11:09:21.000000000 +0100
+++ new/structlog-25.2.0/docs/index.md  2025-03-11 18:32:04.000000000 +0100
@@ -22,6 +22,7 @@
 <a href="https://www.variomedia.de/";><img title="Variomedia AG" 
src="_static/sponsors/Variomedia.svg" width="190" /></a>
 <a 
href="https://tidelift.com/?utm_source=lifter&utm_medium=referral&utm_campaign=hynek";><img
 title="Tidelift" src="_static/sponsors/Tidelift.svg" width="190" /></a>
 <a href="https://klaviyo.com/";><img title="Klaviyo" 
src="_static/sponsors/Klaviyo.svg" width="190" /></a>
+<a href="https://privacy-solutions.org/";><img title="Privacy Solutions" 
src="_static/sponsors/Privacy-Solutions.svg" width="190" /></a>
 <a href="https://www.emsys-renewables.com/";><img title="emsys renewables" 
src="_static/sponsors/emsys-renewables.svg" width="190" /></a>
 <a href="https://filepreviews.io/";><img title="FilePreviews" 
src="_static/sponsors/FilePreviews.svg" width="190" /></a>
 <a href="https://polar.sh/";><img title="Polar" 
src="_static/sponsors/Polar.svg" width="190" /></a>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/structlog-25.1.0/docs/standard-library.md 
new/structlog-25.2.0/docs/standard-library.md
--- old/structlog-25.1.0/docs/standard-library.md       2025-01-16 
11:09:21.000000000 +0100
+++ new/structlog-25.2.0/docs/standard-library.md       2025-03-11 
18:32:04.000000000 +0100
@@ -32,7 +32,7 @@
 
 This will send all log messages with the [log 
level](https://docs.python.org/3/library/logging.html#logging-levels) 
`logging.INFO` and above (that means that, for example, `logging.debug` calls 
are ignored) to standard out without any special formatting by the standard 
library.
 
-If you require more complex behavior, please refer to the standard library's 
`logging` documentation.
+If you require more complex behavior, please refer to the standard library's 
{mod}`logging` documentation.
 
 
 ## Concrete bound logger
@@ -48,7 +48,7 @@
 
 ### `asyncio`
 
-For `asyncio` applications, you may not want your whole application to block 
while the processor chain is formatting your log entries.
+In {mod}`asyncio` applications, you may not want your whole application to 
block while the processor chain is formatting your log entries.
 
 For that use case *structlog* comes with a set of non-standard methods that 
will do all processing in a thread pool executor.
 They have the same names as the regular methods, except they are prefixed by 
an `a`.
@@ -151,7 +151,7 @@
 For instance, if you log JSON in production, configure `logging` to use 
[*python-json-logger*] to make it print JSON too, and then tweak the 
configuration to match their outputs.
 You can also use {class}`~structlog.stdlib.ProcessorFormatter` as a formatter 
for `logging` to get the same output for both *structlog* and `logging` log 
entries -- see [below](processor-formatter) for an example.
 
-:::{note}
+:::{important}
 If you want to use same file (for example, `sys.stdout` or `sys.stderr`) for 
both *structlog* and `logging.StreamHandler` output, you must use 
{class}`~structlog.WriteLogger` instead of {class}`~structlog.PrintLogger`.
 
 This is because {class}`~structlog.PrintLogger` uses `print(log, file=file, 
flush=True)` to write log, and `print` writes the `log` message and a newline 
("\n") to the stream separately.
@@ -171,7 +171,8 @@
 flowchart TD
     User
     structlog
-    stdlib[Standard Library\ne.g. logging.StreamHandler]
+    stdlib[Standard Library
+    e.g. logging.StreamHandler]
 
     User --> |"structlog.get_logger().info('foo')"| structlog
     User --> |"logging.getLogger().info('foo')"| stdlib
@@ -231,7 +232,7 @@
 )
 ```
 
-To make your program behave like a proper [*12 Factor 
App*](https://12factor.net/logs) that outputs only JSON to `stdout`, configure 
the `logging` module like this:
+To make your program behave like a proper [12 Factor 
App](https://12factor.net/logs) that outputs only JSON to `stdout`, configure 
the `logging` module like this:
 
 ```
 import logging
@@ -265,7 +266,8 @@
 flowchart TD
     User
     structlog
-    stdlib[Standard Library\ne.g. logging.StreamHandler]
+    stdlib[Standard Library
+    e.g. logging.StreamHandler]
 
     User --> |"structlog.get_logger().info('foo', bar=42)"| structlog
     User --> |"logging.getLogger().info('foo')"| stdlib
@@ -354,9 +356,11 @@
     structlog --> |"logging.getLogger().info(event_dict, {#quot;extra#quot;: 
{#quot;_logger#quot;: logger, #quot;_name#quot;: name})"| stdlib
 
     stdlib --> |"structlog.stdlib.ProcessorFormatter.format(logging.Record)"| 
structlog2
-    structlog2 --> |"Returns a string that is passed into logging 
handlers.\nThis flow is controlled by the logging configuration."| stdlib2
+    structlog2 --> |"Returns a string that is passed into logging handlers.
+    This flow is controlled by the logging configuration."| stdlib2
 
-    stdlib2[Standard Library\ne.g. logging.StreamHandler] ==> Output
+    stdlib2[Standard Library
+    e.g. logging.StreamHandler] ==> Output
 ```
 
 {class}`~structlog.stdlib.ProcessorFormatter` has two parts to its API:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/structlog-25.1.0/docs/thread-local.md 
new/structlog-25.2.0/docs/thread-local.md
--- old/structlog-25.1.0/docs/thread-local.md   2025-01-16 11:09:21.000000000 
+0100
+++ new/structlog-25.2.0/docs/thread-local.md   2025-03-11 18:32:04.000000000 
+0100
@@ -128,7 +128,7 @@
 The convenience of having a thread-local context comes at a price though:
 
 :::{warning}
-- If you can't rule out that your application re-uses threads, you *must* 
remember to **initialize your thread-local context** at the start of each 
request using {func}`~structlog.BoundLogger.new` (instead of 
{func}`~structlog.BoundLogger.bind`).
+- If you can't rule out that your application reuses threads, you *must* 
remember to **initialize your thread-local context** at the start of each 
request using {func}`~structlog.BoundLogger.new` (instead of 
{func}`~structlog.BoundLogger.bind`).
   Otherwise you may start a new request with the context still filled with 
data from the request before.
 
 - **Don't** stop assigning the results of your `bind()`s and `new()`s!
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/structlog-25.1.0/pyproject.toml 
new/structlog-25.2.0/pyproject.toml
--- old/structlog-25.1.0/pyproject.toml 2025-01-16 11:09:21.000000000 +0100
+++ new/structlog-25.2.0/pyproject.toml 2025-03-11 18:32:04.000000000 +0100
@@ -258,6 +258,11 @@
 img = "Klaviyo.svg"
 
 [[tool.sponcon.sponsors]]
+title = "Privacy Solutions"
+url = "https://privacy-solutions.org/";
+img = "Privacy-Solutions.svg"
+
+[[tool.sponcon.sponsors]]
 title = "emsys renewables"
 url = "https://www.emsys-renewables.com/";
 img = "emsys-renewables.svg"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/structlog-25.1.0/src/structlog/_base.py 
new/structlog-25.2.0/src/structlog/_base.py
--- old/structlog-25.1.0/src/structlog/_base.py 2025-01-16 11:09:21.000000000 
+0100
+++ new/structlog-25.2.0/src/structlog/_base.py 2025-03-11 18:32:04.000000000 
+0100
@@ -111,7 +111,7 @@
 
         Only necessary with dict implementations that keep global state like
         those wrapped by `structlog.threadlocal.wrap_dict` when threads
-        are re-used.
+        are reused.
         """
         self._context.clear()
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/structlog-25.1.0/src/structlog/dev.py 
new/structlog-25.2.0/src/structlog/dev.py
--- old/structlog-25.1.0/src/structlog/dev.py   2025-01-16 11:09:21.000000000 
+0100
+++ new/structlog-25.2.0/src/structlog/dev.py   2025-03-11 18:32:04.000000000 
+0100
@@ -55,6 +55,7 @@
 
 __all__ = [
     "ConsoleRenderer",
+    "RichTracebackFormatter",
     "better_traceback",
     "plain_traceback",
     "rich_traceback",
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/structlog-25.1.0/src/structlog/processors.py 
new/structlog-25.2.0/src/structlog/processors.py
--- old/structlog-25.1.0/src/structlog/processors.py    2025-01-16 
11:09:21.000000000 +0100
+++ new/structlog-25.2.0/src/structlog/processors.py    2025-03-11 
18:32:04.000000000 +0100
@@ -55,6 +55,7 @@
     "ExceptionPrettyPrinter",
     "JSONRenderer",
     "KeyValueRenderer",
+    "LogfmtRenderer",
     "StackInfoRenderer",
     "TimeStamper",
     "UnicodeDecoder",
@@ -524,7 +525,8 @@
     else:
 
         def now() -> datetime.datetime:
-            # A naive local datetime is fine here, because we only format it.
+            # We don't need the TZ for our own formatting. We add it only for
+            # user-defined formats later.
             return datetime.datetime.now()  # noqa: DTZ005
 
     if fmt is None:
@@ -552,7 +554,7 @@
         return stamper_iso_local
 
     def stamper_fmt(event_dict: EventDict) -> EventDict:
-        event_dict[key] = now().strftime(fmt)
+        event_dict[key] = now().astimezone().strftime(fmt)
 
         return event_dict
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/structlog-25.1.0/src/structlog/stdlib.py 
new/structlog-25.2.0/src/structlog/stdlib.py
--- old/structlog-25.1.0/src/structlog/stdlib.py        2025-01-16 
11:09:21.000000000 +0100
+++ new/structlog-25.2.0/src/structlog/stdlib.py        2025-03-11 
18:32:04.000000000 +0100
@@ -21,6 +21,13 @@
 from functools import partial
 from typing import Any, Callable, Collection, Dict, Iterable, Sequence, cast
 
+
+if sys.version_info >= (3, 11):
+    from typing import Self
+else:
+    from typing_extensions import Self
+
+
 from . import _config
 from ._base import BoundLoggerBase
 from ._frames import _find_first_app_frame_and_name, _format_stack
@@ -155,13 +162,13 @@
 
     _logger: logging.Logger
 
-    def bind(self, **new_values: Any) -> BoundLogger:
+    def bind(self, **new_values: Any) -> Self:
         """
         Return a new logger with *new_values* added to the existing ones.
         """
         return super().bind(**new_values)
 
-    def unbind(self, *keys: str) -> BoundLogger:
+    def unbind(self, *keys: str) -> Self:
         """
         Return a new logger with *keys* removed from the context.
 
@@ -170,7 +177,7 @@
         """
         return super().unbind(*keys)
 
-    def try_unbind(self, *keys: str) -> BoundLogger:
+    def try_unbind(self, *keys: str) -> Self:
         """
         Like :meth:`unbind`, but best effort: missing keys are ignored.
 
@@ -178,13 +185,13 @@
         """
         return super().try_unbind(*keys)
 
-    def new(self, **new_values: Any) -> BoundLogger:
+    def new(self, **new_values: Any) -> Self:
         """
         Clear context and binds *initial_values* using `bind`.
 
         Only necessary with dict implementations that keep global state like
         those wrapped by `structlog.threadlocal.wrap_dict` when threads
-        are re-used.
+        are reused.
         """
         return super().new(**new_values)
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/structlog-25.1.0/src/structlog/testing.py 
new/structlog-25.2.0/src/structlog/testing.py
--- old/structlog-25.1.0/src/structlog/testing.py       2025-01-16 
11:09:21.000000000 +0100
+++ new/structlog-25.2.0/src/structlog/testing.py       2025-03-11 
18:32:04.000000000 +0100
@@ -194,7 +194,7 @@
     r"""
     Produce and cache `CapturingLogger`\ s.
 
-    Each factory produces and re-uses only **one** logger.
+    Each factory produces and reuses only **one** logger.
 
     You can access it via the ``logger`` attribute.
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/structlog-25.1.0/src/structlog/tracebacks.py 
new/structlog-25.2.0/src/structlog/tracebacks.py
--- old/structlog-25.1.0/src/structlog/tracebacks.py    2025-01-16 
11:09:21.000000000 +0100
+++ new/structlog-25.2.0/src/structlog/tracebacks.py    2025-03-11 
18:32:04.000000000 +0100
@@ -81,10 +81,14 @@
 class Stack:
     """
     Represents an exception and a list of stack frames.
+
+    .. versionchanged:: 25.2.0
+       Added the *exc_notes* field.
     """
 
     exc_type: str
     exc_value: str
+    exc_notes: list[str] = field(default_factory=list)
     syntax_error: SyntaxError_ | None = None
     is_cause: bool = False
     frames: list[Frame] = field(default_factory=list)
@@ -230,6 +234,9 @@
         stack = Stack(
             exc_type=safe_str(exc_type.__name__),
             exc_value=safe_str(exc_value),
+            exc_notes=[
+                safe_str(note) for note in getattr(exc_value, "__notes__", ())
+            ],
             is_cause=is_cause,
         )
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/structlog-25.1.0/tests/processors/test_renderers.py 
new/structlog-25.2.0/tests/processors/test_renderers.py
--- old/structlog-25.1.0/tests/processors/test_renderers.py     2025-01-16 
11:09:21.000000000 +0100
+++ new/structlog-25.2.0/tests/processors/test_renderers.py     2025-03-11 
18:32:04.000000000 +0100
@@ -396,8 +396,8 @@
     @freeze_time("1980-03-25 16:00:00")
     def test_local(self):
         """
-        Timestamp in local timezone work.  We can't add a timezone to the
-        string without additional libraries.
+        Timestamp in local timezone work. Due to historic reasons, the default
+        format does not include a timezone.
         """
         ts = TimeStamper(fmt="iso", utc=False)
         d = ts(None, None, {})
@@ -415,6 +415,17 @@
         assert "1980" == d["timestamp"]
 
     @freeze_time("1980-03-25 16:00:00")
+    def test_tz_aware(self):
+        """
+        The timestamp that is used for formatting is timezone-aware.
+        """
+        ts = TimeStamper(fmt="%z")
+        d = ts(None, None, {})
+
+        assert "" == datetime.datetime.now().strftime("%z")  # noqa: DTZ005
+        assert "" != d["timestamp"]
+
+    @freeze_time("1980-03-25 16:00:00")
     def test_adds_Z_to_iso(self):
         """
         stdlib's isoformat is buggy, so we fix it.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/structlog-25.1.0/tests/test_tracebacks.py 
new/structlog-25.2.0/tests/test_tracebacks.py
--- old/structlog-25.1.0/tests/test_tracebacks.py       2025-01-16 
11:09:21.000000000 +0100
+++ new/structlog-25.2.0/tests/test_tracebacks.py       2025-03-11 
18:32:04.000000000 +0100
@@ -160,6 +160,40 @@
     ] == trace.stacks
 
 
+@pytest.mark.skipif(
+    sys.version_info < (3, 11), reason="Requires Python 3.11 or higher"
+)
+def test_simple_exception_with_notes():
+    """
+    Notes are included in the traceback.
+    """
+    try:
+        lineno = get_next_lineno()
+        1 / 0
+    except Exception as e:
+        e.add_note("This is a note.")
+        e.add_note("This is another note.")
+        trace = tracebacks.extract(type(e), e, e.__traceback__)
+
+    assert [
+        tracebacks.Stack(
+            exc_type="ZeroDivisionError",
+            exc_value="division by zero",
+            exc_notes=["This is a note.", "This is another note."],
+            syntax_error=None,
+            is_cause=False,
+            frames=[
+                tracebacks.Frame(
+                    filename=__file__,
+                    lineno=lineno,
+                    name="test_simple_exception_with_notes",
+                    locals=None,
+                ),
+            ],
+        ),
+    ] == trace.stacks
+
+
 def test_raise_hide_cause():
     """
     If "raise ... from None" is used, the trace looks like from a simple
@@ -588,6 +622,7 @@
         {
             "exc_type": "ZeroDivisionError",
             "exc_value": "division by zero",
+            "exc_notes": [],
             "frames": [
                 {
                     "filename": __file__,
@@ -601,6 +636,40 @@
     ] == result
 
 
+@pytest.mark.skipif(
+    sys.version_info < (3, 11), reason="Requires Python 3.11 or higher"
+)
+def test_json_traceback_with_notes():
+    """
+    Tracebacks are formatted to JSON with all information.
+    """
+    try:
+        lineno = get_next_lineno()
+        1 / 0
+    except Exception as e:
+        e.add_note("This is a note.")
+        e.add_note("This is another note.")
+        format_json = tracebacks.ExceptionDictTransformer(show_locals=False)
+        result = format_json((type(e), e, e.__traceback__))
+
+    assert [
+        {
+            "exc_type": "ZeroDivisionError",
+            "exc_value": "division by zero",
+            "exc_notes": ["This is a note.", "This is another note."],
+            "frames": [
+                {
+                    "filename": __file__,
+                    "lineno": lineno,
+                    "name": "test_json_traceback_with_notes",
+                }
+            ],
+            "is_cause": False,
+            "syntax_error": None,
+        },
+    ] == result
+
+
 def test_json_traceback_locals_max_string():
     """
     Local variables in each frame are trimmed to locals_max_string.
@@ -617,6 +686,7 @@
         {
             "exc_type": "ZeroDivisionError",
             "exc_value": "division by zero",
+            "exc_notes": [],
             "frames": [
                 {
                     "filename": __file__,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/structlog-25.1.0/tox.ini new/structlog-25.2.0/tox.ini
--- old/structlog-25.1.0/tox.ini        2025-01-16 11:09:21.000000000 +0100
+++ new/structlog-25.2.0/tox.ini        2025-03-11 18:32:04.000000000 +0100
@@ -109,6 +109,5 @@
 commands =
     rm -rf structlog.docset structlog.tgz docs/_build
     sphinx-build -n -T -W -b html -d {envtmpdir}/doctrees docs docs/_build/html
-    doc2dash --index-page index.html --icon docs/_static/docset-icon.png 
--online-redirect-url https://www.structlog.org/en/latest/ docs/_build/html
-    cp docs/_static/docset-i...@2x.png structlog.docset/i...@2x.png
+    doc2dash --index-page index.html --icon docs/_static/docset-icon.png 
--icon-2x docs/_static/docset-i...@2x.png --online-redirect-url 
https://www.structlog.org/en/latest/ docs/_build/html
     tar --exclude='.DS_Store' -cvzf structlog.tgz structlog.docset

Reply via email to