1# DO NOT EDIT, GENERATED FILE

2 from __future__ import annotations

3

4 import typing

5 from typing import Any, Optional, Union

6

7 import pytest

8

9 from muutils.validate_type import IncorrectTypeException, validate_type

10

11

12# Tests for basic types and common use cases

13@pytest.mark.parametrize(

14 "value, expected_type, expected_result",

15 [

16 (42, int, True),

17 (3.14, float, True),

18 (5, int, True),

19 (5.0, int, False),

20 ("hello", str, True),

21 (True, bool, True),

22 (None, type(None), True),

23 (None, int, False),

24 ([1, 2, 3], list, True),

25 ([1, 2, 3], list, True),

26 ({"a": 1, "b": 2}, dict, True),

27 ({"a": 1, "b": 2}, dict, True),

28 ({1, 2, 3}, set, True),

29 ({1, 2, 3}, set, True),

30 ((1, 2, 3), tuple, True),

31 ((1, 2, 3), tuple, True),

32 (b"bytes", bytes, True),

33 (b"bytes", str, False),

34 ("3.14", float, False),

35 ("hello", Any, True),

36 (5, Any, True),

37 (3.14, Any, True),

38 # ints

39 (int(0), int, True),

40 (int(1), int, True),

41 (int(-1), int, True),

42 # bools

43 (True, bool, True),

44 (False, bool, True),

45 ],

46)

47 def test_validate_type_basic(value, expected_type, expected_result):

48 try:

49 assert validate_type(value, expected_type) == expected_result

50 except Exception as e:

51 raise Exception(

52 f"{value = }, {expected_type = }, {expected_result = }, {e}"

53 ) from e

54

55

56@pytest.mark.parametrize(

57 "value",

58 [

59 42,

60 "hello",

61 3.14,

62 True,

63 None,

64 [1, 2, 3],

65 {"a": 1, "b": 2},

66 {1, 2, 3},

67 (1, 2, 3),

68 b"bytes",

69 "3.14",

70 ],

71)

72 def test_validate_type_any(value):

73 try:

74 assert validate_type(value, Any)

75 except Exception as e:

76 raise Exception(f"{value = }, expected `Any`, {e}") from e

77

78

79@pytest.mark.parametrize(

80 "value, expected_type, expected_result",

81 [

82 (42, Union[int, str], True),

83 ("hello", Union[int, str], True),

84 (3.14, Union[int, float], True),

85 (True, Union[int, str], True),

86 (None, Union[int, type(None)], True),

87 (None, Union[int, str], False),

88 (5, Union[int, str], True),

89 (5.0, Union[int, str], False),

90 ("hello", Union[int, str], True),

91 (5, typing.Union[int, str], True),

92 ("hello", typing.Union[int, str], True),

93 (5.0, typing.Union[int, str], False),

94 (5, Union[int, str], True),

95 ("hello", Union[int, str], True),

96 (5.0, Union[int, str], False),

97 ],

98)

99 def test_validate_type_union(value, expected_type, expected_result):

100 try:

101 assert validate_type(value, expected_type) == expected_result

102 except Exception as e:

103 raise Exception(

104 f"{value = }, {expected_type = }, {expected_result = }, {e}"

105 ) from e

106

107

108@pytest.mark.parametrize(

109 "value, expected_type, expected_result",

110 [

111 (42, Optional[int], True),

112 ("hello", Optional[int], False),

113 (3.14, Optional[int], False),

114 ([1], Optional[list[int]], True),

115 (None, Optional[int], True),

116 (None, Optional[str], True),

117 (None, Optional[int], True),

118 (None, Optional[None], True),

119 (None, Optional[list[dict[str, int]]], True),

120 ],

121)

122 def test_validate_type_optional(value, expected_type, expected_result):

123 try:

124 assert validate_type(value, expected_type) == expected_result

125 except Exception as e:

126 raise Exception(

127 f"{value = }, {expected_type = }, {expected_result = }, {e}"

128 ) from e

129

130

