Fix Pylint warnings.

This commit is contained in:
Sergey Vartanov 2021-11-08 02:21:34 +03:00
parent 11596c4cd8
commit 868a417afc
19 changed files with 137 additions and 148 deletions

View file

@ -18,7 +18,7 @@ def check_file(file_name: str) -> Optional[str]:
:param file_name: commit message file name
"""
with open(file_name) as input_file:
with open(file_name, encoding="utf-8") as input_file:
parts: List[str] = list(map(lambda x: x[:-1], input_file.readlines()))
return check_commit_message(parts)
@ -94,15 +94,15 @@ def check_commit_message(parts: List[str]) -> Optional[str]:
for verb in verbs_2:
verbs[verb + "d"] = verb
for verb in verbs:
if short_message.startswith(f"{verb} ") or short_message.startswith(
f"{first_letter_uppercase(verb)} "
for wrong_verb, right_verb in verbs.items():
if short_message.startswith(f"{wrong_verb} ") or short_message.startswith(
f"{first_letter_uppercase(wrong_verb)} "
):
return (
f'Commit message should start with the verb in infinitive '
f'form. Please, use '
f'"{first_letter_uppercase(verbs[verb])} ..." instead of '
f'"{first_letter_uppercase(verb)} ...".'
f'"{first_letter_uppercase(right_verb)} ..." instead of '
f'"{first_letter_uppercase(wrong_verb)} ...".'
)
@ -113,6 +113,7 @@ def check(commit_message: str) -> None:
def test():
"""Test rules."""
check("start with lowercase letter.")
check("Added foo.")
check("Created foo.")

View file

@ -217,7 +217,7 @@ class Constructor:
outers: list[list[OSMNode]],
) -> None:
"""
Way or relation construction.
Construct way or relation.
:param line: OpenStreetMap way or relation
:param inners: list of polygons that compose inner boundary
@ -310,7 +310,13 @@ class Constructor:
)
self.points.append(point)
if not line_styles:
if line_styles:
return
self.add_point_for_line(center_point, inners, line, outers)
def add_point_for_line(self, center_point, inners, line, outers) -> None:
"""Add icon at the center point of the way or relation."""
if DEBUG:
style: dict[str, Any] = {
"fill": "none",
@ -323,14 +329,10 @@ class Constructor:
self.figures.append(figure)
processed: set[str] = set()
priority: int
icon_set: IconSet
icon_set, priority = self.scheme.get_icon(
self.extractor,
line.tags,
processed,
self.configuration,
self.extractor, line.tags, processed, self.configuration
)
if icon_set is not None:
labels: list[Label] = self.scheme.construct_text(

View file

@ -56,10 +56,8 @@ class ArgumentParser(argparse.ArgumentParser):
def add_argument(self, *args, **kwargs) -> None:
"""Just store argument with options."""
super().add_argument(*args, **kwargs)
argument: dict[str, Any] = {"arguments": [x for x in args]}
for key in kwargs:
argument[key] = kwargs[key]
argument: dict[str, Any] = {"arguments": args}
argument |= kwargs
self.arguments.append(argument)
@ -116,9 +114,7 @@ class ArgumentParser(argparse.ArgumentParser):
class MapMachineMoire(Default, ABC):
"""
Moire extension stub for Map Machine.
"""
"""Moire extension stub for Map Machine."""
def osm(self, args: Arguments) -> str:
"""OSM tag key or keyvalue pair of tag."""
@ -130,7 +126,7 @@ class MapMachineMoire(Default, ABC):
+ "="
+ self.get_ref_(f"{PREFIX}Tag:{key}={tag}", self.m([tag]))
)
else:
return self.get_ref_(f"{PREFIX}Key:{spec}", self.m([spec]))
def color(self, args: Arguments) -> str:
@ -181,9 +177,7 @@ class MapMachineMoire(Default, ABC):
class MapMachineHTML(MapMachineMoire, DefaultHTML):
"""
Simple HTML.
"""
"""Simple HTML."""
def __init__(self) -> None:
super().__init__()
@ -196,9 +190,9 @@ class MapMachineHTML(MapMachineMoire, DefaultHTML):
["<th>" + self.parse(td, in_block=True) + "</th>" for td in arg[0]]
)
content += f"<tr>{cell}</tr>"
for tr in arg[1:]:
for row in arg[1:]:
cell: str = "".join(
["<td>" + self.parse(td, in_block=True) + "</td>" for td in tr]
["<td>" + self.parse(td, in_block=True) + "</td>" for td in row]
)
content += f"<tr>{cell}</tr>"
return f"<table>{content}</table>"
@ -260,7 +254,7 @@ class MapMachineOSMWiki(MapMachineMoire, DefaultWiki):
if "=" in spec:
key, tag = spec.split("=")
return f"{{{{Key|{key}|{tag}}}}}"
else:
return f"{{{{Tag|{spec}}}}}"
def color(self, args: Arguments) -> str:
@ -276,9 +270,7 @@ class MapMachineOSMWiki(MapMachineMoire, DefaultWiki):
class MapMachineMarkdown(MapMachineMoire, DefaultMarkdown):
"""
GitHub flavored markdown.
"""
"""GitHub flavored markdown."""
images = {}

