Skip to content
Projeler
Gruplar
Parçacıklar
Yardım
Yükleniyor...
Oturum aç / Kaydol
Gezinmeyi değiştir
C
cpython
Proje
Proje
Ayrıntılar
Etkinlik
Cycle Analytics
Depo (repository)
Depo (repository)
Dosyalar
Kayıtlar (commit)
Dallar (branch)
Etiketler
Katkıda bulunanlar
Grafik
Karşılaştır
Grafikler
Konular (issue)
0
Konular (issue)
0
Liste
Pano
Etiketler
Kilometre Taşları
Birleştirme (merge) Talepleri
0
Birleştirme (merge) Talepleri
0
CI / CD
CI / CD
İş akışları (pipeline)
İşler
Zamanlamalar
Grafikler
Paketler
Paketler
Wiki
Wiki
Parçacıklar
Parçacıklar
Üyeler
Üyeler
Collapse sidebar
Close sidebar
Etkinlik
Grafik
Grafikler
Yeni bir konu (issue) oluştur
İşler
Kayıtlar (commit)
Konu (issue) Panoları
Kenar çubuğunu aç
Batuhan Osman TASKAYA
cpython
Commits
8252cc98
Kaydet (Commit)
8252cc98
authored
May 23, 2015
tarafından
Larry Hastings
Dosyalara gözat
Seçenekler
Dosyalara Gözat
İndir
Eposta Yamaları
Sade Fark
Backed out changeset 57776eee74f2
üst
1c858c35
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
116 additions
and
203 deletions
+116
-203
functools.py
Lib/functools.py
+99
-108
test_functools.py
Lib/test/test_functools.py
+17
-92
NEWS
Misc/NEWS
+0
-3
_functoolsmodule.c
Modules/_functoolsmodule.c
+0
-0
No files found.
Lib/functools.py
Dosyayı görüntüle @
8252cc98
...
@@ -419,129 +419,120 @@ def lru_cache(maxsize=128, typed=False):
...
@@ -419,129 +419,120 @@ def lru_cache(maxsize=128, typed=False):
if
maxsize
is
not
None
and
not
isinstance
(
maxsize
,
int
):
if
maxsize
is
not
None
and
not
isinstance
(
maxsize
,
int
):
raise
TypeError
(
'Expected maxsize to be an integer or None'
)
raise
TypeError
(
'Expected maxsize to be an integer or None'
)
def
decorating_function
(
user_function
):
wrapper
=
_lru_cache_wrapper
(
user_function
,
maxsize
,
typed
,
_CacheInfo
)
return
update_wrapper
(
wrapper
,
user_function
)
return
decorating_function
def
_lru_cache_wrapper
(
user_function
,
maxsize
,
typed
,
_CacheInfo
):
# Constants shared by all lru cache instances:
# Constants shared by all lru cache instances:
sentinel
=
object
()
# unique object used to signal cache misses
sentinel
=
object
()
# unique object used to signal cache misses
make_key
=
_make_key
# build a key from the function arguments
make_key
=
_make_key
# build a key from the function arguments
PREV
,
NEXT
,
KEY
,
RESULT
=
0
,
1
,
2
,
3
# names for the link fields
PREV
,
NEXT
,
KEY
,
RESULT
=
0
,
1
,
2
,
3
# names for the link fields
cache
=
{}
def
decorating_function
(
user_function
):
hits
=
misses
=
0
cache
=
{}
full
=
False
hits
=
misses
=
0
cache_get
=
cache
.
get
# bound method to lookup a key or return None
full
=
False
lock
=
RLock
()
# because linkedlist updates aren't threadsafe
cache_get
=
cache
.
get
# bound method to lookup a key or return None
root
=
[]
# root of the circular doubly linked list
lock
=
RLock
()
# because linkedlist updates aren't threadsafe
root
[:]
=
[
root
,
root
,
None
,
None
]
# initialize by pointing to self
root
=
[]
# root of the circular doubly linked list
root
[:]
=
[
root
,
root
,
None
,
None
]
# initialize by pointing to self
if
maxsize
==
0
:
if
maxsize
==
0
:
def
wrapper
(
*
args
,
**
kwds
):
# No caching -- just a statistics update after a successful call
def
wrapper
(
*
args
,
**
kwds
):
nonlocal
misses
# No caching -- just a statistics update after a successful call
result
=
user_function
(
*
args
,
**
kwds
)
nonlocal
misses
misses
+=
1
result
=
user_function
(
*
args
,
**
kwds
)
return
result
misses
+=
1
elif
maxsize
is
None
:
def
wrapper
(
*
args
,
**
kwds
):
# Simple caching without ordering or size limit
nonlocal
hits
,
misses
key
=
make_key
(
args
,
kwds
,
typed
)
result
=
cache_get
(
key
,
sentinel
)
if
result
is
not
sentinel
:
hits
+=
1
return
result
return
result
result
=
user_function
(
*
args
,
**
kwds
)
cache
[
key
]
=
result
misses
+=
1
return
result
els
e
:
elif
maxsize
is
Non
e
:
def
wrapper
(
*
args
,
**
kwds
):
def
wrapper
(
*
args
,
**
kwds
):
# Size limited caching that tracks accesses by recency
# Simple caching without ordering or size limit
nonlocal
root
,
hits
,
misses
,
full
nonlocal
hits
,
misses
key
=
make_key
(
args
,
kwds
,
typed
)
key
=
make_key
(
args
,
kwds
,
typed
)
with
lock
:
result
=
cache_get
(
key
,
sentinel
)
link
=
cache_get
(
key
)
if
result
is
not
sentinel
:
if
link
is
not
None
:
# Move the link to the front of the circular queue
link_prev
,
link_next
,
_key
,
result
=
link
link_prev
[
NEXT
]
=
link_next
link_next
[
PREV
]
=
link_prev
last
=
root
[
PREV
]
last
[
NEXT
]
=
root
[
PREV
]
=
link
link
[
PREV
]
=
last
link
[
NEXT
]
=
root
hits
+=
1
hits
+=
1
return
result
return
result
result
=
user_function
(
*
args
,
**
kwds
)
result
=
user_function
(
*
args
,
**
kwds
)
with
lock
:
cache
[
key
]
=
result
if
key
in
cache
:
# Getting here means that this same key was added to the
# cache while the lock was released. Since the link
# update is already done, we need only return the
# computed result and update the count of misses.
pass
elif
full
:
# Use the old root to store the new key and result.
oldroot
=
root
oldroot
[
KEY
]
=
key
oldroot
[
RESULT
]
=
result
# Empty the oldest link and make it the new root.
# Keep a reference to the old key and old result to
# prevent their ref counts from going to zero during the
# update. That will prevent potentially arbitrary object
# clean-up code (i.e. __del__) from running while we're
# still adjusting the links.
root
=
oldroot
[
NEXT
]
oldkey
=
root
[
KEY
]
oldresult
=
root
[
RESULT
]
root
[
KEY
]
=
root
[
RESULT
]
=
None
# Now update the cache dictionary.
del
cache
[
oldkey
]
# Save the potentially reentrant cache[key] assignment
# for last, after the root and links have been put in
# a consistent state.
cache
[
key
]
=
oldroot
else
:
# Put result in a new link at the front of the queue.
last
=
root
[
PREV
]
link
=
[
last
,
root
,
key
,
result
]
last
[
NEXT
]
=
root
[
PREV
]
=
cache
[
key
]
=
link
full
=
(
len
(
cache
)
>=
maxsize
)
misses
+=
1
misses
+=
1
return
result
return
result
def
cache_info
():
else
:
"""Report cache statistics"""
with
lock
:
return
_CacheInfo
(
hits
,
misses
,
maxsize
,
len
(
cache
))
def
cache_clear
():
def
wrapper
(
*
args
,
**
kwds
):
"""Clear the cache and cache statistics"""
# Size limited caching that tracks accesses by recency
nonlocal
hits
,
misses
,
full
nonlocal
root
,
hits
,
misses
,
full
with
lock
:
key
=
make_key
(
args
,
kwds
,
typed
)
cache
.
clear
()
with
lock
:
root
[:]
=
[
root
,
root
,
None
,
None
]
link
=
cache_get
(
key
)
hits
=
misses
=
0
if
link
is
not
None
:
full
=
False
# Move the link to the front of the circular queue
link_prev
,
link_next
,
_key
,
result
=
link
link_prev
[
NEXT
]
=
link_next
link_next
[
PREV
]
=
link_prev
last
=
root
[
PREV
]
last
[
NEXT
]
=
root
[
PREV
]
=
link
link
[
PREV
]
=
last
link
[
NEXT
]
=
root
hits
+=
1
return
result
result
=
user_function
(
*
args
,
**
kwds
)
with
lock
:
if
key
in
cache
:
# Getting here means that this same key was added to the
# cache while the lock was released. Since the link
# update is already done, we need only return the
# computed result and update the count of misses.
pass
elif
full
:
# Use the old root to store the new key and result.
oldroot
=
root
oldroot
[
KEY
]
=
key
oldroot
[
RESULT
]
=
result
# Empty the oldest link and make it the new root.
# Keep a reference to the old key and old result to
# prevent their ref counts from going to zero during the
# update. That will prevent potentially arbitrary object
# clean-up code (i.e. __del__) from running while we're
# still adjusting the links.
root
=
oldroot
[
NEXT
]
oldkey
=
root
[
KEY
]
oldresult
=
root
[
RESULT
]
root
[
KEY
]
=
root
[
RESULT
]
=
None
# Now update the cache dictionary.
del
cache
[
oldkey
]
# Save the potentially reentrant cache[key] assignment
# for last, after the root and links have been put in
# a consistent state.
cache
[
key
]
=
oldroot
else
:
# Put result in a new link at the front of the queue.
last
=
root
[
PREV
]
link
=
[
last
,
root
,
key
,
result
]
last
[
NEXT
]
=
root
[
PREV
]
=
cache
[
key
]
=
link
full
=
(
len
(
cache
)
>=
maxsize
)
misses
+=
1
return
result
wrapper
.
cache_info
=
cache_info
def
cache_info
():
wrapper
.
cache_clear
=
cache_clear
"""Report cache statistics"""
return
update_wrapper
(
wrapper
,
user_function
)
with
lock
:
return
_CacheInfo
(
hits
,
misses
,
maxsize
,
len
(
cache
))
try
:
def
cache_clear
():
from
_functools
import
_lru_cache_wrapper
"""Clear the cache and cache statistics"""
except
ImportError
:
nonlocal
hits
,
misses
,
full
pass
with
lock
:
cache
.
clear
()
root
[:]
=
[
root
,
root
,
None
,
None
]
hits
=
misses
=
0
full
=
False
wrapper
.
cache_info
=
cache_info
wrapper
.
cache_clear
=
cache_clear
return
update_wrapper
(
wrapper
,
user_function
)
return
decorating_function
################################################################################
################################################################################
...
...
Lib/test/test_functools.py
Dosyayı görüntüle @
8252cc98
...
@@ -7,10 +7,6 @@ import sys
...
@@ -7,10 +7,6 @@ import sys
from
test
import
support
from
test
import
support
import
unittest
import
unittest
from
weakref
import
proxy
from
weakref
import
proxy
try
:
import
threading
except
ImportError
:
threading
=
None
import
functools
import
functools
...
@@ -916,12 +912,12 @@ class Orderable_LT:
...
@@ -916,12 +912,12 @@ class Orderable_LT:
return
self
.
value
==
other
.
value
return
self
.
value
==
other
.
value
class
TestLRU
:
class
TestLRU
(
unittest
.
TestCase
)
:
def
test_lru
(
self
):
def
test_lru
(
self
):
def
orig
(
x
,
y
):
def
orig
(
x
,
y
):
return
3
*
x
+
y
return
3
*
x
+
y
f
=
self
.
module
.
lru_cache
(
maxsize
=
20
)(
orig
)
f
=
functools
.
lru_cache
(
maxsize
=
20
)(
orig
)
hits
,
misses
,
maxsize
,
currsize
=
f
.
cache_info
()
hits
,
misses
,
maxsize
,
currsize
=
f
.
cache_info
()
self
.
assertEqual
(
maxsize
,
20
)
self
.
assertEqual
(
maxsize
,
20
)
self
.
assertEqual
(
currsize
,
0
)
self
.
assertEqual
(
currsize
,
0
)
...
@@ -959,7 +955,7 @@ class TestLRU:
...
@@ -959,7 +955,7 @@ class TestLRU:
self
.
assertEqual
(
currsize
,
1
)
self
.
assertEqual
(
currsize
,
1
)
# test size zero (which means "never-cache")
# test size zero (which means "never-cache")
@
self.module
.lru_cache
(
0
)
@
functools
.lru_cache
(
0
)
def
f
():
def
f
():
nonlocal
f_cnt
nonlocal
f_cnt
f_cnt
+=
1
f_cnt
+=
1
...
@@ -975,7 +971,7 @@ class TestLRU:
...
@@ -975,7 +971,7 @@ class TestLRU:
self
.
assertEqual
(
currsize
,
0
)
self
.
assertEqual
(
currsize
,
0
)
# test size one
# test size one
@
self.module
.lru_cache
(
1
)
@
functools
.lru_cache
(
1
)
def
f
():
def
f
():
nonlocal
f_cnt
nonlocal
f_cnt
f_cnt
+=
1
f_cnt
+=
1
...
@@ -991,7 +987,7 @@ class TestLRU:
...
@@ -991,7 +987,7 @@ class TestLRU:
self
.
assertEqual
(
currsize
,
1
)
self
.
assertEqual
(
currsize
,
1
)
# test size two
# test size two
@
self.module
.lru_cache
(
2
)
@
functools
.lru_cache
(
2
)
def
f
(
x
):
def
f
(
x
):
nonlocal
f_cnt
nonlocal
f_cnt
f_cnt
+=
1
f_cnt
+=
1
...
@@ -1008,7 +1004,7 @@ class TestLRU:
...
@@ -1008,7 +1004,7 @@ class TestLRU:
self
.
assertEqual
(
currsize
,
2
)
self
.
assertEqual
(
currsize
,
2
)
def
test_lru_with_maxsize_none
(
self
):
def
test_lru_with_maxsize_none
(
self
):
@
self.module
.lru_cache
(
maxsize
=
None
)
@
functools
.lru_cache
(
maxsize
=
None
)
def
fib
(
n
):
def
fib
(
n
):
if
n
<
2
:
if
n
<
2
:
return
n
return
n
...
@@ -1016,26 +1012,17 @@ class TestLRU:
...
@@ -1016,26 +1012,17 @@ class TestLRU:
self
.
assertEqual
([
fib
(
n
)
for
n
in
range
(
16
)],
self
.
assertEqual
([
fib
(
n
)
for
n
in
range
(
16
)],
[
0
,
1
,
1
,
2
,
3
,
5
,
8
,
13
,
21
,
34
,
55
,
89
,
144
,
233
,
377
,
610
])
[
0
,
1
,
1
,
2
,
3
,
5
,
8
,
13
,
21
,
34
,
55
,
89
,
144
,
233
,
377
,
610
])
self
.
assertEqual
(
fib
.
cache_info
(),
self
.
assertEqual
(
fib
.
cache_info
(),
self
.
module
.
_CacheInfo
(
hits
=
28
,
misses
=
16
,
maxsize
=
None
,
currsize
=
16
))
functools
.
_CacheInfo
(
hits
=
28
,
misses
=
16
,
maxsize
=
None
,
currsize
=
16
))
fib
.
cache_clear
()
fib
.
cache_clear
()
self
.
assertEqual
(
fib
.
cache_info
(),
self
.
assertEqual
(
fib
.
cache_info
(),
self
.
module
.
_CacheInfo
(
hits
=
0
,
misses
=
0
,
maxsize
=
None
,
currsize
=
0
))
functools
.
_CacheInfo
(
hits
=
0
,
misses
=
0
,
maxsize
=
None
,
currsize
=
0
))
def
test_lru_with_maxsize_negative
(
self
):
@self.module.lru_cache
(
maxsize
=-
10
)
def
eq
(
n
):
return
n
for
i
in
(
0
,
1
):
self
.
assertEqual
([
eq
(
n
)
for
n
in
range
(
150
)],
list
(
range
(
150
)))
self
.
assertEqual
(
eq
.
cache_info
(),
self
.
module
.
_CacheInfo
(
hits
=
0
,
misses
=
300
,
maxsize
=-
10
,
currsize
=
1
))
def
test_lru_with_exceptions
(
self
):
def
test_lru_with_exceptions
(
self
):
# Verify that user_function exceptions get passed through without
# Verify that user_function exceptions get passed through without
# creating a hard-to-read chained exception.
# creating a hard-to-read chained exception.
# http://bugs.python.org/issue13177
# http://bugs.python.org/issue13177
for
maxsize
in
(
None
,
128
):
for
maxsize
in
(
None
,
128
):
@
self.module
.lru_cache
(
maxsize
)
@
functools
.lru_cache
(
maxsize
)
def
func
(
i
):
def
func
(
i
):
return
'abc'
[
i
]
return
'abc'
[
i
]
self
.
assertEqual
(
func
(
0
),
'a'
)
self
.
assertEqual
(
func
(
0
),
'a'
)
...
@@ -1048,7 +1035,7 @@ class TestLRU:
...
@@ -1048,7 +1035,7 @@ class TestLRU:
def
test_lru_with_types
(
self
):
def
test_lru_with_types
(
self
):
for
maxsize
in
(
None
,
128
):
for
maxsize
in
(
None
,
128
):
@
self.module
.lru_cache
(
maxsize
=
maxsize
,
typed
=
True
)
@
functools
.lru_cache
(
maxsize
=
maxsize
,
typed
=
True
)
def
square
(
x
):
def
square
(
x
):
return
x
*
x
return
x
*
x
self
.
assertEqual
(
square
(
3
),
9
)
self
.
assertEqual
(
square
(
3
),
9
)
...
@@ -1063,7 +1050,7 @@ class TestLRU:
...
@@ -1063,7 +1050,7 @@ class TestLRU:
self
.
assertEqual
(
square
.
cache_info
()
.
misses
,
4
)
self
.
assertEqual
(
square
.
cache_info
()
.
misses
,
4
)
def
test_lru_with_keyword_args
(
self
):
def
test_lru_with_keyword_args
(
self
):
@
self.module
.lru_cache
()
@
functools
.lru_cache
()
def
fib
(
n
):
def
fib
(
n
):
if
n
<
2
:
if
n
<
2
:
return
n
return
n
...
@@ -1073,13 +1060,13 @@ class TestLRU:
...
@@ -1073,13 +1060,13 @@ class TestLRU:
[
0
,
1
,
1
,
2
,
3
,
5
,
8
,
13
,
21
,
34
,
55
,
89
,
144
,
233
,
377
,
610
]
[
0
,
1
,
1
,
2
,
3
,
5
,
8
,
13
,
21
,
34
,
55
,
89
,
144
,
233
,
377
,
610
]
)
)
self
.
assertEqual
(
fib
.
cache_info
(),
self
.
assertEqual
(
fib
.
cache_info
(),
self
.
module
.
_CacheInfo
(
hits
=
28
,
misses
=
16
,
maxsize
=
128
,
currsize
=
16
))
functools
.
_CacheInfo
(
hits
=
28
,
misses
=
16
,
maxsize
=
128
,
currsize
=
16
))
fib
.
cache_clear
()
fib
.
cache_clear
()
self
.
assertEqual
(
fib
.
cache_info
(),
self
.
assertEqual
(
fib
.
cache_info
(),
self
.
module
.
_CacheInfo
(
hits
=
0
,
misses
=
0
,
maxsize
=
128
,
currsize
=
0
))
functools
.
_CacheInfo
(
hits
=
0
,
misses
=
0
,
maxsize
=
128
,
currsize
=
0
))
def
test_lru_with_keyword_args_maxsize_none
(
self
):
def
test_lru_with_keyword_args_maxsize_none
(
self
):
@
self.module
.lru_cache
(
maxsize
=
None
)
@
functools
.lru_cache
(
maxsize
=
None
)
def
fib
(
n
):
def
fib
(
n
):
if
n
<
2
:
if
n
<
2
:
return
n
return
n
...
@@ -1087,71 +1074,15 @@ class TestLRU:
...
@@ -1087,71 +1074,15 @@ class TestLRU:
self
.
assertEqual
([
fib
(
n
=
number
)
for
number
in
range
(
16
)],
self
.
assertEqual
([
fib
(
n
=
number
)
for
number
in
range
(
16
)],
[
0
,
1
,
1
,
2
,
3
,
5
,
8
,
13
,
21
,
34
,
55
,
89
,
144
,
233
,
377
,
610
])
[
0
,
1
,
1
,
2
,
3
,
5
,
8
,
13
,
21
,
34
,
55
,
89
,
144
,
233
,
377
,
610
])
self
.
assertEqual
(
fib
.
cache_info
(),
self
.
assertEqual
(
fib
.
cache_info
(),
self
.
module
.
_CacheInfo
(
hits
=
28
,
misses
=
16
,
maxsize
=
None
,
currsize
=
16
))
functools
.
_CacheInfo
(
hits
=
28
,
misses
=
16
,
maxsize
=
None
,
currsize
=
16
))
fib
.
cache_clear
()
fib
.
cache_clear
()
self
.
assertEqual
(
fib
.
cache_info
(),
self
.
assertEqual
(
fib
.
cache_info
(),
self
.
module
.
_CacheInfo
(
hits
=
0
,
misses
=
0
,
maxsize
=
None
,
currsize
=
0
))
functools
.
_CacheInfo
(
hits
=
0
,
misses
=
0
,
maxsize
=
None
,
currsize
=
0
))
def
test_lru_cache_decoration
(
self
):
def
f
(
zomg
:
'zomg_annotation'
):
"""f doc string"""
return
42
g
=
self
.
module
.
lru_cache
()(
f
)
for
attr
in
self
.
module
.
WRAPPER_ASSIGNMENTS
:
self
.
assertEqual
(
getattr
(
g
,
attr
),
getattr
(
f
,
attr
))
@unittest.skipUnless
(
threading
,
'This test requires threading.'
)
def
test_lru_cache_threaded
(
self
):
def
orig
(
x
,
y
):
return
3
*
x
+
y
f
=
self
.
module
.
lru_cache
(
maxsize
=
20
)(
orig
)
hits
,
misses
,
maxsize
,
currsize
=
f
.
cache_info
()
self
.
assertEqual
(
currsize
,
0
)
def
full
(
f
,
*
args
):
for
_
in
range
(
10
):
f
(
*
args
)
def
clear
(
f
):
for
_
in
range
(
10
):
f
.
cache_clear
()
orig_si
=
sys
.
getswitchinterval
()
sys
.
setswitchinterval
(
1e-6
)
try
:
# create 5 threads in order to fill cache
threads
=
[]
for
k
in
range
(
5
):
t
=
threading
.
Thread
(
target
=
full
,
args
=
[
f
,
k
,
k
])
t
.
start
()
threads
.
append
(
t
)
for
t
in
threads
:
t
.
join
()
hits
,
misses
,
maxsize
,
currsize
=
f
.
cache_info
()
self
.
assertEqual
(
hits
,
45
)
self
.
assertEqual
(
misses
,
5
)
self
.
assertEqual
(
currsize
,
5
)
# create 5 threads in order to fill cache and 1 to clear it
cleaner
=
threading
.
Thread
(
target
=
clear
,
args
=
[
f
])
cleaner
.
start
()
threads
=
[
cleaner
]
for
k
in
range
(
5
):
t
=
threading
.
Thread
(
target
=
full
,
args
=
[
f
,
k
,
k
])
t
.
start
()
threads
.
append
(
t
)
for
t
in
threads
:
t
.
join
()
finally
:
sys
.
setswitchinterval
(
orig_si
)
def
test_need_for_rlock
(
self
):
def
test_need_for_rlock
(
self
):
# This will deadlock on an LRU cache that uses a regular lock
# This will deadlock on an LRU cache that uses a regular lock
@
self.module
.lru_cache
(
maxsize
=
10
)
@
functools
.lru_cache
(
maxsize
=
10
)
def
test_func
(
x
):
def
test_func
(
x
):
'Used to demonstrate a reentrant lru_cache call within a single thread'
'Used to demonstrate a reentrant lru_cache call within a single thread'
return
x
return
x
...
@@ -1179,12 +1110,6 @@ class TestLRU:
...
@@ -1179,12 +1110,6 @@ class TestLRU:
def
f
():
def
f
():
pass
pass
class
TestLRUC
(
TestLRU
,
unittest
.
TestCase
):
module
=
c_functools
class
TestLRUPy
(
TestLRU
,
unittest
.
TestCase
):
module
=
py_functools
class
TestSingleDispatch
(
unittest
.
TestCase
):
class
TestSingleDispatch
(
unittest
.
TestCase
):
def
test_simple_overloads
(
self
):
def
test_simple_overloads
(
self
):
...
...
Misc/NEWS
Dosyayı görüntüle @
8252cc98
...
@@ -63,9 +63,6 @@ Core and Builtins
...
@@ -63,9 +63,6 @@ Core and Builtins
Library
Library
-------
-------
- Issue #14373: Added C implementation of functools.lru_cache(). Based on
patches by Matt Joiner and Alexey Kachayev.
- Issue 24230: The tempfile module now accepts bytes for prefix, suffix and dir
- Issue 24230: The tempfile module now accepts bytes for prefix, suffix and dir
parameters and returns bytes in such situations (matching the os module APIs).
parameters and returns bytes in such situations (matching the os module APIs).
...
...
Modules/_functoolsmodule.c
Dosyayı görüntüle @
8252cc98
This diff is collapsed.
Click to expand it.
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment