Skip to content

Conversation

@codeflash-ai
Copy link

@codeflash-ai codeflash-ai bot commented Nov 22, 2025

📄 239% (2.39x) speedup for parse_warning_filter in src/_pytest/config/__init__.py

⏱️ Runtime : 6.66 milliseconds 1.97 milliseconds (best of 67 runs)

📝 Explanation and details

The optimized code achieves a 238% speedup through several key micro-optimizations that reduce function call overhead and improve memory access patterns:

Key Optimizations:

  1. Module Import Hoisting: Moving import builtins as _builtins to module level eliminates repeated import overhead in _resolve_warning_category, which is called frequently during warning filter parsing.

  2. String Concatenation over dedent(): Replaced dedent() calls with direct string concatenation for error templates, avoiding the overhead of text processing functions that analyze indentation.

  3. List Comprehension Optimization: Changed parts.append("") loop to parts += [""] * (5 - nparts) for more efficient list extension when padding to 5 elements.

  4. Tuple Construction in import: Replaced [klass] with (klass,) in the __import__ call, avoiding temporary list creation.

  5. Reduced Function Call Overhead: Cached len(parts) as nparts to avoid repeated len() calls, and streamlined variable assignments.

Performance Impact:

The function references show this optimization is highly impactful because parse_warning_filter is called in hot paths:

  • During pytest configuration when applying warning filters from config files and command line
  • For every test item when processing @pytest.mark.filterwarnings decorators
  • In warning capture contexts that wrap test execution

Test Case Performance:

  • Basic cases (165-216% faster): Simple filters benefit from reduced overhead
  • Large scale cases (215-268% faster): Cache-heavy workloads see the biggest gains from reduced per-call overhead
  • Complex cases with escaping (110-140% faster): String processing optimizations provide consistent benefits

The optimizations are particularly effective for pytest's usage pattern where the same warning filters are parsed repeatedly across many test runs, making the reduced per-call overhead compound significantly.

Correctness verification report:

Test Status
⚙️ Existing Unit Tests 🔘 None Found
🌀 Generated Regression Tests 867 Passed
⏪ Replay Tests 🔘 None Found
🔎 Concolic Coverage Tests 🔘 None Found
📊 Tests Coverage 100.0%
🌀 Generated Regression Tests and Runtime
import re

from _pytest.config.__init__ import parse_warning_filter


# imports


# Minimal UsageError for testing (since pytest's is not available here)
class UsageError(Exception):
    pass


# -----------------
# UNIT TESTS BELOW
# -----------------

# 1. BASIC TEST CASES


def test_basic_action_only():
    # Only action is provided, rest default
    codeflash_output = parse_warning_filter("ignore", escape=False)
    result = codeflash_output  # 12.9μs -> 4.85μs (165% faster)


def test_basic_action_and_message():
    # Action and message provided
    codeflash_output = parse_warning_filter("error:my message", escape=False)
    result = codeflash_output  # 13.4μs -> 4.90μs (174% faster)


def test_basic_all_fields():
    # All fields provided, no escaping
    codeflash_output = parse_warning_filter(
        "default:foo:DeprecationWarning:my_mod:123", escape=False
    )
    result = codeflash_output  # 16.2μs -> 6.01μs (170% faster)


def test_basic_category_with_module_path():
    # Category as fully qualified name
    codeflash_output = parse_warning_filter(
        "once:bar:builtins.UserWarning:some_module:5", escape=False
    )
    result = codeflash_output  # 19.3μs -> 9.86μs (95.5% faster)


def test_basic_escape_message_and_module():
    # Escaping should be applied to message and module
    codeflash_output = parse_warning_filter(
        "ignore:foo.bar[abc]:UserWarning:some.mod-ule:2", escape=True
    )
    result = codeflash_output  # 19.1μs -> 8.99μs (112% faster)


# 2. EDGE TEST CASES


def test_edge_whitespace_stripping():
    # Leading/trailing whitespace in fields should be stripped
    codeflash_output = parse_warning_filter(
        "  ignore  :  foo  :  UserWarning  :  mod  :  4  ", escape=False
    )
    result = codeflash_output  # 19.8μs -> 7.21μs (175% faster)


def test_edge_blank_fields():
    # All fields blank except action
    codeflash_output = parse_warning_filter("ignore::::", escape=False)
    result = codeflash_output  # 14.2μs -> 4.54μs (212% faster)


def test_edge_blank_category_defaults_to_Warning():
    # Blank category should default to Warning
    codeflash_output = parse_warning_filter("ignore:msg::mod:1", escape=False)
    result = codeflash_output  # 14.6μs -> 4.61μs (216% faster)


def test_edge_blank_module_and_lineno():
    # Blank module and lineno
    codeflash_output = parse_warning_filter("ignore:msg:UserWarning::", escape=False)
    result = codeflash_output  # 16.7μs -> 5.94μs (182% faster)


# 3. LARGE SCALE TEST CASES


