From ee14e1da60a5b37c1d3fcdca870e29b8b718ee69 Mon Sep 17 00:00:00 2001 From: Ali Muhammad Date: Sun, 27 Jun 2021 03:23:43 +0500 Subject: [PATCH 1/4] added type annotation to functions --- EXIF.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/EXIF.py b/EXIF.py index 61758e45..1a86de03 100755 --- a/EXIF.py +++ b/EXIF.py @@ -18,15 +18,14 @@ import sys import argparse -import logging import timeit -from exifread.tags import DEFAULT_STOP_TAG, FIELD_TYPES +from exifread.tags import FIELD_TYPES from exifread import process_file, exif_log, __version__ logger = exif_log.get_logger() -def get_args(): +def get_args() -> argparse.Namespace: parser = argparse.ArgumentParser( prog='EXIF.py', description='Extract EXIF information from digital image files.' From 6a2710c9a0abda63be4324568be98b59b90ef0a8 Mon Sep 17 00:00:00 2001 From: Ali Muhammad Date: Sun, 27 Jun 2021 03:29:29 +0500 Subject: [PATCH 2/4] added missing type annotations --- exifread/classes.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/exifread/classes.py b/exifread/classes.py index 9cfbb09c..f0df2115 100644 --- a/exifread/classes.py +++ b/exifread/classes.py @@ -1,6 +1,6 @@ import re import struct -from typing import BinaryIO, Dict, Any +from typing import BinaryIO, Dict, Any, List from .exif_log import get_logger from .utils import Ratio @@ -15,7 +15,7 @@ class IfdTag: """ def __init__(self, printable: str, tag: int, field_type: int, values, - field_offset: int, field_length: int): + field_offset: int, field_length: int) -> None: # printable version of data self.printable = printable # tag ID number @@ -57,7 +57,7 @@ class ExifHeader: """ def __init__(self, file_handle: BinaryIO, endian, offset, fake_exif, strict: bool, - debug=False, detailed=True, truncate_tags=True): + debug=False, detailed=True, truncate_tags=True) -> None: self.file_handle = file_handle self.endian = endian self.offset = offset @@ -133,7 +133,7 @@ def list_ifd(self) -> list: i = self._next_ifd(i) return ifds - def _process_field(self, tag_name, count, field_type, type_length, offset): + def _process_field(self, tag_name, count, field_type, type_length, offset) -> List: values = [] signed = (field_type in [6, 8, 9, 10]) # XXX investigate @@ -174,7 +174,7 @@ def _process_field(self, tag_name, count, field_type, type_length, offset): offset = offset + type_length return values - def _process_field2(self, ifd_name, tag_name, count, offset): + def _process_field2(self, ifd_name, tag_name, count, offset) -> str: values = '' # special case: null-terminated ASCII string # XXX investigate @@ -509,7 +509,7 @@ def decode_maker_note(self) -> None: # def _olympus_decode_tag(self, value, mn_tags): # pass - def _canon_decode_tag(self, value, mn_tags): + def _canon_decode_tag(self, value, mn_tags) -> None: """ Decode Canon MakerNote tag based on offset within tag. @@ -531,7 +531,7 @@ def _canon_decode_tag(self, value, mn_tags): # This will have a "proprietary" type self.tags['MakerNote ' + name] = IfdTag(str(val), 0, 0, val, 0, 0) - def _canon_decode_camera_info(self, camera_info_tag): + def _canon_decode_camera_info(self, camera_info_tag) -> None: """ Decode the variable length encoded camera info section. """ @@ -573,7 +573,7 @@ def _canon_decode_camera_info(self, camera_info_tag): self.tags['MakerNote ' + tag_name] = IfdTag(str(tag_value), 0, 0, tag_value, 0, 0) - def parse_xmp(self, xmp_bytes: bytes): + def parse_xmp(self, xmp_bytes: bytes) -> None: """Adobe's Extensible Metadata Platform, just dump the pretty XML.""" import xml.dom.minidom # pylint: disable=import-outside-toplevel From 9031fafeb53d792c143bc0dc3a205fca4de44672 Mon Sep 17 00:00:00 2001 From: Ali Muhammad Date: Sun, 27 Jun 2021 03:51:43 +0500 Subject: [PATCH 3/4] added missing type annotation --- exifread/exif_log.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/exifread/exif_log.py b/exifread/exif_log.py index 78c27f1b..a0ff1b8a 100644 --- a/exifread/exif_log.py +++ b/exifread/exif_log.py @@ -15,12 +15,12 @@ TEXT_CYAN = 36 -def get_logger(): +def get_logger() -> logging.Logger: """Use this from all files needing to log.""" return logging.getLogger('exifread') -def setup_logger(debug, color): +def setup_logger(debug, color) -> None: """Configure the logger.""" if debug: @@ -39,7 +39,7 @@ class Formatter(logging.Formatter): Custom formatter, we like colors! """ - def __init__(self, debug=False, color=False): + def __init__(self, debug=False, color=False) -> None: self.color = color self.debug = debug if self.debug: @@ -48,7 +48,7 @@ def __init__(self, debug=False, color=False): log_format = '%(message)s' logging.Formatter.__init__(self, log_format) - def format(self, record): + def format(self, record) -> str: if self.debug and self.color: if record.levelno >= logging.CRITICAL: color = TEXT_RED @@ -68,7 +68,7 @@ def format(self, record): class Handler(logging.StreamHandler): - def __init__(self, log_level, debug=False, color=False): + def __init__(self, log_level, debug=False, color=False) -> None: self.color = color self.debug = debug logging.StreamHandler.__init__(self, sys.stdout) From 7b770390ea939cda8ac6721d0661da2382c30c45 Mon Sep 17 00:00:00 2001 From: Ali Muhammad Date: Sun, 27 Jun 2021 04:14:53 +0500 Subject: [PATCH 4/4] added type annotation --- exifread/heic.py | 28 ++++++++++++++-------------- exifread/utils.py | 12 ++++++------ 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/exifread/heic.py b/exifread/heic.py index 033f14b1..c45da65e 100644 --- a/exifread/heic.py +++ b/exifread/heic.py @@ -11,7 +11,7 @@ # gives us position and size information. import struct -from typing import List, Dict, Callable, BinaryIO, Optional +from typing import List, Dict, Callable, BinaryIO, Optional, Tuple from .exif_log import get_logger @@ -52,19 +52,19 @@ class Box: index_size = 0 flags = 0 - def __init__(self, name: str): + def __init__(self, name: str) -> None: self.name = name def __repr__(self) -> str: return "" % self.name - def set_sizes(self, offset: int, length: int, base_offset: int, index: int): + def set_sizes(self, offset: int, length: int, base_offset: int, index: int) -> None: self.offset_size = offset self.length_size = length self.base_offset_size = base_offset self.index_size = index - def set_full(self, vflags: int): + def set_full(self, vflags: int) -> None: """ ISO boxes come in 'old' and 'full' variants. The 'full' variant contains version and flags information. @@ -75,7 +75,7 @@ def set_full(self, vflags: int): class HEICExifFinder: - def __init__(self, file_handle: BinaryIO): + def __init__(self, file_handle: BinaryIO) -> None: self.file_handle = file_handle def get(self, nbytes: int) -> bytes: @@ -100,7 +100,7 @@ def get32(self) -> int: def get64(self) -> int: return struct.unpack('>Q', self.get(8))[0] - def get_int4x2(self) -> tuple: + def get_int4x2(self) -> Tuple: num = struct.unpack('>B', self.get(1))[0] num0 = num >> 4 num1 = num & 0xf @@ -146,10 +146,10 @@ def next_box(self) -> Box: box.pos = self.file_handle.tell() return box - def get_full(self, box: Box): + def get_full(self, box: Box) -> None: box.set_full(self.get32()) - def skip(self, box: Box): + def skip(self, box: Box) -> None: self.file_handle.seek(box.after) def expect_parse(self, name: str) -> Box: @@ -179,7 +179,7 @@ def parse_box(self, box: Box) -> Box: self.file_handle.seek(box.after) return box - def _parse_ftyp(self, box: Box): + def _parse_ftyp(self, box: Box) -> None: box.major_brand = self.get(4) box.minor_version = self.get32() box.compat = [] @@ -188,7 +188,7 @@ def _parse_ftyp(self, box: Box): box.compat.append(self.get(4)) size -= 4 - def _parse_meta(self, meta: Box): + def _parse_meta(self, meta: Box) -> None: self.get_full(meta) while self.file_handle.tell() < meta.after: box = self.next_box() @@ -201,7 +201,7 @@ def _parse_meta(self, meta: Box): # skip any unparsed data self.skip(box) - def _parse_infe(self, box: Box): + def _parse_infe(self, box: Box) -> None: self.get_full(box) if box.version >= 2: if box.version == 2: @@ -213,7 +213,7 @@ def _parse_infe(self, box: Box): box.item_name = self.get_string() # ignore the rest - def _parse_iinf(self, box: Box): + def _parse_iinf(self, box: Box) -> None: self.get_full(box) count = self.get16() box.exif_infe = None @@ -224,7 +224,7 @@ def _parse_iinf(self, box: Box): box.exif_infe = infe break - def _parse_iloc(self, box: Box): + def _parse_iloc(self, box: Box) -> None: self.get_full(box) size0, size1 = self.get_int4x2() size2, size3 = self.get_int4x2() @@ -261,7 +261,7 @@ def _parse_iloc(self, box: Box): extents.append((extent_offset, extent_length)) box.locs[item_id] = extents - def find_exif(self) -> tuple: + def find_exif(self) -> Tuple: ftyp = self.expect_parse('ftyp') assert ftyp.major_brand == b'heic' assert ftyp.minor_version == 0 diff --git a/exifread/utils.py b/exifread/utils.py index aea8b197..102bf551 100644 --- a/exifread/utils.py +++ b/exifread/utils.py @@ -3,10 +3,10 @@ """ from fractions import Fraction -from typing import Union +from typing import Any, Tuple, Union -def ord_(dta): +def ord_(dta) -> int: if isinstance(dta, str): return ord(dta) return dta @@ -53,7 +53,7 @@ def make_string_uc(seq) -> str: return make_string(seq) -def get_gps_coords(tags: dict) -> tuple: +def get_gps_coords(tags: dict) -> Tuple: lng_ref_tag_name = 'GPS GPSLongitudeRef' lng_tag_name = 'GPS GPSLongitude' @@ -88,7 +88,7 @@ class Ratio(Fraction): """ # We're immutable, so use __new__ not __init__ - def __new__(cls, numerator=0, denominator=None): + def __new__(cls, numerator=0, denominator=None) -> Any: try: self = super(Ratio, cls).__new__(cls, numerator, denominator) except ZeroDivisionError: @@ -101,11 +101,11 @@ def __repr__(self) -> str: return str(self) @property - def num(self): + def num(self) -> int: return self.numerator @property - def den(self): + def den(self) -> int: return self.denominator def decimal(self) -> float: