Refactoring in tests: prepare for testing with multiple languages

This commit is contained in:
Michael Panchenko
2025-04-27 13:00:45 +02:00
parent 072b5caefb
commit 433d7f4d59
24 changed files with 103 additions and 159 deletions
@@ -0,0 +1 @@
ignore_this_dir*/
@@ -0,0 +1,3 @@
"""
Custom test package for testing code parsing capabilities.
"""
@@ -0,0 +1,475 @@
"""
Advanced Python features for testing code parsing capabilities.
This module contains various advanced Python code patterns to ensure
that the code parser can correctly handle them.
"""
from __future__ import annotations
import asyncio
import os
from abc import ABC, abstractmethod
from collections.abc import Callable, Iterable
from contextlib import contextmanager
from dataclasses import dataclass, field
from enum import Enum, Flag, IntEnum, auto
from functools import wraps
from typing import (
Annotated,
Any,
ClassVar,
Final,
Generic,
Literal,
NewType,
Protocol,
TypedDict,
TypeVar,
)
# Type variables for generics
T = TypeVar("T")
K = TypeVar("K")
V = TypeVar("V")
# Custom types using NewType
UserId = NewType("UserId", str)
ItemId = NewType("ItemId", int)
# Type aliases
PathLike = str | os.PathLike
JsonDict = dict[str, Any]
# TypedDict
class UserDict(TypedDict):
"""TypedDict representing user data."""
id: str
name: str
email: str
age: int
roles: list[str]
# Enums
class Status(Enum):
"""Status enum for process states."""
PENDING = "pending"
RUNNING = "running"
COMPLETED = "completed"
FAILED = "failed"
class Priority(IntEnum):
"""Priority levels for tasks."""
LOW = 0
MEDIUM = 5
HIGH = 10
CRITICAL = auto()
class Permissions(Flag):
"""Permission flags for access control."""
NONE = 0
READ = 1
WRITE = 2
EXECUTE = 4
ALL = READ | WRITE | EXECUTE
# Abstract class with various method types
class BaseProcessor(ABC):
"""Abstract base class for processors with various method patterns."""
# Class variable with type annotation
DEFAULT_TIMEOUT: ClassVar[int] = 30
MAX_RETRIES: Final[int] = 3
def __init__(self, name: str, config: dict[str, Any] | None = None):
self.name = name
self.config = config or {}
self._status = Status.PENDING
@property
def status(self) -> Status:
"""Status property getter."""
return self._status
@status.setter
def status(self, value: Status) -> None:
"""Status property setter."""
if not isinstance(value, Status):
raise TypeError(f"Expected Status enum, got {type(value)}")
self._status = value
@abstractmethod
def process(self, data: Any) -> Any:
"""Process the input data."""
@classmethod
def create_from_config(cls, config: dict[str, Any]) -> BaseProcessor:
"""Factory classmethod."""
name = config.get("name", "default")
return cls(name=name, config=config)
@staticmethod
def validate_config(config: dict[str, Any]) -> bool:
"""Static method for config validation."""
return "name" in config
def __str__(self) -> str:
return f"{self.__class__.__name__}(name={self.name})"
# Concrete implementation of abstract class
class DataProcessor(BaseProcessor):
"""Concrete implementation of BaseProcessor."""
def __init__(self, name: str, config: dict[str, Any] | None = None, priority: Priority = Priority.MEDIUM):
super().__init__(name, config)
self.priority = priority
self.processed_count = 0
def process(self, data: Any) -> Any:
"""Process the data."""
# Nested function definition
def transform(item: Any) -> Any:
# Nested function within a nested function
def apply_rules(x: Any) -> Any:
return x
return apply_rules(item)
# Lambda function
normalize = lambda x: x / max(x) if hasattr(x, "__iter__") and len(x) > 0 else x # noqa: F841
result = transform(data)
self.processed_count += 1
return result
# Method with complex type hints
def batch_process(self, items: list[str | dict[str, Any] | tuple[Any, ...]]) -> dict[str, list[Any]]:
"""Process multiple items in a batch."""
results: dict[str, list[Any]] = {"success": [], "error": []}
for item in items:
try:
result = self.process(item)
results["success"].append(result)
except Exception as e:
results["error"].append((item, str(e)))
return results
# Generator method
def process_stream(self, data_stream: Iterable[T]) -> Iterable[T]:
"""Process a stream of data, yielding results as they're processed."""
for item in data_stream:
yield self.process(item)
# Async method
async def async_process(self, data: Any) -> Any:
"""Process data asynchronously."""
await asyncio.sleep(0.1)
return self.process(data)
# Method with function parameters
def apply_transform(self, data: Any, transform_func: Callable[[Any], Any]) -> Any:
"""Apply a custom transform function to the data."""
return transform_func(data)
# Dataclass
@dataclass
class Task:
"""Task dataclass for tracking work items."""
id: str
name: str
status: Status = Status.PENDING
priority: Priority = Priority.MEDIUM
metadata: dict[str, Any] = field(default_factory=dict)
dependencies: list[str] = field(default_factory=list)
created_at: float | None = None
def __post_init__(self):
if self.created_at is None:
import time
self.created_at = time.time()
def has_dependencies(self) -> bool:
"""Check if task has dependencies."""
return len(self.dependencies) > 0
# Generic class
class Repository(Generic[T]):
"""Generic repository for managing collections of items."""
def __init__(self):
self.items: dict[str, T] = {}
def add(self, id: str, item: T) -> None:
"""Add an item to the repository."""
self.items[id] = item
def get(self, id: str) -> T | None:
"""Get an item by id."""
return self.items.get(id)
def remove(self, id: str) -> bool:
"""Remove an item by id."""
if id in self.items:
del self.items[id]
return True
return False
def list_all(self) -> list[T]:
"""List all items."""
return list(self.items.values())
# Type with Protocol (structural subtyping)
class Serializable(Protocol):
"""Protocol for objects that can be serialized to dict."""
def to_dict(self) -> dict[str, Any]: ...
#
# Decorator function
def log_execution(func: Callable) -> Callable:
"""Decorator to log function execution."""
@wraps(func)
def wrapper(*args, **kwargs):
print(f"Executing {func.__name__}")
result = func(*args, **kwargs)
print(f"Finished {func.__name__}")
return result
return wrapper
# Context manager
@contextmanager
def transaction_context(name: str = "default"):
"""Context manager for transaction-like operations."""
print(f"Starting transaction: {name}")
try:
yield name
print(f"Committing transaction: {name}")
except Exception as e:
print(f"Rolling back transaction: {name}, error: {e}")
raise
# Function with complex parameter annotations
def advanced_search(
query: str,
filters: dict[str, Any] | None = None,
sort_by: str | None = None,
sort_order: Literal["asc", "desc"] = "asc",
page: int = 1,
page_size: int = 10,
include_metadata: bool = False,
) -> tuple[list[dict[str, Any]], int]:
"""
Advanced search function with many parameters.
Returns search results and total count.
"""
results = []
total = 0
# Simulating search functionality
return results, total
# Class with nested classes
class OuterClass:
"""Outer class with nested classes and methods."""
class NestedClass:
"""Nested class inside OuterClass."""
def __init__(self, value: Any):
self.value = value
def get_value(self) -> Any:
"""Get the stored value."""
return self.value
class DeeplyNestedClass:
"""Deeply nested class for testing parser depth capabilities."""
def deep_method(self) -> str:
"""Method in deeply nested class."""
return "deep"
def __init__(self, name: str):
self.name = name
self.nested = self.NestedClass(name)
def get_nested(self) -> NestedClass:
"""Get the nested class instance."""
return self.nested
# Method with nested functions
def process_with_nested(self, data: Any) -> Any:
"""Method demonstrating deeply nested function definitions."""
def level1(x: Any) -> Any:
"""First level nested function."""
def level2(y: Any) -> Any:
"""Second level nested function."""
def level3(z: Any) -> Any:
"""Third level nested function."""
return z
return level3(y)
return level2(x)
return level1(data)
# Metaclass example
class Meta(type):
"""Metaclass example for testing advanced class handling."""
def __new__(mcs, name, bases, attrs):
print(f"Creating class: {name}")
return super().__new__(mcs, name, bases, attrs)
def __init__(cls, name, bases, attrs):
print(f"Initializing class: {name}")
super().__init__(name, bases, attrs)
class WithMeta(metaclass=Meta):
"""Class that uses a metaclass."""
def __init__(self, value: str):
self.value = value
# Factory function that creates and returns instances
def create_processor(processor_type: str, name: str, config: dict[str, Any] | None = None) -> BaseProcessor:
"""Factory function that creates and returns processor instances."""
if processor_type == "data":
return DataProcessor(name, config)
else:
raise ValueError(f"Unknown processor type: {processor_type}")
# Nested decorator example
def with_retry(max_retries: int = 3):
"""Decorator factory that creates a retry decorator."""
def decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
for attempt in range(max_retries):
try:
return func(*args, **kwargs)
except Exception as e:
if attempt == max_retries - 1:
raise
print(f"Retrying {func.__name__} after error: {e}")
return None
return wrapper
return decorator
@with_retry(max_retries=5)
def unreliable_operation(data: Any) -> Any:
"""Function that might fail and uses the retry decorator."""
import random
if random.random() < 0.5:
raise RuntimeError("Random failure")
return data
# Complex type annotation with Annotated
ValidatedString = Annotated[str, "A string that has been validated"]
PositiveInt = Annotated[int, lambda x: x > 0]
def process_validated_data(data: ValidatedString, count: PositiveInt) -> list[str]:
"""Process data with Annotated type hints."""
return [data] * count
# Example of forward references and string literals in type annotations
class TreeNode:
"""Tree node with forward reference to itself in annotations."""
def __init__(self, value: Any):
self.value = value
self.children: list[TreeNode] = []
def add_child(self, child: TreeNode) -> None:
"""Add a child node."""
self.children.append(child)
def traverse(self) -> list[Any]:
"""Traverse the tree and return all values."""
result = [self.value]
for child in self.children:
result.extend(child.traverse())
return result
# Main entry point for demonstration
def main() -> None:
"""Main function demonstrating the use of various features."""
# Create processor
processor = DataProcessor("test-processor", {"debug": True})
# Create tasks
task1 = Task(id="task1", name="First Task")
task2 = Task(id="task2", name="Second Task", dependencies=["task1"])
# Create repository
repo: Repository[Task] = Repository()
repo.add(task1.id, task1)
repo.add(task2.id, task2)
# Process some data
data = [1, 2, 3, 4, 5]
result = processor.process(data) # noqa: F841
# Use context manager
with transaction_context("main"):
# Process more data
for task in repo.list_all():
processor.process(task.name)
# Use advanced search
results, total = advanced_search(query="test", filters={"status": Status.PENDING}, sort_by="priority", page=1, include_metadata=True)
# Create a tree
root = TreeNode("root")
child1 = TreeNode("child1")
child2 = TreeNode("child2")
root.add_child(child1)
root.add_child(child2)
child1.add_child(TreeNode("grandchild1"))
print("Done!")
if __name__ == "__main__":
main()
@@ -0,0 +1,3 @@
"""
Examples package for demonstrating test_repo module usage.
"""
@@ -0,0 +1,141 @@
"""
Example demonstrating user management with the test_repo module.
This example showcases:
- Creating and managing users
- Using various object types and relationships
- Type annotations and complex Python patterns
"""
import logging
from dataclasses import dataclass
from typing import Any
from test_repo.models import User, create_user_object
from test_repo.services import UserService
# Set up logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
@dataclass
class UserStats:
"""Statistics about user activity."""
user_id: str
login_count: int = 0
last_active_days: int = 0
engagement_score: float = 0.0
def is_active(self) -> bool:
"""Check if the user is considered active."""
return self.last_active_days < 30
class UserManager:
"""Example class demonstrating complex user management."""
def __init__(self, service: UserService):
self.service = service
self.active_users: dict[str, User] = {}
self.user_stats: dict[str, UserStats] = {}
def register_user(self, name: str, email: str, roles: list[str] | None = None) -> User:
"""Register a new user."""
logger.info(f"Registering new user: {name} ({email})")
user = self.service.create_user(name=name, email=email, roles=roles)
self.active_users[user.id] = user
self.user_stats[user.id] = UserStats(user_id=user.id)
return user
def get_user(self, user_id: str) -> User | None:
"""Get a user by ID."""
if user_id in self.active_users:
return self.active_users[user_id]
# Try to fetch from service
user = self.service.get_user(user_id)
if user:
self.active_users[user.id] = user
return user
def update_user_stats(self, user_id: str, login_count: int, days_since_active: int) -> None:
"""Update statistics for a user."""
if user_id not in self.user_stats:
self.user_stats[user_id] = UserStats(user_id=user_id)
stats = self.user_stats[user_id]
stats.login_count = login_count
stats.last_active_days = days_since_active
# Calculate engagement score based on activity
engagement = (100 - min(days_since_active, 100)) * 0.8
engagement += min(login_count, 20) * 0.2
stats.engagement_score = engagement
def get_active_users(self) -> list[User]:
"""Get all active users."""
active_user_ids = [user_id for user_id, stats in self.user_stats.items() if stats.is_active()]
return [self.active_users[user_id] for user_id in active_user_ids if user_id in self.active_users]
def get_user_by_email(self, email: str) -> User | None:
"""Find a user by their email address."""
for user in self.active_users.values():
if user.email == email:
return user
return None
# Example function demonstrating type annotations
def process_user_data(users: list[User], include_inactive: bool = False, transform_func: callable | None = None) -> dict[str, Any]:
"""Process user data with optional transformations."""
result: dict[str, Any] = {"users": [], "total": 0, "admin_count": 0}
for user in users:
if transform_func:
user_data = transform_func(user.to_dict())
else:
user_data = user.to_dict()
result["users"].append(user_data)
result["total"] += 1
if "admin" in user.roles:
result["admin_count"] += 1
return result
def main():
"""Main function demonstrating the usage of UserManager."""
# Initialize service and manager
service = UserService()
manager = UserManager(service)
# Register some users
admin = manager.register_user("Admin User", "admin@example.com", ["admin"])
user1 = manager.register_user("Regular User", "user@example.com", ["user"])
user2 = manager.register_user("Another User", "another@example.com", ["user"])
# Update some stats
manager.update_user_stats(admin.id, 100, 5)
manager.update_user_stats(user1.id, 50, 10)
manager.update_user_stats(user2.id, 10, 45) # Inactive user
# Get active users
active_users = manager.get_active_users()
logger.info(f"Active users: {len(active_users)}")
# Process user data
user_data = process_user_data(active_users, transform_func=lambda u: {**u, "full_name": u.get("name", "")})
logger.info(f"Processed {user_data['total']} users, {user_data['admin_count']} admins")
# Example of calling create_user directly
external_user = create_user_object(id="ext123", name="External User", email="external@example.org", roles=["external"])
logger.info(f"Created external user: {external_user.name}")
if __name__ == "__main__":
main()
@@ -0,0 +1,3 @@
"""
Scripts package containing entry point scripts for the application.
"""
@@ -0,0 +1,164 @@
#!/usr/bin/env python
"""
Main entry point script for the test_repo application.
This script demonstrates how a typical application entry point would be structured,
with command-line arguments, configuration loading, and service initialization.
"""
import argparse
import json
import logging
import os
import sys
from typing import Any
# Add parent directory to path to make imports work
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), "..")))
from test_repo.models import Item, User
from test_repo.services import ItemService, UserService
# Configure logging
logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(name)s - %(levelname)s - %(message)s")
logger = logging.getLogger(__name__)
def parse_args():
"""Parse command line arguments."""
parser = argparse.ArgumentParser(description="Test Repo Application")
parser.add_argument("--config", type=str, default="config.json", help="Path to configuration file")
parser.add_argument("--mode", choices=["user", "item", "both"], default="both", help="Operation mode")
parser.add_argument("--verbose", action="store_true", help="Enable verbose logging")
return parser.parse_args()
def load_config(config_path: str) -> dict[str, Any]:
"""Load configuration from a JSON file."""
if not os.path.exists(config_path):
logger.warning(f"Configuration file not found: {config_path}")
return {}
try:
with open(config_path) as f:
return json.load(f)
except json.JSONDecodeError:
logger.error(f"Invalid JSON in configuration file: {config_path}")
return {}
except Exception as e:
logger.error(f"Error loading configuration: {e}")
return {}
def create_sample_users(service: UserService, count: int = 3) -> list[User]:
"""Create sample users for demonstration."""
users = []
# Create admin user
admin = service.create_user(name="Admin User", email="admin@example.com", roles=["admin"])
users.append(admin)
# Create regular users
for i in range(count - 1):
user = service.create_user(name=f"User {i + 1}", email=f"user{i + 1}@example.com", roles=["user"])
users.append(user)
return users
def create_sample_items(service: ItemService, count: int = 5) -> list[Item]:
"""Create sample items for demonstration."""
categories = ["Electronics", "Books", "Clothing", "Food", "Other"]
items = []
for i in range(count):
category = categories[i % len(categories)]
item = service.create_item(name=f"Item {i + 1}", price=10.0 * (i + 1), category=category)
items.append(item)
return items
def run_user_operations(service: UserService, config: dict[str, Any]) -> None:
"""Run operations related to users."""
logger.info("Running user operations")
# Get configuration
user_count = config.get("user_count", 3)
# Create users
users = create_sample_users(service, user_count)
logger.info(f"Created {len(users)} users")
# Demonstrate some operations
for user in users:
logger.info(f"User: {user.name} (ID: {user.id})")
# Access a method to demonstrate method calls
if user.has_role("admin"):
logger.info(f"{user.name} is an admin")
# Lookup a user
found_user = service.get_user(users[0].id)
if found_user:
logger.info(f"Found user: {found_user.name}")
def run_item_operations(service: ItemService, config: dict[str, Any]) -> None:
"""Run operations related to items."""
logger.info("Running item operations")
# Get configuration
item_count = config.get("item_count", 5)
# Create items
items = create_sample_items(service, item_count)
logger.info(f"Created {len(items)} items")
# Demonstrate some operations
total_price = 0.0
for item in items:
price_display = item.get_display_price()
logger.info(f"Item: {item.name}, Price: {price_display}")
total_price += item.price
logger.info(f"Total price of all items: ${total_price:.2f}")
def main():
"""Main entry point for the application."""
# Parse command line arguments
args = parse_args()
# Configure logging level
if args.verbose:
logging.getLogger().setLevel(logging.DEBUG)
logger.info("Starting Test Repo Application")
# Load configuration
config = load_config(args.config)
logger.debug(f"Loaded configuration: {config}")
# Initialize services
user_service = UserService()
item_service = ItemService()
# Run operations based on mode
if args.mode in ("user", "both"):
run_user_operations(user_service, config)
if args.mode in ("item", "both"):
run_item_operations(item_service, config)
logger.info("Application completed successfully")
item_reference = Item(id="1", name="Item 1", price=10.0, category="Electronics")
if __name__ == "__main__":
main()
@@ -0,0 +1,23 @@
from typing import TypedDict
a: list[int] = [1]
class CustomListInt(list[int]):
def some_method(self):
pass
class CustomTypedDict(TypedDict):
a: int
b: str
class Outer2:
class InnerTypedDict(TypedDict):
a: int
b: str
class ComplexExtension(Outer2.InnerTypedDict, total=False):
c: bool
@@ -0,0 +1,246 @@
"""
Models module that demonstrates various Python class patterns.
"""
from abc import ABC, abstractmethod
from typing import Any, Generic, TypeVar
T = TypeVar("T")
class BaseModel(ABC):
"""
Abstract base class for all models.
"""
def __init__(self, id: str, name: str | None = None):
self.id = id
self.name = name or id
@abstractmethod
def to_dict(self) -> dict[str, Any]:
"""Convert model to dictionary representation"""
@classmethod
def from_dict(cls, data: dict[str, Any]) -> "BaseModel":
"""Create a model instance from dictionary data"""
id = data.get("id", "")
name = data.get("name")
return cls(id=id, name=name)
class User(BaseModel):
"""
User model representing a system user.
"""
def __init__(self, id: str, name: str | None = None, email: str = "", roles: list[str] | None = None):
super().__init__(id, name)
self.email = email
self.roles = roles or []
def to_dict(self) -> dict[str, Any]:
return {"id": self.id, "name": self.name, "email": self.email, "roles": self.roles}
@classmethod
def from_dict(cls, data: dict[str, Any]) -> "User":
instance = super().from_dict(data)
instance.email = data.get("email", "")
instance.roles = data.get("roles", [])
return instance
def has_role(self, role: str) -> bool:
"""Check if user has a specific role"""
return role in self.roles
class Item(BaseModel):
"""
Item model representing a product or service.
"""
def __init__(self, id: str, name: str | None = None, price: float = 0.0, category: str = ""):
super().__init__(id, name)
self.price = price
self.category = category
def to_dict(self) -> dict[str, Any]:
return {"id": self.id, "name": self.name, "price": self.price, "category": self.category}
def get_display_price(self) -> str:
"""Format price for display"""
return f"${self.price:.2f}"
# Generic type example
class Collection(Generic[T]):
def __init__(self, items: list[T] | None = None):
self.items = items or []
def add(self, item: T) -> None:
self.items.append(item)
def get_all(self) -> list[T]:
return self.items
# Factory function
def create_user_object(id: str, name: str, email: str, roles: list[str] | None = None) -> User:
"""Factory function to create a user"""
return User(id=id, name=name, email=email, roles=roles)
# Multiple inheritance examples
class Loggable:
"""
Mixin class that provides logging functionality.
Example of a common mixin pattern used with multiple inheritance.
"""
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.log_entries: list[str] = []
def log(self, message: str) -> None:
"""Add a log entry"""
self.log_entries.append(message)
def get_logs(self) -> list[str]:
"""Get all log entries"""
return self.log_entries
class Serializable:
"""
Mixin class that provides JSON serialization capabilities.
Another example of a mixin for multiple inheritance.
"""
def __init__(self, **kwargs):
super().__init__(**kwargs)
def to_json(self) -> dict[str, Any]:
"""Convert to JSON-serializable dictionary"""
return self.to_dict() if hasattr(self, "to_dict") else {}
@classmethod
def from_json(cls, data: dict[str, Any]) -> Any:
"""Create instance from JSON data"""
return cls.from_dict(data) if hasattr(cls, "from_dict") else cls(**data)
class Auditable:
"""
Mixin for tracking creation and modification timestamps.
"""
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.created_at: str = kwargs.get("created_at", "")
self.updated_at: str = kwargs.get("updated_at", "")
def update_timestamp(self, timestamp: str) -> None:
"""Update the last modified timestamp"""
self.updated_at = timestamp
# Diamond inheritance pattern
class BaseService(ABC):
"""
Base class for service objects - demonstrates diamond inheritance pattern.
"""
def __init__(self, name: str = "base"):
self.service_name = name
@abstractmethod
def get_service_info(self) -> dict[str, str]:
"""Get service information"""
class DataService(BaseService):
"""
Data handling service.
"""
def __init__(self, **kwargs):
name = kwargs.pop("name", "data")
super().__init__(name=name)
self.data_source = kwargs.get("data_source", "default")
def get_service_info(self) -> dict[str, str]:
return {"service_type": "data", "service_name": self.service_name, "data_source": self.data_source}
class NetworkService(BaseService):
"""
Network connectivity service.
"""
def __init__(self, **kwargs):
name = kwargs.pop("name", "network")
super().__init__(name=name)
self.endpoint = kwargs.get("endpoint", "localhost")
def get_service_info(self) -> dict[str, str]:
return {"service_type": "network", "service_name": self.service_name, "endpoint": self.endpoint}
class DataSyncService(DataService, NetworkService):
"""
Service that syncs data over network - example of diamond inheritance.
Inherits from both DataService and NetworkService, which both inherit from BaseService.
"""
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.sync_interval = kwargs.get("sync_interval", 60)
def get_service_info(self) -> dict[str, str]:
info = super().get_service_info()
info.update({"service_type": "data_sync", "sync_interval": str(self.sync_interval)})
return info
# Multiple inheritance with mixins
class LoggableUser(User, Loggable):
"""
User class with logging capabilities.
Example of extending a concrete class with a mixin.
"""
def __init__(self, id: str, name: str | None = None, email: str = "", roles: list[str] | None = None):
super().__init__(id=id, name=name, email=email, roles=roles)
def add_role(self, role: str) -> None:
"""Add a role to the user and log the action"""
if role not in self.roles:
self.roles.append(role)
self.log(f"Added role '{role}' to user {self.id}")
class TrackedItem(Item, Serializable, Auditable):
"""
Item with serialization and auditing capabilities.
Example of a class inheriting from a concrete class and multiple mixins.
"""
def __init__(
self, id: str, name: str | None = None, price: float = 0.0, category: str = "", created_at: str = "", updated_at: str = ""
):
super().__init__(id=id, name=name, price=price, category=category, created_at=created_at, updated_at=updated_at)
self.stock_level = 0
def update_stock(self, quantity: int) -> None:
"""Update stock level and timestamp"""
self.stock_level = quantity
self.update_timestamp(f"stock_update_{quantity}")
def to_dict(self) -> dict[str, Any]:
result = super().to_dict()
result.update({"stock_level": self.stock_level, "created_at": self.created_at, "updated_at": self.updated_at})
return result
@@ -0,0 +1,34 @@
# ruff: noqa
var_will_be_overwritten = 1
var_will_be_overwritten = 2
def func_using_overwritten_var():
print(var_will_be_overwritten)
class ClassWillBeOverwritten:
def method1(self):
pass
class ClassWillBeOverwritten:
def method2(self):
pass
def func_will_be_overwritten():
pass
def func_will_be_overwritten():
pass
def func_calling_overwritten_func():
func_will_be_overwritten()
def func_calling_overwritten_class():
ClassWillBeOverwritten()
@@ -0,0 +1,16 @@
class OuterClass:
class NestedClass:
def find_me(self):
pass
def nested_test(self):
class WithinMethod:
pass
def func_within_func():
pass
a = self.NestedClass() # noqa: F841
b = OuterClass().NestedClass().find_me()
@@ -0,0 +1,75 @@
"""
Module to test parsing of classes with nested module paths in base classes.
"""
from typing import Generic, TypeVar
T = TypeVar("T")
class BaseModule:
"""Base module class for nested module tests."""
class SubModule:
"""Sub-module class for nested paths."""
class NestedBase:
"""Nested base class."""
def base_method(self):
"""Base method."""
return "base"
class NestedLevel2:
"""Nested level 2."""
def nested_level_2_method(self):
"""Nested level 2 method."""
return "nested_level_2"
class GenericBase(Generic[T]):
"""Generic nested base class."""
def generic_method(self, value: T) -> T:
"""Generic method."""
return value
# Classes extending base classes with single-level nesting
class FirstLevel(SubModule):
"""Class extending a class from a nested module path."""
def first_level_method(self):
"""First level method."""
return "first"
# Classes extending base classes with multi-level nesting
class TwoLevel(SubModule.NestedBase):
"""Class extending a doubly-nested base class."""
def multi_level_method(self):
"""Multi-level method."""
return "multi"
def base_method(self):
"""Override of base method."""
return "overridden"
class ThreeLevel(SubModule.NestedBase.NestedLevel2):
"""Class extending a triply-nested base class."""
def three_level_method(self):
"""Three-level method."""
return "three"
# Class extending a generic base class with nesting
class GenericExtension(SubModule.GenericBase[str]):
"""Class extending a generic nested base class."""
def generic_extension_method(self, text: str) -> str:
"""Extension method."""
return f"Extended: {text}"
@@ -0,0 +1,88 @@
"""
Module demonstrating function and method overloading with typing.overload
"""
from typing import Any, overload
# Example of function overloading
@overload
def process_data(data: str) -> dict[str, str]: ...
@overload
def process_data(data: int) -> dict[str, int]: ...
@overload
def process_data(data: list[str | int]) -> dict[str, list[str | int]]: ...
def process_data(data: str | int | list[str | int]) -> dict[str, Any]:
"""
Process data based on its type.
- If string: returns a dict with 'value': <string>
- If int: returns a dict with 'value': <int>
- If list: returns a dict with 'value': <list>
"""
return {"value": data}
# Class with overloaded methods
class DataProcessor:
"""
A class demonstrating method overloading.
"""
@overload
def transform(self, input_value: str) -> str: ...
@overload
def transform(self, input_value: int) -> int: ...
@overload
def transform(self, input_value: list[Any]) -> list[Any]: ...
def transform(self, input_value: str | int | list[Any]) -> str | int | list[Any]:
"""
Transform input based on its type.
- If string: returns the string in uppercase
- If int: returns the int multiplied by 2
- If list: returns the list sorted
"""
if isinstance(input_value, str):
return input_value.upper()
elif isinstance(input_value, int):
return input_value * 2
elif isinstance(input_value, list):
try:
return sorted(input_value)
except TypeError:
return input_value
return input_value
@overload
def fetch(self, id: int) -> dict[str, Any]: ...
@overload
def fetch(self, id: str, cache: bool = False) -> dict[str, Any] | None: ...
def fetch(self, id: int | str, cache: bool = False) -> dict[str, Any] | None:
"""
Fetch data for a given ID.
Args:
id: The ID to fetch, either numeric or string
cache: Whether to use cache for string IDs
Returns:
Data dictionary or None if not found
"""
# Implementation would actually fetch data
if isinstance(id, int):
return {"id": id, "type": "numeric"}
else:
return {"id": id, "type": "string", "cached": cache}
@@ -0,0 +1,78 @@
"""
Services module demonstrating function usage and dependencies.
"""
from typing import Any
from .models import Item, User
class UserService:
"""Service for user-related operations"""
def __init__(self, user_db: dict[str, User] | None = None):
self.users = user_db or {}
def create_user(self, id: str, name: str, email: str) -> User:
"""Create a new user and store it"""
if id in self.users:
raise ValueError(f"User with ID {id} already exists")
user = User(id=id, name=name, email=email)
self.users[id] = user
return user
def get_user(self, id: str) -> User | None:
"""Get a user by ID"""
return self.users.get(id)
def list_users(self) -> list[User]:
"""Get a list of all users"""
return list(self.users.values())
def delete_user(self, id: str) -> bool:
"""Delete a user by ID"""
if id in self.users:
del self.users[id]
return True
return False
class ItemService:
"""Service for item-related operations"""
def __init__(self, item_db: dict[str, Item] | None = None):
self.items = item_db or {}
def create_item(self, id: str, name: str, price: float, category: str) -> Item:
"""Create a new item and store it"""
if id in self.items:
raise ValueError(f"Item with ID {id} already exists")
item = Item(id=id, name=name, price=price, category=category)
self.items[id] = item
return item
def get_item(self, id: str) -> Item | None:
"""Get an item by ID"""
return self.items.get(id)
def list_items(self, category: str | None = None) -> list[Item]:
"""List all items, optionally filtered by category"""
if category:
return [item for item in self.items.values() if item.category == category]
return list(self.items.values())
# Factory function for services
def create_service_container() -> dict[str, Any]:
"""Create a container with all services"""
container = {"user_service": UserService(), "item_service": ItemService()}
return container
user_var_str = "user_var"
user_service = UserService()
user_service.create_user("1", "Alice", "alice@example.com")
@@ -0,0 +1,123 @@
"""
Utility functions and classes demonstrating various Python features.
"""
import logging
from collections.abc import Callable
from typing import Any, TypeVar
# Type variables for generic functions
T = TypeVar("T")
U = TypeVar("U")
def setup_logging(level: str = "INFO") -> logging.Logger:
"""Set up and return a configured logger"""
levels = {
"DEBUG": logging.DEBUG,
"INFO": logging.INFO,
"WARNING": logging.WARNING,
"ERROR": logging.ERROR,
"CRITICAL": logging.CRITICAL,
}
logger = logging.getLogger("test_repo")
logger.setLevel(levels.get(level.upper(), logging.INFO))
handler = logging.StreamHandler()
formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s")
handler.setFormatter(formatter)
logger.addHandler(handler)
return logger
# Decorator example
def log_execution(func: Callable) -> Callable:
"""Decorator to log function execution"""
def wrapper(*args, **kwargs):
logger = logging.getLogger("test_repo")
logger.info(f"Executing function: {func.__name__}")
result = func(*args, **kwargs)
logger.info(f"Completed function: {func.__name__}")
return result
return wrapper
# Higher-order function
def map_list(items: list[T], mapper: Callable[[T], U]) -> list[U]:
"""Map a function over a list of items"""
return [mapper(item) for item in items]
# Class with various Python features
class ConfigManager:
"""Manages configuration with various access patterns"""
_instance = None
# Singleton pattern
def __new__(cls, *args, **kwargs):
if not cls._instance:
cls._instance = super().__new__(cls)
return cls._instance
def __init__(self, initial_config: dict[str, Any] | None = None):
if not hasattr(self, "initialized"):
self.config = initial_config or {}
self.initialized = True
def __getitem__(self, key: str) -> Any:
"""Allow dictionary-like access"""
return self.config.get(key)
def __setitem__(self, key: str, value: Any) -> None:
"""Allow dictionary-like setting"""
self.config[key] = value
@property
def debug_mode(self) -> bool:
"""Property example"""
return self.config.get("debug", False)
@debug_mode.setter
def debug_mode(self, value: bool) -> None:
self.config["debug"] = value
# Context manager example
class Timer:
"""Context manager for timing code execution"""
def __init__(self, name: str = "Timer"):
self.name = name
self.start_time = None
self.end_time = None
def __enter__(self):
import time
self.start_time = time.time()
return self
def __exit__(self, exc_type, exc_val, exc_tb):
import time
self.end_time = time.time()
print(f"{self.name} took {self.end_time - self.start_time:.6f} seconds")
# Functions with default arguments
def retry(func: Callable, max_attempts: int = 3, delay: float = 1.0) -> Any:
"""Retry a function with backoff"""
import time
for attempt in range(max_attempts):
try:
return func()
except Exception as e:
if attempt == max_attempts - 1:
raise e
time.sleep(delay * (2**attempt))
@@ -0,0 +1,96 @@
"""
Test module for variable declarations and usage.
This module tests various types of variable declarations and usages including:
- Module-level variables
- Class-level variables
- Instance variables
- Variable reassignments
"""
from dataclasses import dataclass, field
# Module-level variables
module_var = "Initial module value"
reassignable_module_var = 10
reassignable_module_var = 20 # Reassigned
# Module-level variable with type annotation
typed_module_var: int = 42
# Regular class with class and instance variables
class VariableContainer:
"""Class that contains various variables."""
# Class-level variables
class_var = "Initial class value"
reassignable_class_var = True
reassignable_class_var = False # Reassigned #noqa: PIE794
# Class-level variable with type annotation
typed_class_var: str = "typed value"
def __init__(self):
# Instance variables
self.instance_var = "Initial instance value"
self.reassignable_instance_var = 100
# Instance variable with type annotation
self.typed_instance_var: list[str] = ["item1", "item2"]
def modify_instance_var(self):
# Reassign instance variable
self.instance_var = "Modified instance value"
self.reassignable_instance_var = 200 # Reassigned
def use_module_var(self):
# Use module-level variables
result = module_var + " used in method"
other_result = reassignable_module_var + 5
return result, other_result
def use_class_var(self):
# Use class-level variables
result = VariableContainer.class_var + " used in method"
other_result = VariableContainer.reassignable_class_var
return result, other_result
# Dataclass with variables
@dataclass
class VariableDataclass:
"""Dataclass that contains various fields."""
# Field variables with type annotations
id: int
name: str
items: list[str] = field(default_factory=list)
metadata: dict[str, str] = field(default_factory=dict)
optional_value: float | None = None
# This will be reassigned in various places
status: str = "pending"
# Function that uses the module variables
def use_module_variables():
"""Function that uses module-level variables."""
result = module_var + " used in function"
other_result = reassignable_module_var * 2
return result, other_result
# Create instances and use variables
dataclass_instance = VariableDataclass(id=1, name="Test")
dataclass_instance.status = "active" # Reassign dataclass field
# Use variables at module level
module_result = module_var + " used at module level"
other_module_result = reassignable_module_var + 30
# Create a second dataclass instance with different status
second_dataclass = VariableDataclass(id=2, name="Another Test")
second_dataclass.status = "completed" # Another reassignment of status