131@pytest.mark.parametrize(

132 "value, expected_type, expected_result",

133 [

134 (42, list[int], False),

135 ([1, 2, 3], list[int], True),

136 ([1, 2, 3], list[str], False),

137 (["a", "b", "c"], list[str], True),

138 ([1, "a", 3], list[int], False),

139 (42, list[int], False),

140 ([1, 2, 3], list[int], True),

141 ([1, "2", 3], list[int], False),

142 ],

143)

144 def test_validate_type_list(value, expected_type, expected_result):

145 try:

146 assert validate_type(value, expected_type) == expected_result

147 except Exception as e:

148 raise Exception(

149 f"{value = }, {expected_type = }, {expected_result = }, {e}"

150 ) from e

151

152

153@pytest.mark.parametrize(

154 "value, expected_type, expected_result",

155 [

156 (42, dict[str, int], False),

157 ({"a": 1, "b": 2}, dict[str, int], True),

158 ({"a": 1, "b": 2}, dict[int, str], False),

159 (42, dict[str, int], False),

160 ({"a": 1, "b": 2}, dict[str, int], True),

161 ({"a": 1, "b": 2}, dict[int, str], False),

162 ({1: "a", 2: "b"}, dict[int, str], True),

163 ({1: "a", 2: "b"}, dict[str, int], False),

164 ({"a": 1, "b": "c"}, dict[str, int], False),

165 ([("a", 1), ("b", 2)], dict[str, int], False),

166 ({"key": "value"}, dict[str, str], True),

167 ({"key": 2}, dict[str, str], False),

168 ({"key": 2}, dict[str, int], True),

169 ({"key": 2.0}, dict[str, int], False),

170 ({"a": 1, "b": 2}, dict[str, int], True),

171 ({"a": 1, "b": "2"}, dict[str, int], False),

172 ],

173)

174 def test_validate_type_dict(value, expected_type, expected_result):

175 try:

176 assert validate_type(value, expected_type) == expected_result

177 except Exception as e:

178 raise Exception(

179 f"{value = }, {expected_type = }, {expected_result = }, {e}"

180 ) from e

181

182

183@pytest.mark.parametrize(

184 "value, expected_type, expected_result",

185 [

186 (42, set[int], False),

187 ({1, 2, 3}, set[int], True),

188 (42, set[int], False),

189 ({1, 2, 3}, set[int], True),

190 ({1, 2, 3}, set[str], False),

191 ({"a", "b", "c"}, set[str], True),

192 ({1, "a", 3}, set[int], False),

193 (42, set[int], False),

194 ({1, 2, 3}, set[int], True),

195 ({1, "2", 3}, set[int], False),

196 ([1, 2, 3], set[int], False),

197 ("hello", set[str], False),

198 ],

199)

200 def test_validate_type_set(value, expected_type, expected_result):

201 try:

202 assert validate_type(value, expected_type) == expected_result

203 except Exception as e:

204 raise Exception(

205 f"{value = }, {expected_type = }, {expected_result = }, {e}"

206 ) from e

207

208

209@pytest.mark.parametrize(

210 "value, expected_type, expected_result",

211 [

212 (42, tuple[int, str], False),

213 ((1, "a"), tuple[int, str], True),

214 (42, tuple[int, str], False),

215 ((1, "a"), tuple[int, str], True),

216 ((1, 2), tuple[int, str], False),

217 ((1, 2), tuple[int, int], True),

218 ((1, 2, 3), tuple[int, int], False),

219 ((1, "a", 3.14), tuple[int, str, float], True),

220 (("a", "b", "c"), tuple[str, str, str], True),

221 ((1, "a", 3.14), tuple[int, str], False),

222 ((1, "a", 3.14), tuple[int, str, float], True),

223 ([1, "a", 3.14], tuple[int, str, float], False),

224 (

225 (1, "a", 3.14, "b", True, None, (1, 2, 3)),

226 # no idea why this throws type error, only locally, and only for the generated modern types

227 tuple[ # type: ignore[misc]

228 int, str, float, str, bool, type(None), tuple[int, int, int]

229 ],

230 True,

231 ),

232 ],

233)

234 def test_validate_type_tuple(value, expected_type, expected_result):

235 try:

236 assert validate_type(value, expected_type) == expected_result

237 except Exception as e:

238 raise Exception(

239 f"{value = }, {expected_type = }, {expected_result = }, {e}"

240 ) from e

241

242

