Skip to content

Commit 90897c4

Browse files
committed
Support new 'X | None' union syntax in field types
1 parent 636c906 commit 90897c4

File tree

2 files changed

+22
-2
lines changed

2 files changed

+22
-2
lines changed

osc/util/models.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,15 @@ def get_origin(typ):
3939
else:
4040
from typing import get_origin
4141

42+
43+
# types.UnionType was added in Python 3.10
44+
if sys.version_info < (3, 10):
45+
class UnionType:
46+
pass
47+
else:
48+
from types import UnionType
49+
50+
4251
import urllib3.response
4352

4453
from . import xml
@@ -165,7 +174,7 @@ def inner_type(self):
165174
@property
166175
def is_optional(self):
167176
origin_type = get_origin(self.type) or self.type
168-
return origin_type == Union and len(self.type.__args__) == 2 and type(None) in self.type.__args__
177+
return origin_type in (Union, UnionType) and type(None) in self.type.__args__
169178

170179
@property
171180
def is_model(self):
@@ -193,7 +202,7 @@ def validate_type(self, value, expected_types=None):
193202
origin_type = get_origin(expected_type) or expected_type
194203

195204
# unwrap Union
196-
if origin_type == Union:
205+
if origin_type in (Union, UnionType):
197206
if value is None and type(None) in expected_type.__args__:
198207
valid_type = True
199208
continue

tests/test_models.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import sys
12
import unittest
23
from typing import Set
34

@@ -24,6 +25,16 @@ def test_bool(self):
2425

2526

2627
class Test(unittest.TestCase):
28+
@unittest.skipIf(sys.version_info[:2] < (3, 10), "added in python 3.10")
29+
def test_union_or(self):
30+
class TestModel(BaseModel):
31+
text: str | None = Field()
32+
33+
m = TestModel()
34+
self.assertEqual(m.dict(), {"text": None})
35+
36+
self.assertRaises(TypeError, setattr, m.text, 123)
37+
2738
def test_dict(self):
2839
class TestSubmodel(BaseModel):
2940
text: str = Field(default="default")

0 commit comments

Comments
 (0)