Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package python-mss for openSUSE:Factory 
checked in at 2021-02-02 14:24:16
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-mss (Old)
 and      /work/SRC/openSUSE:Factory/.python-mss.new.28504 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-mss"

Tue Feb  2 14:24:16 2021 rev:2 rq:858348 version:6.1.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-mss/python-mss.changes    2020-08-18 
15:09:45.436008535 +0200
+++ /work/SRC/openSUSE:Factory/.python-mss.new.28504/python-mss.changes 
2021-02-02 14:24:17.983263790 +0100
@@ -1,0 +2,9 @@
+Wed Dec 23 09:33:38 UTC 2020 - Benjamin Greiner <c...@bnavigator.de>
+
+- Update to v6.1.0
+  * MSS: reworked how C functions are initialised
+  * tests: expand Python versions to 3.9 and 3.10
+  * tests: fix test_entry_point() when there are several monitors 
+- clean test rig setup
+
+-------------------------------------------------------------------

Old:
----
  mss-6.0.0.tar.gz

New:
----
  mss-6.1.0.tar.gz

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

Other differences:
------------------
++++++ python-mss.spec ++++++
--- /var/tmp/diff_new_pack.SDbXoE/_old  2021-02-02 14:24:18.791265046 +0100
+++ /var/tmp/diff_new_pack.SDbXoE/_new  2021-02-02 14:24:18.795265052 +0100
@@ -19,7 +19,7 @@
 %{?!python_module:%define python_module() python-%{**} python3-%{**}}
 %define skip_python2 1
 Name:           python-mss
-Version:        6.0.0
+Version:        6.1.0
 Release:        0
 Summary:        Python multiple screenshots module
 License:        MIT
@@ -45,8 +45,6 @@
 
 %prep
 %setup -q -n mss-%{version}
-mv mss/tests .
-rm tests/test_setup.py
 
 %build
 %python_build
@@ -65,12 +63,17 @@
 %check
 export LANG=en_US.UTF-8
 # test_region_out_of_monitor_bounds fails on ppc64 only
-%python_expand PYTHONPATH=%{buildroot}%{$python_sitelib} xvfb-run 
--server-args "-screen 0 1920x1080x24" $python -m pytest tests/test_*.py -k 
'not test_region_out_of_monitor_bounds'
+echo '
+%pytest --ignore mss/tests/test_setup.py -k "not 
test_region_out_of_monitor_bounds" 
+'> pytest_script.sh
+# need explicitly set up screen.
+xvfb-run --server-args "-screen 0 1920x1080x24" sh pytest_script.sh
 
 %files %{python_files}
 %doc README.rst
 %license LICENSE
 %python_alternative %{_bindir}/mss
