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
4c337993
Kaydet (Commit)
4c337993
authored
Şub 07, 2005
tarafından
Alex Martelli
Dosyalara gözat
Seçenekler
Dosyalara Gözat
İndir
Eposta Yamaları
Sade Fark
forwardport of 2.3.5 fixes to copy.py
üst
33987012
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
295 additions
and
4 deletions
+295
-4
copy.py
Lib/copy.py
+19
-3
test_copy.py
Lib/test/test_copy.py
+101
-0
_testcapimodule.c
Modules/_testcapimodule.c
+175
-1
No files found.
Lib/copy.py
Dosyayı görüntüle @
4c337993
...
...
@@ -62,6 +62,16 @@ except ImportError:
__all__
=
[
"Error"
,
"copy"
,
"deepcopy"
]
import
inspect
def
_getspecial
(
cls
,
name
):
for
basecls
in
inspect
.
getmro
(
cls
):
try
:
return
basecls
.
__dict__
[
name
]
except
:
pass
else
:
return
None
def
copy
(
x
):
"""Shallow copy operation on arbitrary Python objects.
...
...
@@ -74,7 +84,7 @@ def copy(x):
if
copier
:
return
copier
(
x
)
copier
=
getattr
(
cls
,
"__copy__"
,
None
)
copier
=
_getspecial
(
cls
,
"__copy__"
)
if
copier
:
return
copier
(
x
)
...
...
@@ -90,6 +100,9 @@ def copy(x):
if
reductor
:
rv
=
reductor
()
else
:
copier
=
getattr
(
x
,
"__copy__"
,
None
)
if
copier
:
return
copier
()
raise
Error
(
"un(shallow)copyable object of type
%
s"
%
cls
)
return
_reconstruct
(
x
,
rv
,
0
)
...
...
@@ -167,9 +180,9 @@ def deepcopy(x, memo=None, _nil=[]):
if
issc
:
y
=
_deepcopy_atomic
(
x
,
memo
)
else
:
copier
=
getattr
(
x
,
"__deepcopy__"
,
None
)
copier
=
_getspecial
(
cls
,
"__deepcopy__"
)
if
copier
:
y
=
copier
(
memo
)
y
=
copier
(
x
,
memo
)
else
:
reductor
=
dispatch_table
.
get
(
cls
)
if
reductor
:
...
...
@@ -183,6 +196,9 @@ def deepcopy(x, memo=None, _nil=[]):
if
reductor
:
rv
=
reductor
()
else
:
copier
=
getattr
(
x
,
"__deepcopy__"
,
None
)
if
copier
:
return
copier
(
memo
)
raise
Error
(
"un(deep)copyable object of type
%
s"
%
cls
)
y
=
_reconstruct
(
x
,
rv
,
1
,
memo
)
...
...
Lib/test/test_copy.py
Dosyayı görüntüle @
4c337993
...
...
@@ -166,6 +166,107 @@ class TestCopy(unittest.TestCase):
x
=
C
(
42
)
self
.
assertEqual
(
copy
.
copy
(
x
),
x
)
# tests for copying extension types, iff module trycopy is installed
def
test_copy_classictype
(
self
):
from
_testcapi
import
make_copyable
x
=
make_copyable
([
23
])
y
=
copy
.
copy
(
x
)
self
.
assertEqual
(
x
,
y
)
self
.
assertEqual
(
x
.
tag
,
y
.
tag
)
self
.
assert_
(
x
is
not
y
)
self
.
assert_
(
x
.
tag
is
y
.
tag
)
def
test_deepcopy_classictype
(
self
):
from
_testcapi
import
make_copyable
x
=
make_copyable
([
23
])
y
=
copy
.
deepcopy
(
x
)
self
.
assertEqual
(
x
,
y
)
self
.
assertEqual
(
x
.
tag
,
y
.
tag
)
self
.
assert_
(
x
is
not
y
)
self
.
assert_
(
x
.
tag
is
not
y
.
tag
)
# regression tests for class-vs-instance and metaclass-confusion
def
test_copy_classoverinstance
(
self
):
class
C
(
object
):
def
__init__
(
self
,
v
):
self
.
v
=
v
def
__cmp__
(
self
,
other
):
return
-
cmp
(
other
,
self
.
v
)
def
__copy__
(
self
):
return
self
.
__class__
(
self
.
v
)
x
=
C
(
23
)
self
.
assertEqual
(
copy
.
copy
(
x
),
x
)
x
.
__copy__
=
lambda
:
42
self
.
assertEqual
(
copy
.
copy
(
x
),
x
)
def
test_deepcopy_classoverinstance
(
self
):
class
C
(
object
):
def
__init__
(
self
,
v
):
self
.
v
=
v
def
__cmp__
(
self
,
other
):
return
-
cmp
(
other
,
self
.
v
)
def
__deepcopy__
(
self
,
memo
):
return
self
.
__class__
(
copy
.
deepcopy
(
self
.
v
,
memo
))
x
=
C
(
23
)
self
.
assertEqual
(
copy
.
deepcopy
(
x
),
x
)
x
.
__deepcopy__
=
lambda
memo
:
42
self
.
assertEqual
(
copy
.
deepcopy
(
x
),
x
)
def
test_copy_metaclassconfusion
(
self
):
class
MyOwnError
(
copy
.
Error
):
pass
class
Meta
(
type
):
def
__copy__
(
cls
):
raise
MyOwnError
(
"can't copy classes w/this metaclass"
)
class
C
:
__metaclass__
=
Meta
def
__init__
(
self
,
tag
):
self
.
tag
=
tag
def
__cmp__
(
self
,
other
):
return
-
cmp
(
other
,
self
.
tag
)
# the metaclass can forbid shallow copying of its classes
self
.
assertRaises
(
MyOwnError
,
copy
.
copy
,
C
)
# check that there is no interference with instances
x
=
C
(
23
)
self
.
assertEqual
(
copy
.
copy
(
x
),
x
)
def
test_deepcopy_metaclassconfusion
(
self
):
class
MyOwnError
(
copy
.
Error
):
pass
class
Meta
(
type
):
def
__deepcopy__
(
cls
,
memo
):
raise
MyOwnError
(
"can't deepcopy classes w/this metaclass"
)
class
C
:
__metaclass__
=
Meta
def
__init__
(
self
,
tag
):
self
.
tag
=
tag
def
__cmp__
(
self
,
other
):
return
-
cmp
(
other
,
self
.
tag
)
# types are ALWAYS deepcopied atomically, no matter what
self
.
assertEqual
(
copy
.
deepcopy
(
C
),
C
)
# check that there is no interference with instances
x
=
C
(
23
)
self
.
assertEqual
(
copy
.
deepcopy
(
x
),
x
)
def
_nomro
(
self
):
class
C
(
type
):
def
__getattribute__
(
self
,
attr
):
if
attr
==
'__mro__'
:
raise
AttributeError
,
"What, *me*, a __mro__? Nevah!"
return
super
(
C
,
self
)
.
__getattribute__
(
attr
)
class
D
(
object
):
__metaclass__
=
C
return
D
()
def
test_copy_mro
(
self
):
x
=
self
.
_nomro
()
y
=
copy
.
copy
(
x
)
def
test_deepcopy_mro
(
self
):
x
=
self
.
_nomro
()
y
=
copy
.
deepcopy
(
x
)
# The deepcopy() method
def
test_deepcopy_basic
(
self
):
...
...
Modules/_testcapimodule.c
Dosyayı görüntüle @
4c337993
...
...
@@ -588,6 +588,169 @@ test_thread_state(PyObject *self, PyObject *args)
}
#endif
/* a classic-type with copyable instances */
typedef
struct
{
PyObject_HEAD
/* instance tag (a string). */
PyObject
*
tag
;
}
CopyableObject
;
staticforward
PyTypeObject
Copyable_Type
;
#define Copyable_CheckExact(op) ((op)->ob_type == &Copyable_Type)
/* -------------------------------------------------------------------- */
/* copyable constructor and destructor */
static
PyObject
*
copyable_new
(
PyObject
*
tag
)
{
CopyableObject
*
self
;
self
=
PyObject_New
(
CopyableObject
,
&
Copyable_Type
);
if
(
self
==
NULL
)
return
NULL
;
Py_INCREF
(
tag
);
self
->
tag
=
tag
;
return
(
PyObject
*
)
self
;
}
static
PyObject
*
copyable
(
PyObject
*
self
,
PyObject
*
args
,
PyObject
*
kw
)
{
PyObject
*
elem
;
PyObject
*
tag
;
if
(
!
PyArg_ParseTuple
(
args
,
"O:Copyable"
,
&
tag
))
return
NULL
;
elem
=
copyable_new
(
tag
);
return
elem
;
}
static
void
copyable_dealloc
(
CopyableObject
*
self
)
{
/* discard attributes */
Py_DECREF
(
self
->
tag
);
PyObject_Del
(
self
);
}
/* copyable methods */
static
PyObject
*
copyable_copy
(
CopyableObject
*
self
,
PyObject
*
args
)
{
CopyableObject
*
copyable
;
if
(
!
PyArg_ParseTuple
(
args
,
":__copy__"
))
return
NULL
;
copyable
=
(
CopyableObject
*
)
copyable_new
(
self
->
tag
);
if
(
!
copyable
)
return
NULL
;
return
(
PyObject
*
)
copyable
;
}
PyObject
*
_copy_deepcopy
;
static
PyObject
*
copyable_deepcopy
(
CopyableObject
*
self
,
PyObject
*
args
)
{
CopyableObject
*
copyable
=
0
;
PyObject
*
memo
;
PyObject
*
tag_copy
;
if
(
!
PyArg_ParseTuple
(
args
,
"O:__deepcopy__"
,
&
memo
))
return
NULL
;
tag_copy
=
PyObject_CallFunctionObjArgs
(
_copy_deepcopy
,
self
->
tag
,
memo
,
NULL
);
if
(
tag_copy
)
{
copyable
=
(
CopyableObject
*
)
copyable_new
(
tag_copy
);
Py_DECREF
(
tag_copy
);
}
return
(
PyObject
*
)
copyable
;
}
static
PyObject
*
copyable_repr
(
CopyableObject
*
self
)
{
PyObject
*
repr
;
char
buffer
[
100
];
repr
=
PyString_FromString
(
"<Copyable {"
);
PyString_ConcatAndDel
(
&
repr
,
PyObject_Repr
(
self
->
tag
));
sprintf
(
buffer
,
"} at %p>"
,
self
);
PyString_ConcatAndDel
(
&
repr
,
PyString_FromString
(
buffer
));
return
repr
;
}
static
int
copyable_compare
(
CopyableObject
*
obj1
,
CopyableObject
*
obj2
)
{
return
PyObject_Compare
(
obj1
->
tag
,
obj2
->
tag
);
}
static
PyMethodDef
copyable_methods
[]
=
{
{
"__copy__"
,
(
PyCFunction
)
copyable_copy
,
METH_VARARGS
},
{
"__deepcopy__"
,
(
PyCFunction
)
copyable_deepcopy
,
METH_VARARGS
},
{
NULL
,
NULL
}
};
static
PyObject
*
copyable_getattr
(
CopyableObject
*
self
,
char
*
name
)
{
PyObject
*
res
;
res
=
Py_FindMethod
(
copyable_methods
,
(
PyObject
*
)
self
,
name
);
if
(
res
)
return
res
;
PyErr_Clear
();
if
(
strcmp
(
name
,
"tag"
)
==
0
)
{
res
=
self
->
tag
;
}
else
{
PyErr_SetString
(
PyExc_AttributeError
,
name
);
return
NULL
;
}
if
(
!
res
)
return
NULL
;
Py_INCREF
(
res
);
return
res
;
}
static
int
copyable_setattr
(
CopyableObject
*
self
,
const
char
*
name
,
PyObject
*
value
)
{
if
(
value
==
NULL
)
{
PyErr_SetString
(
PyExc_AttributeError
,
"can't delete copyable attributes"
);
return
-
1
;
}
if
(
strcmp
(
name
,
"tag"
)
==
0
)
{
Py_DECREF
(
self
->
tag
);
self
->
tag
=
value
;
Py_INCREF
(
self
->
tag
);
}
else
{
PyErr_SetString
(
PyExc_AttributeError
,
name
);
return
-
1
;
}
return
0
;
}
statichere
PyTypeObject
Copyable_Type
=
{
PyObject_HEAD_INIT
(
NULL
)
0
,
"Copyable"
,
sizeof
(
CopyableObject
),
0
,
/* methods */
(
destructor
)
copyable_dealloc
,
/* tp_dealloc */
0
,
/* tp_print */
(
getattrfunc
)
copyable_getattr
,
/* tp_getattr */
(
setattrfunc
)
copyable_setattr
,
/* tp_setattr */
(
cmpfunc
)
copyable_compare
,
/* tp_compare */
(
reprfunc
)
copyable_repr
,
/* tp_repr */
0
,
/* tp_as_number */
};
static
PyMethodDef
TestMethods
[]
=
{
{
"raise_exception"
,
raise_exception
,
METH_VARARGS
},
{
"test_config"
,
(
PyCFunction
)
test_config
,
METH_NOARGS
},
...
...
@@ -614,9 +777,11 @@ static PyMethodDef TestMethods[] = {
{
"test_u_code"
,
(
PyCFunction
)
test_u_code
,
METH_NOARGS
},
#endif
#ifdef WITH_THREAD
{
"_test_thread_state"
,
(
PyCFunction
)
test_thread_state
,
METH_VARARGS
},
{
"_test_thread_state"
,
(
PyCFunction
)
test_thread_state
,
METH_VARARGS
},
#endif
{
"make_copyable"
,
(
PyCFunction
)
copyable
,
METH_VARARGS
},
{
NULL
,
NULL
}
/* sentinel */
};
#define AddSym(d, n, f, v) {PyObject *o = f(v); PyDict_SetItemString(d, n, o); Py_DECREF(o);}
...
...
@@ -625,6 +790,15 @@ PyMODINIT_FUNC
init_testcapi
(
void
)
{
PyObject
*
m
;
PyObject
*
copy_module
;
copy_module
=
PyImport_ImportModule
(
"copy"
);
if
(
!
copy_module
)
return
;
_copy_deepcopy
=
PyObject_GetAttrString
(
copy_module
,
"deepcopy"
);
Py_DECREF
(
copy_module
);
Copyable_Type
.
ob_type
=
&
PyType_Type
;
m
=
Py_InitModule
(
"_testcapi"
,
TestMethods
);
...
...
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