2025-03-05 18:11:29 - 
=== PROJECT STATEMENT ===
2025-03-05 18:11:29 - ---
title: Opero Project Rules
glob: "**/*.py"
---

# Opero Project Rules

## Project Overview

Opero is a Python library for orchestrating function execution with retries, fallbacks, and concurrency control. It provides a flexible way to handle errors and ensure reliable execution of functions.

## Code Style

- Follow PEP 8 for code style
- Use type hints for all functions and methods
- Write clear docstrings for all public functions and classes
- Use f-strings for string formatting
- Keep functions and methods small and focused
- Extract complex logic into helper methods
- Use descriptive variable names

## Error Handling

- Use appropriate exception types
- Handle errors gracefully with retries and fallbacks
- Log errors with appropriate context
- Provide helpful error messages

## Testing

- Write unit tests for all functionality
- Test edge cases and error conditions
- Use pytest for testing
- Aim for high test coverage

## Logging

- Use the built-in logging module
- Log at appropriate levels (debug, info, warning, error)
- Include context in log messages
- Configure logging in a way that doesn't interfere with applications using the library

## Performance

- Optimize critical paths
- Minimize overhead in the orchestration layer
- Use async/await for I/O-bound operations
- Use appropriate concurrency mechanisms for CPU-bound operations 
2025-03-05 18:11:29 - 
=== Current Status ===
2025-03-05 18:11:29 - Error: LOG.md is missing
2025-03-05 18:11:29 - [ 992]  .
├── [  96]  .cursor
│   └── [ 128]  rules
│       ├── [1.3K]  0project.mdc
│       └── [2.9K]  filetree.mdc
├── [  96]  .github
│   └── [ 128]  workflows
│       ├── [2.7K]  push.yml
│       └── [1.4K]  release.yml
├── [4.4K]  .gitignore
├── [ 470]  .pre-commit-config.yaml
├── [  96]  .specstory
│   └── [ 384]  history
│       ├── [2.7K]  .what-is-this.md
│       ├── [574K]  2025-03-04_03-16-comprehensive-plan-for-opero-package-implementation.md
│       ├── [4.1K]  2025-03-04_05-40-cleanup-analysis-and-todo-update.md
│       ├── [157K]  2025-03-04_06-07-implementing-todo-md-phases-1-and-2.md
│       ├── [129K]  2025-03-04_07-28-implementing-todo-md-phases-1-and-2.md
│       ├── [ 67K]  2025-03-04_07-59-project-maintenance-and-documentation-update.md
│       ├── [198K]  2025-03-04_08-40-managing-todo-list-tasks.md
│       ├── [138K]  2025-03-05_12-35-improving-opero-api-with-new-decorators.md
│       ├── [2.2K]  2025-03-05_13-36-repository-analysis-and-todo-update.md
│       └── [574K]  2025-03-05_14-22-implementing-todo-md-for-opero-library.md
├── [2.0K]  CHANGELOG.md
├── [1.5K]  CLEANUP.txt
├── [1.0K]  LICENSE
├── [2.2K]  PROGRESS.md
├── [7.0K]  README.md
├── [349K]  REPO_CONTENT.txt
├── [2.3K]  TODO.md
├── [ 13K]  cleanup.py
├── [ 224]  dist
│   └── [   0]  .gitkeep
├── [  96]  examples
│   └── [9.6K]  basic_usage.py
├── [2.2M]  get-pip.py
├── [ 426]  package.toml
├── [6.0K]  pyproject.toml
├── [ 128]  src
│   └── [ 320]  opero
│       ├── [1.5K]  __init__.py
│       ├── [ 160]  concurrency
│       │   ├── [ 439]  __init__.py
│       │   └── [ 11K]  pool.py
│       ├── [ 256]  core
│       │   ├── [ 765]  __init__.py
│       │   ├── [2.8K]  cache.py
│       │   ├── [6.4K]  fallback.py
│       │   ├── [3.4K]  rate_limit.py
│       │   └── [3.8K]  retry.py
│       ├── [ 192]  decorators
│       │   ├── [ 348]  __init__.py
│       │   ├── [3.8K]  opero.py
│       │   └── [4.7K]  opmap.py
│       ├── [ 563]  exceptions.py
│       └── [ 192]  utils
│           ├── [ 460]  __init__.py
│           ├── [2.1K]  async_utils.py
│           └── [1.6K]  logging.py
├── [ 192]  tests
│   ├── [4.6K]  test_core.py
│   ├── [4.3K]  test_decorators.py
│   └── [ 139]  test_package.py
├── [194K]  twat-cache.txt
├── [ 78K]  twat-mp.txt
└── [ 91K]  uv.lock