-%{python_sitelib}/*
+%{python_sitelib}/mss
+%{python_sitelib}/mss-%{version}*-info
 
 %changelog

++++++ mss-6.0.0.tar.gz -> mss-6.1.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mss-6.0.0/PKG-INFO new/mss-6.1.0/PKG-INFO
--- old/mss-6.0.0/PKG-INFO      2020-06-30 18:00:14.000000000 +0200
+++ new/mss-6.1.0/PKG-INFO      2020-10-31 18:18:32.501716100 +0100
@@ -1,6 +1,6 @@
 Metadata-Version: 1.2
 Name: mss
-Version: 6.0.0
+Version: 6.1.0
 Summary: An ultra fast cross-platform multiple screenshots module in pure 
python using ctypes.
 Home-page: https://github.com/BoboTiG/python-mss
 Author: Micka??l 'Tiger-222' Schoentgen
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mss-6.0.0/mss/__init__.py 
new/mss-6.1.0/mss/__init__.py
--- old/mss-6.0.0/mss/__init__.py       2020-06-28 19:22:53.000000000 +0200
+++ new/mss-6.1.0/mss/__init__.py       2020-10-31 18:09:38.000000000 +0100
@@ -12,7 +12,7 @@
 from .exception import ScreenShotError
 from .factory import mss
 
-__version__ = "6.0.0"
+__version__ = "6.1.0"
 __author__ = "Micka??l 'Tiger-222' Schoentgen"
 __copyright__ = """
     Copyright (c) 2013-2020, Micka??l 'Tiger-222' Schoentgen
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mss-6.0.0/mss/base.py new/mss-6.1.0/mss/base.py
--- old/mss-6.0.0/mss/base.py   2020-06-30 17:37:13.000000000 +0200
+++ new/mss-6.1.0/mss/base.py   2020-10-31 18:07:02.000000000 +0100
@@ -164,6 +164,7 @@
             try:
                 monitor = monitors[mon]
             except IndexError:
+                # pylint: disable=raise-missing-from
                 raise ScreenShotError("Monitor {!r} does not 
exist.".format(mon))
 
             output = output.format(mon=mon, date=datetime.now(), **monitor)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mss-6.0.0/mss/darwin.py new/mss-6.1.0/mss/darwin.py
--- old/mss-6.0.0/mss/darwin.py 2020-06-28 19:22:53.000000000 +0200
+++ new/mss-6.1.0/mss/darwin.py 2020-10-31 18:07:02.000000000 +0100
@@ -6,6 +6,18 @@
 import ctypes
 import ctypes.util
 import sys
+from ctypes import (
+    POINTER,
+    Structure,
+    c_double,
+    c_float,
+    c_int32,
+    c_uint64,
+    c_ubyte,
+    c_uint32,
+    c_void_p,
+)
+from platform import mac_ver
 from typing import TYPE_CHECKING
 
 from .base import MSSBase
@@ -22,13 +34,13 @@
 
 
 def cgfloat():
-    # type: () -> Union[Type[ctypes.c_double], Type[ctypes.c_float]]
+    # type: () -> Union[Type[c_double], Type[c_float]]
     """ Get the appropriate value for a float. """
 
-    return ctypes.c_double if sys.maxsize > 2 ** 32 else ctypes.c_float
+    return c_double if sys.maxsize > 2 ** 32 else c_float
 
 
-class CGPoint(ctypes.Structure):
+class CGPoint(Structure):
     """ Structure that contains coordinates of a rectangle. """
 
     _fields_ = [("x", cgfloat()), ("y", cgfloat())]
@@ -37,7 +49,7 @@
         return "{}(left={} top={})".format(type(self).__name__, self.x, self.y)
 
 
-class CGSize(ctypes.Structure):
+class CGSize(Structure):
     """ Structure that contains dimensions of an rectangle. """
 
     _fields_ = [("width", cgfloat()), ("height", cgfloat())]
@@ -48,7 +60,7 @@
         )
 
 
-class CGRect(ctypes.Structure):
+class CGRect(Structure):
     """ Structure that contains information about a rectangle. """
 
     _fields_ = [("origin", CGPoint), ("size", CGSize)]
@@ -57,6 +69,42 @@
         return "{}<{} {}>".format(type(self).__name__, self.origin, self.size)
 
 
+# C functions that will be initialised later.
+#
+# This is a dict:
+#    cfunction: (attr, argtypes, restype)
+#
+# Available attr: core.
+#
+# Note: keep it sorted by cfunction.
+CFUNCTIONS = {
+    "CGDataProviderCopyData": ("core", [c_void_p], c_void_p),
+    "CGDisplayBounds": ("core", [c_uint32], CGRect),
+    "CGDisplayRotation": ("core", [c_uint32], c_float),
+    "CFDataGetBytePtr": ("core", [c_void_p], c_void_p),
+    "CFDataGetLength": ("core", [c_void_p], c_uint64),
+    "CFRelease": ("core", [c_void_p], c_void_p),
+    "CGDataProviderRelease": ("core", [c_void_p], c_void_p),
+    "CGGetActiveDisplayList": (
+        "core",
+        [c_uint32, POINTER(c_uint32), POINTER(c_uint32)],
+        c_int32,
+    ),
+    "CGImageGetBitsPerPixel": ("core", [c_void_p], int),
+    "CGImageGetBytesPerRow": ("core", [c_void_p], int),
+    "CGImageGetDataProvider": ("core", [c_void_p], c_void_p),
+    "CGImageGetHeight": ("core", [c_void_p], int),
+    "CGImageGetWidth": ("core", [c_void_p], int),
+    "CGRectStandardize": ("core", [CGRect], CGRect),
+    "CGRectUnion": ("core", [CGRect, CGRect], CGRect),
+    "CGWindowListCreateImage": (
+        "core",
+        [CGRect, c_uint32, c_uint32, c_uint32],
+        c_void_p,
+    ),
+}
+
+
 class MSS(MSSBase):
     """
     Multiple ScreenShots implementation for macOS.
@@ -72,54 +120,37 @@
 
         self.max_displays = 32
 
-        coregraphics = ctypes.util.find_library("CoreGraphics")
+        self._init_library()
+        self._set_cfunctions()
+
+    def _init_library(self):
+        """ Load the CoreGraphics library. """
+        version = float(".".join(mac_ver()[0].split(".")[:2]))
+        if version < 10.16:
+            coregraphics = ctypes.util.find_library("CoreGraphics")
+        else:
+            # macOS Big Sur and newer
+            # pylint: disable=line-too-long
+            coregraphics = 
"/System/Library/Frameworks/CoreGraphics.framework/Versions/Current/CoreGraphics"
+
         if not coregraphics:
             raise ScreenShotError("No CoreGraphics library found.")
         self.core = ctypes.cdll.LoadLibrary(coregraphics)
 
-        self._set_cfunctions()
-
     def _set_cfunctions(self):
         # type: () -> None
         """ Set all ctypes functions and attach them to attributes. """
 
-        def cfactory(func, argtypes, restype):
-            # type: (str, List[Any], Any) -> None
-            """ Factorize ctypes creations. """
-            self._cfactory(
-                attr=self.core, func=func, argtypes=argtypes, restype=restype
+        cfactory = self._cfactory
+        attrs = {"core": self.core}
+        for func, (attr, argtypes, restype) in CFUNCTIONS.items():
+            cfactory(
+                attr=attrs[attr],
+                func=func,
+                argtypes=argtypes,  # type: ignore
+                restype=restype,
             )
 
-        uint32 = ctypes.c_uint32
-        void = ctypes.c_void_p
-        size_t = ctypes.c_size_t
-        pointer = ctypes.POINTER
-
-        cfactory(
-            func="CGGetActiveDisplayList",
-            argtypes=[uint32, pointer(uint32), pointer(uint32)],
-            restype=ctypes.c_int32,
-        )
-        cfactory(func="CGDisplayBounds", argtypes=[uint32], restype=CGRect)
-        cfactory(func="CGRectStandardize", argtypes=[CGRect], restype=CGRect)
-        cfactory(func="CGRectUnion", argtypes=[CGRect, CGRect], restype=CGRect)
-        cfactory(func="CGDisplayRotation", argtypes=[uint32], 
restype=ctypes.c_float)
-        cfactory(
-            func="CGWindowListCreateImage",
-            argtypes=[CGRect, uint32, uint32, uint32],
-            restype=void,
-        )
-        cfactory(func="CGImageGetWidth", argtypes=[void], restype=size_t)
-        cfactory(func="CGImageGetHeight", argtypes=[void], restype=size_t)
-        cfactory(func="CGImageGetDataProvider", argtypes=[void], restype=void)
-        cfactory(func="CGDataProviderCopyData", argtypes=[void], restype=void)
-        cfactory(func="CFDataGetBytePtr", argtypes=[void], restype=void)
-        cfactory(func="CFDataGetLength", argtypes=[void], 
restype=ctypes.c_uint64)
-        cfactory(func="CGImageGetBytesPerRow", argtypes=[void], restype=size_t)
-        cfactory(func="CGImageGetBitsPerPixel", argtypes=[void], 
restype=size_t)
-        cfactory(func="CGDataProviderRelease", argtypes=[void], restype=void)
-        cfactory(func="CFRelease", argtypes=[void], restype=void)
-
     def _monitors_impl(self):
         # type: () -> None
         """ Get positions of monitors. It will populate self._monitors. """
@@ -134,8 +165,8 @@
         self._monitors.append({})
 
         # Each monitors
-        display_count = ctypes.c_uint32(0)
-        active_displays = (ctypes.c_uint32 * self.max_displays)()
+        display_count = c_uint32(0)
+        active_displays = (c_uint32 * self.max_displays)()
         core.CGGetActiveDisplayList(
             self.max_displays, active_displays, ctypes.byref(display_count)
         )
@@ -183,20 +214,20 @@
         if not image_ref:
             raise ScreenShotError("CoreGraphics.CGWindowListCreateImage() 
failed.")
 
-        width = int(core.CGImageGetWidth(image_ref))
-        height = int(core.CGImageGetHeight(image_ref))
+        width = core.CGImageGetWidth(image_ref)
+        height = core.CGImageGetHeight(image_ref)
         prov = copy_data = None
         try:
             prov = core.CGImageGetDataProvider(image_ref)
             copy_data = core.CGDataProviderCopyData(prov)
             data_ref = core.CFDataGetBytePtr(copy_data)
             buf_len = core.CFDataGetLength(copy_data)
-            raw = ctypes.cast(data_ref, ctypes.POINTER(ctypes.c_ubyte * 
buf_len))
+            raw = ctypes.cast(data_ref, POINTER(c_ubyte * buf_len))
             data = bytearray(raw.contents)
 
             # Remove padding per row
-            bytes_per_row = int(core.CGImageGetBytesPerRow(image_ref))
-            bytes_per_pixel = int(core.CGImageGetBitsPerPixel(image_ref))
+            bytes_per_row = core.CGImageGetBytesPerRow(image_ref)
+            bytes_per_pixel = core.CGImageGetBitsPerPixel(image_ref)
             bytes_per_pixel = (bytes_per_pixel + 7) // 8
 
             if bytes_per_pixel * width != bytes_per_row:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mss-6.0.0/mss/linux.py new/mss-6.1.0/mss/linux.py
--- old/mss-6.0.0/mss/linux.py  2020-06-30 17:58:00.000000000 +0200
+++ new/mss-6.1.0/mss/linux.py  2020-10-31 18:07:02.000000000 +0100
@@ -7,6 +7,21 @@
 import ctypes.util
 import os
 import threading
+from ctypes import (
+    POINTER,
+    CFUNCTYPE,
+    Structure,
+    c_char_p,
+    c_int,
+    c_int32,
+    c_long,
+    c_ubyte,
+    c_uint,
+    c_uint32,
+    c_ulong,
+    c_ushort,
+    c_void_p,
+)
 from types import SimpleNamespace
 from typing import TYPE_CHECKING
 
@@ -28,127 +43,127 @@
 ZPIXMAP = 2
 
 
-class Display(ctypes.Structure):
+class Display(Structure):
     """
     Structure that serves as the connection to the X server
     and that contains all the information about that X server.
     """
 
 
-class Event(ctypes.Structure):
+class Event(Structure):
     """
     XErrorEvent to debug eventual errors.
     
https://tronche.com/gui/x/xlib/event-handling/protocol-errors/default-handlers.html
     """
 
     _fields_ = [
-        ("type", ctypes.c_int),
-        ("display", ctypes.POINTER(Display)),
-        ("serial", ctypes.c_ulong),
-        ("error_code", ctypes.c_ubyte),
-        ("request_code", ctypes.c_ubyte),
-        ("minor_code", ctypes.c_ubyte),
-        ("resourceid", ctypes.c_void_p),
+        ("type", c_int),
+        ("display", POINTER(Display)),
+        ("serial", c_ulong),
+        ("error_code", c_ubyte),
+        ("request_code", c_ubyte),
+        ("minor_code", c_ubyte),
+        ("resourceid", c_void_p),
     ]
 
 
-class XWindowAttributes(ctypes.Structure):
+class XWindowAttributes(Structure):
     """ Attributes for the specified window. """
 
     _fields_ = [
-        ("x", ctypes.c_int32),
-        ("y", ctypes.c_int32),
-        ("width", ctypes.c_int32),
-        ("height", ctypes.c_int32),
-        ("border_width", ctypes.c_int32),
-        ("depth", ctypes.c_int32),
-        ("visual", ctypes.c_ulong),
-        ("root", ctypes.c_ulong),
-        ("class", ctypes.c_int32),
-        ("bit_gravity", ctypes.c_int32),
-        ("win_gravity", ctypes.c_int32),
-        ("backing_store", ctypes.c_int32),
-        ("backing_planes", ctypes.c_ulong),
-        ("backing_pixel", ctypes.c_ulong),
-        ("save_under", ctypes.c_int32),
-        ("colourmap", ctypes.c_ulong),
-        ("mapinstalled", ctypes.c_uint32),
-        ("map_state", ctypes.c_uint32),
-        ("all_event_masks", ctypes.c_ulong),
-        ("your_event_mask", ctypes.c_ulong),
-        ("do_not_propagate_mask", ctypes.c_ulong),
-        ("override_redirect", ctypes.c_int32),
-        ("screen", ctypes.c_ulong),
+        ("x", c_int32),
+        ("y", c_int32),
+        ("width", c_int32),
+        ("height", c_int32),
+        ("border_width", c_int32),
+        ("depth", c_int32),
+        ("visual", c_ulong),
+        ("root", c_ulong),
+        ("class", c_int32),
+        ("bit_gravity", c_int32),
+        ("win_gravity", c_int32),
+        ("backing_store", c_int32),
+        ("backing_planes", c_ulong),
+        ("backing_pixel", c_ulong),
+        ("save_under", c_int32),
+        ("colourmap", c_ulong),
+        ("mapinstalled", c_uint32),
+        ("map_state", c_uint32),
+        ("all_event_masks", c_ulong),
+        ("your_event_mask", c_ulong),
+        ("do_not_propagate_mask", c_ulong),
+        ("override_redirect", c_int32),
+        ("screen", c_ulong),
     ]
 
 
-class XImage(ctypes.Structure):
+class XImage(Structure):
     """
     Description of an image as it exists in the client's memory.
     https://tronche.com/gui/x/xlib/graphics/images.html
     """
 
     _fields_ = [
-        ("width", ctypes.c_int),
-        ("height", ctypes.c_int),
-        ("xoffset", ctypes.c_int),
-        ("format", ctypes.c_int),
-        ("data", ctypes.c_void_p),
-        ("byte_order", ctypes.c_int),
-        ("bitmap_unit", ctypes.c_int),
-        ("bitmap_bit_order", ctypes.c_int),
-        ("bitmap_pad", ctypes.c_int),
-        ("depth", ctypes.c_int),
-        ("bytes_per_line", ctypes.c_int),
-        ("bits_per_pixel", ctypes.c_int),
-        ("red_mask", ctypes.c_ulong),
-        ("green_mask", ctypes.c_ulong),
-        ("blue_mask", ctypes.c_ulong),
+        ("width", c_int),
+        ("height", c_int),
+        ("xoffset", c_int),
+        ("format", c_int),
+        ("data", c_void_p),
+        ("byte_order", c_int),
+        ("bitmap_unit", c_int),
+        ("bitmap_bit_order", c_int),
+        ("bitmap_pad", c_int),
+        ("depth", c_int),
+        ("bytes_per_line", c_int),
+        ("bits_per_pixel", c_int),
+        ("red_mask", c_ulong),
+        ("green_mask", c_ulong),
+        ("blue_mask", c_ulong),
     ]
 
 
-class XRRModeInfo(ctypes.Structure):
+class XRRModeInfo(Structure):
     """ Voil??, voil??. """
 
 
-class XRRScreenResources(ctypes.Structure):
+class XRRScreenResources(Structure):
     """
     Structure that contains arrays of XIDs that point to the
     available outputs and associated CRTCs.
     """
 
     _fields_ = [
-        ("timestamp", ctypes.c_ulong),
-        ("configTimestamp", ctypes.c_ulong),
-        ("ncrtc", ctypes.c_int),
-        ("crtcs", ctypes.POINTER(ctypes.c_long)),
-        ("noutput", ctypes.c_int),
-        ("outputs", ctypes.POINTER(ctypes.c_long)),
-        ("nmode", ctypes.c_int),
-        ("modes", ctypes.POINTER(XRRModeInfo)),
+        ("timestamp", c_ulong),
+        ("configTimestamp", c_ulong),
+        ("ncrtc", c_int),
+        ("crtcs", POINTER(c_long)),
+        ("noutput", c_int),
+        ("outputs", POINTER(c_long)),
+        ("nmode", c_int),
+        ("modes", POINTER(XRRModeInfo)),
     ]
 
 
-class XRRCrtcInfo(ctypes.Structure):
+class XRRCrtcInfo(Structure):
     """ Structure that contains CRTC information. """
 
     _fields_ = [
-        ("timestamp", ctypes.c_ulong),
-        ("x", ctypes.c_int),
-        ("y", ctypes.c_int),
-        ("width", ctypes.c_int),
-        ("height", ctypes.c_int),
-        ("mode", ctypes.c_long),
-        ("rotation", ctypes.c_int),
-        ("noutput", ctypes.c_int),
-        ("outputs", ctypes.POINTER(ctypes.c_long)),
-        ("rotations", ctypes.c_ushort),
-        ("npossible", ctypes.c_int),
-        ("possible", ctypes.POINTER(ctypes.c_long)),
+        ("timestamp", c_ulong),
+        ("x", c_int),
+        ("y", c_int),
+        ("width", c_int),
+        ("height", c_int),
+        ("mode", c_long),
+        ("rotation", c_int),
+        ("noutput", c_int),
+        ("outputs", POINTER(c_long)),
+        ("rotations", c_ushort),
+        ("npossible", c_int),
+        ("possible", POINTER(c_long)),
     ]
 
 
-@ctypes.CFUNCTYPE(ctypes.c_int, ctypes.POINTER(Display), ctypes.POINTER(Event))
+@CFUNCTYPE(c_int, POINTER(Display), POINTER(Event))
 def error_handler(_, event):
     # type: (Any, Any) -> int
     """ Specifies the program's supplied error handler. """
@@ -176,6 +191,71 @@
     raise ScreenShotError(err, details=details)
 
 
+# C functions that will be initialised later.
+# See https://tronche.com/gui/x/xlib/function-index.html for details.
+#
+# This is a dict:
+#    cfunction: (attr, argtypes, restype)
+#
+# Available attr: xlib, xrandr.
+#
+# Note: keep it sorted by cfunction.
+CFUNCTIONS = {
+    "XDefaultRootWindow": ("xlib", [POINTER(Display)], 
POINTER(XWindowAttributes)),
+    "XDestroyImage": ("xlib", [POINTER(XImage)], c_void_p),
+    "XGetErrorText": ("xlib", [POINTER(Display), c_int, c_char_p, c_int], 
c_void_p),
+    "XGetImage": (
+        "xlib",
+        [
+            POINTER(Display),
+            POINTER(Display),
+            c_int,
+            c_int,
+            c_uint,
+            c_uint,
+            c_ulong,
+            c_int,
+        ],
+        POINTER(XImage),
+    ),
+    "XGetWindowAttributes": (
+        "xlib",
+        [POINTER(Display), POINTER(XWindowAttributes), 
POINTER(XWindowAttributes)],
+        c_int,
+    ),
+    "XOpenDisplay": ("xlib", [c_char_p], POINTER(Display)),
+    "XQueryExtension": (
+        "xlib",
+        [
+            POINTER(Display),
+            c_char_p,
+            POINTER(c_int),
+            POINTER(c_int),
+            POINTER(c_int),
+        ],
+        c_uint,
+    ),
+    "XRRFreeCrtcInfo": ("xrandr", [POINTER(XRRCrtcInfo)], c_void_p),
+    "XRRFreeScreenResources": ("xrandr", [POINTER(XRRScreenResources)], 
c_void_p),
+    "XRRGetCrtcInfo": (
+        "xrandr",
+        [POINTER(Display), POINTER(XRRScreenResources), c_long],
+        POINTER(XRRCrtcInfo),
+    ),
+    "XRRGetScreenResources": (
+        "xrandr",
+        [POINTER(Display), POINTER(Display)],
+        POINTER(XRRScreenResources),
+    ),
+    "XRRGetScreenResourcesCurrent": (
+        "xrandr",
+        [POINTER(Display), POINTER(Display)],
+        POINTER(XRRScreenResources),
+    ),
+    "XSetErrorHandler": ("xlib", [c_void_p], c_int),
+}
+
+
 class MSS(MSSBase):
     """
     Multiple ScreenShots implementation for GNU/Linux.
@@ -197,6 +277,7 @@
             try:
                 display = os.environ["DISPLAY"].encode("utf-8")
             except KeyError:
+                # pylint: disable=raise-missing-from
                 raise ScreenShotError("$DISPLAY not set.")
 
         if not isinstance(display, bytes):
@@ -228,14 +309,12 @@
 
         # Fix for XRRGetScreenResources and XGetImage:
         #     expected LP_Display instance instead of LP_XWindowAttributes
-        self.drawable = ctypes.cast(self.root, ctypes.POINTER(Display))
+        self.drawable = ctypes.cast(self.root, POINTER(Display))
 
     def has_extension(self, extension):
         # type: (str) -> bool
         """Return True if the given *extension* is part of the extensions list 
of the server."""
         with lock:
-            byref = ctypes.byref
-            c_int = ctypes.c_int
             major_opcode_return = c_int()
             first_event_return = c_int()
             first_error_return = c_int()
@@ -244,9 +323,9 @@
                 self.xlib.XQueryExtension(
                     self._get_display(),
                     extension.encode("latin1"),
-                    byref(major_opcode_return),
-                    byref(first_event_return),
-                    byref(first_error_return),
+                    ctypes.byref(major_opcode_return),
+                    ctypes.byref(first_event_return),
+                    ctypes.byref(first_error_return),
                 )
             except ScreenShotError:
                 return False
@@ -271,93 +350,24 @@
         return display
 
     def _set_cfunctions(self):
-        """
-        Set all ctypes functions and attach them to attributes.
-        See https://tronche.com/gui/x/xlib/function-index.html for details.
-        """
-
-        def cfactory(func, argtypes, restype, attr=self.xlib):
-            # type: (str, List[Any], Any, Any) -> None
-            """ Factorize ctypes creations. """
-            self._cfactory(
-                attr=attr,
-                errcheck=validate,
-                func=func,
-                argtypes=argtypes,
-                restype=restype,
-            )
+        """ Set all ctypes functions and attach them to attributes. """
 
-        void = ctypes.c_void_p
-        c_int = ctypes.c_int
-        uint = ctypes.c_uint
-        ulong = ctypes.c_ulong
-        c_long = ctypes.c_long
-        char_p = ctypes.c_char_p
-        pointer = ctypes.POINTER
-
-        cfactory("XSetErrorHandler", [void], c_int)
-        cfactory("XGetErrorText", [pointer(Display), c_int, char_p, c_int], 
void)
-        cfactory("XOpenDisplay", [char_p], pointer(Display))
-        cfactory("XDefaultRootWindow", [pointer(Display)], 
pointer(XWindowAttributes))
-        cfactory(
-            "XGetWindowAttributes",
-            [pointer(Display), pointer(XWindowAttributes), 
pointer(XWindowAttributes)],
-            c_int,
-        )
-        cfactory(
-            "XGetImage",
-            [
-                pointer(Display),
-                pointer(Display),
-                c_int,
-                c_int,
-                uint,
-                uint,
-                ulong,
-                c_int,
-            ],
-            pointer(XImage),
-        )
-        cfactory("XDestroyImage", [pointer(XImage)], void)
-        cfactory(
-            "XQueryExtension",
-            [pointer(Display), char_p, pointer(c_int), pointer(c_int), 
pointer(c_int)],
-            uint,
-        )
-
-        # A simple benchmark calling 10 times those 2 functions:
-        # XRRGetScreenResources():        0.1755971429956844 s
-        # XRRGetScreenResourcesCurrent(): 0.0039125580078689 s
-        # The second is faster by a factor of 44! So try to use it first.
-        try:
-            cfactory(
-                "XRRGetScreenResourcesCurrent",
-                [pointer(Display), pointer(Display)],
-                pointer(XRRScreenResources),
-                attr=self.xrandr,
-            )
-        except AttributeError:
-            cfactory(
-                "XRRGetScreenResources",
-                [pointer(Display), pointer(Display)],
-                pointer(XRRScreenResources),
-                attr=self.xrandr,
-            )
-            self.xrandr.XRRGetScreenResourcesCurrent = 
self.xrandr.XRRGetScreenResources
-
-        cfactory(
-            "XRRGetCrtcInfo",
-            [pointer(Display), pointer(XRRScreenResources), c_long],
-            pointer(XRRCrtcInfo),
-            attr=self.xrandr,
-        )
-        cfactory(
-            "XRRFreeScreenResources",
-            [pointer(XRRScreenResources)],
-            void,
-            attr=self.xrandr,
-        )
-        cfactory("XRRFreeCrtcInfo", [pointer(XRRCrtcInfo)], void, 
attr=self.xrandr)
+        cfactory = self._cfactory
+        attrs = {
+            "xlib": self.xlib,
+            "xrandr": self.xrandr,
+        }
+        for func, (attr, argtypes, restype) in CFUNCTIONS.items():
+            try:
+                cfactory(
+                    attr=attrs[attr],
+                    errcheck=validate,
+                    func=func,
+                    argtypes=argtypes,
+                    restype=restype,
+                )  # type: ignore
+            except AttributeError:
+                pass
 
     def get_error_details(self):
         # type: () -> Optional[Dict[str, Any]]
@@ -402,7 +412,15 @@
         )
 
         # Each monitors
-        mon = xrandr.XRRGetScreenResourcesCurrent(display, 
self.drawable).contents
+        # A simple benchmark calling 10 times those 2 functions:
+        # XRRGetScreenResources():        0.1755971429956844 s
+        # XRRGetScreenResourcesCurrent(): 0.0039125580078689 s
+        # The second is faster by a factor of 44! So try to use it first.
+        try:
+            mon = xrandr.XRRGetScreenResourcesCurrent(display, 
self.drawable).contents
+        except AttributeError:
+            mon = xrandr.XRRGetScreenResources(display, self.drawable).contents
+
         crtcs = mon.crtcs
         for idx in range(mon.ncrtc):
             crtc = xrandr.XRRGetCrtcInfo(display, mon, crtcs[idx]).contents
@@ -447,9 +465,7 @@
 
             raw_data = ctypes.cast(
                 ximage.contents.data,
-                ctypes.POINTER(
-                    ctypes.c_ubyte * monitor["height"] * monitor["width"] * 4
-                ),
+                POINTER(c_ubyte * monitor["height"] * monitor["width"] * 4),
             )
             data = bytearray(raw_data.contents)
         finally:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mss-6.0.0/mss/screenshot.py 
new/mss-6.1.0/mss/screenshot.py
--- old/mss-6.0.0/mss/screenshot.py     2019-04-23 16:35:25.000000000 +0200
+++ new/mss-6.1.0/mss/screenshot.py     2020-10-31 18:07:02.000000000 +0100
@@ -152,6 +152,7 @@
         try:
             return self.pixels[coord_y][coord_x]  # type: ignore
         except IndexError:
+            # pylint: disable=raise-missing-from
             raise ScreenShotError(
                 "Pixel location ({}, {}) is out of range.".format(coord_x, 
coord_y)
             )
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mss-6.0.0/mss/tests/test_gnu_linux.py 
new/mss-6.1.0/mss/tests/test_gnu_linux.py
--- old/mss-6.0.0/mss/tests/test_gnu_linux.py   2020-06-30 17:37:13.000000000 
+0200
+++ new/mss-6.1.0/mss/tests/test_gnu_linux.py   2020-10-31 18:07:02.000000000 
+0100
@@ -37,14 +37,15 @@
 
     # macOS
     monkeypatch.setattr(platform, "system", lambda: "Darwin")
-    with pytest.raises(ScreenShotError):
+    with pytest.raises((ScreenShotError, ValueError)):
+        # ValueError on macOS Big Sur
         mss.mss()
     monkeypatch.undo()
 
     # Windows
     monkeypatch.setattr(platform, "system", lambda: "wInDoWs")
-    with pytest.raises(ValueError):
-        # wintypes.py:19: ValueError: _type_ 'v' not supported
+    with pytest.raises(ImportError):
+        # ImportError: cannot import name 'WINFUNCTYPE'
         mss.mss()
 
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mss-6.0.0/mss/tests/test_implementation.py 
new/mss-6.1.0/mss/tests/test_implementation.py
--- old/mss-6.0.0/mss/tests/test_implementation.py      2020-06-28 
18:08:11.000000000 +0200
+++ new/mss-6.1.0/mss/tests/test_implementation.py      2020-10-31 
18:07:02.000000000 +0100
@@ -96,11 +96,12 @@
     fmt = "sct-{width}x{height}.png"
     for opt in ("-o", "--out"):
         main([opt, fmt])
-        filename = fmt.format(**sct.monitors[1])
         out, _ = capsys.readouterr()
-        assert out.endswith(filename + "\n")
-        assert os.path.isfile(filename)
-        os.remove(filename)
+        for monitor, line in zip(sct.monitors[1:], out.splitlines()):
+            filename = fmt.format(**monitor)
+            assert line.endswith(filename)
+            assert os.path.isfile(filename)
+            os.remove(filename)
 
     fmt = "sct_{mon}-{date:%Y-%m-%d}.png"
     for opt in ("-o", "--out"):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mss-6.0.0/mss/tests/test_macos.py 
new/mss-6.1.0/mss/tests/test_macos.py
--- old/mss-6.0.0/mss/tests/test_macos.py       2019-12-31 18:37:33.000000000 
+0100
+++ new/mss-6.1.0/mss/tests/test_macos.py       2020-10-31 18:07:02.000000000 
+0100
@@ -44,10 +44,13 @@
 
 def test_implementation(monkeypatch):
     # No `CoreGraphics` library
-    monkeypatch.setattr(ctypes.util, "find_library", lambda x: None)
-    with pytest.raises(ScreenShotError):
-        mss.mss()
-    monkeypatch.undo()
+    version = float(".".join(platform.mac_ver()[0].split(".")[:2]))
+
+    if version < 10.16:
+        monkeypatch.setattr(ctypes.util, "find_library", lambda x: None)
+        with pytest.raises(ScreenShotError):
+            mss.mss()
+        monkeypatch.undo()
 
     with mss.mss() as sct:
         # Test monitor's rotation
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mss-6.0.0/mss/tests/test_third_party.py 
new/mss-6.1.0/mss/tests/test_third_party.py
--- old/mss-6.0.0/mss/tests/test_third_party.py 2020-01-04 21:27:05.000000000 
+0100
+++ new/mss-6.1.0/mss/tests/test_third_party.py 2020-10-31 18:07:02.000000000 
+0100
@@ -11,7 +11,8 @@
 
 try:
     import numpy
-except ImportError:
+except (ImportError, RuntimeError):
+    # RuntimeError on Python 3.9 (macOS): Polyfit sanity test emitted a 
warning, ...
     numpy = None
 
 try:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mss-6.0.0/mss/windows.py new/mss-6.1.0/mss/windows.py
--- old/mss-6.0.0/mss/windows.py        2020-06-28 19:22:53.000000000 +0200
+++ new/mss-6.1.0/mss/windows.py        2020-10-31 18:07:02.000000000 +0100
@@ -6,6 +6,7 @@
 import sys
 import ctypes
 import threading
+from ctypes import POINTER, Structure, WINFUNCTYPE, c_void_p
 from ctypes.wintypes import (
     BOOL,
     DOUBLE,
@@ -40,7 +41,7 @@
 SRCCOPY = 0x00CC0020
 
 
-class BITMAPINFOHEADER(ctypes.Structure):
+class BITMAPINFOHEADER(Structure):
     """ Information about the dimensions and color format of a DIB. """
 
     _fields_ = [
@@ -58,7 +59,7 @@
     ]
 
 
-class BITMAPINFO(ctypes.Structure):
+class BITMAPINFO(Structure):
     """
     Structure that defines the dimensions and color information for a DIB.
     """
@@ -66,10 +67,39 @@
     _fields_ = [("bmiHeader", BITMAPINFOHEADER), ("bmiColors", DWORD * 3)]
 
 
+MONITORNUMPROC = WINFUNCTYPE(INT, DWORD, DWORD, POINTER(RECT), DOUBLE)
+
+
+# C functions that will be initialised later.
+#
+# This is a dict:
+#    cfunction: (attr, argtypes, restype)
+#
+# Available attr: gdi32, user32.
+#
+# Note: keep it sorted by cfunction.
+CFUNCTIONS = {
+    "BitBlt": ("gdi32", [HDC, INT, INT, INT, INT, HDC, INT, INT, DWORD], BOOL),
+    "CreateCompatibleBitmap": ("gdi32", [HDC, INT, INT], HBITMAP),
+    "CreateCompatibleDC": ("gdi32", [HDC], HDC),
+    "DeleteObject": ("gdi32", [HGDIOBJ], INT),
+    "EnumDisplayMonitors": ("user32", [HDC, c_void_p, MONITORNUMPROC, LPARAM], 
BOOL),
+    "GetDeviceCaps": ("gdi32", [HWND, INT], INT),
+    "GetDIBits": (
+        "gdi32",
+        [HDC, HBITMAP, UINT, UINT, c_void_p, POINTER(BITMAPINFO), UINT],
+        BOOL,
+    ),
+    "GetSystemMetrics": ("user32", [INT], INT),
+    "GetWindowDC": ("user32", [HWND], HDC),
+    "SelectObject": ("gdi32", [HDC, HGDIOBJ], HGDIOBJ),
+}
+
+
 class MSS(MSSBase):
     """ Multiple ScreenShots implementation for Microsoft Windows. """
 
-    __slots__ = {"_bbox", "_bmi", "_data", "gdi32", "monitorenumproc", 
"user32"}
+    __slots__ = {"_bbox", "_bmi", "_data", "gdi32", "user32"}
 
     # Class attributes instanced one time to prevent resource leaks.
     bmp = None
@@ -84,10 +114,6 @@
 
         super().__init__()
 
-        self.monitorenumproc = ctypes.WINFUNCTYPE(
-            INT, DWORD, DWORD, ctypes.POINTER(RECT), DOUBLE
-        )
-
         self.user32 = ctypes.WinDLL("user32")
         self.gdi32 = ctypes.WinDLL("gdi32")
         self._set_cfunctions()
@@ -112,55 +138,18 @@
     def _set_cfunctions(self):
         """ Set all ctypes functions and attach them to attributes. """
 
-        void = ctypes.c_void_p
-        pointer = ctypes.POINTER
-
-        self._cfactory(
-            attr=self.user32, func="GetSystemMetrics", argtypes=[INT], 
restype=INT
-        )
-        self._cfactory(
-            attr=self.user32,
-            func="EnumDisplayMonitors",
-            argtypes=[HDC, void, self.monitorenumproc, LPARAM],
-            restype=BOOL,
-        )
-        self._cfactory(
-            attr=self.user32, func="GetWindowDC", argtypes=[HWND], restype=HDC
-        )
-
-        self._cfactory(
-            attr=self.gdi32, func="GetDeviceCaps", argtypes=[HWND, INT], 
restype=INT
-        )
-        self._cfactory(
-            attr=self.gdi32, func="CreateCompatibleDC", argtypes=[HDC], 
restype=HDC
-        )
-        self._cfactory(
-            attr=self.gdi32,
-            func="CreateCompatibleBitmap",
-            argtypes=[HDC, INT, INT],
-            restype=HBITMAP,
-        )
-        self._cfactory(
-            attr=self.gdi32,
-            func="SelectObject",
-            argtypes=[HDC, HGDIOBJ],
-            restype=HGDIOBJ,
-        )
-        self._cfactory(
-            attr=self.gdi32,
-            func="BitBlt",
-            argtypes=[HDC, INT, INT, INT, INT, HDC, INT, INT, DWORD],
-            restype=BOOL,
-        )
-        self._cfactory(
-            attr=self.gdi32, func="DeleteObject", argtypes=[HGDIOBJ], 
restype=INT
-        )
-        self._cfactory(
-            attr=self.gdi32,
-            func="GetDIBits",
-            argtypes=[HDC, HBITMAP, UINT, UINT, void, pointer(BITMAPINFO), 
UINT],
-            restype=BOOL,
-        )
+        cfactory = self._cfactory
+        attrs = {
+            "gdi32": self.gdi32,
+            "user32": self.user32,
+        }
+        for func, (attr, argtypes, restype) in CFUNCTIONS.items():
+            cfactory(
+                attr=attrs[attr],
+                func=func,
+                argtypes=argtypes,
+                restype=restype,
+            )  # type: ignore
 
     def _set_dpi_awareness(self):
         """ Set DPI aware to capture full screen on Hi-DPI monitors. """
@@ -229,7 +218,7 @@
             )
             return 1
 
-        callback = self.monitorenumproc(_callback)
+        callback = MONITORNUMPROC(_callback)
         user32.EnumDisplayMonitors(0, 0, callback, 0)
 
     def _grab_impl(self, monitor):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mss-6.0.0/mss.egg-info/PKG-INFO 
new/mss-6.1.0/mss.egg-info/PKG-INFO
--- old/mss-6.0.0/mss.egg-info/PKG-INFO 2020-06-30 18:00:14.000000000 +0200
+++ new/mss-6.1.0/mss.egg-info/PKG-INFO 2020-10-31 18:18:32.000000000 +0100
@@ -1,6 +1,6 @@
 Metadata-Version: 1.2
 Name: mss
-Version: 6.0.0
+Version: 6.1.0
 Summary: An ultra fast cross-platform multiple screenshots module in pure 
python using ctypes.
 Home-page: https://github.com/BoboTiG/python-mss
 Author: Micka??l 'Tiger-222' Schoentgen
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mss-6.0.0/setup.cfg new/mss-6.1.0/setup.cfg
--- old/mss-6.0.0/setup.cfg     2020-06-30 18:00:14.000000000 +0200
+++ new/mss-6.1.0/setup.cfg     2020-10-31 18:18:32.503833500 +0100
@@ -1,6 +1,6 @@
 [metadata]
 name = mss
-version = 6.0.0
+version = 6.1.0
 author = Micka??l 'Tiger-222' Schoentgen
 author-email = cont...@tiger-222.fr
 description = An ultra fast cross-platform multiple screenshots module in pure 
python using ctypes.

Reply via email to