Hello community,

here is the log from the commit of package python-PyScreeze for 
openSUSE:Factory checked in at 2020-01-16 18:21:26
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-PyScreeze (Old)
 and      /work/SRC/openSUSE:Factory/.python-PyScreeze.new.26092 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-PyScreeze"

Thu Jan 16 18:21:26 2020 rev:8 rq:764770 version:0.1.26

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-PyScreeze/python-PyScreeze.changes        
2019-09-25 08:41:59.810274716 +0200
+++ 
/work/SRC/openSUSE:Factory/.python-PyScreeze.new.26092/python-PyScreeze.changes 
    2020-01-16 18:21:28.416982713 +0100
@@ -1,0 +2,7 @@
+Wed Jan 15 15:02:19 UTC 2020 - Marketa Calabkova <mcalabk...@suse.com>
+
+- update to 0.1.26
+  * Added some comments and docstring. Updated setup.py to Python 3.8
+  * Made Pillow a hard requirement for the general unit test.
+
+-------------------------------------------------------------------

Old:
----
  PyScreeze-0.1.22.tar.gz

New:
----
  PyScreeze-0.1.26.tar.gz

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

Other differences:
------------------
++++++ python-PyScreeze.spec ++++++
--- /var/tmp/diff_new_pack.JS8mo0/_old  2020-01-16 18:21:30.072983649 +0100
+++ /var/tmp/diff_new_pack.JS8mo0/_new  2020-01-16 18:21:30.072983649 +0100
@@ -1,7 +1,7 @@
 #
 # spec file for package python-PyScreeze
 #
-# Copyright (c) 2019 SUSE LINUX GmbH, Nuernberg, Germany.
+# Copyright (c) 2020 SUSE LLC
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -18,7 +18,7 @@
 
 %{?!python_module:%define python_module() python-%{**} python3-%{**}}
 Name:           python-PyScreeze
-Version:        0.1.22
+Version:        0.1.26
 Release:        0
 Summary:        A screenshot Python module
 License:        BSD-3-Clause

++++++ PyScreeze-0.1.22.tar.gz -> PyScreeze-0.1.26.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/PyScreeze-0.1.22/PKG-INFO 
new/PyScreeze-0.1.26/PKG-INFO
--- old/PyScreeze-0.1.22/PKG-INFO       2019-06-28 06:55:17.462100500 +0200
+++ new/PyScreeze-0.1.26/PKG-INFO       2020-01-14 07:57:11.000000000 +0100
@@ -1,11 +1,11 @@
 Metadata-Version: 1.1
 Name: PyScreeze
-Version: 0.1.22
+Version: 0.1.26
 Summary: A simple, cross-platform screenshot module for Python 2 and 3.
 Home-page: https://github.com/asweigart/pyscreeze
 Author: Al Sweigart
 Author-email: a...@inventwithpython.com
-License: BSD
+License: MIT
 Description: PyScreeze
         =========
         
@@ -134,20 +134,21 @@
         
 Keywords: screenshot screen screencap capture scrot screencapture image
 Platform: UNKNOWN
-Classifier: Development Status :: 3 - Alpha
+Classifier: Development Status :: 4 - Beta
 Classifier: Environment :: Win32 (MS Windows)
 Classifier: Environment :: X11 Applications
 Classifier: Environment :: MacOS X
 Classifier: Intended Audience :: Developers
-Classifier: License :: OSI Approved :: BSD License
+Classifier: License :: OSI Approved :: MIT License
 Classifier: Operating System :: OS Independent
 Classifier: Programming Language :: Python
 Classifier: Programming Language :: Python :: 2
-Classifier: Programming Language :: Python :: 2.5
-Classifier: Programming Language :: Python :: 2.6
 Classifier: Programming Language :: Python :: 2.7
 Classifier: Programming Language :: Python :: 3
-Classifier: Programming Language :: Python :: 3.1
 Classifier: Programming Language :: Python :: 3.2
 Classifier: Programming Language :: Python :: 3.3
 Classifier: Programming Language :: Python :: 3.4
+Classifier: Programming Language :: Python :: 3.5
+Classifier: Programming Language :: Python :: 3.6
+Classifier: Programming Language :: Python :: 3.7
+Classifier: Programming Language :: Python :: 3.8
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/PyScreeze-0.1.22/PyScreeze.egg-info/PKG-INFO 
new/PyScreeze-0.1.26/PyScreeze.egg-info/PKG-INFO
--- old/PyScreeze-0.1.22/PyScreeze.egg-info/PKG-INFO    2019-06-28 
06:55:17.000000000 +0200
+++ new/PyScreeze-0.1.26/PyScreeze.egg-info/PKG-INFO    2020-01-14 
07:57:11.000000000 +0100
@@ -1,11 +1,11 @@
 Metadata-Version: 1.1
 Name: PyScreeze
