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

View file

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

View file

@ -2,6 +2,7 @@
Construct Map Machine nodes and ways. Construct Map Machine nodes and ways.
""" """
import logging import logging
import sys
from datetime import datetime from datetime import datetime
from hashlib import sha256 from hashlib import sha256
from typing import Any, Iterator, Optional, Union from typing import Any, Iterator, Optional, Union
@ -26,6 +27,7 @@ from map_machine.osm.osm_reader import (
OSMRelation, OSMRelation,
OSMWay, OSMWay,
parse_levels, parse_levels,
Tags,
) )
from map_machine.pictogram.icon import ( from map_machine.pictogram.icon import (
DEFAULT_SMALL_SHAPE_ID, DEFAULT_SMALL_SHAPE_ID,
@ -231,8 +233,14 @@ class Constructor:
color: Color color: Color
if self.configuration.drawing_mode == DrawingMode.AUTHOR: if self.configuration.drawing_mode == DrawingMode.AUTHOR:
color = get_user_color(line.user, self.configuration.seed) 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) 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) self.draw_special_mode(line, inners, outers, color)
return return
@ -475,7 +483,7 @@ class Constructor:
self.points.append(point) 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.""" """Check if element described by tags is no the specified level."""
if "level" in tags: if "level" in tags:
if level not in parse_levels(tags["level"]): 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 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.""" """Check if element described by tags is overground."""
if "level" in tags: if "level" in tags:
try: try:
levels: map = map(float, tags["level"].replace(",", ".").split(";")) for level in map(float, tags["level"].replace(",", ".").split(";")):
for level in levels:
if level < 0: if level < 0:
return False return False
except ValueError: except ValueError:

View file

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

View file

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

View file

@ -35,7 +35,8 @@ def draw_element(options: argparse.Namespace) -> None:
tags_description = options.area tags_description = options.area
tags: dict[str, str] = { 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) scheme: Scheme = Scheme(workspace.DEFAULT_SCHEME_PATH)
extractor: ShapeExtractor = ShapeExtractor( extractor: ShapeExtractor = ShapeExtractor(

View file

@ -149,7 +149,7 @@ class DirectionSet:
:return: true if direction is right, false if direction is left, and :return: true if direction is right, false if direction is left, and
None otherwise. 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): if result == [True] * len(result):
return True return True
if result == [False] * len(result): 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: def get_path(nodes: list[OSMNode], shift: np.ndarray, flinger: Flinger) -> str:
"""Construct SVG path commands from nodes.""" """Construct SVG path commands from nodes."""
return Polyline( return Polyline(
[flinger.fling(x.coordinates) + shift for x in nodes] [flinger.fling(node.coordinates) + shift for node in nodes]
).get_path() ).get_path()

View file

@ -121,13 +121,13 @@ class BoundaryBox:
"""Get maximum coordinates.""" """Get maximum coordinates."""
return np.array((self.top, self.right)) 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.""" """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.""" """Get right bottom corner of the boundary box."""
return self.bottom, self.right return np.array((self.bottom, self.right))
def round(self) -> "BoundaryBox": def round(self) -> "BoundaryBox":
"""Round boundary box.""" """Round boundary box."""

View file

@ -62,8 +62,12 @@ class Polyline:
) )
except ValueError: except ValueError:
points = self.points 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: def shorten(self, index: int, length: float) -> None:
"""Make shorten part specified with index.""" """Make shorten part specified with index."""

View file

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

View file

@ -353,7 +353,7 @@ class Icon:
point: np.ndarray, point: np.ndarray,
tags: dict[str, Any] = None, tags: dict[str, Any] = None,
outline: bool = False, outline: bool = False,
scale: float = 1, scale: float = 1.0,
) -> None: ) -> None:
""" """
Draw icon to SVG. Draw icon to SVG.
@ -362,6 +362,7 @@ class Icon:
:param point: 2D position of the icon centre :param point: 2D position of the icon centre
:param tags: tags to be displayed as a tooltip :param tags: tags to be displayed as a tooltip
:param outline: draw outline for the icon :param outline: draw outline for the icon
:param scale: scale icon by the magnitude
""" """
if outline: if outline:
bright: bool = is_bright(self.shape_specifications[0].color) 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.feature.direction import DirectionSet
from map_machine.map_configuration import MapConfiguration, LabelMode from map_machine.map_configuration import MapConfiguration, LabelMode
from map_machine.osm.osm_reader import Tags
from map_machine.pictogram.icon import ( from map_machine.pictogram.icon import (
DEFAULT_COLOR, DEFAULT_COLOR,
DEFAULT_SHAPE_ID, DEFAULT_SHAPE_ID,
@ -52,7 +53,7 @@ class MatchingType(Enum):
def is_matched_tag( def is_matched_tag(
matcher_tag_key: str, matcher_tag_key: str,
matcher_tag_value: Union[str, list], matcher_tag_value: Union[str, list],
tags: dict[str, str], tags: Tags,
) -> tuple[MatchingType, list[str]]: ) -> tuple[MatchingType, list[str]]:
""" """
Check whether element tags contradict tag matcher. Check whether element tags contradict tag matcher.
@ -107,7 +108,7 @@ class Matcher:
def __init__( def __init__(
self, structure: dict[str, Any], group: Optional[dict[str, Any]] = None self, structure: dict[str, Any], group: Optional[dict[str, Any]] = None
) -> None: ) -> None:
self.tags: dict[str, str] = structure["tags"] self.tags: Tags = structure["tags"]
self.exception: dict[str, str] = {} self.exception: dict[str, str] = {}
if "exception" in structure: if "exception" in structure:
@ -132,9 +133,7 @@ class Matcher:
) )
def is_matched( def is_matched(
self, self, tags: Tags, configuration: Optional[MapConfiguration] = None
tags: dict[str, str],
configuration: Optional[MapConfiguration] = None,
) -> tuple[bool, dict[str, str]]: ) -> tuple[bool, dict[str, str]]:
""" """
Check whether element tags matches tag matcher. Check whether element tags matches tag matcher.
@ -294,7 +293,7 @@ class RoadMatcher(Matcher):
if "priority" in structure: if "priority" in structure:
self.priority = structure["priority"] 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.""" """Get priority for drawing order."""
layer: float = 0 layer: float = 0
if "layer" in tags: if "layer" in tags:
@ -556,7 +555,7 @@ class Scheme:
return None return None
def construct_text( 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]: ) -> list[Label]:
"""Construct labels for not processed tags.""" """Construct labels for not processed tags."""
texts: list[Label] = construct_text(tags, processed, label_mode) texts: list[Label] = construct_text(tags, processed, label_mode)
@ -566,7 +565,7 @@ class Scheme:
texts.append(Label(tags[tag])) texts.append(Label(tags[tag]))
return texts 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.""" """Check whether way described by tags is area."""
for matcher in self.area_matchers: for matcher in self.area_matchers:
matching, _ = matcher.is_matched(tags) matching, _ = matcher.is_matched(tags)
@ -574,9 +573,7 @@ class Scheme:
return True return True
return False return False
def process_ignored( def process_ignored(self, tags: Tags, processed: set[str]) -> None:
self, tags: dict[str, str], processed: set[str]
) -> None:
""" """
Mark all ignored tag as processed. Mark all ignored tag as processed.

View file

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

View file

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

View file

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

View file

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