16 directories, 50 files

2025-03-05 18:11:29 - 
Project structure:
2025-03-05 18:11:29 - [ 992]  .
├── [  96]  .cursor
│   └── [ 128]  rules
│       ├── [1.3K]  0project.mdc
│       └── [2.9K]  filetree.mdc
├── [  96]  .github
│   └── [ 128]  workflows
│       ├── [2.7K]  push.yml
│       └── [1.4K]  release.yml
├── [4.4K]  .gitignore
├── [ 470]  .pre-commit-config.yaml
├── [  96]  .specstory
│   └── [ 384]  history
│       ├── [2.7K]  .what-is-this.md
│       ├── [574K]  2025-03-04_03-16-comprehensive-plan-for-opero-package-implementation.md
│       ├── [4.1K]  2025-03-04_05-40-cleanup-analysis-and-todo-update.md
│       ├── [157K]  2025-03-04_06-07-implementing-todo-md-phases-1-and-2.md
│       ├── [129K]  2025-03-04_07-28-implementing-todo-md-phases-1-and-2.md
│       ├── [ 67K]  2025-03-04_07-59-project-maintenance-and-documentation-update.md
│       ├── [198K]  2025-03-04_08-40-managing-todo-list-tasks.md
│       ├── [138K]  2025-03-05_12-35-improving-opero-api-with-new-decorators.md
│       ├── [2.2K]  2025-03-05_13-36-repository-analysis-and-todo-update.md
│       └── [574K]  2025-03-05_14-22-implementing-todo-md-for-opero-library.md
├── [2.0K]  CHANGELOG.md
├── [1.5K]  CLEANUP.txt
├── [1.0K]  LICENSE
├── [2.2K]  PROGRESS.md
├── [7.0K]  README.md
├── [349K]  REPO_CONTENT.txt
├── [2.3K]  TODO.md
├── [ 13K]  cleanup.py
├── [ 224]  dist
│   └── [   0]  .gitkeep
├── [  96]  examples
│   └── [9.6K]  basic_usage.py
├── [2.2M]  get-pip.py
├── [ 426]  package.toml
├── [6.0K]  pyproject.toml
├── [ 128]  src
│   └── [ 320]  opero
│       ├── [1.5K]  __init__.py
│       ├── [ 160]  concurrency
│       │   ├── [ 439]  __init__.py
│       │   └── [ 11K]  pool.py
│       ├── [ 256]  core
│       │   ├── [ 765]  __init__.py
│       │   ├── [2.8K]  cache.py
│       │   ├── [6.4K]  fallback.py
│       │   ├── [3.4K]  rate_limit.py
│       │   └── [3.8K]  retry.py
│       ├── [ 192]  decorators
│       │   ├── [ 348]  __init__.py
│       │   ├── [3.8K]  opero.py
│       │   └── [4.7K]  opmap.py
│       ├── [ 563]  exceptions.py
│       └── [ 192]  utils
│           ├── [ 460]  __init__.py
│           ├── [2.1K]  async_utils.py
│           └── [1.6K]  logging.py
├── [ 192]  tests
│   ├── [4.6K]  test_core.py
│   ├── [4.3K]  test_decorators.py
│   └── [ 139]  test_package.py
├── [194K]  twat-cache.txt
├── [ 78K]  twat-mp.txt
└── [ 91K]  uv.lock

16 directories, 50 files

