Repository: rogiervandergeer/pydargs (language: python)

Issue:
Decide whether to support `pydantic.BaseModel`



Discussion / hints:

Fix patch:
diff --git a/README.md b/README.md
index 84d8b76..39d8c08 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
 # pydargs
 
-Pydargs allows configuring a dataclass through command line arguments.
+Pydargs allows configuring a (Pydantic) dataclass through command line arguments.
 
 ## Installation
 
diff --git a/pyproject.toml b/pyproject.toml
index 9e2bb31..804c2a8 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -29,6 +29,7 @@ dynamic = ["version"]
 
 [project.optional-dependencies]
 dev = ["mypy==1.6.1", "pre-commit==3.5.0", "ruff==0.1.5", "pytest==7.4.3"]
+pydantic = ["pydantic>=2.0"]
 
 [project.urls]
 Repository = "https://github.com/rogiervandergeer/pydargs"


Test patch:
diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml
index 292abaf..6214571 100644
--- a/.github/workflows/test.yaml
+++ b/.github/workflows/test.yaml
@@ -25,7 +25,7 @@ jobs:
 
       - name: Install Dependencies
         run: |
-          pip3 install -e ".[dev]"
+          pip3 install ".[dev,pydantic]"
 
       - name: Run pre-commit
         run: pre-commit run --all-files
diff --git a/tests/test_pydantic.py b/tests/test_pydantic.py
new file mode 100644
index 0000000..e1a7645
--- /dev/null
+++ b/tests/test_pydantic.py
@@ -0,0 +1,44 @@
+from dataclasses import field
+
+from pydargs import parse
+from pytest import approx, importorskip, fixture, raises
+
+pydantic = importorskip("pydantic")
+
+
+class TestPydanticDataclass:
+    @fixture
+    def config(self):
+        @pydantic.dataclasses.dataclass
+        class Config:
+            a: int = field(metadata=dict(positional=True))
+            b: str
+            c: float = 1.0
+            d: int = 4
+            e: str = field(metadata=dict(positional=True), default="e")
+            f: int = field(default_factory=lambda: 1)
+
+            @pydantic.field_validator("c")
+            @classmethod
+            def validate_c_is_positive(cls, v: float) -> float:
+                if v <= 0:
+                    raise ValueError("c must be positive")
+                return v
+
+        return Config
+
+    def test_instantiate(self, config):
+        c = parse(config, ["1", "--b", "b"])
+        assert c.a == 1
+        assert c.b == "b"
+        assert c.c == 1.0
+        assert c.d == 4
+        assert c.e == "e"
+        assert c.f == 1
+
+    def test_validation(self, config):
+        c = parse(config, ["1", "--b", "b", "--c", "1.5"])
+        assert c.c == approx(1.5)
+
+        with raises(pydantic.ValidationError):
+            parse(config, ["1", "--b", "b", "--c", "-1.5"])