Repository: abey79/vpype

Issue:
`write` command: cannot infer page size when it should in HPGL mode
```
$ vpype rect 0 0 10cm 2cm layout a4 write -f hpgl -
ERROR:root:write: the plotter page size could not be inferred from the current page size (use the `--page-size SIZE` option)
```
`write` command: cannot infer page size when it should in HPGL mode
```
$ vpype rect 0 0 10cm 2cm layout a4 write -f hpgl -
ERROR:root:write: the plotter page size could not be inferred from the current page size (use the `--page-size SIZE` option)
```


Discussion:
Issue: the logic in `_get_hpgl_config()` (io.py) should be moved to `get_plotter_config()` (in config.py), to benefit the write command implementation.


Issue: the logic in `_get_hpgl_config()` (io.py) should be moved to `get_plotter_config()` (in config.py), to benefit the write command implementation.



Resolving patch:
diff --git a/vpype/config.py b/vpype/config.py
--- a/vpype/config.py
+++ b/vpype/config.py
@@ -203,18 +203,24 @@ def get_plotter_list(self) -> List[str]:
         """
         return list(self.config.get("device", {}).keys())
 
-    def get_plotter_config(self, name: Optional[str]) -> Optional[PlotterConfig]:
-        """Returns a :class:`PlotterConfig` instance for plotter ``name``.
+    def get_plotter_config(self, device: Optional[str]) -> Optional[PlotterConfig]:
+        """Returns a :class:`PlotterConfig` instance for plotter ``device``.
+
+        If ``None`` is passed, this function attempts to use the default device if one is
+        configured, or the function returns None.
 
         Args:
-            name: name of desired plotter (may be ``None``, in which case ``None`` is returned)
+            device: name of desired plotter (or ``None`` to use the default device if
+                configured)
 
         Returns:
             :class:`PlotterConfig` instance or None if not found
         """
         devices = self.config.get("device", {})
-        if name in devices:
-            return PlotterConfig.from_config(devices[name])
+        if device is None:
+            device = self.get_command_config("write").get("default_hpgl_device", None)
+        if device in devices:
+            return PlotterConfig.from_config(devices[device])
         else:
             return None
 
diff --git a/vpype/io.py b/vpype/io.py
--- a/vpype/io.py
+++ b/vpype/io.py
@@ -472,9 +472,7 @@ def write_svg(
 def _get_hpgl_config(
     device: Optional[str], page_size: str
 ) -> Tuple[PlotterConfig, PaperConfig]:
-    if device is None:
-        device = config_manager.get_command_config("write").get("default_hpgl_device", None)
-    plotter_config = config_manager.get_plotter_config(str(device))
+    plotter_config = config_manager.get_plotter_config(device)
     if plotter_config is None:
         raise ValueError(f"no configuration available for plotter '{device}'")
     paper_config = plotter_config.paper_config(page_size)


Test patch:
diff --git a/tests/test_hpgl.py b/tests/test_hpgl.py
--- a/tests/test_hpgl.py
+++ b/tests/test_hpgl.py
@@ -312,6 +312,21 @@ def test_hpgl_paper_size_inference(runner):
     )
 
 
+def test_hpgl_paper_size_inference_default_device(runner, tmp_path):
+    config_file = tmp_path / "config.toml"
+    config_file.write_text("[command.write]\ndefault_hpgl_device = 'hp7475a'\n")
+
+    res = runner.invoke(
+        cli, f"-c '{config_file}' rect 5cm 5cm 5cm 5cm pagesize a4 write --absolute -f hpgl -"
+    )
+
+    assert res.exit_code == 0
+    assert res.stdout.strip() == (
+        "IN;DF;PS4;SP1;PU1608,1849;PD3617,1849,3617,3859,1608,3859,1608,1849;PU11040,7721;"
+        "SP0;IN;"
+    )
+
+
 def test_hpgl_paper_size_inference_fail(runner):
     res = runner.invoke(cli, "rect 5cm 5cm 5cm 5cm pagesize a6 write -f hpgl -d hp7475a -")
 
@@ -350,3 +365,25 @@ def test_hpgl_wrong_ref(simple_printer_config):
             page_size="wrong_ref",
             velocity=None,
         )
+
+
+def test_hpgl_config_manager(config_manager, simple_printer_config, config_file_factory):
+    config_manager.load_config_file(simple_printer_config)
+
+    # WITHOUT DEFAULT CONFIG
+    assert config_manager.get_plotter_config("simple") is not None
+    assert config_manager.get_plotter_config(None) is None
+    assert config_manager.get_plotter_config("doesntexist") is None
+
+    # WITH DEFAULT CONFIG
+    default_device_config = config_file_factory(
+        """
+        [command.write]
+        default_hpgl_device = "simple"
+        """
+    )
+    config_manager.load_config_file(default_device_config)
+
+    assert config_manager.get_plotter_config("simple") is not None
+    assert config_manager.get_plotter_config(None) is not None
+    assert config_manager.get_plotter_config("doesntexist") is None