View file

@ -9,6 +9,7 @@ import numpy as np
import svgwrite
from svgwrite.path import Path as SVGPath
from map_machine.map_configuration import LabelMode
from map_machine.pictogram.icon import ShapeExtractor
from map_machine.pictogram.point import Point
from map_machine.scheme import LineStyle, Scheme
@ -33,17 +34,17 @@ def draw_element(options: argparse.Namespace) -> None:
target = "area"
tags_description = options.area
tags: dict[str, str] = dict(
[x.split("=") for x in tags_description.split(",")]
)
tags: dict[str, str] = {
x.split("=")[0]: x.split("=")[1] for x in tags_description.split(",")
}
scheme: Scheme = Scheme(workspace.DEFAULT_SCHEME_PATH)
extractor: ShapeExtractor = ShapeExtractor(
workspace.ICONS_PATH, workspace.ICONS_CONFIG_PATH
)
processed: set[str] = set()
icon, priority = scheme.get_icon(extractor, tags, processed)
icon, _ = scheme.get_icon(extractor, tags, processed)
is_for_node: bool = target == "node"
labels: list[Label] = scheme.construct_text(tags, "all", processed)
labels: list[Label] = scheme.construct_text(tags, processed, LabelMode.ALL)
point: Point = Point(
icon,
labels,

View file

@ -109,11 +109,12 @@ class Sector:
if self.main_direction is not None:
if np.allclose(self.main_direction[0], 0):
return None
elif self.main_direction[0] > 0:
if self.main_direction[0] > 0:
return True
else:
return False
return None
def __str__(self) -> str:
return f"{self.start}-{self.end}"

View file

@ -293,9 +293,8 @@ class Intersection:
def __init__(self, parts: list[RoadPart]) -> None:
self.parts: list[RoadPart] = sorted(parts, key=lambda x: x.get_angle())
for index in range(len(self.parts)):
for index, part_1 in enumerate(self.parts):
next_index: int = 0 if index == len(self.parts) - 1 else index + 1
part_1: RoadPart = self.parts[index]
part_2: RoadPart = self.parts[next_index]
line_1: Line = Line(
part_1.point_1 + part_1.right_vector,
@ -312,9 +311,8 @@ class Intersection:
part_1.update()
part_2.update()
for index in range(len(self.parts)):
for index, part_1 in enumerate(self.parts):
next_index: int = 0 if index == len(self.parts) - 1 else index + 1
part_1: RoadPart = self.parts[index]
part_2: RoadPart = self.parts[next_index]
part_1.update()
part_2.update()
@ -412,10 +410,10 @@ class Road(Tagged):
number: int
if "lanes:forward" in tags:
number = int(tags["lanes:forward"])
[x.set_forward(True) for x in self.lanes[-number:]]
map(lambda x: x.set_forward(True), self.lanes[-number:])
if "lanes:backward" in tags:
number = int(tags["lanes:backward"])
[x.set_forward(False) for x in self.lanes[:number]]
map(lambda x: x.set_forward(False), self.lanes[:number])
if "width" in tags:
try:
@ -731,20 +729,8 @@ class ComplexConnector(Connector):
]
# fmt: on
def draw(self, svg: Drawing, draw_circle: bool = False) -> None:
def draw(self, svg: Drawing) -> None:
"""Draw connection fill."""
if draw_circle:
for road, index in [
(self.road_1, self.index_1),
(self.road_2, self.index_2),
]:
circle: Circle = svg.circle(
road.line.points[index] - road.placement_offset,
road.width * self.scale / 2,
fill=road.get_color(),
)
svg.add(circle)
path: Path = svg.path(
d=["M"] + self.curve_1 + ["L"] + self.curve_2 + ["Z"],
fill=self.road_1.get_color(),

View file

@ -34,7 +34,7 @@ def main() -> None:
elif arguments.command == "tile":
from map_machine.slippy import tile
tile.ui(arguments)
tile.generate_tiles(arguments)
elif arguments.command == "icons":
from map_machine.pictogram.icon_collection import draw_icons
@ -54,11 +54,11 @@ def main() -> None:
elif arguments.command == "server":
from map_machine.slippy import server
server.ui(arguments)
server.run_server(arguments)
elif arguments.command == "taginfo":
from map_machine.scheme import Scheme
from doc.taginfo import write_taginfo_project_file
from map_machine.doc.taginfo import write_taginfo_project_file
write_taginfo_project_file(Scheme(workspace.DEFAULT_SCHEME_PATH))

View file

@ -231,7 +231,7 @@ def render_map(arguments: argparse.Namespace) -> None:
for input_file_name in input_file_names:
if not input_file_name.is_file():
logging.fatal(f"No such file: {input_file_name}.")
exit(1)
sys.exit(1)
if input_file_name.name.endswith(".json"):
osm_data.parse_overpass(input_file_name)

View file

@ -51,7 +51,7 @@ def get_osm(
"Cannot download data: too many nodes (limit is 50000). Try "
"to request smaller area."
)
else:
raise NetworkError("Cannot download data.")
with cache_file_path.open("bw+") as output_file:

View file

@ -127,9 +127,9 @@ class OSMNode(Tagged):
def from_xml_structure(cls, element: Element) -> "OSMNode":
"""Parse node from OSM XML `<node>` element."""
attributes = element.attrib
tags: dict[str, str] = dict(
[(x.attrib["k"], x.attrib["v"]) for x in element if x.tag == "tag"]
)
tags: dict[str, str] = {
x.attrib["k"]: x.attrib["v"] for x in element if x.tag == "tag"
}
return cls(
tags,
int(attributes["id"]),
@ -182,9 +182,9 @@ class OSMWay(Tagged):
) -> "OSMWay":
"""Parse way from OSM XML `<way>` element."""
attributes = element.attrib
tags: dict[str, str] = dict(
[(x.attrib["k"], x.attrib["v"]) for x in element if x.tag == "tag"]
)
tags: dict[str, str] = {
x.attrib["k"]: x.attrib["v"] for x in element if x.tag == "tag"
}
return cls(
tags,
int(element.attrib["id"]),
@ -302,8 +302,6 @@ class NotWellFormedOSMDataException(Exception):
OSM data structure is not well-formed.
"""
pass
class OSMData:
"""

View file

@ -367,14 +367,16 @@ class Scheme:
specification: Union[str, dict] = self.colors[color]
if isinstance(specification, str):
return Color(self.colors[color])
else:
color: Color = self.get_color(specification["color"])
if "darken" in specification:
percent: float = float(specification["darken"])
color.set_luminance(color.get_luminance() * (1 - percent))
return color
if color.lower() in self.colors:
return Color(self.colors[color.lower()])
try:
return Color(color)
except (ValueError, AttributeError):
@ -593,11 +595,9 @@ class Scheme:
:param tags: input tag dictionary
:param processed: processed set
"""
[
processed.add(tag)
for tag in tags
if self.is_no_drawable(tag, tags[tag])
]
processed.update(
set(tag for tag in tags if self.is_no_drawable(tag, tags[tag]))
)
def get_shape_specification(
self,

View file

@ -66,7 +66,7 @@ class _Handler(SimpleHTTPRequestHandler):
return
def ui(options: argparse.Namespace) -> None:
def run_server(options: argparse.Namespace) -> None:
"""Command-line interface for tile server."""
server: Optional[HTTPServer] = None
try:

View file

@ -457,9 +457,9 @@ def parse_zoom_level(zoom_level_specification: str) -> list[int]:
result: list[int] = []
for part in parts:
if "-" in part:
from_, to = part.split("-")
from_zoom_level: int = parse(from_)
to_zoom_level: int = parse(to)
start, end = part.split("-")
from_zoom_level: int = parse(start)
to_zoom_level: int = parse(end)
if from_zoom_level > to_zoom_level:
raise ScaleConfigurationException("Wrong range.")
result += range(from_zoom_level, to_zoom_level + 1)
@ -469,7 +469,7 @@ def parse_zoom_level(zoom_level_specification: str) -> list[int]:
return result
def ui(options: argparse.Namespace) -> None:
def generate_tiles(options: argparse.Namespace) -> None:
"""Simple user interface for tile generation."""
directory: Path = workspace.get_tile_path()

View file

@ -104,6 +104,7 @@ def get_text(tags: dict[str, Any], processed: set[str]) -> list[Label]:
def construct_text(
tags: dict[str, str], processed: set[str], label_mode: LabelMode
) -> list[Label]:
"""Construct list of labels from OSM tags."""
texts: list[Label] = []

View file

@ -14,7 +14,7 @@ from map_machine import (
REQUIREMENTS,
)
with Path("README.md").open() as input_file:
with Path("README.md").open(encoding="utf-8") as input_file:
long_description: str = input_file.read()
setup(

View file

@ -24,17 +24,17 @@ LOG: bytes = (
def error_run(arguments: list[str], message: bytes) -> None:
"""Run command that should fail and check error message."""
p = Popen(["map-machine"] + arguments, stderr=PIPE)
_, error = p.communicate()
assert p.returncode != 0
with Popen(["map-machine"] + arguments, stderr=PIPE) as pipe:
_, error = pipe.communicate()
assert pipe.returncode != 0
assert error == message
def run(arguments: list[str], message: bytes) -> None:
"""Run command that should fail and check error message."""
p = Popen(["map-machine"] + arguments, stderr=PIPE)
_, error = p.communicate()
assert p.returncode == 0
with Popen(["map-machine"] + arguments, stderr=PIPE) as pipe:
_, error = pipe.communicate()
assert pipe.returncode == 0
assert error == message
@ -53,7 +53,7 @@ def test_render() -> None:
COMMAND_LINES["render"] + ["--cache", "tests/data"],
LOG + b"INFO Writing output SVG to out/map.svg...\n",
)
with Path("out/map.svg").open() as output_file:
with Path("out/map.svg").open(encoding="utf-8") as output_file:
root: Element = ElementTree.parse(output_file).getroot()
# 4 expected elements: `defs`, `rect` (background), `g` (outline),
@ -70,7 +70,7 @@ def test_render_with_tooltips() -> None:
COMMAND_LINES["render_with_tooltips"] + ["--cache", "tests/data"],
LOG + b"INFO Writing output SVG to out/map.svg...\n",
)
with Path("out/map.svg").open() as output_file:
with Path("out/map.svg").open(encoding="utf-8") as output_file:
root: Element = ElementTree.parse(output_file).getroot()
# 4 expected elements: `defs`, `rect` (background), `g` (outline),

View file

@ -159,7 +159,7 @@ def road_features(
grid: Grid = Grid()
for i in range(len(types)):
for i, type_ in enumerate(types):
previous: Optional[OSMNode] = None
for j in range(len(features) + 1):
@ -167,7 +167,7 @@ def road_features(
if previous:
tags: dict[str, str] = dict(features[j - 1])
tags |= types[i]
tags |= type_
way: OSMWay = OSMWay(
tags, i * (len(features) + 1) + j, [previous, node]
)

View file

@ -7,7 +7,7 @@ import pytest
from colour import Color
from map_machine.pictogram.icon_collection import IconCollection
from map_machine.pictogram.icon import IconSet
from map_machine.pictogram.icon import IconSet, ShapeSpecification, Icon
from tests import SCHEME, SHAPE_EXTRACTOR, workspace
__author__ = "Sergey Vartanov"
@ -47,14 +47,14 @@ def test_no_icons() -> None:
Tags that has no description in scheme and should be visualized with default
shape.
"""
icon = get_icon({"aaa": "bbb"})
icon: IconSet = get_icon({"aaa": "bbb"})
assert icon.main_icon.is_default()
def check_icon_set(
icon: IconSet,
main_specification: list[tuple[str, Optional[str]]],
extra_specification: list[list[tuple[str, Optional[str]]]],
extra_specifications: list[list[tuple[str, Optional[str]]]],
) -> None:
"""Check icon set using simple specification."""
if not main_specification:
@ -64,17 +64,20 @@ def check_icon_set(
assert len(main_specification) == len(
icon.main_icon.shape_specifications
)
for i, s in enumerate(main_specification):
assert icon.main_icon.shape_specifications[i].shape.id_ == s[0]
assert icon.main_icon.shape_specifications[i].color == Color(s[1])
for index, shape in enumerate(main_specification):
shape_specification: ShapeSpecification = (
icon.main_icon.shape_specifications[index]
)
assert shape_specification.shape.id_ == shape[0]
assert shape_specification.color == Color(shape[1])
assert len(extra_specification) == len(icon.extra_icons)
for i, x in enumerate(extra_specification):
extra_icon = icon.extra_icons[i]
assert len(x) == len(extra_icon.shape_specifications)
for j, s in enumerate(x):
assert extra_icon.shape_specifications[j].shape.id_ == s[0]
assert extra_icon.shape_specifications[j].color == Color(s[1])
assert len(extra_specifications) == len(icon.extra_icons)
for i, extra_specification in enumerate(extra_specifications):
extra_icon: Icon = icon.extra_icons[i]
assert len(extra_specification) == len(extra_icon.shape_specifications)
for j, shape in enumerate(extra_specification):
assert extra_icon.shape_specifications[j].shape.id_ == shape[0]
assert extra_icon.shape_specifications[j].color == Color(shape[1])
def test_icon() -> None:
@ -90,7 +93,7 @@ def test_icon_1_extra() -> None:
"""
Tags that should be visualized with single main icon and single extra icon.
"""
icon = get_icon({"barrier": "gate", "access": "private"})
icon: IconSet = get_icon({"barrier": "gate", "access": "private"})
check_icon_set(
icon, [("gate", "#444444")], [[("lock_with_keyhole", "#888888")]]
)
@ -100,7 +103,9 @@ def test_icon_2_extra() -> None:
"""
Tags that should be visualized with single main icon and two extra icons.
"""
icon = get_icon({"barrier": "gate", "access": "private", "bicycle": "yes"})
icon: IconSet = get_icon(
{"barrier": "gate", "access": "private", "bicycle": "yes"}
)
check_icon_set(
icon,
[("gate", "#444444")],
@ -115,7 +120,7 @@ def test_no_icon_1_extra() -> None:
"""
Tags that should be visualized with default main icon and single extra icon.
"""
icon = get_icon({"access": "private"})
icon: IconSet = get_icon({"access": "private"})
check_icon_set(icon, [], [[("lock_with_keyhole", "#888888")]])
@ -123,7 +128,7 @@ def test_no_icon_2_extra() -> None:
"""
Tags that should be visualized with default main icon and two extra icons.
"""
icon = get_icon({"access": "private", "bicycle": "yes"})
icon: IconSet = get_icon({"access": "private", "bicycle": "yes"})
check_icon_set(
icon,
[],
@ -138,7 +143,7 @@ def test_icon_regex() -> None:
"""
Tags that should be visualized with default main icon and single extra icon.
"""
icon = get_icon({"traffic_sign": "maxspeed", "maxspeed": "42"})
icon: IconSet = get_icon({"traffic_sign": "maxspeed", "maxspeed": "42"})
check_icon_set(
icon,
[

View file

@ -1,13 +1,15 @@
"""
Check whether `requirements.txt` contains all requirements from `setup.py`.
"""
from map_machine import REQUIREMENTS
from pathlib import Path
from map_machine import REQUIREMENTS
def test_requirements() -> None:
"""Test whether `requirements.txt` has the same packages as `setup.py`."""
requirements: list[str]
with Path("requirements.txt").open() as requirements_file:
with Path("requirements.txt").open(encoding="utf-8") as requirements_file:
requirements = list(
map(lambda x: x[:-1], requirements_file.readlines())
)