From 12e019c051dc1830148f0608c434bc3e43c92c51 Mon Sep 17 00:00:00 2001 From: Martin Genet <10851655+mrtgenet@users.noreply.github.com> Date: Wed, 28 Jan 2026 10:15:32 +0100 Subject: [PATCH 1/4] Update filename handling in InferableTypeStage for filespec --- src/pdal/pipeline.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/pdal/pipeline.py b/src/pdal/pipeline.py index 60a181c0..42ea251c 100644 --- a/src/pdal/pipeline.py +++ b/src/pdal/pipeline.py @@ -217,7 +217,10 @@ def __or__(self, other: Union[Stage, Pipeline]) -> Pipeline: class InferableTypeStage(Stage): def __init__(self, filename: Optional[str] = None, **options: Any): if filename: - options["filename"] = filename + if isinstance(filename, dict): + options["filename"] = filename.get("path") + else: + options["filename"] = filename super().__init__(**options) @property From 199b695731f8f233d073a5fef3e89c8179df2606 Mon Sep 17 00:00:00 2001 From: Martin Genet <10851655+mrtgenet@users.noreply.github.com> Date: Wed, 28 Jan 2026 15:31:23 +0100 Subject: [PATCH 2/4] Validate 'path' in filename for InferableTypeStage Raise ValueError if 'path' is missing in filename dict --- src/pdal/pipeline.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/pdal/pipeline.py b/src/pdal/pipeline.py index 42ea251c..f5b78bb6 100644 --- a/src/pdal/pipeline.py +++ b/src/pdal/pipeline.py @@ -218,7 +218,9 @@ class InferableTypeStage(Stage): def __init__(self, filename: Optional[str] = None, **options: Any): if filename: if isinstance(filename, dict): - options["filename"] = filename.get("path") + if "path" not in filename: + raise ValueError(f"'path' is missing in the provided filespec: {filename}") + options["filename"] = filename["path"] else: options["filename"] = filename super().__init__(**options) From 6a1583678520bf9e6ade9b11e7e73e2bcdc6cfa3 Mon Sep 17 00:00:00 2001 From: Martin Genet <10851655+mrtgenet@users.noreply.github.com> Date: Wed, 28 Jan 2026 16:12:50 +0100 Subject: [PATCH 3/4] Enhance tests for pdal.Reader and pdal.Writer types Added assertions to validate reader and writer types for filespec format. --- test/test_pipeline.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/test/test_pipeline.py b/test/test_pipeline.py index 46e0a18d..136150c6 100644 --- a/test/test_pipeline.py +++ b/test/test_pipeline.py @@ -3,7 +3,6 @@ import os import sys -from typing import List from itertools import product import numpy as np import pytest @@ -284,6 +283,12 @@ def test_infer_stage_type(self): assert pdal.Writer("foo.xxx").type == "" assert pdal.Reader().type == "" assert pdal.Writer().type == "" + assert pdal.Reader({"path": "foo.las"}).type == "readers.las" + assert pdal.Writer({"path": "foo.las"}).type == "writers.las" + assert pdal.Reader({"path": "foo.xxx"}).type == "" + assert pdal.Writer({"path": "foo.xxx"}).type == "" + assert pdal.Reader({}).type == "" + assert pdal.Writer({}).type == "" def test_streamable(self): """Can we distinguish streamable from non-streamable stages and pipeline""" From 26c1cd94696cf5186210fed990cae5ebc485fb95 Mon Sep 17 00:00:00 2001 From: Howard Butler Date: Wed, 8 Jul 2026 16:33:25 -0500 Subject: [PATCH 4/4] support and test full filespec definitions --- src/pdal/pipeline.py | 16 +++++++++++++--- test/test_pipeline.py | 7 +++++++ 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/src/pdal/pipeline.py b/src/pdal/pipeline.py index f5b78bb6..e00b8c2d 100644 --- a/src/pdal/pipeline.py +++ b/src/pdal/pipeline.py @@ -220,9 +220,11 @@ def __init__(self, filename: Optional[str] = None, **options: Any): if isinstance(filename, dict): if "path" not in filename: raise ValueError(f"'path' is missing in the provided filespec: {filename}") - options["filename"] = filename["path"] - else: options["filename"] = filename + + else: + filespec = {'path':str(filename)} + options["filename"] = filespec super().__init__(**options) @property @@ -231,7 +233,15 @@ def type(self) -> str: return super().type except KeyError: filename = self._options.get("filename") - return str(self._infer_type(filename) if filename else "") + if isinstance(filename, dict): + if "path" not in filename: + raise ValueError(f"'path' is missing in the provided filespec: {filename}") + path = filename.get('path') + else: + path = str(filename) + + + return str(self._infer_type(path) if filename else "") _infer_type = staticmethod(lambda filename: "") diff --git a/test/test_pipeline.py b/test/test_pipeline.py index 136150c6..8760b1b5 100644 --- a/test/test_pipeline.py +++ b/test/test_pipeline.py @@ -290,6 +290,13 @@ def test_infer_stage_type(self): assert pdal.Reader({}).type == "" assert pdal.Writer({}).type == "" + def test_filespec(self): + """Can transit filespecs""" + spec = {'path':'junk.las', 'headers':{'header1':'header_1', 'header2':'header_2'}, 'query':{'query1':'query_1', 'query2':'query_2'}} + assert pdal.Reader(spec).type == "readers.las" + assert pdal.Reader(spec).options['filename']['path'] == "junk.las" + assert pdal.Writer("foo.las").type == "writers.las" + def test_streamable(self): """Can we distinguish streamable from non-streamable stages and pipeline""" rs = pdal.Reader(type="readers.las", filename="foo")