Fix Pylint warnings.

This commit is contained in:
Sergey Vartanov 2021-11-10 02:20:48 +03:00
parent bd1efbfe2c
commit c3dfaf0604
18 changed files with 101 additions and 71 deletions

View file

@ -29,7 +29,8 @@ def check_commit_message(parts: List[str]) -> Optional[str]:
if short_message[0] != short_message[0].upper():
return (
short_message + "\n^"
short_message
+ "\n^"
+ "\nCommit message short description should start with uppercase "
+ "letter."
)
@ -95,12 +96,12 @@ def check_commit_message(parts: List[str]) -> Optional[str]:
verbs[verb + "d"] = 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)} "
):
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"Commit message should start with the verb in infinitive "
f"form. Please, use "
f'"{first_letter_uppercase(right_verb)} ..." instead of '
f'"{first_letter_uppercase(wrong_verb)} ...".'
)

View file

@ -1,8 +1,10 @@
#!/bin/sh
python_files="map_machine setup.py tests data/githooks/commit-msg"
echo "Checking code format with Black..."
if ! black -l 80 --check tests map_machine; then
black -l 80 --diff --color tests map_machine
if ! black -l 80 --check ${python_files}; then
black -l 80 --diff --color ${python_files}
echo "FAIL"
exit 1
fi
@ -13,5 +15,5 @@ echo "Lint with Flake8..."
flake8 \
--max-line-length=80 \
--ignore=E203,W503,ANN002,ANN003,ANN101,ANN102 \
map_machine setup.py tests \
${python_files} \
|| { echo "FAIL"; exit 1; }

View file

@ -2,6 +2,7 @@
Construct Map Machine nodes and ways.
"""
import logging
import sys
from datetime import datetime
from hashlib import sha256
from typing import Any, Iterator, Optional, Union
@ -26,6 +27,7 @@ from map_machine.osm.osm_reader import (
OSMRelation,
OSMWay,
parse_levels,
Tags,
)
from map_machine.pictogram.icon import (
DEFAULT_SMALL_SHAPE_ID,
@ -231,8 +233,14 @@ class Constructor:
color: Color
if self.configuration.drawing_mode == DrawingMode.AUTHOR:
color = get_user_color(line.user, self.configuration.seed)
else: # self.mode == TIME_MODE
elif self.configuration.drawing_mode == DrawingMode.TIME:
color = get_time_color(line.timestamp, self.osm_data.time)
elif self.configuration.drawing_mode != DrawingMode.NORMAL:
logging.fatal(
f"Drawing mode {self.configuration.drawing_mode} is not "
f"supported."
)
sys.exit(1)
self.draw_special_mode(line, inners, outers, color)
return
@ -475,7 +483,7 @@ class Constructor:
self.points.append(point)
def check_level_number(tags: dict[str, Any], level: float) -> bool:
def check_level_number(tags: Tags, level: float) -> bool:
"""Check if element described by tags is no the specified level."""
if "level" in tags:
if level not in parse_levels(tags["level"]):
@ -485,12 +493,11 @@ def check_level_number(tags: dict[str, Any], level: float) -> bool:
return True
def check_level_overground(tags: dict[str, Any]) -> bool:
def check_level_overground(tags: Tags) -> bool:
"""Check if element described by tags is overground."""
if "level" in tags:
try:
levels: map = map(float, tags["level"].replace(",", ".").split(";"))
for level in levels:
for level in map(float, tags["level"].replace(",", ".").split(";")):
if level < 0:
return False
except ValueError:

View file

@ -73,8 +73,8 @@ class ArgumentParser(argparse.ArgumentParser):
continue
array: Code = [
[Tag("no_wrap", [Tag("m", [x])]), ", "]
for x in option["arguments"]
[Tag("no_wrap", [Tag("m", [text])]), ", "]
for text in option["arguments"]
]
cell: Code = [x for y in array for x in y][:-1]
if "metavar" in option:

View file

@ -53,8 +53,8 @@ class TaginfoProjectFile:
key: str = list(matcher.tags.keys())[0]
value: str = matcher.tags[key]
ids: list[str] = [
(x if isinstance(x, str) else x["shape"])
for x in matcher.shapes
(shape if isinstance(shape, str) else shape["shape"])
for shape in matcher.shapes
]
icon_id: str = "___".join(ids)
if value == "*":

View file

@ -35,7 +35,8 @@ def draw_element(options: argparse.Namespace) -> None:
tags_description = options.area
tags: dict[str, str] = {
x.split("=")[0]: x.split("=")[1] for x in tags_description.split(",")
tag.split("=")[0]: tag.split("=")[1]
for tag in tags_description.split(",")
}
scheme: Scheme = Scheme(workspace.DEFAULT_SCHEME_PATH)
extractor: ShapeExtractor = ShapeExtractor(

View file

@ -149,7 +149,7 @@ class DirectionSet:
:return: true if direction is right, false if direction is left, and
None otherwise.
"""
result: list[bool] = [x.is_right() for x in self.sectors]
result: list[bool] = [sector.is_right() for sector in self.sectors]
if result == [True] * len(result):
return True
if result == [False] * len(result):

View file

@ -395,5 +395,5 @@ def make_counter_clockwise(polygon: list[OSMNode]) -> list[OSMNode]:
def get_path(nodes: list[OSMNode], shift: np.ndarray, flinger: Flinger) -> str:
"""Construct SVG path commands from nodes."""
return Polyline(
[flinger.fling(x.coordinates) + shift for x in nodes]
[flinger.fling(node.coordinates) + shift for node in nodes]
).get_path()

View file

@ -121,13 +121,13 @@ class BoundaryBox:
"""Get maximum coordinates."""
return np.array((self.top, self.right))
def get_left_top(self) -> (np.ndarray, np.ndarray):
def get_left_top(self) -> np.ndarray:
"""Get left top corner of the boundary box."""
return self.top, self.left
return np.array((self.top, self.left))
def get_right_bottom(self) -> (np.ndarray, np.ndarray):
def get_right_bottom(self) -> np.ndarray:
"""Get right bottom corner of the boundary box."""
return self.bottom, self.right
return np.array((self.bottom, self.right))
def round(self) -> "BoundaryBox":
"""Round boundary box."""

View file

@ -62,8 +62,12 @@ class Polyline:
)
except ValueError:
points = self.points
path: str = "M " + " L ".join(f"{x[0]},{x[1]}" for x in points)
return path + (" Z" if np.allclose(points[0], points[-1]) else "")
return (
"M "
+ " L ".join(f"{point[0]},{point[1]}" for point in points)
+ (" Z" if np.allclose(points[0], points[-1]) else "")
)
def shorten(self, index: int, length: float) -> None:
"""Make shorten part specified with index."""

View file

@ -191,6 +191,9 @@
"name": "comb and scissors"
},
"counterclockwise": {},
"crane": {
"name": "crane"
},
"crater": {
"name": "crater"
},
@ -500,6 +503,9 @@
},
"oat": {},
"oat_2": {},
"observatory": {
"name": "observatory"
},
"onion_roof_shape": {
"name": "onion roof shape"
},

View file

