Skip to content

Commit

Permalink
Tidy up some typing
Browse files Browse the repository at this point in the history
  • Loading branch information
SmileyChris committed Mar 14, 2022
1 parent 812dc93 commit 91a1c4d
Show file tree
Hide file tree
Showing 15 changed files with 68 additions and 110 deletions.
Empty file added qrcode/compat/__init__.py
Empty file.
4 changes: 4 additions & 0 deletions qrcode/compat/etree.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
try:
import lxml.etree as ET # type: ignore # noqa: F401
except ImportError:
import xml.etree.ElementTree as ET # type: ignore # noqa: F401
12 changes: 12 additions & 0 deletions qrcode/compat/pil.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Try to import PIL in either of the two ways it can be installed.
Image = None
ImageDraw = None

try:
from PIL import Image, ImageDraw # type: ignore # noqa: F401
except ImportError: # pragma: no cover
try:
import Image # type: ignore # noqa: F401
import ImageDraw # type: ignore # noqa: F401
except ImportError:
pass
2 changes: 1 addition & 1 deletion qrcode/console_scripts.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@

# The next block is added to get the terminal to display properly on MS platforms
if sys.platform.startswith(("win", "cygwin")): # pragma: no cover
import colorama
import colorama # type: ignore

colorama.init()

Expand Down
10 changes: 1 addition & 9 deletions qrcode/image/pil.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,5 @@
# Needed on case-insensitive filesystems

# Try to import PIL in either of the two ways it can be installed.
try:
from PIL import Image, ImageDraw
except ImportError: # pragma: no cover
import Image
import ImageDraw

import qrcode.image.base
from qrcode.compat.pil import Image, ImageDraw


class PilImage(qrcode.image.base.BaseImage):
Expand Down
19 changes: 9 additions & 10 deletions qrcode/image/pure.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import qrcode.image.base
from pymaging import Image
from pymaging.colors import RGB
from pymaging.formats import registry
from pymaging.shapes import Line
from pymaging.webcolors import Black, White
from pymaging_png.png import PNG
from pymaging import Image # type: ignore
from pymaging.colors import RGB # type: ignore
from pymaging.formats import registry # type: ignore
from pymaging.shapes import Line # type: ignore
from pymaging.webcolors import Black, White # type: ignore
from pymaging_png.png import PNG # type: ignore


class PymagingImage(qrcode.image.base.BaseImage):
Expand Down Expand Up @@ -43,9 +43,8 @@ def check_kind(self, kind, transform=None, **kwargs):
"""
pymaging (pymaging_png at least) uses lower case for the type.
"""
if transform is None:

def transform(x):
return x.lower()
def lower_case(x):
return x.lower()

return super().check_kind(kind, transform=transform, **kwargs)
return super().check_kind(kind, transform=transform or lower_case, **kwargs)
9 changes: 3 additions & 6 deletions qrcode/image/styledpil.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,8 @@
# Needed on case-insensitive filesystems
from __future__ import absolute_import

# Try to import PIL in either of the two ways it can be installed.
try:
from PIL import Image
except ImportError: # pragma: no cover
import Image

import qrcode.image.base
from qrcode.compat.pil import Image
from qrcode.image.styles.colormasks import QRColorMask, SolidFillColorMask
from qrcode.image.styles.moduledrawers import SquareModuleDrawer

Expand Down Expand Up @@ -88,6 +83,8 @@ def process(self):
self.draw_embeded_image()

def draw_embeded_image(self):
if not self.embeded_image:
return
total_width, _ = self._img.size
total_width = int(total_width)
logo_width_ish = int(total_width / 4)
Expand Down
25 changes: 8 additions & 17 deletions qrcode/image/styles/colormasks.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,10 @@
# Needed on case-insensitive filesystems
from __future__ import absolute_import

# Try to import PIL in either of the two ways it can be installed.
try:
from PIL import Image
except ImportError: # pragma: no cover
import Image

import math

from qrcode.compat.pil import Image