def test_large_scale_many_unique_calls():
    # Test LRU cache and correctness for many unique filter strings (<1000)
    for i in range(500):
        action = "ignore" if i % 2 == 0 else "default"
        message = f"msg{i}"
        category = "UserWarning"
        module = f"mod{i}"
        lineno = i
        arg = f"{action}:{message}:{category}:{module}:{lineno}"
        codeflash_output = parse_warning_filter(arg, escape=(i % 3 == 0))
        result = codeflash_output  # 3.70ms -> 1.08ms (242% faster)
        expected_message = re.escape(message) if (i % 3 == 0) else message
        expected_module = re.escape(module) + r"\Z" if (i % 3 == 0) else module


def test_large_scale_all_builtin_warning_categories():
    # Try all built-in warning categories
    warning_types = [
        "Warning",
        "UserWarning",
        "DeprecationWarning",
        "SyntaxWarning",
        "RuntimeWarning",
        "FutureWarning",
        "PendingDeprecationWarning",
        "ImportWarning",
        "UnicodeWarning",
        "BytesWarning",
        "ResourceWarning",
    ]
    for category in warning_types:
        arg = f"ignore:msg:{category}:mod:1"
        codeflash_output = parse_warning_filter(arg, escape=False)
        result = codeflash_output  # 96.7μs -> 28.9μs (234% faster)


def test_large_scale_varied_fields():
    # Vary which fields are blank, for many combinations
    for i in range(100):
        fields = [
            "ignore" if i % 2 == 0 else "default",
            "" if i % 3 == 0 else f"msg{i}",
            "" if i % 4 == 0 else "UserWarning",
            "" if i % 5 == 0 else f"mod{i}",
            "" if i % 6 == 0 else str(i),
        ]
        arg = ":".join(fields)
        codeflash_output = parse_warning_filter(arg, escape=False)
        result = codeflash_output  # 717μs -> 196μs (265% faster)
        # Check message
        expected_message = "" if fields[1] == "" else fields[1]
        # Check category
        expected_category = UserWarning if fields[2] == "UserWarning" else Warning
        # Check module
        expected_module = "" if fields[3] == "" else fields[3]
        # Check lineno
        expected_lineno = 0 if fields[4] == "" else int(fields[4])


def test_large_scale_cache_eviction():
    # LRU cache size is 50, so after 60 unique calls, the first 10 are evicted
    seen = []
    for i in range(60):
        arg = f"ignore:msg{i}:UserWarning:mod{i}:{i}"
        seen.append(
            parse_warning_filter(arg, escape=False)
        )  # 440μs -> 119μs (268% faster)
    # The 0th call will be evicted from cache, so calling it again will re-parse
    # This test is just to ensure no crash and correct result
    codeflash_output = parse_warning_filter(
        "ignore:msg0:UserWarning:mod0:0", escape=False
    )
    result = codeflash_output  # 7.48μs -> 2.19μs (241% faster)


# codeflash_output is used to check that the output of the original code is the same as that of the optimized code.
import re

from _pytest.config.__init__ import parse_warning_filter


# imports


class UsageError(Exception):
    pass


# unit tests

# ------------------- BASIC TEST CASES -------------------


def test_basic_action_only():
    # Only action provided, should default other fields
    codeflash_output = parse_warning_filter("ignore", escape=False)
    result = codeflash_output  # 13.2μs -> 4.90μs (170% faster)


def test_basic_action_and_message():
    # Action and message provided
    codeflash_output = parse_warning_filter("error:foo", escape=False)
    result = codeflash_output  # 13.6μs -> 5.26μs (159% faster)


def test_basic_all_fields():
    # All fields provided, no escaping
    codeflash_output = parse_warning_filter(
        "default:mymsg:UserWarning:some.module:42", escape=False
    )
    result = codeflash_output  # 17.0μs -> 5.96μs (185% faster)


def test_basic_all_fields_with_escaping():
    # All fields provided, with escaping
    codeflash_output = parse_warning_filter(
        "once:foo.bar:DeprecationWarning:mod.name:7", escape=True
    )
    result = codeflash_output  # 18.8μs -> 8.95μs (110% faster)


def test_basic_category_builtin():
    # Category is a builtin warning type
    codeflash_output = parse_warning_filter("always::SyntaxWarning", escape=False)
    result = codeflash_output  # 16.0μs -> 6.27μs (154% faster)


def test_basic_colons_and_spaces():
    # Fields with spaces and extra colons
    codeflash_output = parse_warning_filter(
        "module : my message : RuntimeWarning : mymod : 1", escape=False
    )
    result = codeflash_output  # 16.9μs -> 6.34μs (167% faster)


# ------------------- EDGE TEST CASES -------------------


def test_edge_module_escaping():
    # Module name with regex metacharacters, with escaping
    codeflash_output = parse_warning_filter("default::Warning:foo.bar[1]:", escape=True)
    result = codeflash_output  # 20.6μs -> 8.55μs (140% faster)


def test_edge_message_escaping():
    # Message with regex metacharacters, with escaping
    codeflash_output = parse_warning_filter("default:foo.bar[1]", escape=True)
    result = codeflash_output  # 15.5μs -> 6.75μs (130% faster)