-Version: 0.1.22
+Version: 0.1.26
 Summary: A simple, cross-platform screenshot module for Python 2 and 3.
 Home-page: https://github.com/asweigart/pyscreeze
 Author: Al Sweigart
 Author-email: a...@inventwithpython.com
-License: BSD
+License: MIT
 Description: PyScreeze
         =========
         
@@ -134,20 +134,21 @@
         
 Keywords: screenshot screen screencap capture scrot screencapture image
 Platform: UNKNOWN
-Classifier: Development Status :: 3 - Alpha
+Classifier: Development Status :: 4 - Beta
 Classifier: Environment :: Win32 (MS Windows)
 Classifier: Environment :: X11 Applications
 Classifier: Environment :: MacOS X
 Classifier: Intended Audience :: Developers
-Classifier: License :: OSI Approved :: BSD License
+Classifier: License :: OSI Approved :: MIT License
 Classifier: Operating System :: OS Independent
 Classifier: Programming Language :: Python
 Classifier: Programming Language :: Python :: 2
-Classifier: Programming Language :: Python :: 2.5
-Classifier: Programming Language :: Python :: 2.6
 Classifier: Programming Language :: Python :: 2.7
 Classifier: Programming Language :: Python :: 3
-Classifier: Programming Language :: Python :: 3.1
 Classifier: Programming Language :: Python :: 3.2
 Classifier: Programming Language :: Python :: 3.3
 Classifier: Programming Language :: Python :: 3.4
+Classifier: Programming Language :: Python :: 3.5
+Classifier: Programming Language :: Python :: 3.6
+Classifier: Programming Language :: Python :: 3.7
+Classifier: Programming Language :: Python :: 3.8
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/PyScreeze-0.1.22/PyScreeze.egg-info/SOURCES.txt 
new/PyScreeze-0.1.26/PyScreeze.egg-info/SOURCES.txt
--- old/PyScreeze-0.1.22/PyScreeze.egg-info/SOURCES.txt 2019-06-28 
06:55:17.000000000 +0200
+++ new/PyScreeze-0.1.26/PyScreeze.egg-info/SOURCES.txt 2020-01-14 
07:57:11.000000000 +0100
@@ -16,4 +16,5 @@
 docs/screenshot.rst
 pyscreeze/__init__.py
 tests/benchmarks.py
+tests/test_pillow_unavailable.py
 tests/test_pyscreeze.py
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/PyScreeze-0.1.22/PyScreeze.egg-info/requires.txt 
new/PyScreeze-0.1.26/PyScreeze.egg-info/requires.txt
--- old/PyScreeze-0.1.22/PyScreeze.egg-info/requires.txt        2019-06-28 
06:55:17.000000000 +0200
+++ new/PyScreeze-0.1.26/PyScreeze.egg-info/requires.txt        2020-01-14 
07:57:11.000000000 +0100
@@ -1 +1,24 @@
-Pillow
+
+[:python_version == "2.7"]
+Pillow>=2.0.0
+
+[:python_version == "3.2"]
+Pillow<=3.4.2,>=2.0.0
+
+[:python_version == "3.3"]
+Pillow<=4.3.0,>=2.0.0
+
+[:python_version == "3.4"]
+Pillow<=5.4.1,>=2.5.0
+
+[:python_version == "3.5"]
+Pillow>=3.2.0
+
+[:python_version == "3.6"]
+Pillow>=4.0.0
+
+[:python_version == "3.7"]
+Pillow>=5.2.0
+
+[:python_version == "3.8"]
+Pillow>=6.2.1
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/PyScreeze-0.1.22/pyscreeze/__init__.py 
new/PyScreeze-0.1.26/pyscreeze/__init__.py
--- old/PyScreeze-0.1.22/pyscreeze/__init__.py  2019-06-28 06:50:27.000000000 
+0200
+++ new/PyScreeze-0.1.26/pyscreeze/__init__.py  2020-01-14 07:55:42.000000000 
+0100
@@ -1,30 +1,45 @@
 # PyScreeze
-# by Al Sweigart
-# https://github.com/asweigart/pyscreeze
-# BSD license
 
 """
-So, apparently Pillow support on Ubuntu 64-bit has several additional steps 
since it doesn't have JPEG/PNG support out of the box. Description here:
+NOTE:
+Apparently Pillow support on Ubuntu 64-bit has several additional steps since 
it doesn't have JPEG/PNG support out of the box. Description here:
 
 
https://stackoverflow.com/questions/7648200/pip-install-pil-e-tickets-1-no-jpeg-png-support
 http://ubuntuforums.org/showthread.php?t=1751455
 """
 
