Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package python-pycairo for openSUSE:Factory 
checked in at 2022-11-29 10:52:26
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-pycairo (Old)
 and      /work/SRC/openSUSE:Factory/.python-pycairo.new.1597 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-pycairo"

Tue Nov 29 10:52:26 2022 rev:9 rq:1038683 version:1.22.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-pycairo/python-pycairo.changes    
2022-09-21 14:40:19.093403150 +0200
+++ /work/SRC/openSUSE:Factory/.python-pycairo.new.1597/python-pycairo.changes  
2022-11-29 10:52:28.328521221 +0100
@@ -1,0 +2,19 @@
+Mon Nov 28 12:32:35 UTC 2022 - Dominique Leuenberger <dims...@opensuse.org>
+
+- Updtae to version 1.22.0:
+  * Officially support Python 3.11.
+  * PDFSurface.version_to_string(): Fix crash with negative
+    versions.
+  * typing: ImageSurface.get_stride() returns an int.
+  * typing: Fix incorrect interface for Matrix constructor.
+  * typing: Use Generic for Context.
+  * docs: some cairo.Context fixes.
+  * docs: try to make create_from_png/write_to_png more clear.
+  * docs: add an example for how to convert a surface to pillow.
+  * docs: cairo.Format.RGB24: document that unused bytes may be
+    overwritten.
+  * tests: don’t depend on specific ref counts.
+  * tests: compatibility fixes for cairo 1.17.6.
+- Drop f5a795ea.patch: fixed upstream.
+
+-------------------------------------------------------------------

Old:
----
  f5a795ea.patch
  pycairo-1.21.0.tar.gz

New:
----
  pycairo-1.22.0.tar.gz

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

Other differences:
------------------
++++++ python-pycairo.spec ++++++
--- /var/tmp/diff_new_pack.o1doeq/_old  2022-11-29 10:52:28.796523680 +0100
+++ /var/tmp/diff_new_pack.o1doeq/_new  2022-11-29 10:52:28.800523701 +0100
@@ -20,14 +20,12 @@
 %define skip_python2 1
 %define         oldpython python
 Name:           python-pycairo
-Version:        1.21.0
+Version:        1.22.0
 Release:        0
 Summary:        Python Bindings for Cairo
 License:        LGPL-2.1-or-later OR MPL-1.1
 URL:            https://github.com/pygobject/pycairo
 Source:         %{url}/releases/download/v%{version}/pycairo-%{version}.tar.gz
-# PATCH-FIX-UPSTREAM f5a795ea.patch -- Some test improvements for cairo 1.17.6
-Patch:          %{url}/commit/f5a795ea.patch
 
 BuildRequires:  %{python_module devel}
 BuildRequires:  %{python_module pytest}

++++++ pycairo-1.21.0.tar.gz -> pycairo-1.22.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pycairo-1.21.0/NEWS new/pycairo-1.22.0/NEWS
--- old/pycairo-1.21.0/NEWS     2022-03-07 07:22:20.000000000 +0100
+++ new/pycairo-1.22.0/NEWS     2022-11-19 14:14:24.000000000 +0100
@@ -1,3 +1,22 @@
+Since version 1.11.0 Pycairo uses `Semantic Versioning <http://semver.org/>`__
+
+.. _v1.22.0:
+
+1.22.0 - 2022-11-19
+-------------------
+
+* Officially support Python 3.11 :pr:`285`
+* PDFSurface.version_to_string(): Fix crash with negative versions :pr:`279`
+* typing: ImageSurface.get_stride() returns an int :pr:`282`
+* typing: Fix incorrect interface for Matrix constructor :pr:`271`
+* typing: Use Generic for Context :pr:`274`
+* docs: some cairo.Context fixes :pr:`276`
+* docs: try to make create_from_png/write_to_png more clear :pr:`261`
+* docs: add an example for how to convert a surface to pillow :pr:`281`
+* docs: cairo.Format.RGB24: document that unused bytes may be overwritten 
:pr:`289`
+* tests: don't depend on specific ref counts :pr:`291`
+* tests: compatibility fixes for cairo 1.17.6 :pr:`264`
+
 .. _v1.21.0:
 
 1.21.0 - 2022-03-07
@@ -77,7 +96,7 @@
 
 * meson: install .egg-info to platlib
 * meson: fix configure error with meson 0.50 re absolute paths :pr:`145`
-* PyPy: don't use PyOS_FSPath() with PyPy3.6, it's missing: 
https://bitbucket.org/pypy/pypy/issues/2961
+* PyPy: don't use PyOS_FSPath() with PyPy3.6, it's missing: 
https://foss.heptapod.net/pypy/pypy/-/issues/2961
 * Docs fixes :pr:`134` (:user:`Matteo Italia <cvtsi2sd>`)
 
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pycairo-1.21.0/PKG-INFO new/pycairo-1.22.0/PKG-INFO
--- old/pycairo-1.21.0/PKG-INFO 2022-03-07 07:41:38.199820300 +0100
+++ new/pycairo-1.22.0/PKG-INFO 2022-11-19 14:16:05.907942000 +0100
@@ -1,6 +1,6 @@
 Metadata-Version: 2.1
 Name: pycairo
