Skip to content

Fix caching regression: enable_caching() now affects existing decorators#279

Merged
shaypal5 merged 4 commits intomasterfrom
copilot/fix-254
Jul 10, 2025
Merged

Fix caching regression: enable_caching() now affects existing decorators#279
shaypal5 merged 4 commits intomasterfrom
copilot/fix-254

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Jul 9, 2025

Problem

There was a regression in cachier v3.1.2 where enable_caching() and disable_caching() calls did not affect decorators that were defined when caching was in a different state. This broke the expected behavior where global caching enable/disable should work for all existing cached functions.

Consider this example that worked in v3.0.1 but failed in v3.1.2:

import datetime
import cachier

# Start with caching disabled
cachier.set_default_params(caching_enabled=False, separate_files=True)

class Test:
    def __init__(self, cache_ttl=None):
        self.counter = 0
        if cache_ttl is not None:
            stale_after = datetime.timedelta(seconds=cache_ttl)
            cachier.set_default_params(stale_after=stale_after)
            cachier.enable_caching()  # This should enable caching for existing decorators

    @cachier.cachier()  # Decorator defined when caching was disabled
    def test(self, param):
        self.counter += 1
        assert self.counter < 2  # Should only be called once due to caching
        return param

t = Test(cache_ttl=1)
t.test("a")
t.test("a")  # This should come from cache, not call the function again

Root Cause

The issue was in src/cachier/core.py where _global_params.caching_enabled was imported statically at decorator definition time rather than being checked dynamically at function call time. This meant that decorators captured a snapshot of the caching state when they were defined, and subsequent calls to enable_caching() or disable_caching() had no effect on them.

Solution

Made the caching_enabled check dynamic by:

  1. Removing the static import of _global_params from the cachier decorator function
  2. Adding a dynamic import of _global_params in the _call function right before the caching check
  3. This ensures that each function call checks the current global caching state, not the state from when the decorator was defined

The fix is minimal and surgical, following the same pattern used for other dynamic parameters in the codebase.

Changes

  • Fixed: Dynamic checking of _global_params.caching_enabled in function calls
  • Added: Comprehensive test coverage for the regression scenario
  • Verified: Existing functionality remains unchanged

Testing

Added three test cases that verify:

  1. Decorators defined when caching is disabled can be enabled later
  2. Decorators defined when caching is enabled can be disabled later
  3. The exact scenario from the original issue report works correctly

Fixes #254.


💬 Share your feedback on Copilot coding agent for the chance to win a $200 gift card! Click here to start the survey.

Copilot AI and others added 2 commits July 9, 2025 16:03
Co-authored-by: shaypal5 <917954+shaypal5@users.noreply.github.com>
Co-authored-by: shaypal5 <917954+shaypal5@users.noreply.github.com>
Copilot AI changed the title [WIP] Caching regression with cachier v3.1.2 Fix caching regression: enable_caching() now affects existing decorators Jul 9, 2025
Copilot AI requested a review from shaypal5 July 9, 2025 16:12
@shaypal5
Copy link
Copy Markdown
Member

pre-commit.ci autofix

@shaypal5 shaypal5 marked this pull request as ready for review July 10, 2025 08:29
@shaypal5 shaypal5 merged commit 6f2127f into master Jul 10, 2025
42 checks passed
@shaypal5 shaypal5 deleted the copilot/fix-254 branch July 10, 2025 08:29
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.

Caching regression with cachier v3.1.2

2 participants