Skip to content

Conversation

Copy link

Copilot AI commented Jan 16, 2026

The special case parsing logic now tracks all special case lines from docstrings during module load time, enabling visibility into which cases are being processed (successfully parsed, failed to parse, or triggered warnings).

Changes

  • Global registry: Added special_cases_registry list at module level to accumulate special case entries
  • Recording in parsers: Modified parse_unary_case_block() and parse_binary_case_block() to append f"{func_name}: {case_str}" for every line matching the r_case pattern
  • Output in test_unary: Added print statement with once-only flag to emit the full registry when tests start

Output

Running pytest array_api_tests/test_special_cases.py::test_unary -s now prints:

=== Special Cases Registry ===
abs: If ``x_i`` is ``NaN``, the result is ``NaN``
abs: If ``x_i`` is ``-0``, the result is ``+0``
abs: If ``x_i`` is ``-infinity``, the result is ``+infinity``
sinh: If ``x_i`` is ``NaN``, the result is ``NaN``
sinh: If ``x_i`` is ``+0``, the result is ``+0``
sinh: If ``x_i`` is ``-0``, the result is ``-0``
...
==============================

The registry captures 473 entries including both successfully parsed cases and cases that triggered warnings, excluding non-case lines like descriptive text.

Original prompt

Summary

When parsing special cases from docstrings, record the exact line for each special case along with the function name. Emit this list during the test run so that running $ ARRAY_API_TESTS_MODULE=array_api_strict pytest array_api_tests/test_special_cases.py::test_unary -s prints out the registry.

Requirements

  1. Record special case lines: When parsing special cases in parse_unary_case_block and parse_binary_case_block, record each special case line with its function name in the format: "function_name: special_case_line".

  2. Include all lines: Record ALL special case lines that match the r_case pattern, including:

    • Successfully parsed cases
    • Cases that failed to parse (with ParseError)
    • Cases that triggered warnings
  3. Exclude non-case lines: Do NOT include lines like "For real-valued floating-point operands," that don't match the r_case pattern (i.e., lines that don't start with - ).

  4. Store globally: Create a global list (e.g., special_cases_registry) to store these records at module level.

  5. Print during test_unary: The registry should be printed when test_unary runs. This can be achieved by:

    • Adding a print statement at the beginning of the test_unary function that prints the registry once (use a flag to ensure it only prints once)
    • OR using a pytest fixture with autouse=True and scope="module" that prints the registry
    • The output should go to stdout so it's visible with the -s flag
  6. Timing: The registry should be populated during module load time (when the for stub in category_to_funcs["elementwise"]: loop runs), and then printed when tests start.

Example Output Format

When running pytest array_api_tests/test_special_cases.py::test_unary -s, the output should include something like:

=== Special Cases Registry ===
abs: If x_i is NaN, the result is NaN
abs: If x_i is +0, the result is +0
abs: If x_i is -0, the result is +0
abs: If x_i is +infinity, the result is +infinity
abs: If x_i is -infinity, the result is +infinity
sinh: If x_i is NaN, the result is NaN
sinh: If x_i is +0, the result is +0
sinh: If x_i is -0, the result is -0
sinh: If x_i is +infinity, the result is +infinity
sinh: If x_i is -infinity, the result is -infinity
...
==============================

Implementation Details

  1. Add a global list at module level:
# Global registry to store all special case lines
special_cases_registry = []
  1. In parse_unary_case_block, add recording for each case:
def parse_unary_case_block(case_block: str, func_name: str) -> List[UnaryCase]:
    cases = []
    for case_m in r_case.finditer(case_block):
        case_str = case_m.group(1)
        special_cases_registry.append(f"{func_name}: {case_str}")  # Record here
        # ... rest of parsing logic
  1. In parse_binary_case_block, add recording for each case:
def parse_binary_case_block(case_block: str, func_name: str) -> List[BinaryCase]:
    cases = []
    for case_m in r_case.finditer(case_block):
        case_str = case_m.group(1)
        special_cases_registry.append(f"{func_name}: {case_str}")  # Record here
        # ... rest of parsing logic
  1. Add printing mechanism in test_unary:
@pytest.mark.parametrize("func_name, func, case", unary_params)
def test_unary(func_name, func, case):
    # Print registry once at the start
    if not hasattr(test_unary, '_registry_printed'):
        print("\n=== Special Cases Registry ===")
        for entry in special_cases_registry:
            print(entry)
        print("=" * 30)
        test_unary._registry_printed = True
    
    # ... rest of test logic

Files to Modify

  • array_api_tests/test_special_cases.py - Add recording logic and printing in test_unary function

This pull request was created from Copilot chat.


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

Copilot AI changed the title [WIP] Record special case lines in docstring parsing Record and emit special case lines during test execution Jan 16, 2026
Copilot AI requested a review from ev-br January 16, 2026 17:31
@ev-br
Copy link
Owner

ev-br commented Jan 16, 2026

NB: this is a helper for gh-3: compare the list of all "special cases" in master and in the branch which parses complex values, to make sure that the parser rewrite still catches all special cases.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants