Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions LOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# LOG

## 2026-06-09 — v0.2.2 — validazione upfront target in `batch`

- `batch`: check immediato che `--to` sia un target valido per `--from`; fallisce prima di leggere il CSV con messaggio chiaro (`Run 'openverto targets <from>'`).
- 2 nuovi test offline (`test_batch_rejects_invalid_target`, `test_batch_accepts_valid_target_combination`).

## 2026-06-09 — docs: disclaimer non-affiliazione + nota Z/M planimetrica

- Spunti da `sag1687/geobridge` (plugin QGIS per lo stesso servizio IGM): aggiunti due punti che mancavano.
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "openverto"
version = "0.2.1"
version = "0.2.2"
description = "Python CLI and library for the official IGM Verto Online coordinate transforms between Italian reference systems"
readme = "README.md"
authors = [
Expand Down
10 changes: 10 additions & 0 deletions src/openverto/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -396,6 +396,16 @@ def batch(
"""
in_e = _parse_epsg(from_epsg)
out_e = _parse_epsg(to_epsg)
try:
valid_targets = lib_targets(in_e)
Comment thread
Copilot marked this conversation as resolved.
Outdated
except KeyError:
_die(f"EPSG {in_e} is not IGM-supported; run 'openverto systems'", EXIT_NOT_FOUND)
if out_e not in {r["epsg"] for r in valid_targets}:
Comment on lines +399 to +403

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Potentially-unbound variable visible to static analysis

valid_targets is only assigned inside the try block. If KeyError is raised and _die is called, execution never reaches the if statement below — but _die is typed -> None, not -> NoReturn. Static type checkers (mypy/pyright) will therefore report valid_targets as possibly unbound on the next line, and any future change to _die that makes it return normally (e.g. for testing) would produce a NameError. Annotating _die as -> NoReturn (or restructuring with an else block) is the minimal fix.

Fix in Claude Code

_die(
f"EPSG {out_e} is not a valid target for EPSG {in_e}. "
f"Run 'openverto targets {in_e}' to see valid options.",
EXIT_USAGE,
)
if fmt not in ("csv", "geojson"):
_die(f"--format must be 'csv' or 'geojson', got {fmt!r}", EXIT_USAGE)
try:
Expand Down
42 changes: 42 additions & 0 deletions tests/test_offline.py
Original file line number Diff line number Diff line change
Expand Up @@ -159,3 +159,45 @@ def test_resolve_column_by_alias_and_missing():
assert resolve_column(header, "nord", ["n"]) == 2 # explicit name
with pytest.raises(ValueError):
resolve_column(header, "manca", E_ALIASES)


def test_batch_rejects_invalid_target(tmp_path):
"""batch must fail upfront when --to is not a valid target for --from."""
from typer.testing import CliRunner

from openverto.cli import app

p = tmp_path / "coords.csv"
p.write_text("lon,lat\n12.0,41.0\n", encoding="utf-8")

runner = CliRunner()
result = runner.invoke(app, ["batch", str(p), "--from", "23033", "--to", "32633"])
normalized = " ".join(result.output.split())
assert result.exit_code != 0
assert "32633" in normalized
assert "23033" in normalized
assert "targets 23033" in normalized


def test_batch_accepts_valid_target_combination(tmp_path, monkeypatch):
"""batch must pass the target check for a known-valid from/to pair."""
import openverto.transform as convmod

def fake_post(body):
return {
"stato": "successo",
"coordinate": [{"e": c["e"] + 0.001, "n": c["n"] + 0.002} for c in body["coordinate"]],
}

monkeypatch.setattr(convmod, "post", fake_post)

from typer.testing import CliRunner

from openverto.cli import app

p = tmp_path / "coords.csv"
p.write_text("lon,lat\n290000.0,4640000.0\n", encoding="utf-8")

runner = CliRunner()
result = runner.invoke(app, ["batch", str(p), "--from", "23033", "--to", "6706"])
assert result.exit_code == 0
Loading