mirror of https://github.com/kivy/kivy.git
Use `filetype` as `imghdr` built-in module is deprecated and slated for removal in Python 3.13 (#8581)
* Ensure Imghdr compatibility with Kivy * Use iletype to get file extension * Reformat file and Refactor string formats * Delete kivy/lib/imghdr.py * Add filetype to `full` * fix PEP8_test * Fix integer bug
This commit is contained in:
parent
6bb27a91cb
commit
7e6d86197a
|
@ -62,7 +62,7 @@ Or you can get the bytes (new in `1.11.0`):
|
|||
'''
|
||||
import re
|
||||
from base64 import b64decode
|
||||
import imghdr
|
||||
from filetype import guess_extension
|
||||
|
||||
__all__ = ('Image', 'ImageLoader', 'ImageData')
|
||||
|
||||
|
@ -79,11 +79,9 @@ from kivy.setupconfig import USE_SDL2
|
|||
import zipfile
|
||||
from io import BytesIO
|
||||
|
||||
|
||||
# late binding
|
||||
Texture = TextureRegion = None
|
||||
|
||||
|
||||
# register image caching only for keep_data=True
|
||||
Cache.register('kv.image', timeout=60)
|
||||
Cache.register('kv.atlas')
|
||||
|
@ -187,7 +185,7 @@ class ImageData(object):
|
|||
.. versionadded:: 1.0.7
|
||||
'''
|
||||
if level == 0:
|
||||
return (self.width, self.height, self.data, self.rowlength)
|
||||
return self.width, self.height, self.data, self.rowlength
|
||||
assert level < len(self.mipmaps)
|
||||
return self.mipmaps[level]
|
||||
|
||||
|
@ -257,17 +255,15 @@ class ImageLoaderBase(object):
|
|||
|
||||
# first, check if a texture with the same name already exist in the
|
||||
# cache
|
||||
chr = type(fname)
|
||||
uid = chr(u'%s|%d|%d') % (fname, self._mipmap, count)
|
||||
uid = f'{fname}|{self._mipmap:d}|{count:d}'
|
||||
texture = Cache.get('kv.texture', uid)
|
||||
|
||||
# if not create it and append to the cache
|
||||
if texture is None:
|
||||
imagedata = self._data[count]
|
||||
source = '{}{}|'.format(
|
||||
'zip|' if fname.endswith('.zip') else '',
|
||||
self._nocache)
|
||||
imagedata.source = chr(source) + uid
|
||||
source = (f"{'zip|' if fname.endswith('.zip') else ''}"
|
||||
f"{self._nocache}|")
|
||||
imagedata.source = f'{source}{uid}'
|
||||
texture = Texture.create_from_data(
|
||||
imagedata, mipmap=self._mipmap)
|
||||
if not self._nocache:
|
||||
|
@ -298,7 +294,7 @@ class ImageLoaderBase(object):
|
|||
def size(self):
|
||||
'''Image size (width, height)
|
||||
'''
|
||||
return (self._data[0].width, self._data[0].height)
|
||||
return self._data[0].width, self._data[0].height
|
||||
|
||||
@property
|
||||
def texture(self):
|
||||
|
@ -330,7 +326,6 @@ class ImageLoaderBase(object):
|
|||
|
||||
|
||||
class ImageLoader(object):
|
||||
|
||||
loaders = []
|
||||
|
||||
@staticmethod
|
||||
|
@ -413,8 +408,8 @@ class ImageLoader(object):
|
|||
# kv.texture cache.
|
||||
if atlas:
|
||||
texture = atlas[uid]
|
||||
fn = 'atlas://%s/%s' % (rfn, uid)
|
||||
cid = '{}|{:d}|{:d}'.format(fn, False, 0)
|
||||
fn = f'atlas://{rfn}/{uid}'
|
||||
cid = f'{fn}|0|0'
|
||||
Cache.append('kv.texture', cid, texture)
|
||||
return Image(texture)
|
||||
|
||||
|
@ -429,8 +424,8 @@ class ImageLoader(object):
|
|||
Cache.append('kv.atlas', rfn, atlas)
|
||||
# first time, fill our texture cache.
|
||||
for nid, texture in atlas.textures.items():
|
||||
fn = 'atlas://%s/%s' % (rfn, nid)
|
||||
cid = '{}|{:d}|{:d}'.format(fn, False, 0)
|
||||
fn = f'atlas://{rfn}/{nid}'
|
||||
cid = f'{fn}|0|0'
|
||||
Cache.append('kv.texture', cid, texture)
|
||||
return Image(atlas[uid])
|
||||
|
||||
|
@ -438,11 +433,14 @@ class ImageLoader(object):
|
|||
ext = filename.split('.')[-1].lower()
|
||||
|
||||
# prevent url querystrings
|
||||
if filename.startswith((('http://', 'https://'))):
|
||||
if filename.startswith(('http://', 'https://')):
|
||||
ext = ext.split('?')[0]
|
||||
|
||||
filename = resource_find(filename)
|
||||
|
||||
# Get actual image format instead of extension if possible
|
||||
ext = guess_extension(filename) or ext
|
||||
|
||||
# special case. When we are trying to load a "zip" file with image, we
|
||||
# will use the special zip_loader in ImageLoader. This might return a
|
||||
# sequence of images contained in the zip.
|
||||
|
@ -450,17 +448,14 @@ class ImageLoader(object):
|
|||
return ImageLoader.zip_loader(filename)
|
||||
else:
|
||||
im = None
|
||||
# Get actual image format instead of extension if possible
|
||||
ext = imghdr.what(filename) or ext
|
||||
for loader in ImageLoader.loaders:
|
||||
if ext not in loader.extensions():
|
||||
continue
|
||||
Logger.debug('Image%s: Load <%s>' %
|
||||
(loader.__name__[11:], filename))
|
||||
Logger.debug(f'Image{loader.__name__[11:]}: Load <{filename}>')
|
||||
im = loader(filename, **kwargs)
|
||||
break
|
||||
if im is None:
|
||||
raise Exception('Unknown <%s> type, no loader found.' % ext)
|
||||
raise Exception(f'Unknown <{ext}> type, no loader found.')
|
||||
return im
|
||||
|
||||
|
||||
|
@ -578,14 +573,12 @@ class Image(EventDispatcher):
|
|||
|
||||
'''
|
||||
count = 0
|
||||
f = self.filename
|
||||
pat = type(f)(u'%s|%d|%d')
|
||||
uid = pat % (f, self._mipmap, count)
|
||||
uid = f'{self.filename}|{self._mipmap:d}|{count:d}'
|
||||
Cache.remove("kv.image", uid)
|
||||
while Cache.get("kv.texture", uid):
|
||||
Cache.remove("kv.texture", uid)
|
||||
count += 1
|
||||
uid = pat % (f, self._mipmap, count)
|
||||
uid = f'{self.filename}|{self._mipmap:d}|{count:d}'
|
||||
|
||||
def _anim(self, *largs):
|
||||
if not self._image:
|
||||
|
@ -724,7 +717,7 @@ class Image(EventDispatcher):
|
|||
|
||||
# construct uid as a key for Cache
|
||||
f = self.filename
|
||||
uid = type(f)(u'%s|%d|%d') % (f, self._mipmap, 0)
|
||||
uid = f'{f}|{self._mipmap:d}|0'
|
||||
|
||||
# in case of Image have been asked with keep_data
|
||||
# check the kv.image cache instead of texture.
|
||||
|
@ -777,10 +770,10 @@ class Image(EventDispatcher):
|
|||
loader.can_load_memory() and
|
||||
ext in loader.extensions()]
|
||||
if not loaders:
|
||||
raise Exception('No inline loader found to load {}'.format(ext))
|
||||
raise Exception(f'No inline loader found to load {ext}')
|
||||
image = loaders[0](filename, ext=ext, rawdata=data, inline=True,
|
||||
nocache=self._nocache, mipmap=self._mipmap,
|
||||
keep_data=self._keep_data)
|
||||
nocache=self._nocache, mipmap=self._mipmap,
|
||||
keep_data=self._keep_data)
|
||||
if isinstance(image, Texture):
|
||||
self._texture = image
|
||||
self._size = image.size
|
||||
|
@ -908,9 +901,9 @@ class Image(EventDispatcher):
|
|||
|
||||
def _find_format_from_filename(self, filename):
|
||||
ext = filename.rsplit(".", 1)[-1].lower()
|
||||
if ext in {
|
||||
'bmp', 'jpe', 'lbm', 'pcx', 'png', 'pnm',
|
||||
'tga', 'tiff', 'webp', 'xcf', 'xpm', 'xv'}:
|
||||
if (ext in
|
||||
{'bmp', 'jpe', 'lbm', 'pcx', 'png', 'pnm', 'tga',
|
||||
'tiff', 'webp', 'xcf', 'xpm', 'xv'}):
|
||||
return ext
|
||||
elif ext in ('jpg', 'jpeg'):
|
||||
return 'jpg'
|
||||
|
@ -945,7 +938,7 @@ class Image(EventDispatcher):
|
|||
# check bounds
|
||||
x, y = int(x), int(y)
|
||||
if not (0 <= x < data.width and 0 <= y < data.height):
|
||||
raise IndexError('Position (%d, %d) is out of range.' % (x, y))
|
||||
raise IndexError(f'Position ({x:d}, {y:d}) is out of range.')
|
||||
|
||||
assert data.fmt in ImageData._supported_fmts
|
||||
size = 3 if data.fmt in ('rgb', 'bgr') else 4
|
||||
|
@ -992,6 +985,7 @@ image_libs += [
|
|||
libs_loaded = core_register_libs('image', image_libs)
|
||||
|
||||
from os import environ
|
||||
|
||||
if 'KIVY_DOC' not in environ and not libs_loaded:
|
||||
import sys
|
||||
|
||||
|
|
|
@ -50,6 +50,7 @@ dev =
|
|||
base =
|
||||
pillow>=9.5.0,<11
|
||||
requests
|
||||
filetype
|
||||
docutils
|
||||
pygments
|
||||
kivy_deps.angle~=0.4.0; sys_platform == "win32"
|
||||
|
@ -63,6 +64,7 @@ full =
|
|||
pillow>=9.5.0,<11
|
||||
docutils
|
||||
pygments
|
||||
filetype
|
||||
kivy_deps.gstreamer~=0.3.3; sys_platform == "win32"
|
||||
kivy_deps.angle~=0.4.0; sys_platform == "win32"
|
||||
kivy_deps.sdl2~=0.7.0; sys_platform == "win32"
|
||||
|
|
Loading…
Reference in New Issue