class QRColorMask:
"""
Expand Down Expand Up @@ -78,19 +74,14 @@ def extrap_num(self, n1, n2, interped_num):

# find the interpolation coefficient between two numbers
def extrap_color(self, col1, col2, interped_color):
normed = list(
filter(
lambda i: i is not None,
[
self.extrap_num(col1[i], col2[i], interped_color[i])
for i in range(len(col1))
],
)
)
normed = []
for c1, c2, ci in zip(col1, col2, interped_color):
extrap = self.extrap_num(c1, c2, ci)
if extrap is not None:
normed.append(extrap)
if not normed:
return None
else:
return sum(normed) / len(normed)
return sum(normed) / len(normed)


class SolidFillColorMask(QRColorMask):
Expand Down
5 changes: 2 additions & 3 deletions qrcode/image/styles/moduledrawers/base.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
from __future__ import absolute_import

import abc
from typing import TYPE_CHECKING, Union
from typing import TYPE_CHECKING

if TYPE_CHECKING:
from qrcode.image.base import BaseImage
from qrcode.main import ActiveWithNeighbors


class QRModuleDrawer(abc.ABC):
Expand Down Expand Up @@ -33,5 +32,5 @@ def initialize(self, img: "BaseImage") -> None:
self.img = img

@abc.abstractmethod
def drawrect(self, box, is_active: "Union[bool, ActiveWithNeighbors]") -> None:
def drawrect(self, box, is_active) -> None:
...
31 changes: 8 additions & 23 deletions qrcode/image/styles/moduledrawers/pil.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,11 @@
# Needed on case-insensitive filesystems
from __future__ import absolute_import

import abc
from typing import TYPE_CHECKING, List, Union
from typing import TYPE_CHECKING, List

from qrcode.compat.pil import Image, ImageDraw
from qrcode.image.styles.moduledrawers.base import QRModuleDrawer

# Try to import PIL in either of the two ways it can be installed.
try:
from PIL import Image, ImageDraw
except ImportError: # pragma: no cover
import Image
import ImageDraw

if TYPE_CHECKING:
from qrcode.image.styledpil import StyledPilImage
from qrcode.main import ActiveWithNeighbors
Expand All @@ -33,10 +26,6 @@ class StyledPilQRModuleDrawer(QRModuleDrawer):

img: "StyledPilImage"

@abc.abstractmethod
def drawrect(self, box, is_active: Union[bool, "ActiveWithNeighbors"]) -> None:
...


class SquareModuleDrawer(StyledPilQRModuleDrawer):
"""
Expand All @@ -47,7 +36,7 @@ def initialize(self, *args, **kwargs):
super().initialize(*args, **kwargs)
self.imgDraw = ImageDraw.Draw(self.img._img)

def drawrect(self, box, is_active):
def drawrect(self, box, is_active: bool):
if is_active:
self.imgDraw.rectangle(box, fill=self.img.paint_color)

Expand All @@ -68,7 +57,7 @@ def initialize(self, *args, **kwargs):
self.imgDraw = ImageDraw.Draw(self.img._img)
self.delta = (1 - self.size_ratio) * self.img.box_size / 2

def drawrect(self, box, is_active: "Union[bool, ActiveWithNeighbors]"):
def drawrect(self, box, is_active: bool):
if is_active:
smaller_box = (
box[0][0] + self.delta,
Expand Down Expand Up @@ -100,7 +89,7 @@ def initialize(self, *args, **kwargs):
)
self.circle = self.circle.resize((box_size, box_size), Image.LANCZOS)

def drawrect(self, box, is_active: "Union[bool, ActiveWithNeighbors]"):
def drawrect(self, box, is_active: bool):
if is_active:
self.img._img.paste(self.circle, (box[0][0], box[0][1]))

Expand Down Expand Up @@ -150,9 +139,7 @@ def setup_corners(self):
self.SE_ROUND = self.NW_ROUND.transpose(Image.ROTATE_180)
self.NE_ROUND = self.NW_ROUND.transpose(Image.FLIP_LEFT_RIGHT)

def drawrect(
self, box: List[List[int]], is_active: "Union[bool, ActiveWithNeighbors]"
):
def drawrect(self, box: List[List[int]], is_active: "ActiveWithNeighbors"):
if not is_active:
return
# find rounded edges
Expand Down Expand Up @@ -212,8 +199,7 @@ def setup_edges(self):
self.ROUND_TOP = base.resize((shrunken_width, height), Image.LANCZOS)
self.ROUND_BOTTOM = self.ROUND_TOP.transpose(Image.FLIP_TOP_BOTTOM)

def drawrect(self, box, is_active: "Union[bool, ActiveWithNeighbors]"):
assert not isinstance(is_active, bool)
def drawrect(self, box, is_active: "ActiveWithNeighbors"):
if is_active:
# find rounded edges
top_rounded = not is_active.N
Expand Down Expand Up @@ -266,8 +252,7 @@ def setup_edges(self):
self.ROUND_LEFT = base.resize((width, shrunken_height), Image.LANCZOS)
self.ROUND_RIGHT = self.ROUND_LEFT.transpose(Image.FLIP_LEFT_RIGHT)

def drawrect(self, box, is_active: "Union[bool, ActiveWithNeighbors]"):
assert not isinstance(is_active, bool)
def drawrect(self, box, is_active: "ActiveWithNeighbors"):
if is_active:
# find rounded edges
left_rounded = not is_active.W
Expand Down
14 changes: 5 additions & 9 deletions qrcode/image/styles/moduledrawers/svg.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,8 @@
from decimal import Decimal
from typing import TYPE_CHECKING, NamedTuple

try:
import lxml.etree as ET
except ImportError:
import xml.etree.ElementTree as ET # type: ignore

from qrcode.image.styles.moduledrawers.base import QRModuleDrawer
from qrcode.compat.etree import ET

