|
29 | 29 | from hypothesis.internal.conjecture.data import ConjectureData |
30 | 30 | from hypothesis.internal.conjecture.providers import ( |
31 | 31 | COLLECTION_DEFAULT_MAX_SIZE, |
| 32 | + HypothesisProvider, |
32 | 33 | PrimitiveProvider, |
| 34 | + with_register_backend, |
33 | 35 | ) |
34 | 36 | from hypothesis.internal.floats import SMALLEST_SUBNORMAL, sign_aware_lte |
35 | 37 | from hypothesis.internal.intervalsets import IntervalSet |
@@ -369,119 +371,132 @@ def test_conformance(): |
369 | 371 | treat those exceptions as fatal errors. |
370 | 372 | """ |
371 | 373 |
|
372 | | - @Settings(settings, suppress_health_check=[HealthCheck.too_slow]) |
373 | | - class ProviderConformanceTest(RuleBasedStateMachine): |
374 | | - def __init__(self): |
375 | | - super().__init__() |
376 | | - |
377 | | - @initialize(random=st.randoms()) |
378 | | - def setup(self, random): |
379 | | - if Provider.lifetime == "test_case": |
380 | | - data = ConjectureData(random=random, provider=Provider) |
381 | | - self.provider = data.provider |
382 | | - else: |
383 | | - self.provider = Provider(None) |
384 | | - |
385 | | - self.context_manager = self.provider.per_test_case_context_manager() |
386 | | - self.context_manager.__enter__() |
387 | | - self.frozen = False |
388 | | - |
389 | | - def _draw(self, choice_type, constraints): |
390 | | - del constraints["forced"] |
391 | | - draw_func = getattr(self.provider, f"draw_{choice_type}") |
392 | | - |
393 | | - try: |
394 | | - choice = draw_func(**constraints) |
395 | | - note(f"drew {choice_type} {choice}") |
396 | | - expected_type = { |
397 | | - "integer": int, |
398 | | - "float": float, |
399 | | - "bytes": bytes, |
400 | | - "string": str, |
401 | | - "boolean": bool, |
402 | | - }[choice_type] |
403 | | - assert isinstance(choice, expected_type) |
404 | | - assert choice_permitted(choice, constraints) |
405 | | - except context_manager_exceptions as e: |
406 | | - note(f"caught exception {type(e)} in context_manager_exceptions: {e}") |
| 374 | + class CopiesRealizationProvider(HypothesisProvider): |
| 375 | + avoid_realization = Provider.avoid_realization |
| 376 | + |
| 377 | + with with_register_backend("copies_realization", CopiesRealizationProvider): |
| 378 | + |
| 379 | + @Settings( |
| 380 | + settings, |
| 381 | + suppress_health_check=[HealthCheck.too_slow], |
| 382 | + backend="copies_realization", |
| 383 | + ) |
| 384 | + class ProviderConformanceTest(RuleBasedStateMachine): |
| 385 | + def __init__(self): |
| 386 | + super().__init__() |
| 387 | + |
| 388 | + @initialize(random=st.randoms()) |
| 389 | + def setup(self, random): |
| 390 | + if Provider.lifetime == "test_case": |
| 391 | + data = ConjectureData(random=random, provider=Provider) |
| 392 | + self.provider = data.provider |
| 393 | + else: |
| 394 | + self.provider = Provider(None) |
| 395 | + |
| 396 | + self.context_manager = self.provider.per_test_case_context_manager() |
| 397 | + self.context_manager.__enter__() |
| 398 | + self.frozen = False |
| 399 | + |
| 400 | + def _draw(self, choice_type, constraints): |
| 401 | + del constraints["forced"] |
| 402 | + draw_func = getattr(self.provider, f"draw_{choice_type}") |
| 403 | + |
407 | 404 | try: |
408 | | - self.context_manager.__exit__(type(e), e, None) |
409 | | - except BackendCannotProceed: |
410 | | - self.frozen = True |
411 | | - return None |
412 | | - |
413 | | - return choice |
414 | | - |
415 | | - @precondition(lambda self: not self.frozen) |
416 | | - @rule(constraints=integer_constraints()) |
417 | | - def draw_integer(self, constraints): |
418 | | - self._draw("integer", constraints) |
419 | | - |
420 | | - @precondition(lambda self: not self.frozen) |
421 | | - @rule(constraints=float_constraints()) |
422 | | - def draw_float(self, constraints): |
423 | | - self._draw("float", constraints) |
424 | | - |
425 | | - @precondition(lambda self: not self.frozen) |
426 | | - @rule(constraints=bytes_constraints()) |
427 | | - def draw_bytes(self, constraints): |
428 | | - self._draw("bytes", constraints) |
429 | | - |
430 | | - @precondition(lambda self: not self.frozen) |
431 | | - @rule(constraints=string_constraints()) |
432 | | - def draw_string(self, constraints): |
433 | | - self._draw("string", constraints) |
434 | | - |
435 | | - @precondition(lambda self: not self.frozen) |
436 | | - @rule(constraints=boolean_constraints()) |
437 | | - def draw_boolean(self, constraints): |
438 | | - self._draw("boolean", constraints) |
439 | | - |
440 | | - @precondition(lambda self: not self.frozen) |
441 | | - @rule(label=st.integers()) |
442 | | - def span_start(self, label): |
443 | | - self.provider.span_start(label) |
444 | | - |
445 | | - @precondition(lambda self: not self.frozen) |
446 | | - @rule(discard=st.booleans()) |
447 | | - def span_end(self, discard): |
448 | | - self.provider.span_end(discard) |
449 | | - |
450 | | - @precondition(lambda self: not self.frozen) |
451 | | - @rule() |
452 | | - def freeze(self): |
453 | | - # phase-transition, mimicking data.freeze() at the end of a test case. |
454 | | - self.frozen = True |
455 | | - self.context_manager.__exit__(None, None, None) |
456 | | - |
457 | | - @precondition(lambda self: self.frozen) |
458 | | - @rule(value=_realize_objects) |
459 | | - def realize(self, value): |
460 | | - # filter out nans and weirder things |
461 | | - try: |
462 | | - assume(value == value) |
463 | | - except Exception: |
464 | | - # e.g. value = Decimal('-sNaN') |
465 | | - assume(False) |
466 | | - |
467 | | - # if `value` is non-symbolic, the provider should return it as-is. |
468 | | - assert self.provider.realize(value) == value |
469 | | - |
470 | | - @precondition(lambda self: self.frozen) |
471 | | - @rule() |
472 | | - def observe_test_case(self): |
473 | | - observations = self.provider.observe_test_case() |
474 | | - assert isinstance(observations, dict) |
475 | | - |
476 | | - @precondition(lambda self: self.frozen) |
477 | | - @rule(lifetime=st.sampled_from(["test_function", "test_case"])) |
478 | | - def observe_information_messages(self, lifetime): |
479 | | - observations = self.provider.observe_information_messages(lifetime=lifetime) |
480 | | - for observation in observations: |
481 | | - assert isinstance(observation, dict) |
482 | | - |
483 | | - def teardown(self): |
484 | | - if not self.frozen: |
| 405 | + choice = draw_func(**constraints) |
| 406 | + note(f"drew {choice_type} {choice}") |
| 407 | + expected_type = { |
| 408 | + "integer": int, |
| 409 | + "float": float, |
| 410 | + "bytes": bytes, |
| 411 | + "string": str, |
| 412 | + "boolean": bool, |
| 413 | + }[choice_type] |
| 414 | + assert isinstance(choice, expected_type) |
| 415 | + assert choice_permitted(choice, constraints) |
| 416 | + except context_manager_exceptions as e: |
| 417 | + note( |
| 418 | + f"caught exception {type(e)} in context_manager_exceptions: {e}" |
| 419 | + ) |
| 420 | + try: |
| 421 | + self.context_manager.__exit__(type(e), e, None) |
| 422 | + except BackendCannotProceed: |
| 423 | + self.frozen = True |
| 424 | + return None |
| 425 | + |
| 426 | + return choice |
| 427 | + |
| 428 | + @precondition(lambda self: not self.frozen) |
| 429 | + @rule(constraints=integer_constraints()) |
| 430 | + def draw_integer(self, constraints): |
| 431 | + self._draw("integer", constraints) |
| 432 | + |
| 433 | + @precondition(lambda self: not self.frozen) |
| 434 | + @rule(constraints=float_constraints()) |
| 435 | + def draw_float(self, constraints): |
| 436 | + self._draw("float", constraints) |
| 437 | + |
| 438 | + @precondition(lambda self: not self.frozen) |
| 439 | + @rule(constraints=bytes_constraints()) |
| 440 | + def draw_bytes(self, constraints): |
| 441 | + self._draw("bytes", constraints) |
| 442 | + |
| 443 | + @precondition(lambda self: not self.frozen) |
| 444 | + @rule(constraints=string_constraints()) |
| 445 | + def draw_string(self, constraints): |
| 446 | + self._draw("string", constraints) |
| 447 | + |
| 448 | + @precondition(lambda self: not self.frozen) |
| 449 | + @rule(constraints=boolean_constraints()) |
| 450 | + def draw_boolean(self, constraints): |
| 451 | + self._draw("boolean", constraints) |
| 452 | + |
| 453 | + @precondition(lambda self: not self.frozen) |
| 454 | + @rule(label=st.integers()) |
| 455 | + def span_start(self, label): |
| 456 | + self.provider.span_start(label) |
| 457 | + |
| 458 | + @precondition(lambda self: not self.frozen) |
| 459 | + @rule(discard=st.booleans()) |
| 460 | + def span_end(self, discard): |
| 461 | + self.provider.span_end(discard) |
| 462 | + |
| 463 | + @precondition(lambda self: not self.frozen) |
| 464 | + @rule() |
| 465 | + def freeze(self): |
| 466 | + # phase-transition, mimicking data.freeze() at the end of a test case. |
| 467 | + self.frozen = True |
485 | 468 | self.context_manager.__exit__(None, None, None) |
486 | 469 |
|
487 | | - ProviderConformanceTest.TestCase().runTest() |
| 470 | + @precondition(lambda self: self.frozen) |
| 471 | + @rule(value=_realize_objects) |
| 472 | + def realize(self, value): |
| 473 | + # filter out nans and weirder things |
| 474 | + try: |
| 475 | + assume(value == value) |
| 476 | + except Exception: |
| 477 | + # e.g. value = Decimal('-sNaN') |
| 478 | + assume(False) |
| 479 | + |
| 480 | + # if `value` is non-symbolic, the provider should return it as-is. |
| 481 | + assert self.provider.realize(value) == value |
| 482 | + |
| 483 | + @precondition(lambda self: self.frozen) |
| 484 | + @rule() |
| 485 | + def observe_test_case(self): |
| 486 | + observations = self.provider.observe_test_case() |
| 487 | + assert isinstance(observations, dict) |
| 488 | + |
| 489 | + @precondition(lambda self: self.frozen) |
| 490 | + @rule(lifetime=st.sampled_from(["test_function", "test_case"])) |
| 491 | + def observe_information_messages(self, lifetime): |
| 492 | + observations = self.provider.observe_information_messages( |
| 493 | + lifetime=lifetime |
| 494 | + ) |
| 495 | + for observation in observations: |
| 496 | + assert isinstance(observation, dict) |
| 497 | + |
| 498 | + def teardown(self): |
| 499 | + if not self.frozen: |
| 500 | + self.context_manager.__exit__(None, None, None) |
| 501 | + |
| 502 | + ProviderConformanceTest.TestCase().runTest() |
0 commit comments