Skip to content

Commit 290054d

Browse files
authored
git - Merge pull request #107 from eumiro/modernize
Modernize code
2 parents 1f10a27 + c36c5fb commit 290054d

File tree

10 files changed

+69
-126
lines changed

10 files changed

+69
-126
lines changed

README.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ Install
3333

3434
Supported Python versions:
3535

36-
* Python >= 3.6.2
36+
* Python >= 3.7
3737
* PyPy3
3838

3939
**Install:**

docs/source/introduction.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ Requirements
66

77
Supported Python versions:
88

9-
* Python 3.6+
9+
* Python 3.7+
1010
* PyPy3
1111

1212
Installation

examples/get_nodes.py

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,9 @@
88
result = api.query(f"node({jet_deau}); out meta;")
99
node = result.get_node(jet_deau)
1010

11-
print(
12-
"The node for the famous Geneva {} ({},{}) was:".format(
13-
node.tags['name'],
14-
node.lat,
15-
node.lon
16-
)
17-
)
11+
print(f"The node for the famous Geneva {node.tags['name']} ({node.lat},{node.lon}) was:")
1812
attrs = node.attributes
1913

20-
print("* last modified {}".format(attrs['timestamp']))
21-
print("* by {} (uid: {})".format(attrs['user'], attrs['uid']))
22-
print("* in changeset {}".format(attrs['changeset']))
14+
print(f"* last modified {attrs['timestamp']}")
15+
print(f"* by {attrs['user']} (uid: {attrs['uid']})")
16+
print(f"* in changeset {attrs['changeset']}")