if TYPE_CHECKING:
from qrcode.image.svg import SvgFragmentImage, SvgPathImage
Expand Down Expand Up @@ -58,7 +54,7 @@ def initialize(self, *args, **kwargs) -> None:
super().initialize(*args, **kwargs)
self.tag_qname = ET.QName(self.img._SVG_namespace, self.tag)

def drawrect(self, box, is_active):
def drawrect(self, box, is_active: bool):
if not is_active:
return
self.img._img.append(self.el(box))
Expand All @@ -76,7 +72,7 @@ def initialize(self, *args, **kwargs) -> None:
def el(self, box):
coords = self.coords(box)
return ET.Element(
self.tag_qname,
self.tag_qname, # type: ignore
x=self.img.units(coords.x0),
y=self.img.units(coords.y0),
width=self.unit_size,
Expand All @@ -94,7 +90,7 @@ def initialize(self, *args, **kwargs) -> None:
def el(self, box):
coords = self.coords(box)
return ET.Element(
self.tag_qname,
self.tag_qname, # type: ignore
cx=self.img.units(coords.xh),
cy=self.img.units(coords.yh),
r=self.radius,
Expand All @@ -104,7 +100,7 @@ def el(self, box):
class SvgPathQRModuleDrawer(BaseSvgQRModuleDrawer):
img: "SvgPathImage"

def drawrect(self, box, is_active):
def drawrect(self, box, is_active: bool):
if not is_active:
return
self.img._subpaths.append(self.subpath(box))
Expand Down
16 changes: 8 additions & 8 deletions qrcode/image/svg.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,10 @@
from typing_extensions import Literal

import qrcode.image.base
from qrcode.compat.etree import ET
from qrcode.image.styles.moduledrawers import svg as svg_drawers
from qrcode.image.styles.moduledrawers.base import QRModuleDrawer

try:
import lxml.etree as ET
except ImportError:
import xml.etree.ElementTree as ET # type: ignore


class SvgFragmentImage(qrcode.image.base.BaseImageWithDrawer):
"""
Expand Down Expand Up @@ -71,7 +67,11 @@ def _svg(self, tag=None, version="1.1", **kwargs):
tag = ET.QName(self._SVG_namespace, "svg")
dimension = self.units(self.pixel_size)
return ET.Element(
tag, width=dimension, height=dimension, version=version, **kwargs
tag, # type: ignore
width=dimension,
height=dimension,
version=version,
**kwargs,
)

def _write(self, stream):
Expand Down Expand Up @@ -126,7 +126,7 @@ class SvgPathImage(SvgImage):
}

needs_processing = True
path: ET.Element = None
path: Optional[ET.Element] = None
default_drawer_class: Type[QRModuleDrawer] = svg_drawers.SvgPathSquareDrawer
drawer_aliases = {
"circle": (svg_drawers.SvgPathCircleDrawer, {}),
Expand Down Expand Up @@ -154,7 +154,7 @@ def process(self):
# Store the path just in case someone wants to use it again or in some
# unique way.
self.path = ET.Element(
ET.QName("path"),
ET.QName("path"), # type: ignore
d="".join(self._subpaths),
id="qr-path",
**self.QR_PATH_STYLE,
Expand Down
9 changes: 1 addition & 8 deletions qrcode/tests/test_example.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,7 @@
from unittest import mock

from qrcode import run_example

try:
from PIL import Image
except ImportError:
try:
import Image
except ImportError:
Image = None
from qrcode.compat.pil import Image


class ExampleTest(unittest.TestCase):
Expand Down
13 changes: 5 additions & 8 deletions qrcode/tests/test_qrcode.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,23 +7,20 @@

import qrcode
import qrcode.util
from qrcode.compat.pil import Image as pil_Image
from qrcode.exceptions import DataOverflowError
from qrcode.image.base import BaseImage
from qrcode.image.styles import moduledrawers
from qrcode.image.styledpil import StyledPilImage
from qrcode.image.styles import colormasks, moduledrawers
from qrcode.util import MODE_8BIT_BYTE, MODE_ALPHA_NUM, MODE_NUMBER, QRData

try:
import pymaging_png # type: ignore

from qrcode.image.pure import PymagingImage
except ImportError: # pragma: no cover
pymaging_png = None

try:
from qrcode.image.pil import Image as pil_Image
from qrcode.image.styledpil import StyledPilImage
from qrcode.image.styles import colormasks
except ImportError:
pil_Image = None

UNICODE_TEXT = "\u03b1\u03b2\u03b3"
WHITE = (255, 255, 255)
Expand Down Expand Up @@ -204,7 +201,7 @@ def test_render_pymaging_png_bad_kind(self):
img.save(io.BytesIO(), kind="FISH")

@unittest.skipIf(not pil_Image, "Requires PIL")
def test_render_styled_pil_image(self):
def test_render_styled_Image(self):
qr = qrcode.QRCode(error_correction=qrcode.ERROR_CORRECT_L)
qr.add_data(UNICODE_TEXT)
img = qr.make_image(image_factory=StyledPilImage)
Expand Down
Loading

0 comments on commit 91a1c4d

Please sign in to comment.