2025-03-05 18:11:29 - On branch main
Your branch is up to date with 'origin/main'.

Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
	deleted:    src/opero/_version.py
	deleted:    src/opero/concurrency.py
	deleted:    src/opero/core.py
	deleted:    src/opero/decorators.py
	deleted:    src/opero/opero.py
	deleted:    src/opero/rate_limit.py
	deleted:    src/opero/retry.py
	deleted:    src/opero/utils.py
	deleted:    src/opero/version.py

Changes not staged for commit:
  (use "git add/rm <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
	modified:   .cursor/rules/filetree.mdc
	modified:   .gitignore
	modified:   .specstory/history/2025-03-05_12-35-improving-opero-api-with-new-decorators.md
	modified:   .specstory/history/2025-03-05_14-22-implementing-todo-md-for-opero-library.md
	modified:   CHANGELOG.md
	modified:   CLEANUP.txt
	modified:   LICENSE
	deleted:    LOG.md
	modified:   README.md
	modified:   REPO_CONTENT.txt
	modified:   TODO.md
	modified:   cleanup.py
	modified:   examples/basic_usage.py
	modified:   pyproject.toml
	deleted:    setup.py
	modified:   src/opero/__init__.py
	modified:   src/opero/concurrency/__init__.py
	modified:   src/opero/concurrency/pool.py
	modified:   src/opero/core/__init__.py
	modified:   src/opero/core/cache.py
	modified:   src/opero/core/fallback.py
	modified:   src/opero/core/rate_limit.py
	modified:   src/opero/core/retry.py
	modified:   src/opero/decorators/__init__.py
	modified:   src/opero/decorators/opero.py
	deleted:    src/opero/decorators/operomap.py
	modified:   src/opero/utils/__init__.py
	modified:   src/opero/utils/async_utils.py
	modified:   src/opero/utils/logging.py
	modified:   tests/test_core.py
	modified:   tests/test_decorators.py
	modified:   uv.lock

Untracked files:
  (use "git add <file>..." to include in what will be committed)
	PROGRESS.md
	get-pip.py
	src/opero/decorators/opmap.py


2025-03-05 18:11:29 - On branch main
Your branch is up to date with 'origin/main'.

Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
	deleted:    src/opero/_version.py
	deleted:    src/opero/concurrency.py
	deleted:    src/opero/core.py
	deleted:    src/opero/decorators.py
	deleted:    src/opero/opero.py
	deleted:    src/opero/rate_limit.py
	deleted:    src/opero/retry.py
	deleted:    src/opero/utils.py
	deleted:    src/opero/version.py

Changes not staged for commit:
  (use "git add/rm <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
	modified:   .cursor/rules/filetree.mdc
	modified:   .gitignore
	modified:   .specstory/history/2025-03-05_12-35-improving-opero-api-with-new-decorators.md
	modified:   .specstory/history/2025-03-05_14-22-implementing-todo-md-for-opero-library.md
	modified:   CHANGELOG.md
	modified:   CLEANUP.txt
	modified:   LICENSE
	deleted:    LOG.md
	modified:   README.md
	modified:   REPO_CONTENT.txt
	modified:   TODO.md
	modified:   cleanup.py
	modified:   examples/basic_usage.py
	modified:   pyproject.toml
	deleted:    setup.py
	modified:   src/opero/__init__.py
	modified:   src/opero/concurrency/__init__.py
	modified:   src/opero/concurrency/pool.py
	modified:   src/opero/core/__init__.py
	modified:   src/opero/core/cache.py
	modified:   src/opero/core/fallback.py
	modified:   src/opero/core/rate_limit.py
	modified:   src/opero/core/retry.py
	modified:   src/opero/decorators/__init__.py
	modified:   src/opero/decorators/opero.py
	deleted:    src/opero/decorators/operomap.py
	modified:   src/opero/utils/__init__.py
	modified:   src/opero/utils/async_utils.py
	modified:   src/opero/utils/logging.py
	modified:   tests/test_core.py
	modified:   tests/test_decorators.py
	modified:   uv.lock

Untracked files:
  (use "git add <file>..." to include in what will be committed)
	PROGRESS.md
	get-pip.py
	src/opero/decorators/opmap.py


2025-03-05 18:11:29 - 
=== Environment Status ===
2025-03-05 18:11:29 - Setting up virtual environment
2025-03-05 18:11:29 - Virtual environment created and activated
2025-03-05 18:11:29 - Installing package with all extras
2025-03-05 18:11:29 - Setting up virtual environment
2025-03-05 18:11:29 - Virtual environment created and activated
2025-03-05 18:11:30 - Package installed successfully
2025-03-05 18:11:30 - Running code quality checks
2025-03-05 18:11:30 - >>> Running code fixes...
2025-03-05 18:11:30 - src/opero/concurrency/pool.py:24:5: C901 `get_parallel_executor` is too complex (11 > 10)
   |
24 | def get_parallel_executor(
   |     ^^^^^^^^^^^^^^^^^^^^^ C901
25 |     mode: str = "process",
26 |     workers: int = 4,
   |

src/opero/concurrency/pool.py:27:5: FBT001 Boolean-typed positional argument in function definition
   |
25 |     mode: str = "process",
26 |     workers: int = 4,
27 |     ordered: bool = True,
   |     ^^^^^^^ FBT001
28 |     progress: bool = True,
29 |     **kwargs,
   |

src/opero/concurrency/pool.py:27:5: FBT002 Boolean default positional argument in function definition
   |
25 |     mode: str = "process",
26 |     workers: int = 4,
27 |     ordered: bool = True,
   |     ^^^^^^^ FBT002
28 |     progress: bool = True,
29 |     **kwargs,
   |

src/opero/concurrency/pool.py:28:5: FBT001 Boolean-typed positional argument in function definition
   |
26 |     workers: int = 4,
27 |     ordered: bool = True,
28 |     progress: bool = True,
   |     ^^^^^^^^ FBT001
29 |     **kwargs,
30 | ) -> Callable[[Callable[[T], R], Iterable[T]], list[R]]:
   |

src/opero/concurrency/pool.py:28:5: FBT002 Boolean default positional argument in function definition
   |
26 |     workers: int = 4,
27 |     ordered: bool = True,
28 |     progress: bool = True,
   |     ^^^^^^^^ FBT002
29 |     **kwargs,
30 | ) -> Callable[[Callable[[T], R], Iterable[T]], list[R]]:
   |

src/opero/concurrency/pool.py:168:5: C901 `get_parallel_map_decorator` is too complex (18 > 10)
    |
168 | def get_parallel_map_decorator(
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^ C901
169 |     mode: str = "process",
170 |     workers: int = 4,
    |

src/opero/concurrency/pool.py:171:5: FBT001 Boolean-typed positional argument in function definition
    |
169 |     mode: str = "process",
170 |     workers: int = 4,
171 |     ordered: bool = True,
    |     ^^^^^^^ FBT001
172 |     progress: bool = True,
173 |     **kwargs,
    |

src/opero/concurrency/pool.py:171:5: FBT002 Boolean default positional argument in function definition
    |
169 |     mode: str = "process",
170 |     workers: int = 4,
171 |     ordered: bool = True,
    |     ^^^^^^^ FBT002
172 |     progress: bool = True,
173 |     **kwargs,
    |

src/opero/concurrency/pool.py:172:5: FBT001 Boolean-typed positional argument in function definition
    |
170 |     workers: int = 4,
171 |     ordered: bool = True,
172 |     progress: bool = True,
    |     ^^^^^^^^ FBT001
173 |     **kwargs,
174 | ) -> Callable[[Callable[[T], R]], Callable[[Iterable[T]], list[R]]]:
    |

src/opero/concurrency/pool.py:172:5: FBT002 Boolean default positional argument in function definition
    |
170 |     workers: int = 4,
171 |     ordered: bool = True,
172 |     progress: bool = True,
    |     ^^^^^^^^ FBT002
173 |     **kwargs,
174 | ) -> Callable[[Callable[[T], R]], Callable[[Iterable[T]], list[R]]]:
    |

