Skip to content

Commit

Permalink
Lint fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
heynemann committed Jan 30, 2022
1 parent 301124c commit f4e5c6a
Show file tree
Hide file tree
Showing 6 changed files with 67 additions and 27 deletions.
16 changes: 6 additions & 10 deletions tests/test_context.py
Original file line number Diff line number Diff line change
Expand Up @@ -125,10 +125,8 @@ def test_can_create_server_parameters():
expect(params.log_level).to_equal("debug")
expect(params.app_class).to_equal("app")
expect(
params._security_key
).to_equal( # pylint: disable=protected-access
"SECURITY_KEY_FILE"
)
params._security_key # pylint: disable=protected-access
).to_equal("SECURITY_KEY_FILE")
expect(params.fd).to_equal("fd")
expect(params.gifsicle_path).to_equal("gifsicle_path")

Expand All @@ -149,10 +147,8 @@ def test_can_set_security_key():

params.security_key = "testé"
expect(
params._security_key
).to_equal( # pylint: disable=protected-access
"testé".encode("utf-8")
)
params._security_key # pylint: disable=protected-access
).to_equal("testé".encode("utf-8"))

@staticmethod
def test_loading_does_nothing_if_no_keyfile():
Expand All @@ -167,8 +163,8 @@ def test_loading_does_nothing_if_no_keyfile():
gifsicle_path="gifsicle_path",
)
expect(
params._security_key
).to_be_null() # pylint: disable=protected-access
params._security_key # pylint: disable=protected-access
).to_be_null()

@staticmethod
def test_cant_load_invalid_security_key_file():
Expand Down
19 changes: 15 additions & 4 deletions thumbor/context.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,10 @@ def __init__(
):
self.server = server
self.config = config

if importer:
self.modules = ContextImporter(self, importer)

