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
df3f7935
Kaydet (Commit)
df3f7935
authored
Tem 11, 2002
tarafından
Jeremy Hylton
Dosyalara gözat
Seçenekler
Dosyalara Gözat
İndir
Eposta Yamaları
Sade Fark
Extend function() to support an optional closure argument.
Also, simplify some ref counting for other optional arguments.
üst
14cb1e1e
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
89 additions
and
12 deletions
+89
-12
test_new.py
Lib/test/test_new.py
+24
-0
funcobject.c
Objects/funcobject.c
+65
-12
No files found.
Lib/test/test_new.py
Dosyayı görüntüle @
df3f7935
...
...
@@ -71,6 +71,30 @@ func()
verify
(
g
[
'c'
]
==
3
,
'Could not create a proper function object'
)
# test the various extended flavors of function.new
def
f
(
x
):
def
g
(
y
):
return
x
+
y
return
g
g
=
f
(
4
)
new
.
function
(
f
.
func_code
,
{},
"blah"
)
g2
=
new
.
function
(
g
.
func_code
,
{},
"blah"
,
(
2
,),
g
.
func_closure
)
verify
(
g2
()
==
6
)
g3
=
new
.
function
(
g
.
func_code
,
{},
"blah"
,
None
,
g
.
func_closure
)
verify
(
g3
(
5
)
==
9
)
def
test_closure
(
func
,
closure
,
exc
):
try
:
new
.
function
(
func
.
func_code
,
{},
""
,
None
,
closure
)
except
exc
:
pass
else
:
print
"corrupt closure accepted"
test_closure
(
g
,
None
,
TypeError
)
# invalid closure
test_closure
(
g
,
(
1
,),
TypeError
)
# non-cell in closure
test_closure
(
g
,
(
1
,
1
),
ValueError
)
# closure is wrong size
test_closure
(
f
,
g
.
func_closure
,
ValueError
)
# no closure needed
print
'new.code()'
# bogus test of new.code()
# Note: Jython will never have new.code()
...
...
Objects/funcobject.c
Dosyayı görüntüle @
df3f7935
...
...
@@ -267,47 +267,100 @@ static PyGetSetDef func_getsetlist[] = {
};
PyDoc_STRVAR
(
func_doc
,
"function(code, globals[, name[, argdefs]])
\n
\
"function(code, globals[, name[, argdefs
[, closure]
]])
\n
\
\n
\
Create a function object from a code object and a dictionary.
\n
\
The optional name string overrides the name from the code object.
\n
\
The optional argdefs tuple specifies the default argument values."
);
The optional argdefs tuple specifies the default argument values.
\n
\
The optional closure tuple supplies the bindings for free variables."
);
/* func_new() maintains the following invariants for closures. The
closure must correspond to the free variables of the code object.
if len(code.co_freevars) == 0:
closure = NULL
else:
len(closure) == len(code.co_freevars)
for every elt in closure, type(elt) == cell
*/
static
PyObject
*
func_new
(
PyTypeObject
*
type
,
PyObject
*
args
,
PyObject
*
kw
)
{
PyObject
*
code
;
Py
Code
Object
*
code
;
PyObject
*
globals
;
PyObject
*
name
=
Py_None
;
PyObject
*
defaults
=
Py_None
;
PyObject
*
closure
=
Py_None
;
PyFunctionObject
*
newfunc
;
int
nfree
,
nclosure
;
if
(
!
PyArg_ParseTuple
(
args
,
"O!O!|OO
!
:function"
,
if
(
!
PyArg_ParseTuple
(
args
,
"O!O!|OO
O
:function"
,
&
PyCode_Type
,
&
code
,
&
PyDict_Type
,
&
globals
,
&
name
,
&
PyTuple_Type
,
&
defaults
))
&
name
,
&
defaults
,
&
closure
))
return
NULL
;
if
(
name
!=
Py_None
&&
!
PyString_Check
(
name
))
{
PyErr_SetString
(
PyExc_TypeError
,
"arg 3 (name) must be None or string"
);
return
NULL
;
}
if
(
defaults
!=
Py_None
&&
!
PyTuple_Check
(
defaults
))
{
PyErr_SetString
(
PyExc_TypeError
,
"arg 4 (defaults) must be None or tuple"
);
return
NULL
;
}
nfree
=
PyTuple_GET_SIZE
(
code
->
co_freevars
);
if
(
!
PyTuple_Check
(
closure
))
{
if
(
nfree
&&
closure
==
Py_None
)
{
PyErr_SetString
(
PyExc_TypeError
,
"arg 5 (closure) must be tuple"
);
return
NULL
;
}
else
if
(
closure
!=
Py_None
)
{
PyErr_SetString
(
PyExc_TypeError
,
"arg 5 (closure) must be None or tuple"
);
return
NULL
;
}
}
newfunc
=
(
PyFunctionObject
*
)
PyFunction_New
(
code
,
globals
);
/* check that the closure is well-formed */
nclosure
=
closure
==
Py_None
?
0
:
PyTuple_GET_SIZE
(
closure
);
if
(
nfree
!=
nclosure
)
return
PyErr_Format
(
PyExc_ValueError
,
"%s requires closure of length %d, not %d"
,
PyString_AS_STRING
(
code
->
co_name
),
nfree
,
nclosure
);
if
(
nclosure
)
{
int
i
;
for
(
i
=
0
;
i
<
nclosure
;
i
++
)
{
PyObject
*
o
=
PyTuple_GET_ITEM
(
closure
,
i
);
if
(
!
PyCell_Check
(
o
))
{
return
PyErr_Format
(
PyExc_TypeError
,
"arg 5 (closure) expected cell, found %s"
,
o
->
ob_type
->
tp_name
);
}
}
}
newfunc
=
(
PyFunctionObject
*
)
PyFunction_New
((
PyObject
*
)
code
,
globals
);
if
(
newfunc
==
NULL
)
return
NULL
;
if
(
name
!=
Py_None
)
{
Py_
X
INCREF
(
name
);
Py_
X
DECREF
(
newfunc
->
func_name
);
Py_INCREF
(
name
);
Py_DECREF
(
newfunc
->
func_name
);
newfunc
->
func_name
=
name
;
}
if
(
defaults
!=
Py_None
)
{
Py_XINCREF
(
defaults
);
Py_XDECREF
(
newfunc
->
func_defaults
);
Py_INCREF
(
defaults
);
newfunc
->
func_defaults
=
defaults
;
}
if
(
closure
!=
Py_None
)
{
Py_INCREF
(
closure
);
newfunc
->
func_closure
=
closure
;
}
return
(
PyObject
*
)
newfunc
;
}
...
...
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