approx.py
Overview
This file provides extensive **tests** and utility helpers for the `pytest.approx` functionality, which is part of the `pytest` testing framework. The `approx` function is used for approximate numerical comparisons in tests, allowing floating-point numbers (and more complex data structures containing them) to be compared within specified tolerances (relative and absolute).
The file primarily contains:
Test cases validating the behavior of
pytest.approxacross a wide variety of data types, including native Python numerics, complex numbers, sequences, dictionaries, NumPy arrays, decimals, fractions, and user-defined sequence-like types.Fixtures and helper functions to aid in testing error messages, verbosity, and doctest integration.
A small utility class
MyVec3used to test compatibility with custom sequence-like objects.Tests for the utility function
_recursive_sequence_mapthat recursively applies a function to elements in nested sequences.
This file does **not** implement the `approx` functionality itself but rigorously tests it, ensuring correctness, helpful error reporting, and compatibility with many data types and edge cases.
Classes and Functions
Fixtures and Context Managers
mocked_doctest_runner(monkeypatch) -> MyDocTestRunner
Type:
pytest.fixturePurpose: Provides a mocked doctest runner for running
doctesttests in a controlled environment within pytest.Key Implementation Details:
Monkeypatches doctest._OutputRedirectingPdb with a dummy class that disables debugging.
Overrides report_failure to raise an
AssertionErrorwith a formatted message instead of default doctest failure reporting.
Example usage: Used internally in the
test_doctestsmethod to run doctests onapprox.__doc__.
temporary_verbosity(config, verbosity=0)
Type: Context manager
Parameters:
config: pytest configuration object.verbosity(int): The verbosity level to temporarily set.
Purpose: Temporarily sets pytest verbosity to a specific level during a test.
Usage example:
with temporary_verbosity(pytestconfig, verbosity=2): # Run code with verbosity level 2 ...Useful in tests that verify error message contents at different verbosity levels.
assert_approx_raises_regex(pytestconfig) -> Callable
Type:
pytest.fixtureReturns: A helper function
do_assert(lhs, rhs, expected_message, verbosity_level=0)Purpose: Helper to assert that
lhs == approx(rhs)raises anAssertionErrorwith error messages matching a list of regex patterns.Parameters:
lhs: Left-hand side of comparison.rhs: Right-hand side (expected) forapprox.expected_message: List of regex patterns expected in the error message lines.verbosity_level: Verbosity level to run the assertion under.
Usage example:
def test_example(assert_approx_raises_regex): assert_approx_raises_regex(1.0, 2.0, ["comparison failed", r"Obtained: 1.0", r"Expected: 2.0 ± .*"])
Classes
TestApprox
Purpose: Contains numerous test methods to verify the correctness, robustness, and error reporting of
pytest.approx.Notable methods:
test_error_messages_native_dtypes: Tests error messages for native Python types (float, dict, list, tuple).test_error_messages_numpy_dtypes: Tests error messages with NumPy arrays.test_operator_overloading: Verifies==and!=operators are properly overloaded.test_exactly_equal: Tests cases where values should compare exactly equal.test_custom_tolerances: Tests usage of custom relative and absolute tolerances.test_numpy_array_protocol: Tests compatibility with array-like objects implementing__array__.test_doctests: Runs doctest onapproxdocstring for coverage.test_unicode_plus_minus: Integration test for error message formatting with Unicode characters.test_nonnumeric_okay_if_equal/test_nonnumeric_false_if_unequal: Tests behavior on non-numeric types.test_comparison_operator_type_error: Ensures only==and!=are supported operators.test_generic_ordered_sequence: Tests support for custom ordered sequences.Many tests with
pytest.mark.parametrizeto cover edge cases with nested structures, tolerances, infinity, NaN, complex numbers, decimals, fractions, and more.
MyVec3
Purpose: A small user-defined, sequence-like class used in tests.
Properties:
_x,_y,_z(int): Coordinates.
Methods:
__init__(x: int, y: int, z: int): Constructor.__repr__() -> str: Returns a string representation.__len__() -> int: Returns fixed length3.__getitem__(key: int) -> int: Index access for 0-based x,y,z.
Usage: Used to test that
approxworks correctly with user-defined sequences.
TestRecursiveSequenceMap
Purpose: Tests for the utility function
_recursive_sequence_mapwhich applies a function recursively to all elements in nested sequences.Test cases cover:
Scalar input.
Empty and nested lists.
Tuples.
Mixed sequences (lists & tuples).
User-defined sequence-like objects (
MyVec3).
Important Implementation Details and Algorithms
The file itself does not implement
approxor_recursive_sequence_map. Instead, it tests their behavior thoroughly.The tests validate tolerance handling (relative and absolute), support for complex numbers (including angle tolerances), and behavior with special floating-point values (NaN, inf).
Tests check error message contents using regular expressions to ensure informative and consistent error reports.
There is strong emphasis on compatibility with NumPy and other array-like objects supporting
__array__.The handling of nested containers (lists, tuples, dicts) is validated, including error cases for size or shape mismatches.
The
approxrepresentation string is tested for correctness and readability.Custom user-defined sequences are tested to ensure that
approxaccepts any ordered, indexable sequence (not just built-in types).The
assert_approx_raises_regexhelper enables flexible checks on error messages, including multiline and regex matching.Negative or NaN tolerances are checked to raise
ValueError.The tests include integration with
pytestfixtures and doctests.
Interaction with Other Parts of the System
This file is part of the
pytesttesting framework's internal test suite.It depends on the actual
pytest.approximplementation, which is defined elsewhere in thepytestcodebase.Uses pytest fixtures (
@pytest.fixture) and pytest's testing APIs.Imports
_recursive_sequence_mapfrompytest.python_api(internal utility).Interacts with
doctestfor docstring testing and withpytesterfor integration test scenarios.Tests integration with NumPy if available, importing it conditionally (
pytest.importorskip("numpy")).The tests ensure that the
pytest.approxfeature works correctly as a utility for approximate comparisons in pytest test suites.
Usage Examples
import pytest
def test_my_computation():
result = 0.1 + 0.2
expected = 0.3
# Use approx to allow small floating-point errors
assert result == pytest.approx(expected, rel=1e-6)
def test_list_approx():
actual = [1.000001, 2.000002]
expected = [1.0, 2.0]
assert actual == pytest.approx(expected, abs=1e-5)
def test_dict_approx():
actual = {"a": 1.0001, "b": 2.0001}
expected = {"a": 1.0, "b": 2.0}
assert actual == pytest.approx(expected, rel=1e-4)
Mermaid Diagram: Class Structure
This file mainly contains test classes and one utility class used in tests.
classDiagram
class TestApprox {
+test_error_messages_native_dtypes()
+test_error_messages_numpy_dtypes()
+test_operator_overloading()
+test_exactly_equal()
+test_custom_tolerances()
+test_numpy_array_protocol()
+test_doctests()
+test_unicode_plus_minus()
+test_nonnumeric_okay_if_equal()
+test_nonnumeric_false_if_unequal()
+test_comparison_operator_type_error()
+test_generic_ordered_sequence()
+test_decimal_approx_repr()
+test_allow_ordered_sequences_only()
+test_strange_sequence()
}
class MyVec3 {
-_x: int
-_y: int
-_z: int
+__init__(x: int, y: int, z: int)
+__repr__() -> str
+__len__() -> int
+__getitem__(key: int) -> int
}
class TestRecursiveSequenceMap {
+test_map_over_scalar()
+test_map_over_empty_list()
+test_map_over_list()
+test_map_over_tuple()
+test_map_over_nested_lists()
+test_map_over_mixed_sequence()
+test_map_over_sequence_like()
}
Summary
approx.py is a comprehensive test module for
pytest.approx, focused on verifying floating-point approximate equality checks.It covers many edge cases, data types, containers, and error reporting.
It includes helper fixtures and utilities to facilitate robust testing.
Its tests ensure that
pytest.approxbehaves as expected across a wide range of inputs and usage patterns.It contributes to the reliability of numerical comparisons in pytest-based test suites.