243@pytest.mark.parametrize(

244 "value, expected_type",

245 [

246 (43, typing.Callable),

247 (lambda x: x, typing.Callable),

248 (42, typing.Callable[[], None]),

249 (42, typing.Callable[[int, str], list]),

250 ],

251)

252 def test_validate_type_unsupported_type_hint(value, expected_type):

253 with pytest.raises(NotImplementedError):

254 validate_type(value, expected_type)

255 print(f"Failed to except: {value = }, {expected_type = }")

256

257

258@pytest.mark.parametrize(

259 "value, expected_type, expected_result",

260 [

261 ([1, 2, 3], list[int], True),

262 (["a", "b", "c"], list[str], True),

263 ([1, "a", 3], list[int], False),

264 ([1, 2, [3, 4]], list[Union[int, list[int]]], True),

265 ([(1, 2), (3, 4)], list[tuple[int, int]], True),

266 ([(1, 2), (3, "4")], list[tuple[int, int]], False),

267 ({1: [1, 2], 2: [3, 4]}, dict[int, list[int]], True),

268 ({1: [1, 2], 2: [3, "4"]}, dict[int, list[int]], False),

269 ],

270)

271 def test_validate_type_collections(value, expected_type, expected_result):

272 try:

273 assert validate_type(value, expected_type) == expected_result

274 except Exception as e:

275 raise Exception(

276 f"{value = }, {expected_type = }, {expected_result = }, {e}"

277 ) from e

278

279

280@pytest.mark.parametrize(

281 "value, expected_type, expected_result",

282 [

283 # empty lists

284 ([], list[int], True),

285 ([], list[dict], True),

286 (

287 [],

288 list[tuple[dict[tuple, str], str, None]],

289 True,

290 ),

291 # empty dicts

292 ({}, dict[str, int], True),

293 ({}, dict[str, dict], True),

294 ({}, dict[str, dict[str, int]], True),

295 ({}, dict[str, dict[str, int]], True),

296 # empty sets

297 (set(), set[int], True),

298 (set(), set[dict], True),

299 (

300 set(),

301 set[tuple[dict[tuple, str], str, None]],

302 True,

303 ),

304 # empty tuple

305 (tuple(), tuple, True),

306 # empty string

307 ("", str, True),

308 # empty bytes

309 (b"", bytes, True),

310 # None

311 (None, type(None), True),

312 # bools are ints, ints are not floats

313 (True, int, True),

314 (False, int, True),

315 (True, float, False),

316 (False, float, False),

317 (1, int, True),

318 (0, int, True),

319 (1, float, False),

320 (0, float, False),

321 (0, bool, False),

322 (1, bool, False),

323 # weird floats

324 (float("nan"), float, True),

325 (float("inf"), float, True),

326 (float("-inf"), float, True),

327 (float(0), float, True),

328 # list/tuple

329 ([1], tuple[int, int], False),

330 ((1, 2), list[int], False),

331 ],

332)

333 def test_validate_type_edge_cases(value, expected_type, expected_result):

334 try:

335 assert validate_type(value, expected_type) == expected_result

336 except Exception as e:

337 raise Exception(

338 f"{value = }, {expected_type = }, {expected_result = }, {e}"

339 ) from e

340

341

342@pytest.mark.parametrize(

343 "value, expected_type, expected_result",

344 [

345 (42, list[int], False),

346 ([1, 2, 3], int, False),

347 (3.14, tuple[float], False),

348 (3.14, tuple[float, float], False),

349 (3.14, tuple[bool, str], False),

350 (False, tuple[bool, str], False),

351 (False, tuple[bool], False),

352 ((False,), tuple[bool], True),

353 (("abc",), tuple[str], True),

354 ("test-dict", dict[str, int], False),

355 ("test-dict", dict, False),

356 ],

357)

358 def test_validate_type_wrong_type(value, expected_type, expected_result):

359 try:

360 assert validate_type(value, expected_type) == expected_result

361 except Exception as e:

362 raise Exception(

363 f"{value = }, {expected_type = }, {expected_result = }, {e}"

364 ) from e

365

366

367 def test_validate_type_complex():

368 assert validate_type([1, 2, [3, 4]], list[Union[int, list[int]]])