if importer.metrics:
self.metrics = importer.metrics(config)
else:
Expand Down Expand Up @@ -89,8 +91,8 @@ def __init__(
processes=1,
):
self.port = port
self.ip = (
ip # Other people may depend on this pylint: disable=invalid-name
self.ip = ( # Other people may depend on this pylint: disable=invalid-name
ip
)
self.config_path = config_path
self.keyfile = keyfile
Expand All @@ -99,8 +101,8 @@ def __init__(
self.debug = debug
self._security_key = None
self.load_security_key()
self.fd = (
fd # Other people may depend on this pylint: disable=invalid-name
self.fd = ( # Other people may depend on this pylint: disable=invalid-name
fd
)
self.gifsicle_path = gifsicle_path
self.use_environment = use_environment
Expand All @@ -119,6 +121,7 @@ def load_security_key(self):
return

path = abspath(self.keyfile)

if not exists(path):
raise ValueError(
(
Expand Down Expand Up @@ -172,6 +175,7 @@ def __init__(
self.debug = bool(debug)
self.meta = bool(meta)
self.trim = trim

if trim is not None:
trim_parts = trim.split(":")
self.trim_pos = (
Expand Down Expand Up @@ -251,22 +255,27 @@ def __init__(self, context, importer):
self.importer = importer

self.engine = None

if importer.engine:
self.engine = importer.engine(context)

self.gif_engine = None

if importer.gif_engine:
self.gif_engine = importer.gif_engine(context)

self.storage = None

if importer.storage:
self.storage = importer.storage(context)

self.result_storage = None

if importer.result_storage:
self.result_storage = importer.result_storage(context)

self.upload_photo_storage = None

if importer.upload_photo_storage:
self.upload_photo_storage = importer.upload_photo_storage(context)

Expand All @@ -279,12 +288,14 @@ def __init__(self, context, importer):
self.compatibility_legacy_loader = importer.compatibility_legacy_loader

self.compatibility_legacy_storage = None

if importer.compatibility_legacy_storage is not None:
self.compatibility_legacy_storage = (
importer.compatibility_legacy_storage(context)
)

self.compatibility_legacy_result_storage = None

if importer.compatibility_legacy_result_storage is not None:
self.compatibility_legacy_result_storage = (
importer.compatibility_legacy_result_storage(context)
Expand Down
33 changes: 29 additions & 4 deletions thumbor/engines/pil.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
ImageFile.LOAD_TRUNCATED_IMAGES = True

DECOMPRESSION_BOMB_EXCEPTIONS = (Image.DecompressionBombWarning,)

if hasattr(Image, "DecompressionBombError"):
DECOMPRESSION_BOMB_EXCEPTIONS += (Image.DecompressionBombError,)

Expand All @@ -66,19 +67,22 @@ def gen_image(self, size, color):
if color == "transparent":
color = None
img = Image.new("RGBA", size, color)

return img

def create_image(self, buffer):
try:
img = Image.open(BytesIO(buffer))
except DECOMPRESSION_BOMB_EXCEPTIONS as error:
logger.warning("[PILEngine] create_image failed: %s", error)

return None
self.icc_profile = img.info.get("icc_profile")
self.exif = img.info.get("exif")
self.original_mode = img.mode

self.subsampling = JpegImagePlugin.get_sampling(img)

if self.subsampling == -1: # n/a for this file
self.subsampling = None
self.qtables = getattr(img, "quantization", None)
Expand All @@ -88,10 +92,12 @@ def create_image(self, buffer):
and self.extension == ".gif"
):
frames = []

for frame in ImageSequence.Iterator(img):
frames.append(frame.convert("P"))
img.seek(0)
self.frame_count = len(frames)

return frames

return img
Expand Down Expand Up @@ -128,10 +134,12 @@ def resize(self, width, height):
# Indexed color modes (such as 1 and P) will be forced to use a
# nearest neighbor resampling algorithm. So we convert them to
# RGB(A) mode before resizing to avoid nasty scaling artifacts.

if self.image.mode in ["1", "P"]:
logger.debug(
"converting image from 8-bit/1-bit palette to 32-bit RGB(A) for resize"
)

if self.image.mode == "1":
target_mode = "RGB"
else:
Expand All @@ -153,6 +161,7 @@ def crop(self, left, top, right, bottom):

def rotate(self, degrees):
# PIL rotates counter clockwise

if degrees == 90:
self.image = self.image.transpose(Image.ROTATE_90)
elif degrees == 180:
Expand All @@ -170,19 +179,24 @@ def flip_horizontally(self):

def get_default_extension(self):
# extension is not present => force JPEG or PNG

if self.image.mode in ["P", "RGBA", "LA"]:
return ".png"

return ".jpeg"

# TODO: Refactor this - pylint: disable=too-many-statements,too-many-branches
def read(self, extension=None, quality=None): # NOQA
# TODO: Refactor this
def read( # noqa
self, extension=None, quality=None
): # noqa pylint: disable=too-many-statements,too-many-branches
# returns image buffer in byte format.

img_buffer = BytesIO()
requested_extension = extension or self.extension

# 1 and P mode images will be much smaller if converted back to
# their original mode. So let's do that after resizing. Get $$.

if (
self.context.config.PILLOW_PRESERVE_INDEXED_MODE
and requested_extension in [None, ".png", ".gif"]
Expand All @@ -204,8 +218,10 @@ def read(self, extension=None, quality=None): # NOQA
ext = requested_extension or self.get_default_extension()

options = {"quality": quality}

if ext in (".jpg", ".jpeg"):
options["optimize"] = True

if self.context.config.PROGRESSIVE_JPEG:
# Can't simply set options['progressive'] to the value
# of self.context.config.PROGRESSIVE_JPEG because save
Expand Down Expand Up @@ -271,6 +287,7 @@ def read(self, extension=None, quality=None): # NOQA
logger.debug("webp quality is 100, using lossless instead")
options["lossless"] = True
options.pop("quality")

if self.image.mode not in ["RGB", "RGBA"]:
if self.image.mode == "P":
mode = "RGBA"
Expand All @@ -294,6 +311,7 @@ def read(self, extension=None, quality=None): # NOQA
results = img_buffer.getvalue()
img_buffer.close()
self.extension = ext

return results

def read_multiple(self, images, extension=None):
Expand Down Expand Up @@ -328,9 +346,9 @@ def read_multiple(self, images, extension=None):

command = ["gifsicle", "--colors", "256", tmp_file_path]

popen = Popen(
popen = Popen( # pylint: disable=consider-using-with
command, stdout=PIPE
) # pylint: disable=consider-using-with
)
pipe = popen.stdout
pipe_output = pipe.read()
pipe.close()
Expand All @@ -355,6 +373,7 @@ def get_image_mode(self):

def image_data_as_rgb(self, update_image=True):
converted_image = self.image

if converted_image.mode not in ["RGB", "RGBA"]:
if "A" in converted_image.mode:
converted_image = converted_image.convert("RGBA")
Expand All @@ -363,30 +382,36 @@ def image_data_as_rgb(self, update_image=True):
converted_image = converted_image.convert(None)
else:
converted_image = converted_image.convert("RGB")

if update_image:
self.image = converted_image

return converted_image.mode, converted_image.tobytes()

def convert_to_grayscale(self, update_image=True, alpha=True):
if "A" in self.image.mode and alpha:
image = self.image.convert("LA")
else:
image = self.image.convert("L")

if update_image:
self.image = image

return image

def has_transparency(self):
has_transparency = (
"A" in self.image.mode or "transparency" in self.image.info
)

if has_transparency:
# If the image has alpha channel,
# we check for any pixels that are not opaque (255)
has_transparency = (
min(self.image.convert("RGBA").getchannel("A").getextrema())
< 255
)

return has_transparency

def paste(self, other_engine, pos, merge=True):
Expand Down
5 changes: 3 additions & 2 deletions thumbor/error_handlers/sentry.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,16 +27,17 @@ def __init__(self, config):
}

env = config.get("SENTRY_ENVIRONMENT")

if env is not None:
kwargs["environment"] = env

# Logging integration will create duplicates if below not ignored
ignore_logger("thumbor")
ignore_logger("tornado.access")

sentry_sdk.init(
sentry_sdk.init( # pylint: disable=abstract-class-instantiated
**kwargs
) # pylint: disable=abstract-class-instantiated
)

def handle_error(self, _, handler, exception):
req = handler.request
Expand Down
8 changes: 4 additions & 4 deletions thumbor/optimizers/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,12 @@ def run_optimizer(self, image_extension, buffer):
if not self.should_run(image_extension, buffer):
return buffer

ifile = NamedTemporaryFile(
ifile = NamedTemporaryFile( # pylint: disable=consider-using-with
delete=False
) # pylint: disable=consider-using-with
ofile = NamedTemporaryFile(
)
ofile = NamedTemporaryFile( # pylint: disable=consider-using-with
delete=False
) # pylint: disable=consider-using-with
)
try:
ifile.write(buffer)
ifile.close()
Expand Down
13 changes: 10 additions & 3 deletions thumbor/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,12 @@ def get_importer(config):
importer.import_modules()

if importer.error_handler_class is not None:
importer.error_handler = importer.error_handler_class(
config
) # pylint: disable=not-callable
importer.error_handler = (
importer.error_handler_class( # pylint: disable=not-callable
config
)
)

return importer


Expand All @@ -85,6 +88,7 @@ def validate_config(config, server_parameters):

if config.USE_GIFSICLE_ENGINE:
server_parameters.gifsicle_path = which("gifsicle")

if server_parameters.gifsicle_path is None:
raise RuntimeError(
"If using USE_GIFSICLE_ENGINE configuration to True,"
Expand All @@ -106,6 +110,7 @@ def run_server(application, context):

if context.server.fd is not None:
fd_number = get_as_integer(context.server.fd)

if fd_number is not None:
# TODO: replace with socket.socket(fileno=fd_number) when we require Python>=3.7
sock = socket_from_fd( # pylint: disable=too-many-function-args
Expand All @@ -125,11 +130,13 @@ def run_server(application, context):
)

server.start(context.server.processes)

return server


def main(arguments=None):
"""Runs thumbor server with the specified arguments."""

if arguments is None:
arguments = sys.argv[1:]

Expand Down

0 comments on commit f4e5c6a

Please sign in to comment.