@ -25,6 +25,9 @@ METERS_PATTERN: re.Pattern = re.compile("^(?P<value>\\d*\\.?\\d*)\\s*m$")
KILOMETERS_PATTERN: re.Pattern = re.compile("^(?P<value>\\d*\\.?\\d*)\\s*km$")
MILES_PATTERN: re.Pattern = re.compile("^(?P<value>\\d*\\.?\\d*)\\s*mi$")
EARTH_EQUATOR_LENGTH: float = 40_075_017.0
Tags = dict[str, str]
# See https://wiki.openstreetmap.org/wiki/Lifecycle_prefix#Stages_of_decay
STAGES_OF_DECAY: list[str] = [
@ -61,7 +64,7 @@ def parse_levels(string: str) -> list[float]:
class Tagged:
"""Something with tags (string to string mapping)."""
tags: dict[str, str]
tags: Tags
def get_tag(self, key: str) -> Optional[str]:
"""
@ -125,7 +128,7 @@ 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] = {
tags: Tags = {
x.attrib["k"]: x.attrib["v"] for x in element if x.tag == "tag"
}
return cls(
@ -180,7 +183,7 @@ class OSMWay(Tagged):
) -> "OSMWay":
"""Parse way from OSM XML `<way>` element."""
attributes = element.attrib
tags: dict[str, str] = {
tags: Tags = {
x.attrib["k"]: x.attrib["v"] for x in element if x.tag == "tag"
}
return cls(
@ -250,7 +253,7 @@ class OSMRelation(Tagged):
"""Parse relation from OSM XML `<relation>` element."""
attributes = element.attrib
members: list[OSMMember] = []
tags: dict[str, str] = {}
tags: Tags = {}
for subelement in element:
if subelement.tag == "member":
subattributes = subelement.attrib
@ -309,7 +312,7 @@ class OSMData:
self.levels: set[float] = set()
self.time: MinMax = MinMax()
self.view_box: Optional[BoundaryBox] = None
self.equator_length: float = 40_075_017.0
self.equator_length: float = EARTH_EQUATOR_LENGTH
def add_node(self, node: OSMNode) -> None:
"""Add node and update map parameters."""

View file

@ -353,7 +353,7 @@ class Icon:
point: np.ndarray,
tags: dict[str, Any] = None,
outline: bool = False,
scale: float = 1,
scale: float = 1.0,
) -> None:
"""
Draw icon to SVG.
@ -362,6 +362,7 @@ class Icon:
:param point: 2D position of the icon centre
:param tags: tags to be displayed as a tooltip
:param outline: draw outline for the icon
:param scale: scale icon by the magnitude
"""
if outline:
bright: bool = is_bright(self.shape_specifications[0].color)

View file

@ -14,6 +14,7 @@ from colour import Color
from map_machine.feature.direction import DirectionSet
from map_machine.map_configuration import MapConfiguration, LabelMode
from map_machine.osm.osm_reader import Tags
from map_machine.pictogram.icon import (
DEFAULT_COLOR,
DEFAULT_SHAPE_ID,
@ -52,7 +53,7 @@ class MatchingType(Enum):
def is_matched_tag(
matcher_tag_key: str,
matcher_tag_value: Union[str, list],
tags: dict[str, str],
tags: Tags,
) -> tuple[MatchingType, list[str]]:
"""
Check whether element tags contradict tag matcher.
@ -107,7 +108,7 @@ class Matcher:
def __init__(
self, structure: dict[str, Any], group: Optional[dict[str, Any]] = None
) -> None:
self.tags: dict[str, str] = structure["tags"]
self.tags: Tags = structure["tags"]
self.exception: dict[str, str] = {}
if "exception" in structure:
@ -132,9 +133,7 @@ class Matcher:
)
def is_matched(
self,
tags: dict[str, str],
configuration: Optional[MapConfiguration] = None,
self, tags: Tags, configuration: Optional[MapConfiguration] = None
) -> tuple[bool, dict[str, str]]:
"""
Check whether element tags matches tag matcher.
@ -294,7 +293,7 @@ class RoadMatcher(Matcher):
if "priority" in structure:
self.priority = structure["priority"]
def get_priority(self, tags: dict[str, str]) -> float:
def get_priority(self, tags: Tags) -> float:
"""Get priority for drawing order."""
layer: float = 0
if "layer" in tags:
@ -556,7 +555,7 @@ class Scheme:
return None
def construct_text(
self, tags: dict[str, str], processed: set[str], label_mode: LabelMode
self, tags: Tags, processed: set[str], label_mode: LabelMode
) -> list[Label]:
"""Construct labels for not processed tags."""
texts: list[Label] = construct_text(tags, processed, label_mode)
@ -566,7 +565,7 @@ class Scheme:
texts.append(Label(tags[tag]))
return texts
def is_area(self, tags: dict[str, str]) -> bool:
def is_area(self, tags: Tags) -> bool:
"""Check whether way described by tags is area."""
for matcher in self.area_matchers:
matching, _ = matcher.is_matched(tags)
@ -574,9 +573,7 @@ class Scheme:
return True
return False
def process_ignored(
self, tags: dict[str, str], processed: set[str]
) -> None:
def process_ignored(self, tags: Tags, processed: set[str]) -> None:
"""
Mark all ignored tag as processed.

View file