examples/get_ways.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@
1111
""")
1212

1313
for way in result.ways:
14-
print("Name: %s" % way.tags.get("name", "n/a"))
15-
print(" Highway: %s" % way.tags.get("highway", "n/a"))
14+
print(f"Name: {way.tags.get('name', 'n/a')}")
15+
print(f" Highway: {way.tags.get('highway', 'n/a')}")
1616
print(" Nodes:")
1717
for node in way.nodes:
1818
print(f" Lat: {node.lat:f}, Lon: {node.lon:f}")

overpy/__about__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,4 @@
1919
__email__ = ""
2020

2121
__license__ = "MIT"
22-
__copyright__ = "Copyright 2014-2023 %s" % __author__
22+
__copyright__ = f"Copyright 2014-2023 {__author__}"

overpy/__init__.py

Lines changed: 45 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
from collections import OrderedDict
21
from datetime import datetime
32
from decimal import Decimal
3+
from functools import partial
44
from urllib.request import urlopen
55
from urllib.error import HTTPError
66
from xml.sax import handler, make_parser
@@ -121,43 +121,31 @@ def query(self, query: Union[bytes, str]) -> "Result":
121121
if not isinstance(query, bytes):
122122
query = query.encode("utf-8")
123123

124-
retry_num: int = 0
125124
retry_exceptions: List[exception.OverPyException] = []
126-
do_retry: bool = True if self.max_retry_count > 0 else False
127-
while retry_num <= self.max_retry_count:
128-
if retry_num > 0:
125+
126+
for run in range(self.max_retry_count + 1):
127+
if run:
129128
time.sleep(self.retry_timeout)
130-
retry_num += 1
129+
130+
response = b""
131131
try:
132-
f = urlopen(self.url, query)
133-
except HTTPError as e:
134-
f = e
135-
136-
response = f.read(self.read_chunk_size)
137-
while True:
138-
data = f.read(self.read_chunk_size)
139-
if len(data) == 0:
140-
break
141-
response = response + data
142-
f.close()
132+
with urlopen(self.url, query) as f:
133+
f_read = partial(f.read, self.read_chunk_size)
134+
for data in iter(f_read, b""):
135+
response += data
136+
except HTTPError as exc:
137+
f = exc
143138

144139
current_exception: exception.OverPyException
145140
if f.code == 200:
146141
content_type = f.getheader("Content-Type")
147-
148142
if content_type == "application/json":
149143
return self.parse_json(response)
150-
151-
if content_type == "application/osm3s+xml":
144+
elif content_type == "application/osm3s+xml":
152145
return self.parse_xml(response)
153-
154-
current_exception = exception.OverpassUnknownContentType(content_type)
155-
if not do_retry:
156-
raise current_exception
157-
retry_exceptions.append(current_exception)
158-
continue
159-
160-
if f.code == 400:
146+
else:
147+
current_exception = exception.OverpassUnknownContentType(content_type)
148+
elif f.code == 400:
161149
msgs: List[str] = []
162150
for msg_raw in self._regex_extract_error_msg.finditer(response):
163151
msg_clean_bytes = self._regex_remove_tag.sub(b"", msg_raw.group("msg"))
@@ -166,37 +154,17 @@ def query(self, query: Union[bytes, str]) -> "Result":
166154
except UnicodeDecodeError:
167155
msg = repr(msg_clean_bytes)
168156
msgs.append(msg)
169-
170-
current_exception = exception.OverpassBadRequest(
171-
query,
172-
msgs=msgs
173-
)
174-
if not do_retry:
175-
raise current_exception
176-
retry_exceptions.append(current_exception)
177-
continue
178-
179-
if f.code == 429:
157+
current_exception = exception.OverpassBadRequest(query, msgs=msgs)
158+
elif f.code == 429:
180159
current_exception = exception.OverpassTooManyRequests()
181-
if not do_retry:
182-
raise current_exception
183-
retry_exceptions.append(current_exception)
184-
continue
185-
186-
if f.code == 504:
160+
elif f.code == 504:
187161
current_exception = exception.OverpassGatewayTimeout()
188-
if not do_retry:
189-
raise current_exception
190-
retry_exceptions.append(current_exception)
191-
continue
192-
193-
current_exception = exception.OverpassUnknownHTTPStatusCode(f.code)
194-
if not do_retry:
162+
else:
163+
current_exception = exception.OverpassUnknownHTTPStatusCode(f.code)
164+
if not self.max_retry_count:
195165
raise current_exception
196166
retry_exceptions.append(current_exception)
197-
continue
198-
199-
raise exception.MaxRetriesReached(retry_count=retry_num, exceptions=retry_exceptions)
167+
raise exception.MaxRetriesReached(retry_count=run + 1, exceptions=retry_exceptions)
200168

201169
def parse_json(self, data: Union[bytes, str], encoding: str = "utf-8") -> "Result":
202170
"""
@@ -250,18 +218,18 @@ def __init__(
250218
"""
251219
if elements is None:
252220
elements = []
253-
self._areas: Dict[int, Union["Area", "Node", "Relation", "Way"]] = OrderedDict(
254-
(element.id, element) for element in elements if is_valid_type(element, Area)
255-
)
256-
self._nodes = OrderedDict(
257-
(element.id, element) for element in elements if is_valid_type(element, Node)
258-
)
259-
self._ways = OrderedDict(
260-
(element.id, element) for element in elements if is_valid_type(element, Way)
261-
)
262-
self._relations = OrderedDict(
263-
(element.id, element) for element in elements if is_valid_type(element, Relation)
264-
)
221+
self._areas: Dict[int, Union["Area", "Node", "Relation", "Way"]] = {
222+
element.id: element for element in elements if is_valid_type(element, Area)
223+
}
224+
self._nodes = {
225+
element.id: element for element in elements if is_valid_type(element, Node)
226+
}
227+
self._ways = {
228+
element.id: element for element in elements if is_valid_type(element, Way)
229+
}
230+
self._relations = {
231+
element.id: element for element in elements if is_valid_type(element, Relation)
232+
}
265233
self._class_collection_map: Dict[Any, Any] = {
266234
Node: self._nodes,
267235
Way: self._ways,
@@ -438,12 +406,9 @@ def get_area(self, area_id: int, resolve_missing: bool = False) -> "Area":
438406

439407
query = ("\n"
440408
"[out:json];\n"
441-
"area({area_id});\n"
409+
f"area({area_id});\n"
442410
"out body;\n"
443411
)
444-
query = query.format(
445-
area_id=area_id
446-
)
447412
tmp_result = self.api.query(query)
448413
self.expand(tmp_result)
449414

@@ -480,12 +445,9 @@ def get_node(self, node_id: int, resolve_missing: bool = False) -> "Node":
480445

481446
query = ("\n"
482447
"[out:json];\n"
483-
"node({node_id});\n"
448+
f"node({node_id});\n"
484449
"out body;\n"
485450
)
486-
query = query.format(
487-
node_id=node_id
488-
)
489451
tmp_result = self.api.query(query)
490452
self.expand(tmp_result)
491453

@@ -523,12 +485,9 @@ def get_relation(self, rel_id: int, resolve_missing: bool = False) -> "Relation"
523485

524486
query = ("\n"
525487
"[out:json];\n"
526-
"relation({relation_id});\n"
488+
f"relation({rel_id});\n"
527489
"out body;\n"
528490
)
529-
query = query.format(
530-
relation_id=rel_id
531-
)
532491
tmp_result = self.api.query(query)
533492
self.expand(tmp_result)
534493

@@ -565,12 +524,9 @@ def get_way(self, way_id: int, resolve_missing: bool = False) -> "Way":
565524

566525
query = ("\n"
567526
"[out:json];\n"
568-
"way({way_id});\n"
527+
f"way({way_id});\n"
569528
"out body;\n"
570529
)
571-
query = query.format(
572-
way_id=way_id
573-
)
574530
tmp_result = self.api.query(query)
575531
self.expand(tmp_result)
576532

@@ -950,13 +906,10 @@ def get_nodes(self, resolve_missing: bool = False) -> List[Node]:
950906

951907
query = ("\n"
952908
"[out:json];\n"
953-
"way({way_id});\n"
909+
f"way({self.id});\n"
954910
"node(w);\n"
955911
"out body;\n"
956912
)
957-
query = query.format(
958-
way_id=self.id
959-
)
960913
tmp_result = self._result.api.query(query)
961914
self._result.expand(tmp_result)
962915
resolved = True
@@ -1423,9 +1376,9 @@ def startElement(self, name: str, attrs: dict):
14231376
if name in self.ignore_start:
14241377
return
14251378
try:
1426-
handler = getattr(self, '_handle_start_%s' % name)
1379+
handler = getattr(self, f"_handle_start_{name}")
14271380
except AttributeError:
1428-
raise KeyError("Unknown element start '%s'" % name)
1381+
raise KeyError(f"Unknown element start {name!r}")
14291382
handler(attrs)
14301383

14311384
def endElement(self, name: str):
@@ -1437,9 +1390,9 @@ def endElement(self, name: str):
14371390
if name in self.ignore_end:
14381391
return
14391392
try:
1440-
handler = getattr(self, '_handle_end_%s' % name)
1393+
handler = getattr(self, f"_handle_end_{name}")
14411394
except AttributeError:
1442-
raise KeyError("Unknown element end '%s'" % name)
1395+
raise KeyError(f"Unknown element end {name!r}")
14431396
handler()
14441397

14451398
def _handle_start_center(self, attrs: dict):
@@ -1617,7 +1570,7 @@ def _handle_start_member(self, attrs: dict):
16171570
}
16181571
cls: Type[RelationMember] = cls_map.get(attrs["type"])
16191572
if cls is None:
1620-
raise ValueError("Undefined type for member: '%s'" % attrs['type'])
1573+
raise ValueError(f"Undefined type for member: {attrs['type']!r}")
16211574

16221575
self.cur_relation_member = cls(**params)
16231576
self._curr['members'].append(self.cur_relation_member)

overpy/exception.py

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,7 @@ def __init__(self, type_expected, type_provided=None):
3131
self.type_provided = type_provided
3232

3333
def __str__(self) -> str:
34-
return "Type expected '{}' but '{}' provided".format(
35-
self.type_expected,
36-
str(self.type_provided)
37-
)
34+
return f"Type expected {self.type_expected!r} but {self.type_provided!r} provided"
3835

3936

4037
class MaxRetriesReached(OverPyException):
@@ -46,7 +43,7 @@ def __init__(self, retry_count, exceptions):
4643
self.retry_count = retry_count
4744

4845
def __str__(self) -> str:
49-
return "Unable get any result from the Overpass API server after %d retries." % self.retry_count
46+
return f"Unable get any result from the Overpass API server after {self.retry_count} retries."
5047

5148

5249
class OverpassBadRequest(OverPyException):
@@ -142,7 +139,7 @@ def __init__(self, content_type):
142139
def __str__(self) -> str:
143140
if self.content_type is None:
144141
return "No content type returned"
145-
return "Unknown content type: %s" % self.content_type
142+
return f"Unknown content type: {self.content_type}"
146143

147144

148145
class OverpassUnknownError(OverpassError):
@@ -163,4 +160,4 @@ def __init__(self, code):
163160
self.code = code
164161

165162
def __str__(self) -> str:
166-
return "Unknown/Unhandled status code: %d" % self.code
163+
return f"Unknown/Unhandled status code: {self.code}"

overpy/helper.py

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,10 @@ def get_street(
2020
if api is None:
2121
api = overpy.Overpass()
2222

23-
query = """
24-
area(%s)->.location;
23+
query = f"""
24+
area({areacode})->.location;
2525
(
26-
way[highway][name="%s"](area.location);
26+
way[highway][name="{street}"](area.location);
2727
- (
2828
way[highway=service](area.location);
2929
way[highway=track](area.location);
@@ -34,7 +34,7 @@ def get_street(
3434
out skel qt;
3535
"""
3636

37-
data = api.query(query % (areacode, street))
37+
data = api.query(query)
3838

3939
return data
4040

@@ -57,16 +57,16 @@ def get_intersection(
5757
if api is None:
5858
api = overpy.Overpass()
5959

60-
query = """
61-
area(%s)->.location;
60+
query = f"""
61+
area({areacode}->.location;
6262
(
63-
way[highway][name="%s"](area.location); node(w)->.n1;
64-
way[highway][name="%s"](area.location); node(w)->.n2;
63+
way[highway][name="{street1}"](area.location); node(w)->.n1;
64+
way[highway][name="{street2}"](area.location); node(w)->.n2;
6565
);
6666
node.n1.n2;
6767
out meta;
6868
"""
6969

70-
data = api.query(query % (areacode, street1, street2))
70+
data = api.query(query)
7171

7272
return data.get_nodes()

setup.cfg

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ classifiers =
88
Operating System :: OS Independent
99
Programming Language :: Python
1010
Programming Language :: Python :: 3
11-
Programming Language :: Python :: 3.6
1211
Programming Language :: Python :: 3.7
1312
Programming Language :: Python :: 3.8
1413
Programming Language :: Python :: 3.9
@@ -20,7 +19,7 @@ project_urls =
2019
Issue Tracker = https://github.com/DinoTools/python-overpy/issues
2120

2221
[options]
23-
python_requires = >=3.6
22+
python_requires = >=3.7
2423
include_package_data = true
2524
zip_safe = false
2625

0 commit comments

Comments
 (0)