Backport of the functools module from Python 3.2.3 for use on 2.7 and PyPy.
npx @tessl/cli install tessl/pypi-functools32@3.2.00
# functools32
1
2
A backport of the functools module from Python 3.2.3 for use on Python 2.7 and PyPy. This package brings modern functional programming utilities and caching decorators to legacy Python environments, enabling cleaner functional programming patterns and performance optimizations.
3
4
## Package Information
5
6
- **Package Name**: functools32
7
- **Language**: Python
8
- **Installation**: `pip install functools32`
9
- **Documentation**: http://docs.python.org/3.2/library/functools.html
10
11
## Core Imports
12
13
```python
14
import functools32
15
```
16
17
For direct access to functions:
18
19
```python
20
from functools32 import lru_cache, partial, wraps, total_ordering
21
```
22
23
OrderedDict is also available (used internally by lru_cache):
24
25
```python
26
from functools32 import OrderedDict
27
```
28
29
Import all public functions:
30
31
```python
32
from functools32 import *
33
```
34
35
## Basic Usage
36
37
```python
38
from functools32 import lru_cache, partial, wraps
39
40
# Use LRU cache decorator for memoization
41
@lru_cache(maxsize=128)
42
def expensive_function(n):
43
# Simulate expensive computation
44
result = sum(i * i for i in range(n))
45
return result
46
47
# Create partial functions
48
multiply_by_2 = partial(lambda x, y: x * y, 2)
49
result = multiply_by_2(5) # Returns 10
50
51
# Use wraps for decorators
52
def my_decorator(func):
53
@wraps(func)
54
def wrapper(*args, **kwargs):
55
print("Calling {}".format(func.__name__))
56
return func(*args, **kwargs)
57
return wrapper
58
59
@my_decorator
60
def greet(name):
61
return "Hello, {}!".format(name)
62
```
63
64
## Capabilities
65
66
### Function Decorators and Utilities
67
68
Essential decorators and utilities for function wrapping, caching, and metadata preservation.
69
70
```python { .api }
71
def lru_cache(maxsize=100):
72
"""
73
Least-recently-used cache decorator.
74
75
Parameters:
76
- maxsize (int, optional): Maximum cache size. Default 100. Set to None for unbounded cache.
77
78
Returns:
79
Decorator function that adds caching to the wrapped function.
80
81
The decorated function gets these additional methods:
82
- cache_info(): Returns CacheInfo namedtuple with hits, misses, maxsize, currsize
83
- cache_clear(): Clears the cache and statistics
84
"""
85
86
def wraps(wrapped, assigned=WRAPPER_ASSIGNMENTS, updated=WRAPPER_UPDATES):
87
"""
88
Decorator factory to apply update_wrapper() to a wrapper function.
89
90
Parameters:
91
- wrapped: Original function to wrap
92
- assigned (tuple, optional): Attributes to assign directly from wrapped to wrapper
93
- updated (tuple, optional): Attributes to update with corresponding wrapper attributes
94
95
Returns:
96
Decorator function that applies update_wrapper() with specified arguments
97
"""
98
99
def update_wrapper(wrapper, wrapped, assigned=WRAPPER_ASSIGNMENTS, updated=WRAPPER_UPDATES):
100
"""
101
Update a wrapper function to look like the wrapped function.
102
103
Parameters:
104
- wrapper: Function to be updated
105
- wrapped: Original function
106
- assigned (tuple, optional): Attributes assigned directly from wrapped to wrapper
107
- updated (tuple, optional): Attributes of wrapper updated with wrapped function attributes
108
109
Returns:
110
Updated wrapper function
111
"""
112
```
113
114
### Class Decorators
115
116
Class-level decorators for enhanced functionality and automatic method generation.
117
118
```python { .api }
119
def total_ordering(cls):
120
"""
121
Class decorator that fills in missing ordering methods.
122
123
Given a class which defines one or more rich comparison ordering methods,
124
this class decorator supplies the rest.
125
126
Parameters:
127
- cls: Class to decorate
128
129
Returns:
130
Class with completed ordering methods (__lt__, __le__, __gt__, __ge__)
131
132
Requirements:
133
The class must define at least one ordering operation: < > <= >=
134
"""
135
```
136
137
### Functional Programming Utilities
138
139
Core functional programming functions for partial application, reduction, and comparison utilities.
140
141
```python { .api }
142
def partial(func, *args, **keywords):
143
"""
144
Return a new partial object which when called will behave like func called with
145
the positional arguments args and keyword arguments keywords.
146
147
Parameters:
148
- func: Function to create partial application for
149
- *args: Positional arguments to pre-fill
150
- **keywords: Keyword arguments to pre-fill
151
152
Returns:
153
Partial object with callable interface
154
"""
155
156
def reduce(function, sequence, initial=None):
157
"""
158
Apply a function of two arguments cumulatively to the items of sequence,
159
from left to right, so as to reduce the sequence to a single value.
160
161
Parameters:
162
- function: Function of two arguments
163
- sequence: Iterable sequence to reduce
164
- initial (optional): Starting value; if not provided, first sequence item is used
165
166
Returns:
167
Reduced result value
168
"""
169
170
def cmp_to_key(mycmp):
171
"""
172
Convert a cmp= function into a key= function for sorting.
173
174
Parameters:
175
- mycmp: Comparison function that returns negative, zero, or positive value
176
177
Returns:
178
Key function suitable for sorting operations (sorted(), list.sort(), etc.)
179
"""
180
```
181
182
### Data Structures
183
184
Ordered dictionary implementation that maintains insertion order while providing standard dictionary operations.
185
186
```python { .api }
187
class OrderedDict(dict):
188
"""
189
Dictionary that remembers insertion order.
190
191
Inherits from dict and maintains insertion order of keys while providing
192
all standard dictionary operations with order-aware behavior.
193
"""
194
195
def __init__(self, *args, **kwds):
196
"""
197
Initialize an ordered dictionary.
198
199
Parameters:
200
- *args: Same as dict() constructor
201
- **kwds: Keyword arguments (insertion order not guaranteed)
202
"""
203
204
def popitem(self, last=True):
205
"""
206
Remove and return a (key, value) pair.
207
208
Parameters:
209
- last (bool, optional): If True (default), return in LIFO order.
210
If False, return in FIFO order.
211
212
Returns:
213
tuple: (key, value) pair
214
215
Raises:
216
KeyError: If dictionary is empty
217
"""
218
219
def move_to_end(self, key, last=True):
220
"""
221
Move an existing element to the end (or beginning if last==False).
222
223
Parameters:
224
- key: Existing key to move
225
- last (bool, optional): If True (default), move to end.
226
If False, move to beginning.
227
228
Raises:
229
KeyError: If key does not exist
230
"""
231
232
def clear(self):
233
"""
234
Remove all items from the ordered dictionary.
235
"""
236
237
def pop(self, key, default=None):
238
"""
239
Remove specified key and return the corresponding value.
240
241
Parameters:
242
- key: Key to remove
243
- default (optional): Value to return if key is not found. If not provided
244
and key doesn't exist, KeyError is raised.
245
246
Returns:
247
Value associated with key, or default if key not found and default provided
248
249
Raises:
250
KeyError: If key is not found and no default is provided
251
"""
252
253
def setdefault(self, key, default=None):
254
"""
255
Get the value of key, or set and return default if key doesn't exist.
256
257
Parameters:
258
- key: Key to get or set
259
- default (optional): Default value to set and return if key doesn't exist
260
261
Returns:
262
Value associated with key or the default value
263
"""
264
265
def copy(self):
266
"""
267
Create a shallow copy of the ordered dictionary.
268
269
Returns:
270
OrderedDict: Shallow copy with same key order
271
"""
272
273
@classmethod
274
def fromkeys(cls, iterable, value=None):
275
"""
276
Create a new ordered dictionary with keys from iterable.
277
278
Parameters:
279
- iterable: Keys for the new dictionary
280
- value (optional): Value for all keys. Defaults to None.
281
282
Returns:
283
OrderedDict: New ordered dictionary
284
"""
285
```
286
287
### Constants
288
289
Pre-defined constants for wrapper function metadata handling.
290
291
```python { .api }
292
WRAPPER_ASSIGNMENTS = ('__module__', '__name__', '__doc__')
293
# Tuple of attributes assigned directly from wrapped to wrapper function
294
295
WRAPPER_UPDATES = ('__dict__',)
296
# Tuple of attributes updated from wrapped to wrapper function
297
```
298
299
## Types
300
301
```python { .api }
302
from collections import namedtuple
303
304
CacheInfo = namedtuple("CacheInfo", "hits misses maxsize currsize")
305
# Named tuple returned by lru_cache.cache_info() containing cache statistics.
306
# Fields:
307
# - hits (int): Number of cache hits
308
# - misses (int): Number of cache misses
309
# - maxsize (int): Maximum cache size (None if unbounded)
310
# - currsize (int): Current cache size
311
```
312
313
## Usage Examples
314
315
### LRU Cache with Custom Size
316
317
```python
318
from functools32 import lru_cache
319
320
@lru_cache(maxsize=256)
321
def fibonacci(n):
322
if n < 2:
323
return n
324
return fibonacci(n-1) + fibonacci(n-2)
325
326
# Check cache statistics
327
print(fibonacci.cache_info()) # CacheInfo(hits=0, misses=0, maxsize=256, currsize=0)
328
329
# Use the function
330
result = fibonacci(100)
331
332
# Check updated statistics
333
print(fibonacci.cache_info()) # Shows hits, misses, and current size
334
335
# Clear cache
336
fibonacci.cache_clear()
337
```
338
339
### Total Ordering Decorator
340
341
```python
342
from functools32 import total_ordering
343
344
@total_ordering
345
class Student:
346
def __init__(self, name, grade):
347
self.name = name
348
self.grade = grade
349
350
def __eq__(self, other):
351
return self.grade == other.grade
352
353
def __lt__(self, other):
354
return self.grade < other.grade
355
356
# Now all comparison operations work
357
student1 = Student("Alice", 85)
358
student2 = Student("Bob", 92)
359
360
print(student1 < student2) # True
361
print(student1 <= student2) # True
362
print(student1 > student2) # False
363
print(student1 >= student2) # False
364
```
365
366
### OrderedDict Operations
367
368
```python
369
from functools32 import OrderedDict
370
371
# Create ordered dictionary
372
od = OrderedDict([('a', 1), ('b', 2), ('c', 3)])
373
374
# Move element to end
375
od.move_to_end('a')
376
print(list(od.keys())) # ['b', 'c', 'a']
377
378
# Pop items in order
379
last_item = od.popitem() # ('a', 1)
380
first_item = od.popitem(last=False) # ('b', 2)
381
382
# Create from keys with default value
383
od2 = OrderedDict.fromkeys(['x', 'y', 'z'], 0)
384
print(od2) # OrderedDict([('x', 0), ('y', 0), ('z', 0)])
385
386
# Use setdefault to get or set values
387
od3 = OrderedDict([('a', 1), ('b', 2)])
388
value = od3.setdefault('c', 3) # Adds 'c': 3, returns 3
389
existing = od3.setdefault('a', 99) # Returns 1, doesn't change 'a'
390
391
# Pop with default value
392
popped = od3.pop('d', 'not found') # Returns 'not found'
393
popped = od3.pop('c') # Returns 3, removes 'c'
394
395
# Clear all items
396
od3.clear() # Now empty
397
```
398
399
### Custom Decorator with Wraps
400
401
```python
402
from functools32 import wraps
403
import time
404
405
def timing_decorator(func):
406
@wraps(func)
407
def wrapper(*args, **kwargs):
408
start = time.time()
409
result = func(*args, **kwargs)
410
end = time.time()
411
print("{} took {:.4f} seconds".format(func.__name__, end - start))
412
return result
413
return wrapper
414
415
@timing_decorator
416
def slow_function():
417
"""A function that takes some time to execute."""
418
time.sleep(1)
419
return "Done"
420
421
# The wrapper preserves the original function's metadata
422
print(slow_function.__name__) # 'slow_function'
423
print(slow_function.__doc__) # 'A function that takes some time to execute.'
424
```