-Version: 1.21.0
+Version: 1.22.0
 Summary: Python interface for cairo
 Home-page: https://pycairo.readthedocs.io
 Maintainer: Christoph Reiter
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pycairo-1.21.0/cairo/__init__.pyi 
new/pycairo-1.22.0/cairo/__init__.pyi
--- old/pycairo-1.21.0/cairo/__init__.pyi       2022-02-27 21:29:48.000000000 
+0100
+++ new/pycairo-1.22.0/cairo/__init__.pyi       2022-11-19 11:28:50.000000000 
+0100
@@ -1,6 +1,6 @@
 from __future__ import annotations
 
-from typing import (Any, BinaryIO, ByteString, Callable, List, Optional,
+from typing import (Any, BinaryIO, ByteString, Callable, Generic, List, 
Optional,
                     Sequence, Text, Tuple, TypeVar, Union)
 
 del annotations
@@ -298,8 +298,10 @@
 
     RGB24: "Format" = ...
     """
-    each pixel is a 32-bit quantity, with the upper 8 bits unused. Red,
+    each pixel is a 32-bit quantity, with the upper 8 bits unused. [#]_  Red,
     Green, and Blue are stored in the remaining 24 bits in that order.
+
+    .. [#] Cairo operators (for example CLEAR and SRC) may overwrite unused 
bytes as an implementation side-effect, their values should be considered 
undefined.
     """
 
     RGB30: "Format" = ...
@@ -958,7 +960,7 @@
     https://www.cairographics.org/cookbook/matrix_transform/
     """
 
-    def __init__(self, xx: float = 1.0, yx: float = 0.0, yy: float = 1.0, x0: 
float = 0.0, y0: float = 0.0) -> None:
+    def __init__(self, xx: float = 1.0, yx: float = 0.0, xy: float = 0.0, yy: 
float = 1.0, x0: float = 0.0, y0: float = 0.0) -> None:
         """
         :param xx: xx component of the affine transformation
         :param yx: yx component of the affine transformation
@@ -2156,13 +2158,14 @@
 
     def write_to_png(self, fobj: Union[_FileLike, _PathLike]) -> None:
         """
-        :param fobj: the file to write to
+        :param fobj: a filename or writable file object
         :raises: :exc:`MemoryError` if memory could not be allocated for the 
operation
 
                 :exc:`IOError` if an I/O error occurs while attempting to write
                 the file
 
-        Writes the contents of *Surface* to *fobj* as a PNG image.
+        Writes the contents of *Surface* to *fobj* as a PNG image. *fobj* can 
either be
+        a filename or a file object opened in binary mode.
         """
 
     def unmap_image(self, image: "ImageSurface") -> None:
@@ -2239,8 +2242,12 @@
         """
         :param fobj:
             a :obj:`_PathLike`, file, or file-like object of the PNG to load.
-        :returns: a new *ImageSurface* initialized the contents to the given
-            PNG file.
+        :returns: a new *ImageSurface* initialized the contents to the given 
PNG
+            file.
+
+        Creates a new image surface and initializes the contents to the given
+        PNG file. *fobj* can either be a filename or a file object opened in
+        binary mode.
         """
 
     format_stride_for_width = Format.stride_for_width
@@ -2272,7 +2279,7 @@
         :returns: the height of the *ImageSurface* in pixels.
         """
 
-    def get_stride(self) -> bytes:
+    def get_stride(self) -> int:
         """
         :returns: the stride of the *ImageSurface* in bytes. The stride is the
             distance in bytes from the beginning of one row of the image data 
to
@@ -2298,7 +2305,7 @@
         .. versionadded:: 1.4
         """
 
-class Context:
+class Context(Generic[_SomeSurface]):
     """
     *Context* is the main object used when drawing with cairo. To draw with 
cairo,
     you create a *Context*, set the target surface, and drawing options for the
@@ -2311,7 +2318,7 @@
     :meth:`Context.restore` to restore to the saved state.
     """
 
-    def __init__(self, target: Surface) -> None:
+    def __init__(self, target: _SomeSurface) -> None:
         """
         :param target: target :class:`Surface` for the context
         :raises: :exc:`MemoryError` in case of no memory
@@ -2646,7 +2653,7 @@
         :meth:`Context.rel_line_to`, :meth:`Context.rel_curve_to`,
         :meth:`Context.arc`, :meth:`Context.arc_negative`,
         :meth:`Context.rectangle`, :meth:`Context.text_path`,
-        :meth:`Context.glyph_path`, `Context.stroke_to_path`.
+        :meth:`Context.glyph_path`.
 
         Some functions use and alter the current point but do not otherwise
         change current path:
@@ -2769,7 +2776,7 @@
         :returns: the current source :class:`Pattern` for  a :class:`Context`.
         """
 
-    def get_target(self) -> Surface:
+    def get_target(self) -> _SomeSurface:
         """
         :returns: the target :class:`Surface` for the :class:`Context`
         """
@@ -2819,6 +2826,21 @@
         device-space unit.
         """
 
+    def in_clip(self, x: float, y: float) -> bool:
+        """
+        :param x: X coordinate of the point to test
+        :param y: Y coordinate of the point to test
+        :returns: :obj:`True` if the point is inside, or :obj:`False` if 
outside.
+
+        Tests whether the given point is inside the area that would be visible
+        through the current clip, i.e. the area that would be filled by a
+        :meth:`paint` operation.
+
+        See :meth:`clip`, and :meth:`clip_preserve`.
+
+        .. versionadded:: 1.12.0
+        """
+
     def in_fill(self, x: float, y: float) -> bool:
         """
         :param x: X coordinate of the point to test
@@ -3335,9 +3357,8 @@
         Sets the current line cap style within the :class:`Context`.
 
         As with the other stroke parameters, the current line cap style is
-        examined by :meth:`.stroke`, :meth:`.stroke_extents`, and
-        `Context.stroke_to_path`, but does not have any effect during path
-        construction.
+        examined by :meth:`.stroke` and :meth:`.stroke_extents`, but does not
+        have any effect during path construction.
 
         The default line cap style is :attr:`cairo.LineCap.BUTT`.
         """
@@ -3349,9 +3370,8 @@
         Sets the current line join style within the :class:`Context`.
 
         As with the other stroke parameters, the current line join style is
-        examined by :meth:`.stroke`, :meth:`.stroke_extents`, and
-        `Context.stroke_to_path`, but does not have any effect during path
-        construction.
+        examined by :meth:`.stroke` and :meth:`.stroke_extents`, but does not
+        have any effect during path construction.
 
         The default line join style is :attr:`cairo.LineJoin.MITER`.
         """
@@ -3375,9 +3395,8 @@
         note.
 
         As with the other stroke parameters, the current line width is examined
-        by :meth:`.stroke`, :meth:`.stroke_extents`, and
-        `Context.stroke_to_path`, but does not have any effect during path
-        construction.
+        by :meth:`.stroke` and :meth:`.stroke_extents`, but does not have any
+        effect during path construction.
 
         The default line width value is 2.0.
         """
@@ -3404,9 +3423,8 @@
         is greater than the miter limit, the style is converted to a bevel.
 
         As with the other stroke parameters, the current line miter limit is
-        examined by :meth:`.stroke`, :meth:`.stroke_extents`, and
-        `Context.stroke_to_path`, but does not have any effect during path
-        construction.
+        examined by :meth:`.stroke` and :meth:`.stroke_extents`, but does not
+        have any effect during path construction.
 
         The default miter limit value is 10.0, which will convert joins with
         interior angles less than 11 degrees to bevels instead of miters. For
@@ -3577,6 +3595,36 @@
         "real" text display API in cairo.
         """
 
+    def show_text_glyphs(self, utf8: str, glyphs: List["Glyph"], clusters: 
List[TextCluster], cluster_flags: TextClusterFlags) -> None:
+        """
+        :param utf8: a string of text
+        :param glyphs: list of glyphs to show
+        :param clusters: list of cluster mapping information
+        :param cluster_flags: cluster mapping flags
+        :raises Error:
+
+        .. versionadded:: 1.15
+
+        This operation has rendering effects similar to
+        :meth:`Context.show_glyphs` but, if the target surface supports it, 
uses
+        the provided text and cluster mapping to embed the text for the glyphs
+        shown in the output. If the target does not support the extended
+        attributes, this function acts like the basic
+        :meth:`Context.show_glyphs` as if it had been passed ``glyphs`` .
+
+        The mapping between utf8 and glyphs is provided by a list of clusters.
+        Each cluster covers a number of text bytes and glyphs, and neighboring
+        clusters cover neighboring areas of utf8 and glyphs . The clusters
+        should collectively cover utf8 and glyphs in entirety.
+
+        The first cluster always covers bytes from the beginning of utf8 . If
+        ``cluster_flags`` do not have the :attr:`TextClusterFlags.BACKWARD` 
set,
+        the first cluster also covers the beginning of glyphs , otherwise it
+        covers the end of the glyphs array and following clusters move 
backward.
+
+        See :class:`TextCluster` for constraints on valid clusters.
+        """
+
     def stroke(self) -> None:
         """
         A drawing operator that strokes the current path according to the
@@ -3647,6 +3695,54 @@
         :meth:`.set_line_cap`, :meth:`.set_dash`, and :meth:`.stroke_preserve`.
         """
 
+    def tag_begin(self, tag_name: str, attributes: str) -> None:
+        """
+        :param tag_name: tag name
+        :param attributes: tag attributes
+
+        Marks the beginning of the tag_name structure. Call :meth:`tag_end`
+        with the same tag_name to mark the end of the structure.
+
+        The attributes string is of the form "key1=value2 key2=value2 ...".
+        Values may be boolean (true/false or 1/0), integer, float, string, or
+        an array.
+
+        String values are enclosed in single quotes ('). Single quotes and
+        backslashes inside the string should be escaped with a backslash.
+
+        Boolean values may be set to true by only specifying the key. eg the
+        attribute string "key" is the equivalent to "key=true".
+
+        Arrays are enclosed in '[]'. eg "rect=[1.2 4.3 2.0 3.0]".
+
+        If no attributes are required, attributes can be an empty string.
+
+        See `Tags and Links Description
+        
<https://www.cairographics.org/manual/cairo-Tags-and-Links.html#cairo-Tags-and-Links.description>`__
+        for the list of tags and attributes.
+
+        Invalid nesting of tags or invalid attributes will cause the context
+        to shutdown with a status of :attr:`Status.TAG_ERROR`.
+
+        See :meth:`tag_end`.
+
+        .. versionadded:: 1.18.0 Only available with cairo 1.15.10+
+        """
+
+    def tag_end(self, tag_name: str) -> None:
+        """
+        :param tag_name: tag name
+
+        Marks the end of the tag_name structure.
+
+        Invalid nesting of tags will cause the context to shutdown with a
+        status of :attr:`Status.TAG_ERROR`.
+
+        See :meth:`tag_begin`.
+
+        .. versionadded:: 1.18.0 Only available with cairo 1.15.10+
+        """
+
     def text_extents(self, text: str) -> TextExtents:
         """
         :param text: text to get extents for
@@ -3739,99 +3835,6 @@
         *(dx,dy)*.
         """
 
-    def in_clip(self, x: float, y: float) -> bool:
-        """
-        :param x: X coordinate of the point to test
-        :param y: Y coordinate of the point to test
-        :returns: :obj:`True` if the point is inside, or :obj:`False` if 
outside.
-
-        Tests whether the given point is inside the area that would be visible
-        through the current clip, i.e. the area that would be filled by a
-        :meth:`paint` operation.
-
-        See :meth:`clip`, and :meth:`clip_preserve`.
-
-        .. versionadded:: 1.12.0
-        """
-
-    def show_text_glyphs(self, utf8: str, glyphs: List["Glyph"], clusters: 
List[TextCluster], cluster_flags: TextClusterFlags) -> None:
-        """
-        :param utf8: a string of text
-        :param glyphs: list of glyphs to show
-        :param clusters: list of cluster mapping information
-        :param cluster_flags: cluster mapping flags
-        :raises Error:
-
-        .. versionadded:: 1.15
-
-        This operation has rendering effects similar to
-        :meth:`Context.show_glyphs` but, if the target surface supports it, 
uses
-        the provided text and cluster mapping to embed the text for the glyphs
-        shown in the output. If the target does not support the extended
-        attributes, this function acts like the basic
-        :meth:`Context.show_glyphs` as if it had been passed ``glyphs`` .
-
-        The mapping between utf8 and glyphs is provided by a list of clusters.
-        Each cluster covers a number of text bytes and glyphs, and neighboring
-        clusters cover neighboring areas of utf8 and glyphs . The clusters
-        should collectively cover utf8 and glyphs in entirety.
-
-        The first cluster always covers bytes from the beginning of utf8 . If
-        ``cluster_flags`` do not have the :attr:`TextClusterFlags.BACKWARD` 
set,
-        the first cluster also covers the beginning of glyphs , otherwise it
-        covers the end of the glyphs array and following clusters move 
backward.
-
-        See :class:`TextCluster` for constraints on valid clusters.
-        """
-
-    def tag_begin(self, tag_name: str, attributes: str) -> None:
-        """
-        :param tag_name: tag name
-        :param attributes: tag attributes
-
-        Marks the beginning of the tag_name structure. Call :meth:`tag_end`
-        with the same tag_name to mark the end of the structure.
-
-        The attributes string is of the form "key1=value2 key2=value2 ...".
-        Values may be boolean (true/false or 1/0), integer, float, string, or
-        an array.
-
-        String values are enclosed in single quotes ('). Single quotes and
-        backslashes inside the string should be escaped with a backslash.
-
-        Boolean values may be set to true by only specifying the key. eg the
-        attribute string "key" is the equivalent to "key=true".
-
-        Arrays are enclosed in '[]'. eg "rect=[1.2 4.3 2.0 3.0]".
-
-        If no attributes are required, attributes can be an empty string.
-
-        See `Tags and Links Description
-        
<https://www.cairographics.org/manual/cairo-Tags-and-Links.html#cairo-Tags-and-Links.description>`__
-        for the list of tags and attributes.
-
-        Invalid nesting of tags or invalid attributes will cause the context
-        to shutdown with a status of :attr:`Status.TAG_ERROR`.
-
-        See :meth:`tag_end`.
-
-        .. versionadded:: 1.18.0 Only available with cairo 1.15.10+
-        """
-
-    def tag_end(self, tag_name: str) -> None:
-        """
-        :param tag_name: tag name
-
-        Marks the end of the tag_name structure.
-
-        Invalid nesting of tags will cause the context to shutdown with a
-        status of :attr:`Status.TAG_ERROR`.
-
-        See :meth:`tag_begin`.
-
-        .. versionadded:: 1.18.0 Only available with cairo 1.15.10+
-        """
-
 class Error(Exception):
     """This exception is raised when a cairo object returns an error status."""
     status: Status = ...
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pycairo-1.21.0/cairo/misc.c 
new/pycairo-1.22.0/cairo/misc.c
--- old/pycairo-1.21.0/cairo/misc.c     2020-10-05 17:45:46.000000000 +0200
+++ new/pycairo-1.22.0/cairo/misc.c     2022-03-27 18:54:40.000000000 +0200
@@ -33,18 +33,11 @@
 
 #include "private.h"
 
-/* PyOS_FSPath() was missing in PyPy for some time:
- * https://bitbucket.org/pypy/pypy/issues/2961 */
-#if PY_MAJOR_VERSION >= 3 && PY_MINOR_VERSION >= 6 && (!defined(PYPY_VERSION) 
|| PYPY_VERSION_NUM >= 0x07030000)
-#define HAS_FSPATH_SUPPORT
-#endif
-
 /* Returns 1 if the object has the correct file type for a filesystem path.
  * Parsing it with Pycairo_fspath_converter() might still fail.
  */
 int
 Pycairo_is_fspath (PyObject *obj) {
-#if defined(HAS_FSPATH_SUPPORT)
     PyObject *real = PyOS_FSPath (obj);
     if (real == NULL) {
         PyErr_Clear ();
@@ -53,20 +46,15 @@
         Py_DECREF (real);
         return 1;
     }
-#else
-    return (PyBytes_Check (obj) || PyUnicode_Check (obj));
-#endif
 }
 
 #if !defined(MS_WINDOWS)
-/* Broken in PyPy: https://bitbucket.org/pypy/pypy/issues/3168 */
+/* Broken in PyPy: https://foss.heptapod.net/pypy/pypy/-/issues/3168 */
 static int
 Pycairo_PyUnicode_FSConverter(PyObject* obj, void* result) {
     int res;
     PyObject *real = NULL;
-#ifdef HAS_FSPATH_SUPPORT
     real = PyOS_FSPath (obj);
-#endif
     if (real == NULL) {
         PyErr_Clear ();
         return PyUnicode_FSConverter (obj, result);
@@ -79,14 +67,12 @@
 #endif
 
 #if defined(MS_WINDOWS)
-/* Broken in PyPy: https://bitbucket.org/pypy/pypy/issues/3168 */
+/* Broken in PyPy: https://foss.heptapod.net/pypy/pypy/-/issues/3168 */
 static int
 Pycairo_PyUnicode_FSDecoder(PyObject* obj, void* result) {
     int res;
     PyObject *real = NULL;
-#ifdef HAS_FSPATH_SUPPORT
     real = PyOS_FSPath (obj);
-#endif
     if (real == NULL) {
         PyErr_Clear ();
         return PyUnicode_FSDecoder (obj, result);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pycairo-1.21.0/cairo/surface.c 
new/pycairo-1.22.0/cairo/surface.c
--- old/pycairo-1.21.0/cairo/surface.c  2020-10-05 17:45:46.000000000 +0200
+++ new/pycairo-1.22.0/cairo/surface.c  2022-11-11 15:17:45.000000000 +0100
@@ -1291,9 +1291,19 @@
 
   version = (cairo_pdf_version_t)version_arg;
 
-  Py_BEGIN_ALLOW_THREADS;
-  version_string = cairo_pdf_version_to_string (version);
-  Py_END_ALLOW_THREADS;
+  /* See https://gitlab.freedesktop.org/cairo/cairo/-/issues/590
+   * if version < 0, cairo_pdf_version_to_string will return out-of-bound
+   * memory address and could cause problems. We avoid those by checking
+   * whether the version is greater than 0 and only then calling
+   * that function.
+  */
+  if (version >= 0) {
+    Py_BEGIN_ALLOW_THREADS;
+    version_string = cairo_pdf_version_to_string (version);
+    Py_END_ALLOW_THREADS;
+  } else {
+    version_string = NULL;
+  }
 
   if (version_string == NULL) {
     PyErr_SetString (PyExc_ValueError, "invalid version");
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pycairo-1.21.0/docs/integration.rst 
new/pycairo-1.22.0/docs/integration.rst
--- old/pycairo-1.21.0/docs/integration.rst     2021-04-30 05:39:59.000000000 
+0200
+++ new/pycairo-1.22.0/docs/integration.rst     2022-11-11 15:17:45.000000000 
+0100
@@ -102,10 +102,11 @@
 
 Creating an ImageSurface from a PIL Image:
     .. code:: python
-        
+
+        import cairo
         import PIL.Image as Image
 
-        def from_pil(im, alpha=1.0, format=cairo.FORMAT_ARGB32):
+        def from_pil(im: Image, alpha: float=1.0, format: 
cairo.Format=cairo.FORMAT_ARGB32) -> cairo.ImageSurface:
             """
             :param im: Pillow Image
             :param alpha: 0..1 alpha to add to non-alpha images
@@ -133,6 +134,37 @@
         im = Image.open(filename)
         surface3 = from_pil(im, alpha=0.5, format=cairo.FORMAT_ARGB32)
 
+Converting an ImageSurface to a PIL Image:
+    .. code:: python
+
+        import cairo
+        import PIL.Image as Image
+
+        def to_pil(surface: cairo.ImageSurface) -> Image:
+            format = surface.get_format()
+            size = (surface.get_width(), surface.get_height())
+            stride = surface.get_stride()
+
+            with surface.get_data() as memory:
+                if format == cairo.Format.RGB24:
+                    return Image.frombuffer(
+                        "RGB", size, memory.tobytes(),
+                        'raw', "BGRX", stride)
+                elif format == cairo.Format.ARGB32:
+                    return Image.frombuffer(
+                        "RGBA", size, memory.tobytes(),
+                        'raw', "BGRa", stride)
+                else:
+                    raise NotImplementedError(repr(format))
+
+        # Create an image surface from a PNG file (or any other source)
+        surface = cairo.ImageSurface.create_from_png("test.png")
+
+        # Convert to a PIL Image
+        im = to_pil(surface)
+
+        # Use Pillow to store it as a JPEG
+        im.save("result.jpg")
 
 Freetype-py & Cairo
 -------------------
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pycairo-1.21.0/docs/reference/constants.rst 
new/pycairo-1.22.0/docs/reference/constants.rst
--- old/pycairo-1.21.0/docs/reference/constants.rst     2022-02-27 
21:29:48.000000000 +0100
+++ new/pycairo-1.22.0/docs/reference/constants.rst     2022-11-19 
11:28:50.000000000 +0100
@@ -126,3 +126,9 @@
     This type only exists for documentation purposes.
 
     This represents a file object opened in binary mode: :obj:`typing.BinaryIO`
+
+.. class:: _SomeSurface
+
+    This type only exists for documentation purposes.
+
+    This represents a :class:`Surface` subclass.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/pycairo-1.21.0/examples/cairo_snippets/snippets_png.py 
new/pycairo-1.22.0/examples/cairo_snippets/snippets_png.py
--- old/pycairo-1.21.0/examples/cairo_snippets/snippets_png.py  2019-08-24 
23:37:20.000000000 +0200
+++ new/pycairo-1.22.0/examples/cairo_snippets/snippets_png.py  2022-11-11 
15:17:45.000000000 +0100
@@ -35,7 +35,7 @@
 
 
 if __name__ == '__main__':
-    if not(cairo.HAS_IMAGE_SURFACE and cairo.HAS_PNG_FUNCTIONS):
+    if not (cairo.HAS_IMAGE_SURFACE and cairo.HAS_PNG_FUNCTIONS):
         raise SystemExit(
             'cairo was not compiled with ImageSurface and PNG support')
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pycairo-1.21.0/examples/gtk/cairo-knockout.py 
new/pycairo-1.22.0/examples/gtk/cairo-knockout.py
--- old/pycairo-1.21.0/examples/gtk/cairo-knockout.py   2019-08-24 
23:37:20.000000000 +0200
+++ new/pycairo-1.22.0/examples/gtk/cairo-knockout.py   2022-11-11 
15:17:45.000000000 +0100
@@ -33,7 +33,7 @@
     # Only works for CHECK_SIZE a power of 2
     for j in range(x & -CHECK_SIZE, height, CHECK_SIZE):
         for i in range(y & -CHECK_SIZE, width, CHECK_SIZE):
-            if((i / CHECK_SIZE + j / CHECK_SIZE) % 2 == 0):
+            if ((i / CHECK_SIZE + j / CHECK_SIZE) % 2 == 0):
                 ctx.rectangle(i, j, CHECK_SIZE, CHECK_SIZE)
 
     ctx.set_source_rgb(0.7, 0.7, 0.7)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pycairo-1.21.0/meson.build 
new/pycairo-1.22.0/meson.build
--- old/pycairo-1.21.0/meson.build      2022-03-07 07:22:30.000000000 +0100
+++ new/pycairo-1.22.0/meson.build      2022-11-19 13:04:34.000000000 +0100
@@ -1,6 +1,6 @@
 project(
   'pycairo', 'c',
-  version: '1.21.0',
+  version: '1.22.0',
   meson_version: '>= 0.53.0',
   license: 'LGPL-2.1-only OR MPL-1.1',
   default_options: [
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pycairo-1.21.0/pycairo.egg-info/PKG-INFO 
new/pycairo-1.22.0/pycairo.egg-info/PKG-INFO
--- old/pycairo-1.21.0/pycairo.egg-info/PKG-INFO        2022-03-07 
07:41:37.000000000 +0100
+++ new/pycairo-1.22.0/pycairo.egg-info/PKG-INFO        2022-11-19 
14:16:05.000000000 +0100
@@ -1,6 +1,6 @@
 Metadata-Version: 2.1
 Name: pycairo
-Version: 1.21.0
+Version: 1.22.0
 Summary: Python interface for cairo
 Home-page: https://pycairo.readthedocs.io
 Maintainer: Christoph Reiter
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pycairo-1.21.0/pyproject.toml 
new/pycairo-1.22.0/pyproject.toml
--- old/pycairo-1.21.0/pyproject.toml   2022-02-26 17:11:57.000000000 +0100
+++ new/pycairo-1.22.0/pyproject.toml   2022-11-19 11:29:06.000000000 +0100
@@ -10,8 +10,8 @@
 [tool.poetry.dev-dependencies]
 pytest = "^7.0.1"
 hypothesis = "^6.0.0"
-mypy = {version = "^0.931", markers = "platform_python_implementation != 
'PyPy'"}
-flake8 = "^3.9.2"
+mypy = {version = "^0.982", markers = "platform_python_implementation != 
'PyPy'"}
+flake8 = "^5.0.4"
 Sphinx = "^4.3.2"
 sphinx-rtd-theme = "^1.0.0"
 coverage = "^6.3.2"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pycairo-1.21.0/setup.py new/pycairo-1.22.0/setup.py
--- old/pycairo-1.21.0/setup.py 2022-03-07 07:22:24.000000000 +0100
+++ new/pycairo-1.22.0/setup.py 2022-11-19 13:04:33.000000000 +0100
@@ -15,7 +15,7 @@
 from distutils import sysconfig
 
 
-PYCAIRO_VERSION = '1.21.0'
+PYCAIRO_VERSION = '1.22.0'
 CAIRO_VERSION_REQUIRED = '1.15.10'
 
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pycairo-1.21.0/tests/test_api.py 
new/pycairo-1.22.0/tests/test_api.py
--- old/pycairo-1.21.0/tests/test_api.py        2020-10-05 17:45:46.000000000 
+0200
+++ new/pycairo-1.22.0/tests/test_api.py        2022-11-19 11:28:50.000000000 
+0100
@@ -281,8 +281,9 @@
     surface = cairo.ImageSurface(cairo.FORMAT_RGB24, 1, 1)
     v = memoryview(b"bla")
     x = v[:1]
-    assert sys.getrefcount(v) == 2
-    assert sys.getrefcount(x) == 2
+    recfcount_v = sys.getrefcount(v)
+    recfcount_x = sys.getrefcount(x)
+    assert recfcount_v == recfcount_x
     surface.set_mime_data("foo", v)
     surface.set_mime_data("foo2", v)
     surface.set_mime_data("foo3", x)
@@ -293,8 +294,8 @@
     surface.set_mime_data("foo2", None)
     surface.set_mime_data("foo3", None)
     surface.finish()
-    assert sys.getrefcount(v) == 2
-    assert sys.getrefcount(x) == 2
+    assert sys.getrefcount(v) == recfcount_v
+    assert sys.getrefcount(x) == recfcount_x
 
 
 @pytest.mark.skipif(
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pycairo-1.21.0/tests/test_context.py 
new/pycairo-1.22.0/tests/test_context.py
--- old/pycairo-1.21.0/tests/test_context.py    2020-01-19 10:57:15.000000000 
+0100
+++ new/pycairo-1.22.0/tests/test_context.py    2022-10-16 19:11:13.000000000 
+0200
@@ -57,7 +57,7 @@
         assert context.get_operator() == val
 
 
-# https://bitbucket.org/pypy/pypy/issues/2741
+# https://foss.heptapod.net/pypy/pypy/-/issues/2741
 @pytest.mark.skipif(platform.python_implementation() == "PyPy", reason="PyPy")
 def test_show_text_glyphs():
     surface = cairo.PDFSurface(None, 300, 300)
@@ -319,7 +319,7 @@
         context.scale(object(), 0)
 
 
-# https://bitbucket.org/pypy/pypy/issues/2741
+# https://foss.heptapod.net/pypy/pypy/-/issues/2741
 @pytest.mark.skipif(platform.python_implementation() == "PyPy", reason="PyPy")
 def test_select_font_face(context):
     context.select_font_face("")
@@ -473,7 +473,7 @@
         context.text_extents()
 
 
-# https://bitbucket.org/pypy/pypy/issues/2741
+# https://foss.heptapod.net/pypy/pypy/-/issues/2741
 @pytest.mark.skipif(platform.python_implementation() == "PyPy", reason="PyPy")
 def test_text_path(context):
     context.text_path("foo")
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pycairo-1.21.0/tests/test_enums.py 
new/pycairo-1.22.0/tests/test_enums.py
--- old/pycairo-1.21.0/tests/test_enums.py      2020-09-02 21:42:19.000000000 
+0200
+++ new/pycairo-1.22.0/tests/test_enums.py      2022-03-26 21:39:53.000000000 
+0100
@@ -6,7 +6,7 @@
 import cairo
 
 
-# https://bitbucket.org/pypy/pypy/issues/2742
+# https://foss.heptapod.net/pypy/pypy/-/issues/2742
 @pytest.mark.skipif(platform.python_implementation() == "PyPy", reason="PyPy")
 def test_type():
     t = cairo.Antialias
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pycairo-1.21.0/tests/test_font.py 
new/pycairo-1.22.0/tests/test_font.py
--- old/pycairo-1.21.0/tests/test_font.py       2020-04-01 16:03:19.000000000 
+0200
+++ new/pycairo-1.22.0/tests/test_font.py       2022-03-26 21:40:00.000000000 
+0100
@@ -178,7 +178,7 @@
     assert isinstance(scaled_font.get_scale_matrix(), cairo.Matrix)
 
 
-# https://bitbucket.org/pypy/pypy/issues/2741
+# https://foss.heptapod.net/pypy/pypy/-/issues/2741
 @pytest.mark.skipif(platform.python_implementation() == "PyPy", reason="PyPy")
 def test_scaled_font_text_extents(scaled_font):
     with pytest.raises(TypeError):
@@ -194,7 +194,7 @@
         scaled_font.glyph_extents()
 
 
-# https://bitbucket.org/pypy/pypy/issues/2741
+# https://foss.heptapod.net/pypy/pypy/-/issues/2741
 @pytest.mark.skipif(platform.python_implementation() == "PyPy", reason="PyPy")
 def test_toy_font_face():
     with pytest.raises(TypeError):
@@ -204,6 +204,10 @@
 def test_toy_font_get_family():
     font_face = cairo.ToyFontFace("")
     assert isinstance(font_face.get_family(), str)
+    font_face = cairo.ToyFontFace("serif")
+    assert isinstance(font_face.get_family(), str)
+    font_face = cairo.ToyFontFace("sans-serif")
+    assert isinstance(font_face.get_family(), str)
 
 
 def test_toy_font_get_slant():
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pycairo-1.21.0/tests/test_hypothesis.py 
new/pycairo-1.22.0/tests/test_hypothesis.py
--- old/pycairo-1.21.0/tests/test_hypothesis.py 2020-04-01 16:03:19.000000000 
+0200
+++ new/pycairo-1.22.0/tests/test_hypothesis.py 2022-03-26 21:34:58.000000000 
+0100
@@ -17,6 +17,16 @@
 from .hypothesis_fspaths import fspaths
 
 
+if "CI" in os.environ:
+    # CI can be slow, so be patient
+    # Also we can run more tests there
+    settings.register_profile(
+        "ci",
+        deadline=settings.default.deadline * 10,
+        max_examples=settings.default.max_examples * 5)
+    settings.load_profile("ci")
+
+
 @pytest.fixture(scope='module')
 def tempdir_path():
     dir_ = tempfile.mkdtemp()
@@ -44,7 +54,6 @@
     platform.python_implementation() == "PyPy" and sys.pypy_version_info < (7, 
3, 0),
     reason="PyPy bugs")
 @given(path=fspaths())
-@settings(max_examples=500)
 def test_fspaths(tempdir_path, path):
     p = _to_temp_path(tempdir_path, path)
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pycairo-1.21.0/tests/test_surface.py 
new/pycairo-1.22.0/tests/test_surface.py
--- old/pycairo-1.21.0/tests/test_surface.py    2020-10-05 17:45:46.000000000 
+0200
+++ new/pycairo-1.22.0/tests/test_surface.py    2022-11-19 11:28:50.000000000 
+0100
@@ -139,11 +139,11 @@
 @pytest.mark.skipif(not hasattr(sys, "getrefcount"), reason="PyPy")
 def test_image_surface_get_data_refcount():
     surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, 10, 10)
-    assert sys.getrefcount(surface) == 2
+    refcount = sys.getrefcount(surface)
     d = surface.get_data()
-    assert sys.getrefcount(surface) == 3
+    assert sys.getrefcount(surface) != refcount
     del d
-    assert sys.getrefcount(surface) == 2
+    assert sys.getrefcount(surface) == refcount
 
 
 def test_image_surface_get_data_crasher():
@@ -267,7 +267,10 @@
                     reason="too old cairo")
 def test_svg_surface_get_document_unit():
     with cairo.SVGSurface(None, 10, 10) as surface:
-        assert surface.get_document_unit() == cairo.SVGUnit.PT
+        # https://gitlab.freedesktop.org/cairo/cairo/-/issues/545
+        assert surface.get_document_unit() in [cairo.SVGUnit.PT, 
cairo.SVGUnit.USER]
+
+    with cairo.SVGSurface(None, 10, 10) as surface:
         surface.set_document_unit(cairo.SVGUnit.PX)
         assert surface.get_document_unit() == cairo.SVGUnit.PX
     with pytest.raises(cairo.Error):
@@ -487,7 +490,7 @@
         surface.supports_mime_type(object())
 
 
-# https://bitbucket.org/pypy/pypy/issues/2751
+# https://foss.heptapod.net/pypy/pypy/-/issues/2751
 @pytest.mark.skipif(platform.python_implementation() == "PyPy", reason="PyPy")
 def test_image_surface_create_for_data_array():
     width, height = 255, 255

Reply via email to