@ -9,6 +9,7 @@ from typing import Optional
import cairosvg
from map_configuration import MapConfiguration
from map_machine.slippy.tile import Tile
from map_machine.workspace import workspace
@ -16,12 +17,12 @@ __author__ = "Sergey Vartanov"
__email__ = "me@enzet.ru"
class _Handler(SimpleHTTPRequestHandler):
class TileServerHandler(SimpleHTTPRequestHandler):
"""HTTP request handler that process sloppy map tile requests."""
cache: Path = Path("cache")
update_cache: bool = False
options = None
options: Optional[argparse.Namespace] = None
def __init__(
self,
@ -29,6 +30,7 @@ class _Handler(SimpleHTTPRequestHandler):
client_address: tuple[str, int],
server: HTTPServer,
) -> None:
# TODO: delete?
super().__init__(request, client_address, server)
def do_GET(self) -> None:
@ -48,7 +50,11 @@ class _Handler(SimpleHTTPRequestHandler):
if self.update_cache:
if not png_path.exists():
if not svg_path.exists():
tile.draw(tile_path, self.cache, self.options)
tile.draw(
tile_path,
self.cache,
MapConfiguration(zoom_level=zoom_level),
)
with svg_path.open(encoding="utf-8") as input_file:
cairosvg.svg2png(
file_obj=input_file, write_to=str(png_path)
@ -68,7 +74,7 @@ def run_server(options: argparse.Namespace) -> None:
"""Command-line interface for tile server."""
server: Optional[HTTPServer] = None
try:
handler = _Handler
handler = TileServerHandler
handler.cache = Path(options.cache)
handler.options = options
server: HTTPServer = HTTPServer(("", options.port), handler)

View file

@ -202,9 +202,7 @@ class Tile:
for i in range(scale):
for j in range(scale):
tile: Tile = Tile(
scale * self.x + i,
scale * self.y + j,
zoom_level,
scale * self.x + i, scale * self.y + j, zoom_level
)
tiles.append(tile)
return tiles

View file

@ -2,11 +2,12 @@
OSM address tag processing.
"""
from dataclasses import dataclass
from typing import Any
from typing import Any, Optional
from colour import Color
from map_machine.map_configuration import LabelMode
from map_machine.osm.osm_reader import Tags
__author__ = "Sergey Vartanov"
__email__ = "me@enzet.ru"
@ -100,14 +101,15 @@ 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
tags: Tags, processed: set[str], label_mode: LabelMode
) -> list[Label]:
"""Construct list of labels from OSM tags."""
texts: list[Label] = []
name = None
alt_name = None
name: Optional[str] = None
alternative_name: Optional[str] = None
if "name" in tags:
name = tags["name"]
processed.add("name")
@ -117,25 +119,25 @@ def construct_text(
processed.add("name:en")
processed.add("name:en")
if "alt_name" in tags:
if alt_name:
alt_name += ", "
if alternative_name:
alternative_name += ", "
else:
alt_name = ""
alt_name += tags["alt_name"]
alternative_name = ""
alternative_name += tags["alt_name"]
processed.add("alt_name")
if "old_name" in tags:
if alt_name:
alt_name += ", "
if alternative_name:
alternative_name += ", "
else:
alt_name = ""
alt_name += "ex " + tags["old_name"]
alternative_name = ""
alternative_name += "ex " + tags["old_name"]
address: list[str] = get_address(tags, processed, label_mode)
if name:
texts.append(Label(name, Color("black")))
if alt_name:
texts.append(Label(f"({alt_name})"))
if alternative_name:
texts.append(Label(f"({alternative_name})"))
if address:
texts.append(Label(", ".join(address)))

View file

@ -119,16 +119,17 @@ def add_map_arguments(parser: argparse.ArgumentParser) -> None:
"--buildings",
metavar="<mode>",
default="flat",
choices=(x.value for x in BuildingMode),
choices=(mode.value for mode in BuildingMode),
help="building drawing mode: "
+ ", ".join(x.value for x in BuildingMode),
+ ", ".join(mode.value for mode in BuildingMode),
)
parser.add_argument(
"--mode",
default="normal",
metavar="<string>",
choices=(x.value for x in DrawingMode),
help="map drawing mode: " + ", ".join(x.value for x in DrawingMode),
choices=(mode.value for mode in DrawingMode),
help="map drawing mode: "
+ ", ".join(mode.value for mode in DrawingMode),
)
parser.add_argument(
"--overlap",
@ -143,8 +144,9 @@ def add_map_arguments(parser: argparse.ArgumentParser) -> None:
dest="label_mode",
default="main",
metavar="<string>",
choices=(x.value for x in LabelMode),
help="label drawing mode: " + ", ".join(x.value for x in LabelMode),
choices=(mode.value for mode in LabelMode),
help="label drawing mode: "
+ ", ".join(mode.value for mode in LabelMode),
)
parser.add_argument(
"--level",