src/opero/core/cache.py:24:5: FBT001 Boolean-typed positional argument in function definition
   |
23 | def get_cache_decorator(
24 |     cache: bool = True,
   |     ^^^^^ FBT001
25 |     cache_ttl: int | None = None,
26 |     cache_backend: str = "memory",
   |

src/opero/core/cache.py:24:5: FBT002 Boolean default positional argument in function definition
   |
23 | def get_cache_decorator(
24 |     cache: bool = True,
   |     ^^^^^ FBT002
25 |     cache_ttl: int | None = None,
26 |     cache_backend: str = "memory",
   |

src/opero/core/fallback.py:37:5: C901 `get_fallback_decorator` is too complex (15 > 10)
   |
37 | def get_fallback_decorator(
   |     ^^^^^^^^^^^^^^^^^^^^^^ C901
38 |     arg_fallback: str | None = None,
39 | ) -> Callable[[Callable[..., R]], Callable[..., R | Coroutine[Any, Any, R]]]:
   |

src/opero/core/fallback.py:54:9: C901 `decorator` is too complex (13 > 10)
   |
52 |         return lambda func: func
53 |
54 |     def decorator(func: Callable[..., R]) -> Callable[..., R | Coroutine[Any, Any, R]]:
   |         ^^^^^^^^^ C901
55 |         """
56 |         Decorator function.
   |

src/opero/core/fallback.py:123:21: B904 Within an `except` clause, raise exceptions with `raise ... from err` or `raise ... from None` to distinguish them from errors in exception handling
    |
121 |                       # If all fallbacks fail, raise a FallbackError with all errors
122 |                       msg = f"All fallback attempts failed for {func.__name__}"
123 | /                     raise FallbackError(
124 | |                         msg,
125 | |                         errors=errors,
126 | |                     )
    | |_____________________^ B904
127 |
128 |               return async_wrapper
    |

src/opero/core/fallback.py:173:21: B904 Within an `except` clause, raise exceptions with `raise ... from err` or `raise ... from None` to distinguish them from errors in exception handling
    |
171 |                       # If all fallbacks fail, raise a FallbackError with all errors
172 |                       msg = f"All fallback attempts failed for {func.__name__}"
173 | /                     raise FallbackError(
174 | |                         msg,
175 | |                         errors=errors,
176 | |                     )
    | |_____________________^ B904
177 |
178 |               return sync_wrapper
    |

src/opero/core/retry.py:25:5: PLR0913 Too many arguments in function definition (6 > 5)
   |
25 | def get_retry_decorator(
   |     ^^^^^^^^^^^^^^^^^^^ PLR0913
26 |     retries: int = 3,
27 |     backoff_factor: float = 1.5,
   |

src/opero/core/retry.py:31:5: FBT001 Boolean-typed positional argument in function definition
   |
29 |     max_delay: float = 30.0,
30 |     retry_on: type[Exception] | tuple[type[Exception], ...] = (Exception,),
31 |     jitter: bool = True,
   |     ^^^^^^ FBT001
32 |     **kwargs,
33 | ) -> Callable[[Callable[..., R]], Callable[..., R]]:
   |

src/opero/core/retry.py:31:5: FBT002 Boolean default positional argument in function definition
   |
29 |     max_delay: float = 30.0,
30 |     retry_on: type[Exception] | tuple[type[Exception], ...] = (Exception,),
31 |     jitter: bool = True,
   |     ^^^^^^ FBT002
32 |     **kwargs,
33 | ) -> Callable[[Callable[..., R]], Callable[..., R]]:
   |

src/opero/decorators/opero.py:22:5: PLR0913 Too many arguments in function definition (12 > 5)
   |
22 | def opero(
   |     ^^^^^ PLR0913
23 |     # Caching options
24 |     cache: bool = True,
   |

src/opero/decorators/opero.py:24:5: FBT001 Boolean-typed positional argument in function definition
   |
22 | def opero(
23 |     # Caching options
24 |     cache: bool = True,
   |     ^^^^^ FBT001
25 |     cache_ttl: int | None = None,
26 |     cache_backend: str = "memory",
   |

src/opero/decorators/opero.py:24:5: FBT002 Boolean default positional argument in function definition
   |
22 | def opero(
23 |     # Caching options
24 |     cache: bool = True,
   |     ^^^^^ FBT002
25 |     cache_ttl: int | None = None,
26 |     cache_backend: str = "memory",
   |

src/opero/decorators/opmap.py:24:5: PLR0913 Too many arguments in function definition (16 > 5)
   |
24 | def opmap(
   |     ^^^^^ PLR0913
25 |     # Caching options
26 |     cache: bool = True,
   |

src/opero/decorators/opmap.py:26:5: FBT001 Boolean-typed positional argument in function definition
   |
24 | def opmap(
25 |     # Caching options
26 |     cache: bool = True,
   |     ^^^^^ FBT001
27 |     cache_ttl: int | None = None,
28 |     cache_backend: str = "memory",
   |

src/opero/decorators/opmap.py:26:5: FBT002 Boolean default positional argument in function definition
   |
24 | def opmap(
25 |     # Caching options
26 |     cache: bool = True,
   |     ^^^^^ FBT002
27 |     cache_ttl: int | None = None,
28 |     cache_backend: str = "memory",
   |

src/opero/decorators/opmap.py:44:5: FBT001 Boolean-typed positional argument in function definition
   |
42 |     mode: str = "process",
43 |     workers: int = 4,
44 |     ordered: bool = True,
   |     ^^^^^^^ FBT001
45 |     progress: bool = True,
46 |     # Additional options
   |

src/opero/decorators/opmap.py:44:5: FBT002 Boolean default positional argument in function definition
   |
42 |     mode: str = "process",
43 |     workers: int = 4,
44 |     ordered: bool = True,
   |     ^^^^^^^ FBT002
45 |     progress: bool = True,
46 |     # Additional options
   |

src/opero/decorators/opmap.py:45:5: FBT001 Boolean-typed positional argument in function definition
   |
43 |     workers: int = 4,
44 |     ordered: bool = True,
45 |     progress: bool = True,
   |     ^^^^^^^^ FBT001
46 |     # Additional options
47 |     **kwargs,
   |

src/opero/decorators/opmap.py:45:5: FBT002 Boolean default positional argument in function definition
   |
43 |     workers: int = 4,
44 |     ordered: bool = True,
45 |     progress: bool = True,
   |     ^^^^^^^^ FBT002
46 |     # Additional options
47 |     **kwargs,
   |

src/opero/utils/logging.py:1:1: A005 Module `logging` shadows a Python standard-library module
src/opero/utils/logging.py:21:5: FBT001 Boolean-typed positional argument in function definition
   |
19 |     format_string: str | None = None,
20 |     stream: TextIO | None = None,
21 |     verbose: bool = False,
   |     ^^^^^^^ FBT001
22 | ) -> logging.Logger:
23 |     """
   |

src/opero/utils/logging.py:21:5: FBT002 Boolean default positional argument in function definition
   |
19 |     format_string: str | None = None,
20 |     stream: TextIO | None = None,
21 |     verbose: bool = False,
   |     ^^^^^^^ FBT002
22 | ) -> logging.Logger:
23 |     """
   |

Found 32 errors.

2025-03-05 18:11:30 - 7 files reformatted, 11 files left unchanged

2025-03-05 18:11:30 - >>>Running type checks...
2025-03-05 18:11:31 - >>> Running tests...
2025-03-05 18:11:33 - ============================= test session starts ==============================
platform darwin -- Python 3.12.8, pytest-8.3.5, pluggy-1.5.0 -- /Users/adam/Developer/vcs/github.twardoch/pub/opero/.venv/bin/python
cachedir: .pytest_cache
rootdir: /Users/adam/Developer/vcs/github.twardoch/pub/opero
configfile: pyproject.toml
plugins: cov-6.0.0, asyncio-0.25.3
asyncio: mode=Mode.AUTO, asyncio_default_fixture_loop_scope=None
collecting ... collected 1 item / 2 errors

==================================== ERRORS ====================================
_____________________ ERROR collecting tests/test_core.py ______________________
ImportError while importing test module '/Users/adam/Developer/vcs/github.twardoch/pub/opero/tests/test_core.py'.
Hint: make sure your test modules/packages have valid Python names.
Traceback:
/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/importlib/__init__.py:90: in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
tests/test_core.py:11: in <module>
    from opero.core.fallback import FallbackError, get_fallback_decorator
src/opero/__init__.py:17: in <module>
    from opero.core import (
src/opero/core/__init__.py:10: in <module>
    from opero.core.cache import clear_cache, get_cache_context, get_cache_decorator
src/opero/core/cache.py:15: in <module>
    from twat_cache import CacheContext, ucache
.venv/lib/python3.12/site-packages/twat_cache/__init__.py:5: in <module>
    from twat_cache.cache import clear_cache, get_stats
.venv/lib/python3.12/site-packages/twat_cache/cache.py:21: in <module>
    from .engines.base import BaseCacheEngine
.venv/lib/python3.12/site-packages/twat_cache/engines/__init__.py:19: in <module>
    from .manager import get_engine_manager
.venv/lib/python3.12/site-packages/twat_cache/engines/manager.py:32: in <module>
    from .klepto import KleptoEngine
.venv/lib/python3.12/site-packages/twat_cache/engines/klepto.py:18: in <module>
    from klepto import lru_cache, lfu_cache, rr_cache
E   ModuleNotFoundError: No module named 'klepto'
__________________ ERROR collecting tests/test_decorators.py ___________________
ImportError while importing test module '/Users/adam/Developer/vcs/github.twardoch/pub/opero/tests/test_decorators.py'.
Hint: make sure your test modules/packages have valid Python names.
Traceback:
/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/importlib/__init__.py:90: in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
tests/test_decorators.py:11: in <module>
    from opero.decorators import opero, opmap
src/opero/__init__.py:17: in <module>
    from opero.core import (
src/opero/core/__init__.py:10: in <module>
    from opero.core.cache import clear_cache, get_cache_context, get_cache_decorator
src/opero/core/cache.py:15: in <module>
    from twat_cache import CacheContext, ucache
.venv/lib/python3.12/site-packages/twat_cache/__init__.py:8: in <module>
    from twat_cache.context import engine_context, CacheContext, get_or_create_engine
.venv/lib/python3.12/site-packages/twat_cache/context.py:27: in <module>
    from twat_cache.engines.manager import get_engine_manager
.venv/lib/python3.12/site-packages/twat_cache/engines/__init__.py:19: in <module>
    from .manager import get_engine_manager
.venv/lib/python3.12/site-packages/twat_cache/engines/manager.py:32: in <module>
    from .klepto import KleptoEngine
.venv/lib/python3.12/site-packages/twat_cache/engines/klepto.py:18: in <module>
    from klepto import lru_cache, lfu_cache, rr_cache
E   ModuleNotFoundError: No module named 'klepto'
=========================== short test summary info ============================
ERROR tests/test_core.py
ERROR tests/test_decorators.py
!!!!!!!!!!!!!!!!!!! Interrupted: 2 errors during collection !!!!!!!!!!!!!!!!!!!!
============================== 2 errors in 1.09s ===============================

2025-03-05 18:11:33 - All checks completed
2025-03-05 18:11:33 - 
=== TODO.md ===
2025-03-05 18:11:33 - ---
this_file: TODO.md
---

# TODO

This file tracks planned features and improvements for the `opero` package.

## 1. High Priority

- [ ] Enhance core functionality
  - [ ] Improve parameter-based fallback mechanism
  - [ ] Add support for custom fallback strategies
  - [ ] Implement retry with exponential backoff and jitter
  - [ ] Add support for custom retry strategies
  - [ ] Implement rate limiting with token bucket algorithm
  - [ ] Add support for distributed rate limiting

- [ ] Improve caching system
  - [ ] Implement memory cache backend
  - [ ] Add disk cache backend
  - [ ] Add Redis cache backend
  - [ ] Support custom cache key generation
  - [ ] Add cache invalidation strategies

- [ ] Enhance parallel execution
  - [ ] Improve process-based parallelism
  - [ ] Add thread-based parallelism
  - [ ] Optimize async-based parallelism
  - [ ] Implement hybrid async-process parallelism
  - [ ] Add progress tracking and cancellation

## 2. Medium Priority

- [ ] Improve error handling and logging
  - [ ] Add structured error reporting
  - [ ] Implement context-based logging
  - [ ] Add performance metrics collection
  - [ ] Support distributed tracing
  - [ ] Add telemetry features

- [ ] Enhance configuration system
  - [ ] Add YAML/JSON configuration support
  - [ ] Implement environment variable configuration
  - [ ] Add dynamic configuration reloading
  - [ ] Support configuration validation

- [ ] Add monitoring and observability
  - [ ] Implement health checks
  - [ ] Add metrics collection
  - [ ] Support OpenTelemetry integration
  - [ ] Add performance profiling tools

## 3. Low Priority

- [ ] Improve documentation
  - [ ] Create comprehensive API reference
  - [ ] Add more usage examples
  - [ ] Write troubleshooting guide
  - [ ] Create architecture documentation
  - [ ] Add performance optimization guide

- [ ] Add developer tools
  - [ ] Create development environment setup script
  - [ ] Add code generation tools
  - [ ] Implement debugging utilities
  - [ ] Add benchmarking tools

- [ ] Enhance testing
  - [ ] Add property-based tests
  - [ ] Implement integration test suite
  - [ ] Add performance tests
  - [ ] Create stress tests
  - [ ] Add chaos testing support

Tip: Periodically run `python ./cleanup.py status` to see results of lints and tests. Use `uv pip ...` not `pip ...`


2025-03-05 18:11:35 - 
📦 Repomix v0.2.29

No custom config found at repomix.config.json or global config at /Users/adam/.config/repomix/repomix.config.json.
You can add a config file for additional settings. Please check https://github.com/yamadashy/repomix for more information.
⠙ Collecting files...
[2K[1A[2K[G⠹ Collecting files...
[2K[1A[2K[G⠸ Collect file... (27/36) cleanup.py
[2K[1A[2K[G⠼ Collect file... (28/36) get-pip.py
[2K[1A[2K[G⠴ Collect file... (35/36) twat-cache.txt
[2K[1A[2K[G⠦ Running security check... (3/36) .github/workflows/push.yml
[2K[1A[2K[G⠧ Running security check... (27/36) cleanup.py
[2K[1A[2K[G⠇ Processing files...
[2K[1A[2K[G⠏ Processing file... (9/36) src/opero/core/cache.py
[2K[1A[2K[G⠋ Processing file... (27/36) cleanup.py
[2K[1A[2K[G⠙ Calculating metrics...
[2K[1A[2K[G⠹ Calculating metrics...
[2K[1A[2K[G⠸ Calculating metrics...
[2K[1A[2K[G⠼ Calculating metrics... (23/36) tests/test_package.py
[2K[1A[2K[G⠴ Calculating metrics... (35/36) twat-cache.txt
[2K[1A[2K[G✔ Packing completed successfully!

📈 Top 5 Files by Character Count and Token Count:
──────────────────────────────────────────────────
1.  twat-cache.txt (198,097 chars, 47,960 tokens)
2.  twat-mp.txt (79,940 chars, 19,212 tokens)
3.  README.md (7,118 chars, 1,723 tokens)
4.  pyproject.toml (6,155 chars, 1,950 tokens)
5.  cleanup.py (6,088 chars, 1,371 tokens)

🔎 Security Check:
──────────────────
✔ No suspicious files detected.

📊 Pack Summary:
────────────────
  Total Files: 36 files
  Total Chars: 338,859 chars
 Total Tokens: 82,935 tokens
       Output: REPO_CONTENT.txt
     Security: ✔ No suspicious files detected

🎉 All Done!
Your repository has been successfully packed.

💡 Repomix is now available in your browser! Try it at https://repomix.com

2025-03-05 18:11:35 - Repository content mixed into REPO_CONTENT.txt
