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
4c7dc48e
Kaydet (Commit)
4c7dc48e
authored
Nis 02, 2015
tarafından
Serhiy Storchaka
Dosyalara gözat
Seçenekler
Dosyalara Gözat
İndir
Sade Fark
Issue #16840: Tkinter now supports 64-bit integers added in Tcl 8.4 and
arbitrary precision integers added in Tcl 8.5.
üst
ea534f79
ea134da9
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
233 additions
and
23 deletions
+233
-23
test_tcl.py
Lib/test/test_tcl.py
+37
-7
NEWS
Misc/NEWS
+3
-0
_tkinter.c
Modules/_tkinter.c
+193
-16
No files found.
Lib/test/test_tcl.py
Dosyayı görüntüle @
4c7dc48e
...
...
@@ -133,9 +133,20 @@ class TclTest(unittest.TestCase):
tcl
=
self
.
interp
self
.
assertRaises
(
TclError
,
tcl
.
unsetvar
,
'a'
)
def
get_integers
(
self
):
integers
=
(
0
,
1
,
-
1
,
2
**
31
-
1
,
-
2
**
31
,
2
**
31
,
-
2
**
31
-
1
,
2
**
63
-
1
,
-
2
**
63
)
if
tcl_version
>=
(
8
,
5
):
# bignum was added in Tcl 8.5
integers
+=
(
2
**
63
,
-
2
**
63
-
1
,
2
**
1000
,
-
2
**
1000
)
return
integers
def
test_getint
(
self
):
tcl
=
self
.
interp
.
tk
self
.
assertEqual
(
tcl
.
getint
(
' 42 '
),
42
)
for
i
in
self
.
get_integers
():
self
.
assertEqual
(
tcl
.
getint
(
'
%
d '
%
i
),
i
)
self
.
assertEqual
(
tcl
.
getint
(
'
%#
o '
%
i
),
i
)
self
.
assertEqual
(
tcl
.
getint
(
'
%#
x '
%
i
),
i
)
if
tcl_version
<
(
8
,
5
):
# bignum was added in Tcl 8.5
self
.
assertRaises
(
TclError
,
tcl
.
getint
,
str
(
2
**
1000
))
self
.
assertEqual
(
tcl
.
getint
(
42
),
42
)
self
.
assertRaises
(
TypeError
,
tcl
.
getint
)
self
.
assertRaises
(
TypeError
,
tcl
.
getint
,
'42'
,
'10'
)
...
...
@@ -270,7 +281,7 @@ class TclTest(unittest.TestCase):
check
(
'"a
\xbd\u20ac
"'
,
'a
\xbd\u20ac
'
)
check
(
r'"a\xbd\u20ac"'
,
'a
\xbd\u20ac
'
)
check
(
r'"a\0b"'
,
'a
\x00
b'
)
if
tcl_version
>=
(
8
,
5
):
if
tcl_version
>=
(
8
,
5
):
# bignum was added in Tcl 8.5
check
(
'2**64'
,
str
(
2
**
64
))
def
test_exprdouble
(
self
):
...
...
@@ -302,7 +313,7 @@ class TclTest(unittest.TestCase):
check
(
'[string length "a
\xbd\u20ac
"]'
,
3.0
)
check
(
r'[string length "a\xbd\u20ac"]'
,
3.0
)
self
.
assertRaises
(
TclError
,
tcl
.
exprdouble
,
'"abc"'
)
if
tcl_version
>=
(
8
,
5
):
if
tcl_version
>=
(
8
,
5
):
# bignum was added in Tcl 8.5
check
(
'2**64'
,
float
(
2
**
64
))
def
test_exprlong
(
self
):
...
...
@@ -334,7 +345,7 @@ class TclTest(unittest.TestCase):
check
(
'[string length "a
\xbd\u20ac
"]'
,
3
)
check
(
r'[string length "a\xbd\u20ac"]'
,
3
)
self
.
assertRaises
(
TclError
,
tcl
.
exprlong
,
'"abc"'
)
if
tcl_version
>=
(
8
,
5
):
if
tcl_version
>=
(
8
,
5
):
# bignum was added in Tcl 8.5
self
.
assertRaises
(
TclError
,
tcl
.
exprlong
,
'2**64'
)
def
test_exprboolean
(
self
):
...
...
@@ -375,7 +386,7 @@ class TclTest(unittest.TestCase):
check
(
'[string length "a
\xbd\u20ac
"]'
,
True
)
check
(
r'[string length "a\xbd\u20ac"]'
,
True
)
self
.
assertRaises
(
TclError
,
tcl
.
exprboolean
,
'"abc"'
)
if
tcl_version
>=
(
8
,
5
):
if
tcl_version
>=
(
8
,
5
):
# bignum was added in Tcl 8.5
check
(
'2**64'
,
True
)
def
test_booleans
(
self
):
...
...
@@ -397,6 +408,21 @@ class TclTest(unittest.TestCase):
check
(
'1 < 2'
,
True
)
check
(
'1 > 2'
,
False
)
def
test_expr_bignum
(
self
):
tcl
=
self
.
interp
for
i
in
self
.
get_integers
():
result
=
tcl
.
call
(
'expr'
,
str
(
i
))
if
self
.
wantobjects
:
self
.
assertEqual
(
result
,
i
)
self
.
assertIsInstance
(
result
,
int
)
else
:
self
.
assertEqual
(
result
,
str
(
i
))
self
.
assertIsInstance
(
result
,
str
)
if
tcl_version
<
(
8
,
5
):
# bignum was added in Tcl 8.5
result
=
tcl
.
call
(
'expr'
,
str
(
2
**
1000
))
self
.
assertEqual
(
result
,
str
(
2
**
1000
))
self
.
assertIsInstance
(
result
,
str
)
def
test_passing_values
(
self
):
def
passValue
(
value
):
return
self
.
interp
.
call
(
'set'
,
'_'
,
value
)
...
...
@@ -414,8 +440,10 @@ class TclTest(unittest.TestCase):
b
'str
\xc0\x80
ing'
if
self
.
wantobjects
else
'str
\xc0\x80
ing'
)
self
.
assertEqual
(
passValue
(
b
'str
\xbd
ing'
),
b
'str
\xbd
ing'
if
self
.
wantobjects
else
'str
\xbd
ing'
)
for
i
in
(
0
,
1
,
-
1
,
2
**
31
-
1
,
-
2
**
31
):
for
i
in
self
.
get_integers
(
):
self
.
assertEqual
(
passValue
(
i
),
i
if
self
.
wantobjects
else
str
(
i
))
if
tcl_version
<
(
8
,
5
):
# bignum was added in Tcl 8.5
self
.
assertEqual
(
passValue
(
2
**
1000
),
str
(
2
**
1000
))
for
f
in
(
0.0
,
1.0
,
-
1.0
,
1
/
3
,
sys
.
float_info
.
min
,
sys
.
float_info
.
max
,
-
sys
.
float_info
.
min
,
-
sys
.
float_info
.
max
):
...
...
@@ -475,8 +503,10 @@ class TclTest(unittest.TestCase):
check
(
b
'str
\x00
ing'
,
'str
\x00
ing'
)
check
(
b
'str
\xc0\x80
ing'
,
'str
\xc0\x80
ing'
)
check
(
b
'str
\xc0\x80
ing
\xe2\x82\xac
'
,
'str
\xc0\x80
ing
\xe2\x82\xac
'
)
for
i
in
(
0
,
1
,
-
1
,
2
**
31
-
1
,
-
2
**
31
):
for
i
in
self
.
get_integers
(
):
check
(
i
,
str
(
i
))
if
tcl_version
<
(
8
,
5
):
# bignum was added in Tcl 8.5
check
(
2
**
1000
,
str
(
2
**
1000
))
for
f
in
(
0.0
,
1.0
,
-
1.0
):
check
(
f
,
repr
(
f
))
for
f
in
(
1
/
3.0
,
sys
.
float_info
.
min
,
sys
.
float_info
.
max
,
...
...
Misc/NEWS
Dosyayı görüntüle @
4c7dc48e
...
...
@@ -16,6 +16,9 @@ Core and Builtins
Library
-------
- Issue #16840: Tkinter now supports 64-bit integers added in Tcl 8.4 and
arbitrary precision integers added in Tcl 8.5.
- Issue #23834: Fix socket.sendto(), use the C Py_ssize_t type to store the
result of sendto() instead of the C int type.
...
...
Modules/_tkinter.c
Dosyayı görüntüle @
4c7dc48e
...
...
@@ -56,6 +56,11 @@ Copyright (C) 1994 Steen Lumholt.
#error "Tk older than 8.4 not supported"
#endif
#if TK_VERSION_HEX >= 0x08050000
#define HAVE_LIBTOMMAMTH
#include <tclTomMath.h>
#endif
#if !(defined(MS_WINDOWS) || defined(__CYGWIN__))
#define HAVE_CREATEFILEHANDLER
#endif
...
...
@@ -234,6 +239,8 @@ typedef struct {
const
Tcl_ObjType
*
ByteArrayType
;
const
Tcl_ObjType
*
DoubleType
;
const
Tcl_ObjType
*
IntType
;
const
Tcl_ObjType
*
WideIntType
;
const
Tcl_ObjType
*
BignumType
;
const
Tcl_ObjType
*
ListType
;
const
Tcl_ObjType
*
ProcBodyType
;
const
Tcl_ObjType
*
StringType
;
...
...
@@ -591,6 +598,8 @@ Tkapp_New(const char *screenName, const char *className,
v
->
ByteArrayType
=
Tcl_GetObjType
(
"bytearray"
);
v
->
DoubleType
=
Tcl_GetObjType
(
"double"
);
v
->
IntType
=
Tcl_GetObjType
(
"int"
);
v
->
WideIntType
=
Tcl_GetObjType
(
"wideInt"
);
v
->
BignumType
=
Tcl_GetObjType
(
"bignum"
);
v
->
ListType
=
Tcl_GetObjType
(
"list"
);
v
->
ProcBodyType
=
Tcl_GetObjType
(
"procbody"
);
v
->
StringType
=
Tcl_GetObjType
(
"string"
);
...
...
@@ -883,12 +892,49 @@ static PyType_Spec PyTclObject_Type_spec = {
#define CHECK_STRING_LENGTH(s)
#endif
#ifdef HAVE_LIBTOMMAMTH
static
Tcl_Obj
*
asBignumObj
(
PyObject
*
value
)
{
Tcl_Obj
*
result
;
int
neg
;
PyObject
*
hexstr
;
char
*
hexchars
;
mp_int
bigValue
;
neg
=
Py_SIZE
(
value
)
<
0
;
hexstr
=
_PyLong_Format
(
value
,
16
);
if
(
hexstr
==
NULL
)
return
NULL
;
hexchars
=
PyUnicode_AsUTF8
(
hexstr
);
if
(
hexchars
==
NULL
)
{
Py_DECREF
(
hexstr
);
return
NULL
;
}
hexchars
+=
neg
+
2
;
/* skip sign and "0x" */
mp_init
(
&
bigValue
);
if
(
mp_read_radix
(
&
bigValue
,
hexchars
,
16
)
!=
MP_OKAY
)
{
mp_clear
(
&
bigValue
);
Py_DECREF
(
hexstr
);
PyErr_NoMemory
();
return
NULL
;
}
Py_DECREF
(
hexstr
);
bigValue
.
sign
=
neg
?
MP_NEG
:
MP_ZPOS
;
result
=
Tcl_NewBignumObj
(
&
bigValue
);
mp_clear
(
&
bigValue
);
if
(
result
==
NULL
)
{
PyErr_NoMemory
();
return
NULL
;
}
return
result
;
}
#endif
static
Tcl_Obj
*
AsObj
(
PyObject
*
value
)
{
Tcl_Obj
*
result
;
long
longVal
;
int
overflow
;
if
(
PyBytes_Check
(
value
))
{
if
(
PyBytes_GET_SIZE
(
value
)
>=
INT_MAX
)
{
...
...
@@ -898,18 +944,45 @@ AsObj(PyObject *value)
return
Tcl_NewByteArrayObj
((
unsigned
char
*
)
PyBytes_AS_STRING
(
value
),
(
int
)
PyBytes_GET_SIZE
(
value
));
}
else
if
(
PyBool_Check
(
value
))
if
(
PyBool_Check
(
value
))
return
Tcl_NewBooleanObj
(
PyObject_IsTrue
(
value
));
else
if
(
PyLong_CheckExact
(
value
)
&&
((
longVal
=
PyLong_AsLongAndOverflow
(
value
,
&
overflow
)),
!
overflow
))
{
if
(
PyLong_CheckExact
(
value
))
{
int
overflow
;
long
longValue
;
#ifdef TCL_WIDE_INT_TYPE
Tcl_WideInt
wideValue
;
#endif
longValue
=
PyLong_AsLongAndOverflow
(
value
,
&
overflow
);
if
(
!
overflow
)
{
return
Tcl_NewLongObj
(
longValue
);
}
/* If there is an overflow in the long conversion,
fall through to wideInt handling. */
#ifdef TCL_WIDE_INT_TYPE
if
(
_PyLong_AsByteArray
((
PyLongObject
*
)
value
,
(
unsigned
char
*
)(
void
*
)
&
wideValue
,
sizeof
(
wideValue
),
PY_LITTLE_ENDIAN
,
/* signed */
1
)
==
0
)
{
return
Tcl_NewWideIntObj
(
wideValue
);
}
PyErr_Clear
();
#endif
/* If there is an overflow in the wideInt conversion,
fall through to bignum handling. */
#ifdef HAVE_LIBTOMMAMTH
return
asBignumObj
(
value
);
#endif
/* If there is no wideInt or bignum support,
fall through to default object handling. */
return
Tcl_NewLongObj
(
longVal
);
}
else
if
(
PyFloat_Check
(
value
))
if
(
PyFloat_Check
(
value
))
return
Tcl_NewDoubleObj
(
PyFloat_AS_DOUBLE
(
value
));
else
if
(
PyTuple_Check
(
value
)
||
PyList_Check
(
value
))
{
if
(
PyTuple_Check
(
value
)
||
PyList_Check
(
value
))
{
Tcl_Obj
**
argv
;
Py_ssize_t
size
,
i
;
...
...
@@ -933,7 +1006,8 @@ AsObj(PyObject *value)
PyMem_Free
(
argv
);
return
result
;
}
else
if
(
PyUnicode_Check
(
value
))
{
if
(
PyUnicode_Check
(
value
))
{
void
*
inbuf
;
Py_ssize_t
size
;
int
kind
;
...
...
@@ -983,12 +1057,14 @@ AsObj(PyObject *value)
PyMem_Free
(
outbuf
);
return
result
;
}
else
if
(
PyTclObject_Check
(
value
))
{
if
(
PyTclObject_Check
(
value
))
{
Tcl_Obj
*
v
=
((
PyTclObject
*
)
value
)
->
value
;
Tcl_IncrRefCount
(
v
);
return
v
;
}
else
{
{
PyObject
*
v
=
PyObject_Str
(
value
);
if
(
!
v
)
return
0
;
...
...
@@ -1007,6 +1083,60 @@ fromBoolean(PyObject* tkapp, Tcl_Obj *value)
return
PyBool_FromLong
(
boolValue
);
}
static
PyObject
*
fromWideIntObj
(
PyObject
*
tkapp
,
Tcl_Obj
*
value
)
{
Tcl_WideInt
wideValue
;
if
(
Tcl_GetWideIntFromObj
(
Tkapp_Interp
(
tkapp
),
value
,
&
wideValue
)
==
TCL_OK
)
{
#ifdef HAVE_LONG_LONG
if
(
sizeof
(
wideValue
)
<=
SIZEOF_LONG_LONG
)
return
PyLong_FromLongLong
(
wideValue
);
#endif
return
_PyLong_FromByteArray
((
unsigned
char
*
)(
void
*
)
&
wideValue
,
sizeof
(
wideValue
),
PY_LITTLE_ENDIAN
,
/* signed */
1
);
}
return
NULL
;
}
#ifdef HAVE_LIBTOMMAMTH
static
PyObject
*
fromBignumObj
(
PyObject
*
tkapp
,
Tcl_Obj
*
value
)
{
mp_int
bigValue
;
unsigned
long
numBytes
;
unsigned
char
*
bytes
;
PyObject
*
res
;
if
(
Tcl_GetBignumFromObj
(
Tkapp_Interp
(
tkapp
),
value
,
&
bigValue
)
!=
TCL_OK
)
return
Tkinter_Error
(
tkapp
);
numBytes
=
mp_unsigned_bin_size
(
&
bigValue
);
bytes
=
PyMem_Malloc
(
numBytes
);
if
(
bytes
==
NULL
)
{
mp_clear
(
&
bigValue
);
return
PyErr_NoMemory
();
}
if
(
mp_to_unsigned_bin_n
(
&
bigValue
,
bytes
,
&
numBytes
)
!=
MP_OKAY
)
{
mp_clear
(
&
bigValue
);
PyMem_Free
(
bytes
);
return
PyErr_NoMemory
();
}
res
=
_PyLong_FromByteArray
(
bytes
,
numBytes
,
/* big-endian */
0
,
/* unsigned */
0
);
PyMem_Free
(
bytes
);
if
(
res
!=
NULL
&&
bigValue
.
sign
==
MP_NEG
)
{
PyObject
*
res2
=
PyNumber_Negative
(
res
);
Py_DECREF
(
res
);
res
=
res2
;
}
mp_clear
(
&
bigValue
);
return
res
;
}
#endif
static
PyObject
*
FromObj
(
PyObject
*
tkapp
,
Tcl_Obj
*
value
)
{
...
...
@@ -1034,9 +1164,31 @@ FromObj(PyObject* tkapp, Tcl_Obj *value)
}
if
(
value
->
typePtr
==
app
->
IntType
)
{
return
PyLong_FromLong
(
value
->
internalRep
.
longValue
);
long
longValue
;
if
(
Tcl_GetLongFromObj
(
interp
,
value
,
&
longValue
)
==
TCL_OK
)
return
PyLong_FromLong
(
longValue
);
/* If there is an error in the long conversion,
fall through to wideInt handling. */
}
if
(
value
->
typePtr
==
app
->
IntType
||
value
->
typePtr
==
app
->
WideIntType
)
{
result
=
fromWideIntObj
(
tkapp
,
value
);
if
(
result
!=
NULL
||
PyErr_Occurred
())
return
result
;
Tcl_ResetResult
(
interp
);
/* If there is an error in the wideInt conversion,
fall through to bignum handling. */
}
#ifdef HAVE_LIBTOMMAMTH
if
(
value
->
typePtr
==
app
->
IntType
||
value
->
typePtr
==
app
->
WideIntType
||
value
->
typePtr
==
app
->
BignumType
)
{
return
fromBignumObj
(
tkapp
,
value
);
}
#endif
if
(
value
->
typePtr
==
app
->
ListType
)
{
int
size
;
int
i
,
status
;
...
...
@@ -1084,6 +1236,15 @@ FromObj(PyObject* tkapp, Tcl_Obj *value)
}
#endif
#ifdef HAVE_LIBTOMMAMTH
if
(
app
->
BignumType
==
NULL
&&
strcmp
(
value
->
typePtr
->
name
,
"bignum"
)
==
0
)
{
/* bignum type is not registered in Tcl */
app
->
BignumType
=
value
->
typePtr
;
return
fromBignumObj
(
tkapp
,
value
);
}
#endif
return
newPyTclObject
(
value
);
}
...
...
@@ -1718,7 +1879,8 @@ static PyObject *
Tkapp_GetInt
(
PyObject
*
self
,
PyObject
*
args
)
{
char
*
s
;
int
v
;
Tcl_Obj
*
value
;
PyObject
*
result
;
if
(
PyTuple_Size
(
args
)
==
1
)
{
PyObject
*
o
=
PyTuple_GetItem
(
args
,
0
);
...
...
@@ -1730,9 +1892,24 @@ Tkapp_GetInt(PyObject *self, PyObject *args)
if
(
!
PyArg_ParseTuple
(
args
,
"s:getint"
,
&
s
))
return
NULL
;
CHECK_STRING_LENGTH
(
s
);
if
(
Tcl_GetInt
(
Tkapp_Interp
(
self
),
s
,
&
v
)
==
TCL_ERROR
)
value
=
Tcl_NewStringObj
(
s
,
-
1
);
if
(
value
==
NULL
)
return
Tkinter_Error
(
self
);
return
Py_BuildValue
(
"i"
,
v
);
/* Don't use Tcl_GetInt() because it returns ambiguous result for value
in ranges -2**32..-2**31-1 and 2**31..2**32-1 (on 32-bit platform).
Prefer bignum because Tcl_GetWideIntFromObj returns ambiguous result for
value in ranges -2**64..-2**63-1 and 2**63..2**64-1 (on 32-bit platform).
*/
#ifdef HAVE_LIBTOMMAMTH
result
=
fromBignumObj
(
self
,
value
);
#else
result
=
fromWideIntObj
(
self
,
value
);
#endif
Tcl_DecrRefCount
(
value
);
if
(
result
!=
NULL
||
PyErr_Occurred
())
return
result
;
return
Tkinter_Error
(
self
);
}
static
PyObject
*
...
...
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