-__version__ = '0.1.22'
+__version__ = '0.1.26'
 
 import collections
 import datetime
+import functools
 import os
 import subprocess
 import sys
 import time
 import errno
+
+from contextlib import contextmanager
+
 try:
     from PIL import Image
     from PIL import ImageOps
+    from PIL import ImageDraw
+    if sys.platform == 'win32': # TODO - Pillow now supports ImageGrab on 
macOS.
+        from PIL import ImageGrab
+    _PILLOW_UNAVAILABLE = False
 except ImportError:
-    pass
-from contextlib import contextmanager
+    # We ignore this because failures due to Pillow not being installed
+    # should only happen when the functions that specifically depend on
+    # Pillow are called. The main use case is when PyAutoGUI imports
+    # PyScreeze, but Pillow isn't installed because the user is running
+    # some platform/version of Python that Pillow doesn't support, then
+    # importing PyAutoGUI should not automatically fail because it
+    # imports PyScreeze.
+    # So we have a `pass` statement here since a failure to import
+    # Pillow shouldn't crash PyScreeze.
+    _PILLOW_UNAVAILABLE = True
+
 
 try:
     import cv2, numpy
@@ -42,6 +57,19 @@
         LOAD_COLOR = cv2.IMREAD_COLOR
         LOAD_GRAYSCALE = cv2.IMREAD_GRAYSCALE
 
+if not RUNNING_PYTHON_2:
+    unicode = str # On Python 3, all the isinstance(spam, (str, unicode)) 
calls will work the same as Python 2.
+
+if sys.platform == 'win32':
+    # On Windows, the monitor scaling can be set to something besides normal 
100%.
+    # PyScreeze and Pillow needs to account for this to make accurate 
screenshots.
+    # TODO - How does macOS and Linux handle monitor scaling?
+    import ctypes
+    try:
+       ctypes.windll.user32.SetProcessDPIAware()
+    except AttributeError:
+        pass # Windows XP doesn't support monitor scaling, so just do nothing.
+
 
 GRAYSCALE_DEFAULT = False
 
@@ -72,6 +100,9 @@
     # win32 DC(DeviceContext) Manager
     @contextmanager
     def __win32_openDC(hWnd):
+        """
+        TODO
+        """
         hDC = windll.user32.GetDC(hWnd)
         if hDC == 0: #NULL
             raise WindowsError("windll.user32.GetDC failed : return NULL")
@@ -85,11 +116,29 @@
 Point = collections.namedtuple('Point', 'x y')
 RGB = collections.namedtuple('RGB', 'red green blue')
 
-class ImageNotFoundException(Exception):
-    pass # This is an exception class raised when the locate functions fail.
+class PyScreezeException(Exception):
+    pass # This is a generic exception class raised when a PyScreeze-related 
error happens.
 
+class ImageNotFoundException(PyScreezeException):
+    pass # This is an exception class raised when the locate functions fail to 
locate an image.
+
+
+def requiresPillow(wrappedFunction):
+    """
+    A decorator that marks a function as requiring Pillow to be installed.
+    This raises PyScreezeException if Pillow wasn't imported.
+    """
+    @functools.wraps(wrappedFunction)
+    def wrapper(*args, **kwargs):
+        if _PILLOW_UNAVAILABLE:
+            raise PyScreezeException('The Pillow package is required to use 
this function.')
+        return wrappedFunction(*args, **kwargs)
+    return wrapper
 
 def _load_cv2(img, grayscale=None):
+    """
+    TODO
+    """
     # load images if given filename, or convert as needed to opencv
     # Alpha layer just causes failures at this point, so flatten to RGB.
     # RGBA: load with -1 * cv2.CV_LOAD_IMAGE_COLOR to preserve alpha
@@ -97,7 +146,7 @@
 
     if grayscale is None:
         grayscale = GRAYSCALE_DEFAULT
-    if isinstance(img, str):
+    if isinstance(img, (str, unicode)):
         # The function imread loads an image from the specified file and
         # returns it. If the image cannot be read (because of missing
         # file, improper permissions, unsupported or invalid format),
@@ -130,7 +179,9 @@
 
 def _locateAll_opencv(needleImage, haystackImage, grayscale=None, limit=10000, 
region=None, step=1,
                       confidence=0.999):
-    """ faster but more memory-intensive than pure python
+    """
+    TODO - rewrite this
+        faster but more memory-intensive than pure python
         step 2 skips every other row and column = ~3x faster but prone to miss;
             to compensate, the algorithm automatically reduces the confidence
             threshold by 5% (which helps but will not avoid all misses).
@@ -182,19 +233,24 @@
         yield Box(x, y, needleWidth, needleHeight)
 
 
+# TODO - We should consider renaming _locateAll_python to _locateAll_pillow, 
since Pillow is the real dependency.
+@requiresPillow
 def _locateAll_python(needleImage, haystackImage, grayscale=None, limit=None, 
region=None, step=1):
+    """
+    TODO
+    """
     # setup all the arguments
     if grayscale is None:
         grayscale = GRAYSCALE_DEFAULT
 
     needleFileObj = None
-    if isinstance(needleImage, str):
+    if isinstance(needleImage, (str, unicode)):
         # 'image' is a filename, load the Image object
         needleFileObj = open(needleImage, 'rb')
         needleImage = Image.open(needleFileObj)
 
     haystackFileObj = None
-    if isinstance(haystackImage, str):
+    if isinstance(haystackImage, (str, unicode)):
         # 'image' is a filename, load the Image object
         haystackFileObj = open(haystackImage, 'rb')
         haystackImage = Image.open(haystackFileObj)
@@ -276,6 +332,9 @@
 
 
 def locate(needleImage, haystackImage, **kwargs):
+    """
+    TODO
+    """
     # Note: The gymnastics in this function is because we want to make sure to 
exhaust the iterator so that the needle and haystack files are closed in 
locateAll.
     kwargs['limit'] = 1
     points = tuple(locateAll(needleImage, haystackImage, **kwargs))
@@ -289,7 +348,8 @@
 
 
 def locateOnScreen(image, minSearchTime=0, **kwargs):
-    """minSearchTime - amount of time in seconds to repeat taking
+    """TODO - rewrite this
+    minSearchTime - amount of time in seconds to repeat taking
     screenshots and trying to locate a match.  The default of 0 performs
     a single search.
     """
@@ -316,6 +376,11 @@
 
 
 def locateAllOnScreen(image, **kwargs):
+    """
+    TODO
+    """
+
+    # TODO - Should this raise an exception if zero instances of the image can 
be found on the screen, instead of always returning a generator?
     screenshotIm = screenshot(region=None) # the locateAll() function must 
handle cropping to return accurate coordinates, so don't pass a region here.
     retVal = locateAll(image, screenshotIm, **kwargs)
     try:
@@ -329,12 +394,22 @@
 
 
 def locateCenterOnScreen(image, **kwargs):
+    """
+    TODO
+    """
     coords = locateOnScreen(image, **kwargs)
-    return center(coords)
+    if coords is None:
+        return None
+    else:
+        return center(coords)
 
 
+@requiresPillow
 def showRegionOnScreen(region, outlineColor='red', 
filename='_showRegionOnScreen.png'):
-    from PIL import ImageDraw # this is the only function that needs this, and 
it's rarely called
+    """
+    TODO
+    """
+    # TODO - This function is useful! Document it!
     screenshotIm = screenshot()
     draw = ImageDraw.Draw(screenshotIm)
     region = (region[0], region[1], region[2] + region[0], region[3] + 
region[1]) # convert from (left, top, right, bottom) to (left, top, width, 
height)
@@ -342,13 +417,14 @@
     screenshotIm.save(filename)
 
 
+@requiresPillow
 def _screenshot_win32(imageFilename=None, region=None):
+    """
+    TODO
+    """
     # TODO - Use the winapi to get a screenshot, and compare performance with 
ImageGrab.grab()
     # https://stackoverflow.com/a/3586280/1893164
-    try:
-        im = ImageGrab.grab()
-    except NameError:
-        raise ImportError('Pillow module must be installed to use screenshot 
functions on Windows.')
+    im = ImageGrab.grab()
     if region is not None:
         assert len(region) == 4, 'region argument must be a tuple of four ints'
         region = [int(x) for x in region]
@@ -359,6 +435,9 @@
 
 
 def _screenshot_osx(imageFilename=None, region=None):
+    """
+    TODO
+    """
     # TODO - use tmp name for this file.
     if imageFilename is None:
         tmpFilename = 'screenshot%s.png' % 
(datetime.datetime.now().strftime('%Y-%m%d_%H-%M-%S-%f'))
@@ -383,6 +462,9 @@
 
 
 def _screenshot_linux(imageFilename=None, region=None):
+    """
+    TODO
+    """
     if not scrotExists:
         raise NotImplementedError('"scrot" must be installed to use screenshot 
functions in Linux. Run: sudo apt-get install scrot')
     if imageFilename is None:
@@ -412,6 +494,9 @@
 
 
 def _kmp(needle, haystack, _dummy): # Knuth-Morris-Pratt search algorithm 
implementation (to be used by screen capture)
+    """
+    TODO
+    """
     # build table of shift amounts
     shifts = [1] * (len(needle) + 1)
     shift = 1
@@ -434,6 +519,9 @@
 
 
 def _steppingFind(needle, haystack, step):
+    """
+    TODO
+    """
     for startPos in range(0, len(haystack) - len(needle) + 1):
         foundMatch = True
         for pos in range(0, len(needle), step):
@@ -445,10 +533,29 @@
 
 
 def center(coords):
+    """
+    Returns a `Point` object with the x and y set to an integer determined by 
the format of `coords`.
+
+    The `coords` argument is a 4-integer tuple of (left, top, width, height).
+
+    For example:
+
+    >>> center((10, 10, 6, 8))
+    Point(x=13, y=14)
+    >>> center((10, 10, 7, 9))
+    Point(x=13, y=14)
+    >>> center((10, 10, 8, 10))
+    Point(x=14, y=15)
+    """
+
+    # TODO - one day, add code to handle a Box namedtuple.
     return Point(coords[0] + int(coords[2] / 2), coords[1] + int(coords[3] / 
2))
 
 
 def pixelMatchesColor(x, y, expectedRGBColor, tolerance=0):
+    """
+    TODO
+    """
     pix = pixel(x, y)
     if len(pix) == 3 or len(expectedRGBColor) == 3: #RGB mode
         r, g, b = pix[:3]
@@ -462,12 +569,15 @@
         assert False, 'Color mode was expected to be length 3 (RGB) or 4 
(RGBA), but pixel is length %s and expectedRGBColor is length %s' % (len(pix), 
len(expectedRGBColor))
 
 def pixel(x, y):
+    """
+    TODO
+    """
     if sys.platform == 'win32':
         # On Windows, calling GetDC() and GetPixel() is twice as fast as using 
our screenshot() function.
         with __win32_openDC(0) as hdc: # handle will be released automatically
             color = windll.gdi32.GetPixel(hdc, x, y)
             if color < 0:
-                raise WindowsError("windll.gdi32.GetPixel faild : return 
{}".format(color))
+                raise WindowsError("windll.gdi32.GetPixel failed : return 
{}".format(color))
             # color is in the format 0xbbggrr 
https://msdn.microsoft.com/en-us/library/windows/desktop/dd183449(v=vs.85).aspx
             bbggrr = "{:0>6x}".format(color) # bbggrr => 'bbggrr' (hex)
             b, g, r = (int(bbggrr[i:i+2], 16) for i in range(0, 6, 2))
@@ -485,16 +595,13 @@
     screenshot = _screenshot_osx
 elif sys.platform == 'win32':
     screenshot = _screenshot_win32
-    try:
-        from PIL import ImageGrab
-    except ImportError:
-        pass
-else:
+else: # TODO - Make this more specific. "Anything else" does not necessarily 
mean "Linux".
     screenshot = _screenshot_linux
 
 grab = screenshot # for compatibility with Pillow/PIL's ImageGrab module.
 
 # set the locateAll function to use opencv if possible; python 3 needs opencv 
3.0+
+# TODO - Should this raise an exception if zero instances of the image can be 
found on the screen, instead of always returning a generator?
 if useOpenCV:
     locateAll = _locateAll_opencv
     if not RUNNING_PYTHON_2 and cv2.__version__ < '3':
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/PyScreeze-0.1.22/setup.py 
new/PyScreeze-0.1.26/setup.py
--- old/PyScreeze-0.1.22/setup.py       2018-07-19 08:07:29.000000000 +0200
+++ new/PyScreeze-0.1.26/setup.py       2019-10-28 20:15:09.000000000 +0100
@@ -1,45 +1,62 @@
+import io
+import os
 import re
 from setuptools import setup
 
+scriptFolder = os.path.dirname(os.path.realpath(__file__))
+os.chdir(scriptFolder)
+
 # Load version from module (without loading the whole module)
-with open('pyscreeze/__init__.py', 'r') as fd:
-    version = re.search(r'^__version__\s*=\s*[\'"]([^\'"]*)[\'"]',
-                        fd.read(), re.MULTILINE).group(1)
+with open("pyscreeze/__init__.py", "r") as fileObj:
+    version = re.search(
+        r'^__version__\s*=\s*[\'"]([^\'"]*)[\'"]', fileObj.read(), re.MULTILINE
+    ).group(1)
 
-# Read in the README.md for the long description.
-with open("README.md", "r") as fh:
-    long_description = fh.read()
+# Use the README.md content for the long description:
+with io.open("README.md", encoding="utf-8") as fileObj:
+    long_description = fileObj.read()
 
 setup(
-    name='PyScreeze',
+    name="PyScreeze",
     version=version,
-    url='https://github.com/asweigart/pyscreeze',
-    author='Al Sweigart',
-    author_email='a...@inventwithpython.com',
-    description='A simple, cross-platform screenshot module for Python 2 and 
3.',
+    url="https://github.com/asweigart/pyscreeze";,
+    author="Al Sweigart",
+    author_email="a...@inventwithpython.com",
+    description="A simple, cross-platform screenshot module for Python 2 and 
3.",
     long_description=long_description,
-    license='BSD',
-    packages=['pyscreeze'],
-    test_suite='tests',
-    install_requires=['Pillow'],
+    license="MIT",
+    packages=["pyscreeze"],
+    test_suite="tests",
+    # NOTE: Update the python_version info for Pillow as Pillow supports later 
versions of Python.
+    install_requires=['Pillow >= 6.2.1; python_version == "3.8"',
+                      'Pillow >= 5.2.0; python_version == "3.7"',
+                      'Pillow >= 4.0.0; python_version == "3.6"',
+                      'Pillow >= 3.2.0; python_version == "3.5"',
+                      'Pillow <= 5.4.1, >= 2.5.0; python_version == "3.4"',
+                      'Pillow <= 4.3.0, >= 2.0.0; python_version == "3.3"',
+                      'Pillow <= 3.4.2, >= 2.0.0; python_version == "3.2"',
+                      'Pillow >= 2.0.0; python_version == "2.7"',
+                      ],
+    requires_python=">=2.7, !=3.0.*, !=3.1.*",  # Pillow library has never 
supported pre-2.7 or 3.0 or 3.1.
     keywords="screenshot screen screencap capture scrot screencapture image",
     classifiers=[
-        'Development Status :: 3 - Alpha',
-        'Environment :: Win32 (MS Windows)',
-        'Environment :: X11 Applications',
-        'Environment :: MacOS X',
-        'Intended Audience :: Developers',
-        'License :: OSI Approved :: BSD License',
-        'Operating System :: OS Independent',
-        'Programming Language :: Python',
-        'Programming Language :: Python :: 2',
-        'Programming Language :: Python :: 2.5',
-        'Programming Language :: Python :: 2.6',
-        'Programming Language :: Python :: 2.7',
-        'Programming Language :: Python :: 3',
-        'Programming Language :: Python :: 3.1',
-        'Programming Language :: Python :: 3.2',
-        'Programming Language :: Python :: 3.3',
-        'Programming Language :: Python :: 3.4',
+        "Development Status :: 4 - Beta",
+        "Environment :: Win32 (MS Windows)",
+        "Environment :: X11 Applications",
+        "Environment :: MacOS X",
+        "Intended Audience :: Developers",
+        "License :: OSI Approved :: MIT License",
+        "Operating System :: OS Independent",
+        "Programming Language :: Python",
+        "Programming Language :: Python :: 2",
+        "Programming Language :: Python :: 2.7",
+        "Programming Language :: Python :: 3",
+        "Programming Language :: Python :: 3.2",
+        "Programming Language :: Python :: 3.3",
+        "Programming Language :: Python :: 3.4",
+        "Programming Language :: Python :: 3.5",
+        "Programming Language :: Python :: 3.6",
+        "Programming Language :: Python :: 3.7",
+        "Programming Language :: Python :: 3.8",
     ],
-)
\ No newline at end of file
+)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/PyScreeze-0.1.22/tests/test_pillow_unavailable.py 
new/PyScreeze-0.1.26/tests/test_pillow_unavailable.py
--- old/PyScreeze-0.1.22/tests/test_pillow_unavailable.py       1970-01-01 
01:00:00.000000000 +0100
+++ new/PyScreeze-0.1.26/tests/test_pillow_unavailable.py       2019-10-10 
00:40:49.000000000 +0200
@@ -0,0 +1,58 @@
+# This unit test will test PyScreeze in a condition where PIL is unavailable.
+# The locate and screenshot functions that require Pillow should fail under
+# this circumstance. This test checks to make sure those failures happen.
+
+# NOTE: This is in a separate .py file because we need to ensure that
+# the real PIL module isn't imported, and there's no convenient way to
+# "unimport" modules in Python after they've been imported.
+
+# NOTE: PIL and Pillow mean the same thing in this document.
+
+import os
+import sys
+import unittest
+
+scriptFolder = os.path.dirname(os.path.realpath(__file__))
+os.chdir(scriptFolder)
+
+sys.path.insert(0, scriptFolder) # Ensure that we import our fake PIL.py even 
if Pillow is actually installed.
+
+class TestPillowNotImported(unittest.TestCase):
+
+    def test_functionsThatRequirePillow(self):
+        try:
+            import cv2, numpy
+            opencvNotInstalled = False
+        except ImportError:
+            opencvNotInstalled = True
+
+        if (sys.platform == 'win32') and (opencvNotInstalled):
+            with self.assertRaises(pyscreeze.PyScreezeException):
+                #import pdb;pdb.set_trace()
+                pyscreeze.screenshot('foo.png')
+
+            with self.assertRaises(pyscreeze.PyScreezeException):
+                pyscreeze.locateOnScreen('foo.png')
+
+            with self.assertRaises(pyscreeze.PyScreezeException):
+                pyscreeze.locateAllOnScreen('foo.png')
+
+            with self.assertRaises(pyscreeze.PyScreezeException):
+                pyscreeze.locateAll('foo.png', 'foo.png')
+        else:
+            pass # TODO - add some kind of warning here that we aren't 
actually testing anything, maybe?
+
+if __name__ == '__main__':
+    # Ensure that our fake PIL module is imported, which simulates PIL not 
being available for importing.
+    fileObj = open('PIL.py', 'w')
+    fileObj.write("""raise ImportError('fake import error')\n""")
+    fileObj.close()
+
+    import pyscreeze # Import pyscreeze and fool it into thinking PIL is 
unavailable.
+
+    try:
+        os.unlink('PIL.py') # Delete the fake PIL.py file so that other tests 
use the real PIL module.
+    except Exception():
+        pass
+
+    unittest.main()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/PyScreeze-0.1.22/tests/test_pyscreeze.py 
new/PyScreeze-0.1.26/tests/test_pyscreeze.py
--- old/PyScreeze-0.1.22/tests/test_pyscreeze.py        2019-01-05 
19:52:06.000000000 +0100
+++ new/PyScreeze-0.1.26/tests/test_pyscreeze.py        2019-10-24 
00:13:52.000000000 +0200
@@ -1,19 +1,28 @@
 import unittest
 import sys
 import os
+import pyscreeze
 
 try:
     from PIL import Image
-except ImportError:
-    pass
-sys.path.insert(0, os.path.abspath('..'))
-import pyscreeze
-
-runningOnPython2 = sys.version_info[0] == 2
-
+except:
+    # TODO - is there a graceful way around this problem?
+    raise Exception("Pillow is not installed. While PyScreeze doesn't require 
Pillow, the PyScreeze unit tests do.")
+
+# Change the cwd to this file's folder, because that's where the test image 
files are located.
+scriptFolder = os.path.dirname(os.path.realpath(__file__))
+os.chdir(scriptFolder)
 
+RUNNING_ON_PYTHON_2 = sys.version_info[0] == 2
 TEMP_FILENAME = '_delete_me.png'
 
+# Delete PIL.py, which is made by test_pillow_unavailable.py, just in case it
+# was left over from some incomplete run of that test.
+try:
+    os.unlink('PIL.py')
+except Exception:
+    pass
+
 
 # Helper functions to get current screen resolution on Windows, Mac OS X, or 
Linux.
 # Non-Windows platforms require additional modules:
@@ -50,7 +59,7 @@
     fp = open(filename, 'rb')
     fileMagicNumbers = fp.read(len(pngMagicNumbers))
     fp.close()
-    if runningOnPython2:
+    if RUNNING_ON_PYTHON_2:
         return fileMagicNumbers == bytearray(pngMagicNumbers)
     else:
         return fileMagicNumbers == bytes(pngMagicNumbers)
@@ -62,7 +71,7 @@
     fp = open(filename, 'rb')
     fileMagicNumbers = fp.read(len(jpgMagicNumbers))
     fp.close()
-    if runningOnPython2:
+    if RUNNING_ON_PYTHON_2:
         return fileMagicNumbers == bytearray(jpgMagicNumbers)
     else:
         return fileMagicNumbers == bytes(jpgMagicNumbers)
@@ -96,24 +105,6 @@
         self.assertFalse(isJpg(__file__))
 
 class TestGeneral(unittest.TestCase):
-    def test_pillowNotPresent(self):
-        # Testing that we can still import pyscreeze
-        # even if pillow is not present
-
-        # Setting module's dictionary entry to None will raise
-        # ImportError while deleting the entry will make the interpreter
-        # continue searching for module
-        sys.modules["PIL"] = None
-
-        if sys.version_info[0] == 2:
-            reload(pyscreeze)
-        elif sys.version_info[:2] <= (3, 3):
-            import imp
-            imp.reload(pyscreeze)
-        else:
-            import importlib
-            importlib.reload(pyscreeze)
-
     def test_namesDefined(self):
         pyscreeze.locateAll
         pyscreeze.locate
@@ -129,7 +120,7 @@
     def test_screenshot(self):
         im = pyscreeze.screenshot(TEMP_FILENAME)
         self.assertTrue(isPng(TEMP_FILENAME))
-        self.assertEqual(im.size, resolution())
+        self.assertEqual(im.size, resolution()) # TODO shouldn't this fail on 
Windows for multi-monitor setups?
         os.unlink(TEMP_FILENAME)
 
 
@@ -151,11 +142,15 @@
         self.assertEqual((94, 94, 4, 4), tuple(pyscreeze.locate('slash.png', 
'haystack1.png', grayscale=True)))
         self.assertEqual((93, 93, 4, 4), tuple(pyscreeze.locate('slash.png', 
'haystack2.png', grayscale=True)))
 
+        pyscreeze.USE_IMAGE_NOT_FOUND_EXCEPTION = True
         with self.assertRaises(pyscreeze.ImageNotFoundException):
             pyscreeze.locate('slash.png', 'colornoise.png')
         with self.assertRaises(pyscreeze.ImageNotFoundException):
             pyscreeze.locate('slash.png', 'colornoise.png', grayscale=True)
 
+        pyscreeze.USE_IMAGE_NOT_FOUND_EXCEPTION = False
+        self.assertEqual(pyscreeze.locate('slash.png', 'colornoise.png'), None)
+        self.assertEqual(pyscreeze.locate('slash.png', 'colornoise.png', 
grayscale=True), None)
 
     def test_locate_im(self):
         slashFp = open('slash.png' ,'rb')
@@ -173,11 +168,16 @@
         self.assertEqual((94, 94, 4, 4), tuple(pyscreeze.locate(slashIm, 
haystack1Im, grayscale=True)))
         self.assertEqual((93, 93, 4, 4), tuple(pyscreeze.locate(slashIm, 
haystack2Im, grayscale=True)))
 
+        pyscreeze.USE_IMAGE_NOT_FOUND_EXCEPTION = True
         with self.assertRaises(pyscreeze.ImageNotFoundException):
             pyscreeze.locate(slashIm, colorNoiseIm)
         with self.assertRaises(pyscreeze.ImageNotFoundException):
             pyscreeze.locate(slashIm, colorNoiseIm, grayscale=True)
 
+        pyscreeze.USE_IMAGE_NOT_FOUND_EXCEPTION = False
+        self.assertEqual(pyscreeze.locate(slashIm, colorNoiseIm), None)
+        self.assertEqual(pyscreeze.locate(slashIm, colorNoiseIm, 
grayscale=True), None)
+
         slashFp.close()
         haystack1Fp.close()
         haystack2Fp.close()
@@ -223,9 +223,13 @@
         slashFp = open('slash.png' ,'rb')
         slashIm = Image.open(slashFp)
 
+        pyscreeze.USE_IMAGE_NOT_FOUND_EXCEPTION = True
         with self.assertRaises(pyscreeze.ImageNotFoundException):
             pyscreeze.locate(slashIm, colorNoiseIm)
 
+        pyscreeze.USE_IMAGE_NOT_FOUND_EXCEPTION = False
+        self.assertEqual(pyscreeze.locate(slashIm, colorNoiseIm), None)
+
         colorNoiseFp.close()
         slashFp.close()
 
@@ -264,6 +268,16 @@
         colorNoiseFp.close()
         """
 
+class TestStressTest(unittest.TestCase):
+    def test_1000screenshots(self):
+        # This test takes about two minutes for 200 screenshots.
+        # On Windows, if I change PyScreeze away from Pillow and make win32 
api calls directly but forget to release
+        # the DCs (display contexts), the program would fail after about 90 or 
screenshots.
+        # 
https://stackoverflow.com/questions/3586046/fastest-way-to-take-a-screenshot-with-python-on-windows
+        for i in range(200):
+            pyscreeze.screenshot(TEMP_FILENAME)
+            self.assertTrue(isPng(TEMP_FILENAME))
+            os.unlink(TEMP_FILENAME)
 
 if __name__ == '__main__':
     unittest.main()


Reply via email to