We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Forcing img_pil causes an error when trying to load PNGs
When I force PIL provider using `export KIVY_IMAGE=img_pil` Kivy exits with this error log:
I have installed Pillow library from PyPI.

```
[INFO   ] [Logger      ] Record log in /mnt/data/logs/kivy_69-12-31_5.txt
[INFO   ] Kivy v1.9.0-dev
[INFO   ] [Python      ] v2.7.8 (default, Sep 24 2014, 05:50:30) 
[GCC 4.8.2 20131219 (prerelease)]
[INFO   ] [Factory     ] 172 symbols loaded
[INFO   ] [Image       ] Providers: img_pil (img_tex, img_dds, img_sdl2, img_pygame, img_ffpyplayer, img_gif ignored)
[INFO   ] [Window      ] Provider: egl_rpi
[INFO   ] [GL          ] OpenGL version <OpenGL ES 2.0>
[INFO   ] [GL          ] OpenGL vendor <Broadcom>
[INFO   ] [GL          ] OpenGL renderer <VideoCore IV HW>
[INFO   ] [GL          ] OpenGL parsed version: 2, 0
[INFO   ] [GL          ] Shading version <OpenGL ES GLSL ES 1.00>
[INFO   ] [GL          ] Texture max size <2048>
[INFO   ] [GL          ] Texture max units <8>
[INFO   ] [Shader      ] fragment shader: <Compiled>
[INFO   ] [Shader      ] vertex shader: <Compiled>
[CRITICAL] [Window      ] Unable to find any valuable Window provider at all!
egl_rpi - AttributeError: dispose
  File "/opt/vendor/lib/python2.7/site-packages/kivy/core/__init__.py", line 65, in core_select_lib
    cls = cls()
  File "/opt/vendor/lib/python2.7/site-packages/kivy/core/window/__init__.py", line 594, in __init__
    self.create_window()
  File "/opt/vendor/lib/python2.7/site-packages/kivy/core/window/window_egl_rpi.py", line 26, in create_window
    super(WindowEglRpi, self).create_window()
  File "/opt/vendor/lib/python2.7/site-packages/kivy/core/window/__init__.py", line 731, in create_window
    self.render_context = RenderContext()
  File "kivy/graphics/instructions.pyx", line 751, in kivy.graphics.instructions.RenderContext.__init__ (kivy/graphics/instructions.c:10225)
  File "/opt/vendor/lib/python2.7/site-packages/kivy/core/image/__init__.py", line 461, in __init__
    self.filename = arg
  File "/opt/vendor/lib/python2.7/site-packages/kivy/core/image/__init__.py", line 650, in _set_filename
    mipmap=self._mipmap, nocache=self._nocache)
  File "/opt/vendor/lib/python2.7/site-packages/kivy/core/image/__init__.py", line 388, in load
    im = loader(filename, **kwargs)
  File "/opt/vendor/lib/python2.7/site-packages/kivy/core/image/__init__.py", line 164, in __init__
    self._data = self.load(filename)
  File "/opt/vendor/lib/python2.7/site-packages/kivy/core/image/img_pil.py", line 96, in load
    return list(self._img_read(im))
  File "/opt/vendor/lib/python2.7/site-packages/kivy/core/image/img_pil.py", line 75, in _img_read
    if not im.dispose and img_ol:
  File "/opt/vendor/lib/python2.7/site-packages/PIL/Image.py", line 608, in __getattr__
    raise AttributeError(name)

[INFO   ] [Text        ] Provider: pil(['text_sdl2', 'text_pygame', 'text_sdlttf'] ignored)
[CRITICAL] [App         ] Unable to get a Window, abort.
 Exception SystemExit: 1 in 'kivy.properties.dpi2px' ignored
[INFO   ] [Audio       ] Providers:  (audio_pygst, audio_ffpyplayer, audio_sdl, audio_pygame ignored)
[CRITICAL] [App         ] Unable to get a Window, abort.
```


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `kivy/core/image/img_pil.py`
Content:
```
1 '''
2 PIL: PIL image loader
3 '''
4 
5 __all__ = ('ImageLoaderPIL', )
6 
7 try:
8     from PIL import Image as PILImage
9 except:
10     import Image as PILImage
11 
12 from kivy.logger import Logger
13 from kivy.core.image import ImageLoaderBase, ImageData, ImageLoader
14 
15 
16 class ImageLoaderPIL(ImageLoaderBase):
17     '''Image loader based on the PIL library.
18 
19     .. versionadded:: 1.0.8
20 
21     Support for GIF animation added.
22 
23     Gif animation has a lot of issues(transparency/color depths... etc).
24     In order to keep it simple, what is implimented here is what is
25     natively supported by the PIL library.
26 
27     As a general rule, try to use gifs that have no transparency.
28     Gif's with transparency will work but be prepared for some
29     artifacts until transparency support is improved.
30 
31     '''
32 
33     @staticmethod
34     def can_save():
35         return True
36 
37     @staticmethod
38     def extensions():
39         '''Return accepted extensions for this loader'''
40         # See http://www.pythonware.com/library/pil/handbook/index.htm
41         return ('bmp', 'bufr', 'cur', 'dcx', 'fits', 'fl', 'fpx', 'gbr',
42                 'gd', 'gif', 'grib', 'hdf5', 'ico', 'im', 'imt', 'iptc',
43                 'jpeg', 'jpg', 'jpe', 'mcidas', 'mic', 'mpeg', 'msp',
44                 'pcd', 'pcx', 'pixar', 'png', 'ppm', 'psd', 'sgi',
45                 'spider', 'tga', 'tiff', 'wal', 'wmf', 'xbm', 'xpm',
46                 'xv')
47 
48     def _img_correct(self, _img_tmp):
49         '''Convert image to the correct format and orientation.
50         '''
51         # image loader work only with rgb/rgba image
52         if _img_tmp.mode.lower() not in ('rgb', 'rgba'):
53             try:
54                 imc = _img_tmp.convert('RGBA')
55             except:
56                 Logger.warning(
57                     'Image: Unable to convert image to rgba (was %s)' %
58                     (_img_tmp.mode.lower()))
59                 raise
60             _img_tmp = imc
61 
62         return _img_tmp
63 
64     def _img_read(self, im):
65         '''Read images from an animated file.
66         '''
67         im.seek(0)
68 
69         # Read all images inside
70         try:
71             img_ol = None
72             while True:
73                 img_tmp = im
74                 img_tmp = self._img_correct(img_tmp)
75                 if not im.dispose and img_ol:
76                     # paste new frame over old so as to handle
77                     # transparency properly
78                     img_ol.paste(img_tmp, (0, 0), img_tmp)
79                     img_tmp = img_ol
80                 img_ol = img_tmp
81                 yield ImageData(img_tmp.size[0], img_tmp.size[1],
82                                 img_tmp.mode.lower(), img_tmp.tostring())
83                 im.seek(im.tell() + 1)
84         except EOFError:
85             pass
86 
87     def load(self, filename):
88         try:
89             im = PILImage.open(filename)
90         except:
91             Logger.warning('Image: Unable to load image <%s>' % filename)
92             raise
93         # update internals
94         self.filename = filename
95         # returns an array of type ImageData len 1 if not a sequence image
96         return list(self._img_read(im))
97 
98     @staticmethod
99     def save(filename, width, height, fmt, pixels):
100         image = PILImage.fromstring(fmt.upper(), (width, height), pixels)
101         image.save(filename)
102         return True
103 
104 
105 # register
106 ImageLoader.register(ImageLoaderPIL)
107
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/kivy/core/image/img_pil.py b/kivy/core/image/img_pil.py
--- a/kivy/core/image/img_pil.py
+++ b/kivy/core/image/img_pil.py
@@ -72,7 +72,7 @@
             while True:
                 img_tmp = im
                 img_tmp = self._img_correct(img_tmp)
-                if not im.dispose and img_ol:
+                if img_ol and (hasattr(im, 'dispose') and not im.dispose):
                     # paste new frame over old so as to handle
                     # transparency properly
                     img_ol.paste(img_tmp, (0, 0), img_tmp)

{"golden_diff": "diff --git a/kivy/core/image/img_pil.py b/kivy/core/image/img_pil.py\n--- a/kivy/core/image/img_pil.py\n+++ b/kivy/core/image/img_pil.py\n@@ -72,7 +72,7 @@\n             while True:\n                 img_tmp = im\n                 img_tmp = self._img_correct(img_tmp)\n-                if not im.dispose and img_ol:\n+                if img_ol and (hasattr(im, 'dispose') and not im.dispose):\n                     # paste new frame over old so as to handle\n                     # transparency properly\n                     img_ol.paste(img_tmp, (0, 0), img_tmp)\n", "issue": "Forcing img_pil causes an error when trying to load PNGs\nWhen I force PIL provider using `export KIVY_IMAGE=img_pil` Kivy exits with this error log:\nI have installed Pillow library from PyPI.\n\n```\n[INFO   ] [Logger      ] Record log in /mnt/data/logs/kivy_69-12-31_5.txt\n[INFO   ] Kivy v1.9.0-dev\n[INFO   ] [Python      ] v2.7.8 (default, Sep 24 2014, 05:50:30) \n[GCC 4.8.2 20131219 (prerelease)]\n[INFO   ] [Factory     ] 172 symbols loaded\n[INFO   ] [Image       ] Providers: img_pil (img_tex, img_dds, img_sdl2, img_pygame, img_ffpyplayer, img_gif ignored)\n[INFO   ] [Window      ] Provider: egl_rpi\n[INFO   ] [GL          ] OpenGL version <OpenGL ES 2.0>\n[INFO   ] [GL          ] OpenGL vendor <Broadcom>\n[INFO   ] [GL          ] OpenGL renderer <VideoCore IV HW>\n[INFO   ] [GL          ] OpenGL parsed version: 2, 0\n[INFO   ] [GL          ] Shading version <OpenGL ES GLSL ES 1.00>\n[INFO   ] [GL          ] Texture max size <2048>\n[INFO   ] [GL          ] Texture max units <8>\n[INFO   ] [Shader      ] fragment shader: <Compiled>\n[INFO   ] [Shader      ] vertex shader: <Compiled>\n[CRITICAL] [Window      ] Unable to find any valuable Window provider at all!\negl_rpi - AttributeError: dispose\n  File \"/opt/vendor/lib/python2.7/site-packages/kivy/core/__init__.py\", line 65, in core_select_lib\n    cls = cls()\n  File \"/opt/vendor/lib/python2.7/site-packages/kivy/core/window/__init__.py\", line 594, in __init__\n    self.create_window()\n  File \"/opt/vendor/lib/python2.7/site-packages/kivy/core/window/window_egl_rpi.py\", line 26, in create_window\n    super(WindowEglRpi, self).create_window()\n  File \"/opt/vendor/lib/python2.7/site-packages/kivy/core/window/__init__.py\", line 731, in create_window\n    self.render_context = RenderContext()\n  File \"kivy/graphics/instructions.pyx\", line 751, in kivy.graphics.instructions.RenderContext.__init__ (kivy/graphics/instructions.c:10225)\n  File \"/opt/vendor/lib/python2.7/site-packages/kivy/core/image/__init__.py\", line 461, in __init__\n    self.filename = arg\n  File \"/opt/vendor/lib/python2.7/site-packages/kivy/core/image/__init__.py\", line 650, in _set_filename\n    mipmap=self._mipmap, nocache=self._nocache)\n  File \"/opt/vendor/lib/python2.7/site-packages/kivy/core/image/__init__.py\", line 388, in load\n    im = loader(filename, **kwargs)\n  File \"/opt/vendor/lib/python2.7/site-packages/kivy/core/image/__init__.py\", line 164, in __init__\n    self._data = self.load(filename)\n  File \"/opt/vendor/lib/python2.7/site-packages/kivy/core/image/img_pil.py\", line 96, in load\n    return list(self._img_read(im))\n  File \"/opt/vendor/lib/python2.7/site-packages/kivy/core/image/img_pil.py\", line 75, in _img_read\n    if not im.dispose and img_ol:\n  File \"/opt/vendor/lib/python2.7/site-packages/PIL/Image.py\", line 608, in __getattr__\n    raise AttributeError(name)\n\n[INFO   ] [Text        ] Provider: pil(['text_sdl2', 'text_pygame', 'text_sdlttf'] ignored)\n[CRITICAL] [App         ] Unable to get a Window, abort.\n Exception SystemExit: 1 in 'kivy.properties.dpi2px' ignored\n[INFO   ] [Audio       ] Providers:  (audio_pygst, audio_ffpyplayer, audio_sdl, audio_pygame ignored)\n[CRITICAL] [App         ] Unable to get a Window, abort.\n```\n\n", "before_files": [{"content": "'''\nPIL: PIL image loader\n'''\n\n__all__ = ('ImageLoaderPIL', )\n\ntry:\n    from PIL import Image as PILImage\nexcept:\n    import Image as PILImage\n\nfrom kivy.logger import Logger\nfrom kivy.core.image import ImageLoaderBase, ImageData, ImageLoader\n\n\nclass ImageLoaderPIL(ImageLoaderBase):\n    '''Image loader based on the PIL library.\n\n    .. versionadded:: 1.0.8\n\n    Support for GIF animation added.\n\n    Gif animation has a lot of issues(transparency/color depths... etc).\n    In order to keep it simple, what is implimented here is what is\n    natively supported by the PIL library.\n\n    As a general rule, try to use gifs that have no transparency.\n    Gif's with transparency will work but be prepared for some\n    artifacts until transparency support is improved.\n\n    '''\n\n    @staticmethod\n    def can_save():\n        return True\n\n    @staticmethod\n    def extensions():\n        '''Return accepted extensions for this loader'''\n        # See http://www.pythonware.com/library/pil/handbook/index.htm\n        return ('bmp', 'bufr', 'cur', 'dcx', 'fits', 'fl', 'fpx', 'gbr',\n                'gd', 'gif', 'grib', 'hdf5', 'ico', 'im', 'imt', 'iptc',\n                'jpeg', 'jpg', 'jpe', 'mcidas', 'mic', 'mpeg', 'msp',\n                'pcd', 'pcx', 'pixar', 'png', 'ppm', 'psd', 'sgi',\n                'spider', 'tga', 'tiff', 'wal', 'wmf', 'xbm', 'xpm',\n                'xv')\n\n    def _img_correct(self, _img_tmp):\n        '''Convert image to the correct format and orientation.\n        '''\n        # image loader work only with rgb/rgba image\n        if _img_tmp.mode.lower() not in ('rgb', 'rgba'):\n            try:\n                imc = _img_tmp.convert('RGBA')\n            except:\n                Logger.warning(\n                    'Image: Unable to convert image to rgba (was %s)' %\n                    (_img_tmp.mode.lower()))\n                raise\n            _img_tmp = imc\n\n        return _img_tmp\n\n    def _img_read(self, im):\n        '''Read images from an animated file.\n        '''\n        im.seek(0)\n\n        # Read all images inside\n        try:\n            img_ol = None\n            while True:\n                img_tmp = im\n                img_tmp = self._img_correct(img_tmp)\n                if not im.dispose and img_ol:\n                    # paste new frame over old so as to handle\n                    # transparency properly\n                    img_ol.paste(img_tmp, (0, 0), img_tmp)\n                    img_tmp = img_ol\n                img_ol = img_tmp\n                yield ImageData(img_tmp.size[0], img_tmp.size[1],\n                                img_tmp.mode.lower(), img_tmp.tostring())\n                im.seek(im.tell() + 1)\n        except EOFError:\n            pass\n\n    def load(self, filename):\n        try:\n            im = PILImage.open(filename)\n        except:\n            Logger.warning('Image: Unable to load image <%s>' % filename)\n            raise\n        # update internals\n        self.filename = filename\n        # returns an array of type ImageData len 1 if not a sequence image\n        return list(self._img_read(im))\n\n    @staticmethod\n    def save(filename, width, height, fmt, pixels):\n        image = PILImage.fromstring(fmt.upper(), (width, height), pixels)\n        image.save(filename)\n        return True\n\n\n# register\nImageLoader.register(ImageLoaderPIL)\n", "path": "kivy/core/image/img_pil.py"}], "after_files": [{"content": "'''\nPIL: PIL image loader\n'''\n\n__all__ = ('ImageLoaderPIL', )\n\ntry:\n    from PIL import Image as PILImage\nexcept:\n    import Image as PILImage\n\nfrom kivy.logger import Logger\nfrom kivy.core.image import ImageLoaderBase, ImageData, ImageLoader\n\n\nclass ImageLoaderPIL(ImageLoaderBase):\n    '''Image loader based on the PIL library.\n\n    .. versionadded:: 1.0.8\n\n    Support for GIF animation added.\n\n    Gif animation has a lot of issues(transparency/color depths... etc).\n    In order to keep it simple, what is implimented here is what is\n    natively supported by the PIL library.\n\n    As a general rule, try to use gifs that have no transparency.\n    Gif's with transparency will work but be prepared for some\n    artifacts until transparency support is improved.\n\n    '''\n\n    @staticmethod\n    def can_save():\n        return True\n\n    @staticmethod\n    def extensions():\n        '''Return accepted extensions for this loader'''\n        # See http://www.pythonware.com/library/pil/handbook/index.htm\n        return ('bmp', 'bufr', 'cur', 'dcx', 'fits', 'fl', 'fpx', 'gbr',\n                'gd', 'gif', 'grib', 'hdf5', 'ico', 'im', 'imt', 'iptc',\n                'jpeg', 'jpg', 'jpe', 'mcidas', 'mic', 'mpeg', 'msp',\n                'pcd', 'pcx', 'pixar', 'png', 'ppm', 'psd', 'sgi',\n                'spider', 'tga', 'tiff', 'wal', 'wmf', 'xbm', 'xpm',\n                'xv')\n\n    def _img_correct(self, _img_tmp):\n        '''Convert image to the correct format and orientation.\n        '''\n        # image loader work only with rgb/rgba image\n        if _img_tmp.mode.lower() not in ('rgb', 'rgba'):\n            try:\n                imc = _img_tmp.convert('RGBA')\n            except:\n                Logger.warning(\n                    'Image: Unable to convert image to rgba (was %s)' %\n                    (_img_tmp.mode.lower()))\n                raise\n            _img_tmp = imc\n\n        return _img_tmp\n\n    def _img_read(self, im):\n        '''Read images from an animated file.\n        '''\n        im.seek(0)\n\n        # Read all images inside\n        try:\n            img_ol = None\n            while True:\n                img_tmp = im\n                img_tmp = self._img_correct(img_tmp)\n                if img_ol and (hasattr(im, 'dispose') and not im.dispose):\n                    # paste new frame over old so as to handle\n                    # transparency properly\n                    img_ol.paste(img_tmp, (0, 0), img_tmp)\n                    img_tmp = img_ol\n                img_ol = img_tmp\n                yield ImageData(img_tmp.size[0], img_tmp.size[1],\n                                img_tmp.mode.lower(), img_tmp.tostring())\n                im.seek(im.tell() + 1)\n        except EOFError:\n            pass\n\n    def load(self, filename):\n        try:\n            im = PILImage.open(filename)\n        except:\n            Logger.warning('Image: Unable to load image <%s>' % filename)\n            raise\n        # update internals\n        self.filename = filename\n        # returns an array of type ImageData len 1 if not a sequence image\n        return list(self._img_read(im))\n\n    @staticmethod\n    def save(filename, width, height, fmt, pixels):\n        image = PILImage.fromstring(fmt.upper(), (width, height), pixels)\n        image.save(filename)\n        return True\n\n\n# register\nImageLoader.register(ImageLoaderPIL)\n", "path": "kivy/core/image/img_pil.py"}]}