369 assert validate_type(

370 {"a": 1, "b": {"c": 2}}, dict[str, Union[int, dict[str, int]]]

371 )

372 assert validate_type({1, (2, 3)}, set[Union[int, tuple[int, int]]])

373 assert validate_type((1, ("a", "b")), tuple[int, tuple[str, str]])

374 assert validate_type([{"key": "value"}], list[dict[str, str]])

375 assert validate_type([{"key": 2}], list[dict[str, str]]) is False

376 assert validate_type([[1, 2], [3, 4]], list[list[int]])

377 assert validate_type([[1, 2], [3, "4"]], list[list[int]]) is False

378 assert validate_type([(1, 2), (3, 4)], list[tuple[int, int]])

379 assert (

380 validate_type([(1, 2), (3, "4")], list[tuple[int, int]]) is False

381 )

382 assert validate_type({1: "one", 2: "two"}, dict[int, str])

383 assert validate_type({1: "one", 2: 2}, dict[int, str]) is False

384 assert validate_type([(1, "one"), (2, "two")], list[tuple[int, str]])

385 assert (

386 validate_type([(1, "one"), (2, 2)], list[tuple[int, str]])

387 is False

388 )

389 assert validate_type({1: [1, 2], 2: [3, 4]}, dict[int, list[int]])

390 assert (

391 validate_type({1: [1, 2], 2: [3, "4"]}, dict[int, list[int]])

392 is False

393 )

394 assert validate_type([(1, "a"), (2, "b")], list[tuple[int, str]])

395 assert (

396 validate_type([(1, "a"), (2, 2)], list[tuple[int, str]]) is False

397 )

398

399

400@pytest.mark.parametrize(

401 "value, expected_type, expected_result",

402 [

403 ([[[[1]]]], list[list[list[list[int]]]], True),

404 ([[[[1]]]], list[list[list[list[str]]]], False),

405 (

406 {"a": {"b": {"c": 1}}},

407 dict[str, dict[str, dict[str, int]]],

408 True,

409 ),

410 (

411 {"a": {"b": {"c": 1}}},

412 dict[str, dict[str, dict[str, str]]],

413 False,

414 ),

415 ({1, 2, 3}, set[int], True),

416 ({1, 2, 3}, set[str], False),

417 (

418 ((1, 2), (3, 4)),

419 tuple[tuple[int, int], tuple[int, int]],

420 True,

421 ),

422 (

423 ((1, 2), (3, 4)),

424 tuple[tuple[int, int], tuple[int, str]],

425 False,

426 ),

427 ],

428)

429 def test_validate_type_nested(value, expected_type, expected_result):

430 try:

431 assert validate_type(value, expected_type) == expected_result

432 except Exception as e:

433 raise Exception(

434 f"{value = }, {expected_type = }, {expected_result = }, {e}"

435 ) from e

436

437

438 def test_validate_type_inheritance():

439 class Parent:

440 def __init__(self, a: int, b: str):

441 self.a: int = a

442 self.b: str = b

443

444 class Child(Parent):

445 def __init__(self, a: int, b: str):

446 self.a: int = 2 * a

447 self.b: str = b

448

449 assert validate_type(Parent(1, "a"), Parent)

450 validate_type(Child(1, "a"), Parent, do_except=True)

451 assert validate_type(Child(1, "a"), Child)

452 assert not validate_type(Parent(1, "a"), Child)

453

454 with pytest.raises(IncorrectTypeException):

455 validate_type(Parent(1, "a"), Child, do_except=True)

456

457

458 def test_validate_type_class():

459 class Parent:

460 def __init__(self, a: int, b: str):

461 self.a: int = a

462 self.b: str = b

463

464 class Child(Parent):

465 def __init__(self, a: int, b: str):

466 self.a: int = 2 * a

467 self.b: str = b

468

469 assert validate_type(Parent, type)

470 assert validate_type(Child, type)

471 assert validate_type(Parent, typing.Type[Parent], do_except=True)

472 assert validate_type(Child, typing.Type[Child])

473 assert not validate_type(Parent, typing.Type[Child])

474

475 assert validate_type(Child, typing.Union[typing.Type[Child], typing.Type[Parent]])

