diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 38ac936..240c7b1 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -8,24 +8,20 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v1 + - uses: actions/checkout@v4 - name: Set up Python 3.13 - uses: actions/setup-python@v1 + uses: actions/setup-python@v5 with: - python-version: 3.13 + python-version: "3.13" - name: Install dependencies run: | python -m pip install --upgrade pip pip install networkx - pip install black codecov flake8 mypy pytest pytest-cov - - name: Lint with flake8 - run: | - # stop the build if there are Python syntax errors or undefined names - flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics - # exit-zero treats all errors as warnings. - flake8 . --count --exit-zero --max-complexity=10 --max-line-length=160 --statistics - - name: Install and run Black - run: black --check . + pip install ruff codecov mypy pytest pytest-cov + - name: Lint with ruff + run: ruff check . + - name: Check formatting with ruff + run: ruff format --check . - name: Typechecking with mypy run: mypy . --ignore-missing-imports - name: Test with pytest diff --git a/README.md b/README.md index ffb151f..9950f30 100644 --- a/README.md +++ b/README.md @@ -55,7 +55,7 @@ As an additional feature, and to make interaction easier, since version 0.5 OsmT - Python 3.13+/PyPy - An OSM XML file -- [Optional: [networkx](https://networkx.github.io/) as dependency: `pip3 install networkx`] +- Optional: [networkx](https://networkx.github.io/) — only required for the `--networkx` JSON output. Install it via the optional dependency: `pip3 install OsmToRoadGraph[networkx]` (or directly: `pip3 install networkx`). ### Older Versions diff --git a/examples/shortest-distances-drawing/shortest-distances-drawing.py b/examples/shortest-distances-drawing/shortest-distances-drawing.py index 5cadfb2..50379ee 100644 --- a/examples/shortest-distances-drawing/shortest-distances-drawing.py +++ b/examples/shortest-distances-drawing/shortest-distances-drawing.py @@ -98,10 +98,7 @@ def draw_graph_on_map(G, lengths, output_filename, width=1600, height=1200): # determine color distance = line_data[2] - if distance < float("inf"): - luminosity = round(float(distance) / float(max_distance) * 100.0, 0) - else: - luminosity = 100.0 + luminosity = round(float(distance) / float(max_distance) * 100.0, 0) if distance < float("inf") else 100.0 color = get_color(luminosity) @@ -163,10 +160,7 @@ def edge_length(_u, _v, data): sys.exit(-1) G = load_graph(args.in_filename) - if args.center: - start_node = find_approximate_central_node(G) - else: - start_node = random.choice(list(G)) + start_node = find_approximate_central_node(G) if args.center else random.choice(list(G)) metric = None if args.metric == "travel-time": diff --git a/graph/algorithms.py b/graph/algorithms.py index ea5fe85..755d6c2 100644 --- a/graph/algorithms.py +++ b/graph/algorithms.py @@ -35,7 +35,7 @@ def computeLCC(graph): # determine largest connected components lcc = max(found_nodes, key=len) - print(f"\t LCC contains {len(lcc)} nodes (removed { len(graph.vertices) - len(lcc)} nodes)") + print(f"\t LCC contains {len(lcc)} nodes (removed {len(graph.vertices) - len(lcc)} nodes)") return lcc diff --git a/osm/way_parser_helper.py b/osm/way_parser_helper.py index c0096b9..124a58f 100644 --- a/osm/way_parser_helper.py +++ b/osm/way_parser_helper.py @@ -17,10 +17,7 @@ def is_way_acceptable(self, way: OSMWay): if way.area == "yes": return False - if way.highway not in self.config.accepted_highways[self.config.network_type]: - return False - - return True + return way.highway in self.config.accepted_highways[self.config.network_type] def parse_direction(self, way): if way.direction == self.ONEWAY_STR: diff --git a/osm/xml_handler.py b/osm/xml_handler.py index b84da5e..2fcbd55 100644 --- a/osm/xml_handler.py +++ b/osm/xml_handler.py @@ -14,7 +14,9 @@ class PercentageFile: def __init__(self, filename: str) -> None: self.size = os.stat(filename)[6] self.delivered = 0 - self.f = open(filename, encoding="utf-8") + # the handle is owned for the lifetime of this wrapper and released + # in close(); a context manager does not fit this streaming use + self.f = open(filename, encoding="utf-8") # noqa: SIM115 self.percentages = [1000] + [100 - 10 * x for x in range(0, 11)] def read(self, size: Optional[int] = None) -> str: @@ -93,12 +95,11 @@ def startElement(self, name: str, attrs: AttributesImpl) -> None: elif attrs["k"] == "junction": if attrs["v"] == "roundabout": self.current_way.direction = "oneway" - elif attrs["k"] == "indoor": - # this is not an ideal solution since it sets the pedestrian flag irrespective of the real value in osm data - # but aims to cover the simple indoor tagging approach: https://wiki.openstreetmap.org/wiki/Simple_Indoor_Tagging - # more info: https://help.openstreetmap.org/questions/61025/pragmatic-single-level-indoor-paths - if attrs["v"] == "corridor": - self.current_way.highway = "pedestrian_indoor" + # this is not an ideal solution since it sets the pedestrian flag irrespective of the real value in osm data + # but aims to cover the simple indoor tagging approach: https://wiki.openstreetmap.org/wiki/Simple_Indoor_Tagging + # more info: https://help.openstreetmap.org/questions/61025/pragmatic-single-level-indoor-paths + elif attrs["k"] == "indoor" and attrs["v"] == "corridor": + self.current_way.highway = "pedestrian_indoor" except Exception as e: print(f"Error while parsing: {e}") diff --git a/pyproject.toml b/pyproject.toml index 537a562..89f08a0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -6,18 +6,20 @@ requires-python = ">=3.13" dependencies = [] [project.optional-dependencies] -dev = ["pytest"] -[tool.black] -line-length = 120 -target-version = ['py311'] - -[tool.ruff.lint] -select = ["I", "F", "SIM", "E", "A", "ARG", "B", "C4", "SIM", "TC", "RET", "TID", "Q"] -ignore = ["E501"] -fixable = ["ALL"] +networkx = ["networkx"] [dependency-groups] dev = [ - "black>=25.1.0", + "mypy", + "pytest", "ruff>=0.12.5", ] + +[tool.ruff] +line-length = 120 +target-version = "py313" + +[tool.ruff.lint] +select = ["I", "F", "SIM", "E", "A", "ARG", "B", "C4", "TC", "RET", "TID", "Q"] +ignore = ["E501"] +fixable = ["ALL"]