def test_edge_whitespace_fields():
    # Fields containing only whitespace should be stripped
    codeflash_output = parse_warning_filter(" always :  :  :  :  ", escape=False)
    result = codeflash_output  # 13.8μs -> 4.61μs (201% faster)


# ------------------- LARGE SCALE TEST CASES -------------------


def test_large_scale_many_unique_calls():
    # Test LRU cache and correctness with many unique calls (should not raise or slow down)
    actions = ["ignore", "default", "error", "always", "module", "once"]
    categories = ["Warning", "UserWarning", "DeprecationWarning", "SyntaxWarning"]
    modules = [f"mod{i}" for i in range(10)]
    for i in range(100):
        action = actions[i % len(actions)]
        message = f"msg{i}"
        category = categories[i % len(categories)]
        module = modules[i % len(modules)]
        lineno = i
        arg = f"{action}:{message}:{category}:{module}:{lineno}"
        codeflash_output = parse_warning_filter(arg, escape=(i % 2 == 0))
        result = codeflash_output  # 794μs -> 252μs (215% faster)
        expected_message = re.escape(message) if (i % 2 == 0) else message
        expected_module = re.escape(module) + "\\Z" if (i % 2 == 0) else module


def test_large_scale_cache_eviction():
    # Test that LRU cache does not break correctness when more than 50 unique calls are made
    for i in range(60):
        arg = f"ignore:msg{i}:Warning:mod{i}:1"
        codeflash_output = parse_warning_filter(arg, escape=False)
        result = codeflash_output  # 436μs -> 118μs (267% faster)


def test_large_scale_long_message_and_module():
    # Very long message and module fields
    long_msg = "x" * 500
    long_mod = "mod" + "y" * 500
    arg = f"error:{long_msg}:UserWarning:{long_mod}:123"
    codeflash_output = parse_warning_filter(arg, escape=True)
    result = codeflash_output  # 36.3μs -> 10.3μs (253% faster)


def test_large_scale_all_actions():
    # All valid actions should be accepted
    actions = ["ignore", "default", "error", "always", "module", "once"]
    for action in actions:
        arg = f"{action}:msg:Warning:mod:2"
        codeflash_output = parse_warning_filter(arg, escape=False)
        result = codeflash_output  # 56.5μs -> 17.2μs (228% faster)


def test_large_scale_many_categories():
    # Many different warning categories
    cats = [
        "Warning",
        "UserWarning",
        "DeprecationWarning",
        "SyntaxWarning",
        "ResourceWarning",
        "FutureWarning",
        "PendingDeprecationWarning",
        "ImportWarning",
        "UnicodeWarning",
        "BytesWarning",
    ]
    for i, cat in enumerate(cats):
        arg = f"ignore:msg:{cat}:mod:{i}"
        codeflash_output = parse_warning_filter(arg, escape=False)
        result = codeflash_output  # 88.9μs -> 26.5μs (236% faster)


# codeflash_output is used to check that the output of the original code is the same as that of the optimized code.

To edit these changes git checkout codeflash/optimize-parse_warning_filter-mi9plvit and push.

Codeflash Static Badge

The optimized code achieves a **238% speedup** through several key micro-optimizations that reduce function call overhead and improve memory access patterns:

**Key Optimizations:**

1. **Module Import Hoisting**: Moving `import builtins as _builtins` to module level eliminates repeated import overhead in `_resolve_warning_category`, which is called frequently during warning filter parsing.

2. **String Concatenation over dedent()**: Replaced `dedent()` calls with direct string concatenation for error templates, avoiding the overhead of text processing functions that analyze indentation.

3. **List Comprehension Optimization**: Changed `parts.append("")` loop to `parts += [""] * (5 - nparts)` for more efficient list extension when padding to 5 elements.

4. **Tuple Construction in __import__**: Replaced `[klass]` with `(klass,)` in the `__import__` call, avoiding temporary list creation.

5. **Reduced Function Call Overhead**: Cached `len(parts)` as `nparts` to avoid repeated `len()` calls, and streamlined variable assignments.

**Performance Impact:**

The function references show this optimization is **highly impactful** because `parse_warning_filter` is called in hot paths:
- During pytest configuration when applying warning filters from config files and command line
- For every test item when processing `@pytest.mark.filterwarnings` decorators  
- In warning capture contexts that wrap test execution

**Test Case Performance:**
- **Basic cases** (165-216% faster): Simple filters benefit from reduced overhead
- **Large scale cases** (215-268% faster): Cache-heavy workloads see the biggest gains from reduced per-call overhead
- **Complex cases** with escaping (110-140% faster): String processing optimizations provide consistent benefits

The optimizations are particularly effective for pytest's usage pattern where the same warning filters are parsed repeatedly across many test runs, making the reduced per-call overhead compound significantly.
@codeflash-ai codeflash-ai bot requested a review from mashraf-222 November 22, 2025 03:08
@codeflash-ai codeflash-ai bot added ⚡️ codeflash Optimization PR opened by Codeflash AI 🎯 Quality: High Optimization Quality according to Codeflash labels Nov 22, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

⚡️ codeflash Optimization PR opened by Codeflash AI 🎯 Quality: High Optimization Quality according to Codeflash

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant