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()