476 assert validate_type(Child, typing.Union[typing.Type[Child], int])

477

478

479@pytest.mark.skip(reason="Not implemented")

480 def test_validate_type_class_union():

481 class Parent:

482 def __init__(self, a: int, b: str):

483 self.a: int = a

484 self.b: str = b

485

486 class Child(Parent):

487 def __init__(self, a: int, b: str):

488 self.a: int = 2 * a

489 self.b: str = b

490

491 class Other:

492 def __init__(self, x: int, y: str):

493 self.x: int = x

494 self.y: str = y

495

496 assert validate_type(Child, typing.Type[typing.Union[Child, Parent]])

497 assert validate_type(Child, typing.Type[typing.Union[Child, Other]])

498 assert validate_type(Parent, typing.Type[typing.Union[Child, Other]])

499 assert validate_type(Parent, typing.Type[typing.Union[Parent, Other]])

500

501

502 def test_validate_type_aliases():

503 AliasInt = int

504 AliasStr = str

505 AliasListInt = list[int]

506 AliasListStr = list[str]

507 AliasDictIntStr = dict[int, str]

508 AliasDictStrInt = dict[str, int]

509 AliasTupleIntStr = tuple[int, str]

510 AliasTupleStrInt = tuple[str, int]

511 AliasSetInt = set[int]

512 AliasSetStr = set[str]

513 AliasUnionIntStr = typing.Union[int, str]

514 AliasUnionStrInt = typing.Union[str, int]

515 AliasOptionalInt = typing.Optional[int]

516 AliasOptionalStr = typing.Optional[str]

517 AliasOptionalListInt = typing.Optional[list[int]]

518 AliasDictStrListInt = dict[str, list[int]]

519

520 assert validate_type(42, AliasInt)

521 assert not validate_type("42", AliasInt)

522 assert validate_type(42, AliasInt)

523 assert not validate_type("42", AliasInt)

524 assert validate_type("hello", AliasStr)

525 assert not validate_type(42, AliasStr)

526 assert validate_type([1, 2, 3], AliasListInt)

527 assert not validate_type([1, "2", 3], AliasListInt)

528 assert validate_type(["hello", "world"], AliasListStr)

529 assert not validate_type(["hello", 42], AliasListStr)

530 assert validate_type({1: "a", 2: "b"}, AliasDictIntStr)

531 assert not validate_type({1: 2, 3: 4}, AliasDictIntStr)

532 assert validate_type({"one": 1, "two": 2}, AliasDictStrInt)

533 assert not validate_type({1: "one", 2: "two"}, AliasDictStrInt)

534 assert validate_type((1, "a"), AliasTupleIntStr)

535 assert not validate_type(("a", 1), AliasTupleIntStr)

536 assert validate_type(("a", 1), AliasTupleStrInt)

537 assert not validate_type((1, "a"), AliasTupleStrInt)

538 assert validate_type({1, 2, 3}, AliasSetInt)

539 assert not validate_type({1, "two", 3}, AliasSetInt)

540 assert validate_type({"one", "two"}, AliasSetStr)

541 assert not validate_type({"one", 2}, AliasSetStr)

542 assert validate_type(42, AliasUnionIntStr)

543 assert validate_type("hello", AliasUnionIntStr)

544 assert not validate_type(3.14, AliasUnionIntStr)

545 assert validate_type("hello", AliasUnionStrInt)

546 assert validate_type(42, AliasUnionStrInt)

547 assert not validate_type(3.14, AliasUnionStrInt)

548 assert validate_type(42, AliasOptionalInt)

549 assert validate_type(None, AliasOptionalInt)

550 assert not validate_type("42", AliasOptionalInt)

551 assert validate_type("hello", AliasOptionalStr)

552 assert validate_type(None, AliasOptionalStr)

553 assert not validate_type(42, AliasOptionalStr)

554 assert validate_type([1, 2, 3], AliasOptionalListInt)

555 assert validate_type(None, AliasOptionalListInt)

556 assert not validate_type(["1", "2", "3"], AliasOptionalListInt)

557 assert validate_type({"key": [1, 2, 3]}, AliasDictStrListInt)

558 assert not validate_type({"key": [1, "2", 3]}, AliasDictStrListInt)

559