Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
P
Pyston
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Boxiang Sun
Pyston
Commits
4480e933
Commit
4480e933
authored
Mar 06, 2015
by
Kevin Modzelewski
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'django_dependencies'
parents
3ec5c835
4c729f7b
Changes
27
Hide whitespace changes
Inline
Side-by-side
Showing
27 changed files
with
355 additions
and
87 deletions
+355
-87
Makefile
Makefile
+1
-1
from_cpython/CMakeLists.txt
from_cpython/CMakeLists.txt
+1
-1
from_cpython/Include/iterobject.h
from_cpython/Include/iterobject.h
+1
-2
from_cpython/Objects/iterobject.c
from_cpython/Objects/iterobject.c
+109
-0
src/analysis/scoping_analysis.cpp
src/analysis/scoping_analysis.cpp
+2
-0
src/capi/abstract.cpp
src/capi/abstract.cpp
+3
-1
src/jit.cpp
src/jit.cpp
+15
-4
src/runtime/capi.cpp
src/runtime/capi.cpp
+0
-4
src/runtime/dict.h
src/runtime/dict.h
+1
-0
src/runtime/file.cpp
src/runtime/file.cpp
+13
-0
src/runtime/float.cpp
src/runtime/float.cpp
+35
-0
src/runtime/objmodel.cpp
src/runtime/objmodel.cpp
+13
-2
src/runtime/str.cpp
src/runtime/str.cpp
+105
-58
src/runtime/types.cpp
src/runtime/types.cpp
+4
-2
test/tests/genexps.py
test/tests/genexps.py
+7
-0
test/tests/gzip_test.py
test/tests/gzip_test.py
+0
-1
test/tests/io_test.py
test/tests/io_test.py
+0
-1
test/tests/kwargs_protocol.py
test/tests/kwargs_protocol.py
+17
-3
test/tests/long.py
test/tests/long.py
+4
-1
test/tests/optparse_test.py
test/tests/optparse_test.py
+0
-1
test/tests/pickle_test.py
test/tests/pickle_test.py
+0
-2
test/tests/prevent_nonascii_attrs.py
test/tests/prevent_nonascii_attrs.py
+0
-1
test/tests/str_encode_decode.py
test/tests/str_encode_decode.py
+0
-1
test/tests/str_functions.py
test/tests/str_functions.py
+3
-0
test/tests/str_subclassing.py
test/tests/str_subclassing.py
+8
-0
test/tests/sys_exit_none.py
test/tests/sys_exit_none.py
+4
-0
test/tests/unicode_test.py
test/tests/unicode_test.py
+9
-1
No files found.
Makefile
View file @
4480e933
...
@@ -293,7 +293,7 @@ STDLIB_RELEASE_OBJS := stdlib.release.bc.o
...
@@ -293,7 +293,7 @@ STDLIB_RELEASE_OBJS := stdlib.release.bc.o
ASM_SRCS
:=
$(
wildcard
src/runtime/
*
.S
)
ASM_SRCS
:=
$(
wildcard
src/runtime/
*
.S
)
STDMODULE_SRCS
:=
errnomodule.c shamodule.c sha256module.c sha512module.c _math.c mathmodule.c md5.c md5module.c _randommodule.c _sre.c operator.c binascii.c pwdmodule.c posixmodule.c _struct.c datetimemodule.c _functoolsmodule.c _collectionsmodule.c itertoolsmodule.c resource.c signalmodule.c selectmodule.c fcntlmodule.c timemodule.c arraymodule.c zlibmodule.c _codecsmodule.c socketmodule.c unicodedata.c _weakref.c cStringIO.c _io/bufferedio.c _io/bytesio.c _io/fileio.c _io/iobase.c _io/_iomodule.c _io/stringio.c _io/textio.c
$(EXTRA_STDMODULE_SRCS)
STDMODULE_SRCS
:=
errnomodule.c shamodule.c sha256module.c sha512module.c _math.c mathmodule.c md5.c md5module.c _randommodule.c _sre.c operator.c binascii.c pwdmodule.c posixmodule.c _struct.c datetimemodule.c _functoolsmodule.c _collectionsmodule.c itertoolsmodule.c resource.c signalmodule.c selectmodule.c fcntlmodule.c timemodule.c arraymodule.c zlibmodule.c _codecsmodule.c socketmodule.c unicodedata.c _weakref.c cStringIO.c _io/bufferedio.c _io/bytesio.c _io/fileio.c _io/iobase.c _io/_iomodule.c _io/stringio.c _io/textio.c
$(EXTRA_STDMODULE_SRCS)
STDOBJECT_SRCS
:=
structseq.c capsule.c stringobject.c exceptions.c unicodeobject.c unicodectype.c bytearrayobject.c bytes_methods.c weakrefobject.c memoryobject.c
$(EXTRA_STDOBJECT_SRCS)
STDOBJECT_SRCS
:=
structseq.c capsule.c stringobject.c exceptions.c unicodeobject.c unicodectype.c bytearrayobject.c bytes_methods.c weakrefobject.c memoryobject.c
iterobject.c
$(EXTRA_STDOBJECT_SRCS)
STDPYTHON_SRCS
:=
pyctype.c getargs.c formatter_string.c pystrtod.c dtoa.c formatter_unicode.c structmember.c
$(EXTRA_STDPYTHON_SRCS)
STDPYTHON_SRCS
:=
pyctype.c getargs.c formatter_string.c pystrtod.c dtoa.c formatter_unicode.c structmember.c
$(EXTRA_STDPYTHON_SRCS)
FROM_CPYTHON_SRCS
:=
$(
addprefix
from_cpython/Modules/,
$(STDMODULE_SRCS)
)
$(
addprefix
from_cpython/Objects/,
$(STDOBJECT_SRCS)
)
$(
addprefix
from_cpython/Python/,
$(STDPYTHON_SRCS)
)
FROM_CPYTHON_SRCS
:=
$(
addprefix
from_cpython/Modules/,
$(STDMODULE_SRCS)
)
$(
addprefix
from_cpython/Objects/,
$(STDOBJECT_SRCS)
)
$(
addprefix
from_cpython/Python/,
$(STDPYTHON_SRCS)
)
...
...
from_cpython/CMakeLists.txt
View file @
4480e933
...
@@ -18,7 +18,7 @@ add_custom_target(copy_stdlib ALL DEPENDS ${STDLIB_TARGETS})
...
@@ -18,7 +18,7 @@ add_custom_target(copy_stdlib ALL DEPENDS ${STDLIB_TARGETS})
file
(
GLOB_RECURSE STDMODULE_SRCS Modules errnomodule.c shamodule.c sha256module.c sha512module.c _math.c mathmodule.c md5.c md5module.c _randommodule.c _sre.c operator.c binascii.c pwdmodule.c posixmodule.c _struct.c datetimemodule.c _functoolsmodule.c _collectionsmodule.c itertoolsmodule.c resource.c signalmodule.c selectmodule.c fcntlmodule.c timemodule.c arraymodule.c zlibmodule.c _codecsmodule.c socketmodule.c unicodedata.c _weakref.c cStringIO.c bufferedio.c bytesio.c fileio.c iobase.c _iomodule.c stringio.c textio.c
)
file
(
GLOB_RECURSE STDMODULE_SRCS Modules errnomodule.c shamodule.c sha256module.c sha512module.c _math.c mathmodule.c md5.c md5module.c _randommodule.c _sre.c operator.c binascii.c pwdmodule.c posixmodule.c _struct.c datetimemodule.c _functoolsmodule.c _collectionsmodule.c itertoolsmodule.c resource.c signalmodule.c selectmodule.c fcntlmodule.c timemodule.c arraymodule.c zlibmodule.c _codecsmodule.c socketmodule.c unicodedata.c _weakref.c cStringIO.c bufferedio.c bytesio.c fileio.c iobase.c _iomodule.c stringio.c textio.c
)
# compile specified files in from_cpython/Objects
# compile specified files in from_cpython/Objects
file
(
GLOB_RECURSE STDOBJECT_SRCS Objects structseq.c capsule.c stringobject.c exceptions.c unicodeobject.c unicodectype.c bytearrayobject.c bytes_methods.c weakrefobject.c memoryobject.c
)
file
(
GLOB_RECURSE STDOBJECT_SRCS Objects structseq.c capsule.c stringobject.c exceptions.c unicodeobject.c unicodectype.c bytearrayobject.c bytes_methods.c weakrefobject.c memoryobject.c
iterobject.c
)
# compile specified files in from_cpython/Python
# compile specified files in from_cpython/Python
file
(
GLOB_RECURSE STDPYTHON_SRCS Python getargs.c pyctype.c formatter_string.c pystrtod.c dtoa.c formatter_unicode.c structmember.c
)
file
(
GLOB_RECURSE STDPYTHON_SRCS Python getargs.c pyctype.c formatter_string.c pystrtod.c dtoa.c formatter_unicode.c structmember.c
)
...
...
from_cpython/Include/iterobject.h
View file @
4480e933
...
@@ -14,8 +14,7 @@ extern "C" {
...
@@ -14,8 +14,7 @@ extern "C" {
PyAPI_FUNC
(
PyObject
*
)
PySeqIter_New
(
PyObject
*
)
PYSTON_NOEXCEPT
;
PyAPI_FUNC
(
PyObject
*
)
PySeqIter_New
(
PyObject
*
)
PYSTON_NOEXCEPT
;
// Pyston change: this is no longer a static object
PyAPI_DATA
(
PyTypeObject
)
PyCallIter_Type
;
//PyAPI_DATA(PyTypeObject) PyCallIter_Type;
#define PyCallIter_Check(op) (Py_TYPE(op) == &PyCallIter_Type)
#define PyCallIter_Check(op) (Py_TYPE(op) == &PyCallIter_Type)
...
...
from_cpython/Objects/iterobject.c
0 → 100644
View file @
4480e933
// This file is originally from CPython 2.7, with modifications for Pyston
// (actually it's just a subset of the CPython version)
#include "Python.h"
extern
PyTypeObject
PyCallIter_Type
;
typedef
struct
{
PyObject_HEAD
PyObject
*
it_callable
;
/* Set to NULL when iterator is exhausted */
PyObject
*
it_sentinel
;
/* Set to NULL when iterator is exhausted */
}
calliterobject
;
PyObject
*
PyCallIter_New
(
PyObject
*
callable
,
PyObject
*
sentinel
)
{
calliterobject
*
it
;
it
=
PyObject_GC_New
(
calliterobject
,
&
PyCallIter_Type
);
if
(
it
==
NULL
)
return
NULL
;
Py_INCREF
(
callable
);
it
->
it_callable
=
callable
;
Py_INCREF
(
sentinel
);
it
->
it_sentinel
=
sentinel
;
_PyObject_GC_TRACK
(
it
);
return
(
PyObject
*
)
it
;
}
static
void
calliter_dealloc
(
calliterobject
*
it
)
{
_PyObject_GC_UNTRACK
(
it
);
Py_XDECREF
(
it
->
it_callable
);
Py_XDECREF
(
it
->
it_sentinel
);
PyObject_GC_Del
(
it
);
}
static
int
calliter_traverse
(
calliterobject
*
it
,
visitproc
visit
,
void
*
arg
)
{
Py_VISIT
(
it
->
it_callable
);
Py_VISIT
(
it
->
it_sentinel
);
return
0
;
}
static
PyObject
*
calliter_iternext
(
calliterobject
*
it
)
{
if
(
it
->
it_callable
!=
NULL
)
{
PyObject
*
args
=
PyTuple_New
(
0
);
PyObject
*
result
;
if
(
args
==
NULL
)
return
NULL
;
result
=
PyObject_Call
(
it
->
it_callable
,
args
,
NULL
);
Py_DECREF
(
args
);
if
(
result
!=
NULL
)
{
int
ok
;
ok
=
PyObject_RichCompareBool
(
result
,
it
->
it_sentinel
,
Py_EQ
);
if
(
ok
==
0
)
return
result
;
/* Common case, fast path */
Py_DECREF
(
result
);
if
(
ok
>
0
)
{
Py_CLEAR
(
it
->
it_callable
);
Py_CLEAR
(
it
->
it_sentinel
);
}
}
else
if
(
PyErr_ExceptionMatches
(
PyExc_StopIteration
))
{
PyErr_Clear
();
Py_CLEAR
(
it
->
it_callable
);
Py_CLEAR
(
it
->
it_sentinel
);
}
}
return
NULL
;
}
PyTypeObject
PyCallIter_Type
=
{
// Pyston change:
PyVarObject_HEAD_INIT
(
NULL
/* &PyType_Type */
,
0
)
"callable-iterator"
,
/* tp_name */
sizeof
(
calliterobject
),
/* tp_basicsize */
0
,
/* tp_itemsize */
/* methods */
(
destructor
)
calliter_dealloc
,
/* tp_dealloc */
0
,
/* tp_print */
0
,
/* tp_getattr */
0
,
/* tp_setattr */
0
,
/* tp_compare */
0
,
/* tp_repr */
0
,
/* tp_as_number */
0
,
/* tp_as_sequence */
0
,
/* tp_as_mapping */
0
,
/* tp_hash */
0
,
/* tp_call */
0
,
/* tp_str */
PyObject_GenericGetAttr
,
/* tp_getattro */
0
,
/* tp_setattro */
0
,
/* tp_as_buffer */
Py_TPFLAGS_DEFAULT
|
Py_TPFLAGS_HAVE_GC
,
/* tp_flags */
0
,
/* tp_doc */
(
traverseproc
)
calliter_traverse
,
/* tp_traverse */
0
,
/* tp_clear */
0
,
/* tp_richcompare */
0
,
/* tp_weaklistoffset */
PyObject_SelfIter
,
/* tp_iter */
(
iternextfunc
)
calliter_iternext
,
/* tp_iternext */
0
,
/* tp_methods */
};
src/analysis/scoping_analysis.cpp
View file @
4480e933
...
@@ -407,6 +407,8 @@ public:
...
@@ -407,6 +407,8 @@ public:
for
(
AST_comprehension
*
c
:
node
->
generators
)
{
for
(
AST_comprehension
*
c
:
node
->
generators
)
{
if
(
!
first
)
if
(
!
first
)
c
->
iter
->
accept
(
this
);
c
->
iter
->
accept
(
this
);
for
(
auto
i
:
c
->
ifs
)
i
->
accept
(
this
);
c
->
target
->
accept
(
this
);
c
->
target
->
accept
(
this
);
first
=
false
;
first
=
false
;
}
}
...
...
src/capi/abstract.cpp
View file @
4480e933
...
@@ -135,7 +135,9 @@ extern "C" void PyBuffer_Release(Py_buffer* view) noexcept {
...
@@ -135,7 +135,9 @@ extern "C" void PyBuffer_Release(Py_buffer* view) noexcept {
PyObject
*
obj
=
view
->
obj
;
PyObject
*
obj
=
view
->
obj
;
if
(
obj
)
{
if
(
obj
)
{
assert
(
obj
->
cls
==
str_cls
);
// This is a Pyston assert
assert
(
isSubclass
(
obj
->
cls
,
str_cls
));
if
(
obj
&&
Py_TYPE
(
obj
)
->
tp_as_buffer
&&
Py_TYPE
(
obj
)
->
tp_as_buffer
->
bf_releasebuffer
)
if
(
obj
&&
Py_TYPE
(
obj
)
->
tp_as_buffer
&&
Py_TYPE
(
obj
)
->
tp_as_buffer
->
bf_releasebuffer
)
Py_TYPE
(
obj
)
->
tp_as_buffer
->
bf_releasebuffer
(
obj
,
view
);
Py_TYPE
(
obj
)
->
tp_as_buffer
->
bf_releasebuffer
(
obj
,
view
);
Py_XDECREF
(
obj
);
Py_XDECREF
(
obj
);
...
...
src/jit.cpp
View file @
4480e933
...
@@ -45,23 +45,28 @@
...
@@ -45,23 +45,28 @@
#error
#error
#endif
#endif
using
namespace
pyston
;
namespace
pyston
{
// returns true iff we got a request to exit, i.e. SystemExit, placing the
// returns true iff we got a request to exit, i.e. SystemExit, placing the
// return code in `*retcode`. does not touch `*retcode* if it returns false.
// return code in `*retcode`. does not touch `*retcode* if it returns false.
static
bool
handle_toplevel_exn
(
const
ExcInfo
&
e
,
int
*
retcode
)
{
static
bool
handle_toplevel_exn
(
const
ExcInfo
&
e
,
int
*
retcode
)
{
if
(
e
.
matches
(
SystemExit
))
{
if
(
e
.
matches
(
SystemExit
))
{
Box
*
code
=
e
.
value
->
getattr
(
"code"
);
Box
*
code
=
e
.
value
->
getattr
(
"code"
);
*
retcode
=
1
;
if
(
code
&&
isSubclass
(
code
->
cls
,
pyston
::
int_cls
))
if
(
!
code
||
code
==
None
)
*
retcode
=
0
;
else
if
(
isSubclass
(
code
->
cls
,
int_cls
))
*
retcode
=
static_cast
<
BoxedInt
*>
(
code
)
->
n
;
*
retcode
=
static_cast
<
BoxedInt
*>
(
code
)
->
n
;
else
*
retcode
=
1
;
return
true
;
return
true
;
}
}
e
.
printExcAndTraceback
();
e
.
printExcAndTraceback
();
return
false
;
return
false
;
}
}
int
main
(
int
argc
,
char
**
argv
)
{
static
int
main
(
int
argc
,
char
**
argv
)
{
Timer
_t
(
"for jit startup"
);
Timer
_t
(
"for jit startup"
);
// llvm::sys::PrintStackTraceOnErrorSignal();
// llvm::sys::PrintStackTraceOnErrorSignal();
// llvm::PrettyStackTraceProgram X(argc, argv);
// llvm::PrettyStackTraceProgram X(argc, argv);
...
@@ -259,3 +264,9 @@ int main(int argc, char** argv) {
...
@@ -259,3 +264,9 @@ int main(int argc, char** argv) {
return
rtncode
;
return
rtncode
;
}
}
}
// namespace pyston
int
main
(
int
argc
,
char
**
argv
)
{
return
pyston
::
main
(
argc
,
argv
);
}
src/runtime/capi.cpp
View file @
4480e933
...
@@ -852,10 +852,6 @@ extern "C" PyObject* PyImport_Import(PyObject* module_name) noexcept {
...
@@ -852,10 +852,6 @@ extern "C" PyObject* PyImport_Import(PyObject* module_name) noexcept {
}
}
extern
"C"
PyObject
*
PyCallIter_New
(
PyObject
*
callable
,
PyObject
*
sentinel
)
noexcept
{
Py_FatalError
(
"unimplemented"
);
}
extern
"C"
void
*
PyObject_Malloc
(
size_t
sz
)
noexcept
{
extern
"C"
void
*
PyObject_Malloc
(
size_t
sz
)
noexcept
{
return
gc_compat_malloc
(
sz
);
return
gc_compat_malloc
(
sz
);
}
}
...
...
src/runtime/dict.h
View file @
4480e933
...
@@ -57,6 +57,7 @@ public:
...
@@ -57,6 +57,7 @@ public:
Box
*
dictViewKeysIter
(
Box
*
self
);
Box
*
dictViewKeysIter
(
Box
*
self
);
Box
*
dictViewValuesIter
(
Box
*
self
);
Box
*
dictViewValuesIter
(
Box
*
self
);
Box
*
dictViewItemsIter
(
Box
*
self
);
Box
*
dictViewItemsIter
(
Box
*
self
);
void
dictMerge
(
BoxedDict
*
self
,
Box
*
other
);
}
}
#endif
#endif
src/runtime/file.cpp
View file @
4480e933
...
@@ -1055,14 +1055,27 @@ extern "C" size_t Py_UniversalNewlineFread(char* buf, size_t n, FILE* stream, Py
...
@@ -1055,14 +1055,27 @@ extern "C" size_t Py_UniversalNewlineFread(char* buf, size_t n, FILE* stream, Py
return
dst
-
buf
;
return
dst
-
buf
;
}
}
static
PyObject
*
file_isatty
(
BoxedFile
*
f
)
noexcept
{
long
res
;
if
(
f
->
f_fp
==
NULL
)
return
err_closed
();
FILE_BEGIN_ALLOW_THREADS
(
f
)
res
=
isatty
((
int
)
fileno
(
f
->
f_fp
));
FILE_END_ALLOW_THREADS
(
f
)
return
PyBool_FromLong
(
res
);
}
PyDoc_STRVAR
(
readlines_doc
,
"readlines([size]) -> list of strings, each a line from the file.
\n
"
PyDoc_STRVAR
(
readlines_doc
,
"readlines([size]) -> list of strings, each a line from the file.
\n
"
"
\n
"
"
\n
"
"Call readline() repeatedly and return a list of the lines so read.
\n
"
"Call readline() repeatedly and return a list of the lines so read.
\n
"
"The optional size argument, if given, is an approximate bound on the
\n
"
"The optional size argument, if given, is an approximate bound on the
\n
"
"total number of bytes in the lines returned."
);
"total number of bytes in the lines returned."
);
PyDoc_STRVAR
(
isatty_doc
,
"isatty() -> true or false. True if the file is connected to a tty device."
);
PyMethodDef
file_methods
[]
=
{
PyMethodDef
file_methods
[]
=
{
{
"readlines"
,
(
PyCFunction
)
file_readlines
,
METH_VARARGS
,
readlines_doc
},
{
"readlines"
,
(
PyCFunction
)
file_readlines
,
METH_VARARGS
,
readlines_doc
},
{
"isatty"
,
(
PyCFunction
)
file_isatty
,
METH_NOARGS
,
isatty_doc
},
};
};
void
fileDestructor
(
Box
*
b
)
{
void
fileDestructor
(
Box
*
b
)
{
...
...
src/runtime/float.cpp
View file @
4480e933
...
@@ -87,6 +87,8 @@ extern "C" Box* floatAdd(BoxedFloat* lhs, Box* rhs) {
...
@@ -87,6 +87,8 @@ extern "C" Box* floatAdd(BoxedFloat* lhs, Box* rhs) {
return
floatAddInt
(
lhs
,
static_cast
<
BoxedInt
*>
(
rhs
));
return
floatAddInt
(
lhs
,
static_cast
<
BoxedInt
*>
(
rhs
));
}
else
if
(
rhs
->
cls
==
float_cls
)
{
}
else
if
(
rhs
->
cls
==
float_cls
)
{
return
floatAddFloat
(
lhs
,
static_cast
<
BoxedFloat
*>
(
rhs
));
return
floatAddFloat
(
lhs
,
static_cast
<
BoxedFloat
*>
(
rhs
));
}
else
if
(
rhs
->
cls
==
long_cls
)
{
return
boxFloat
(
lhs
->
d
+
PyLong_AsDouble
(
rhs
));
}
else
{
}
else
{
return
NotImplemented
;
return
NotImplemented
;
}
}
...
@@ -112,6 +114,8 @@ extern "C" Box* floatDiv(BoxedFloat* lhs, Box* rhs) {
...
@@ -112,6 +114,8 @@ extern "C" Box* floatDiv(BoxedFloat* lhs, Box* rhs) {
return
floatDivInt
(
lhs
,
static_cast
<
BoxedInt
*>
(
rhs
));
return
floatDivInt
(
lhs
,
static_cast
<
BoxedInt
*>
(
rhs
));
}
else
if
(
rhs
->
cls
==
float_cls
)
{
}
else
if
(
rhs
->
cls
==
float_cls
)
{
return
floatDivFloat
(
lhs
,
static_cast
<
BoxedFloat
*>
(
rhs
));
return
floatDivFloat
(
lhs
,
static_cast
<
BoxedFloat
*>
(
rhs
));
}
else
if
(
rhs
->
cls
==
long_cls
)
{
return
boxFloat
(
lhs
->
d
/
PyLong_AsDouble
(
rhs
));
}
else
{
}
else
{
return
NotImplemented
;
return
NotImplemented
;
}
}
...
@@ -123,6 +127,8 @@ extern "C" Box* floatTruediv(BoxedFloat* lhs, Box* rhs) {
...
@@ -123,6 +127,8 @@ extern "C" Box* floatTruediv(BoxedFloat* lhs, Box* rhs) {
return
floatDivInt
(
lhs
,
static_cast
<
BoxedInt
*>
(
rhs
));
return
floatDivInt
(
lhs
,
static_cast
<
BoxedInt
*>
(
rhs
));
}
else
if
(
rhs
->
cls
==
float_cls
)
{
}
else
if
(
rhs
->
cls
==
float_cls
)
{
return
floatDivFloat
(
lhs
,
static_cast
<
BoxedFloat
*>
(
rhs
));
return
floatDivFloat
(
lhs
,
static_cast
<
BoxedFloat
*>
(
rhs
));
}
else
if
(
rhs
->
cls
==
long_cls
)
{
return
boxFloat
(
lhs
->
d
/
PyLong_AsDouble
(
rhs
));
}
else
{
}
else
{
return
NotImplemented
;
return
NotImplemented
;
}
}
...
@@ -148,6 +154,8 @@ extern "C" Box* floatRDiv(BoxedFloat* lhs, Box* rhs) {
...
@@ -148,6 +154,8 @@ extern "C" Box* floatRDiv(BoxedFloat* lhs, Box* rhs) {
return
floatRDivInt
(
lhs
,
static_cast
<
BoxedInt
*>
(
rhs
));
return
floatRDivInt
(
lhs
,
static_cast
<
BoxedInt
*>
(
rhs
));
}
else
if
(
rhs
->
cls
==
float_cls
)
{
}
else
if
(
rhs
->
cls
==
float_cls
)
{
return
floatRDivFloat
(
lhs
,
static_cast
<
BoxedFloat
*>
(
rhs
));
return
floatRDivFloat
(
lhs
,
static_cast
<
BoxedFloat
*>
(
rhs
));
}
else
if
(
rhs
->
cls
==
long_cls
)
{
return
boxFloat
(
PyLong_AsDouble
(
rhs
)
/
lhs
->
d
);
}
else
{
}
else
{
return
NotImplemented
;
return
NotImplemented
;
}
}
...
@@ -196,6 +204,8 @@ extern "C" Box* floatEq(BoxedFloat* lhs, Box* rhs) {
...
@@ -196,6 +204,8 @@ extern "C" Box* floatEq(BoxedFloat* lhs, Box* rhs) {
return
floatEqInt
(
lhs
,
static_cast
<
BoxedInt
*>
(
rhs
));
return
floatEqInt
(
lhs
,
static_cast
<
BoxedInt
*>
(
rhs
));
}
else
if
(
rhs
->
cls
==
float_cls
)
{
}
else
if
(
rhs
->
cls
==
float_cls
)
{
return
floatEqFloat
(
lhs
,
static_cast
<
BoxedFloat
*>
(
rhs
));
return
floatEqFloat
(
lhs
,
static_cast
<
BoxedFloat
*>
(
rhs
));
}
else
if
(
rhs
->
cls
==
long_cls
)
{
return
boxBool
(
lhs
->
d
==
PyLong_AsDouble
(
rhs
));
}
else
{
}
else
{
return
NotImplemented
;
return
NotImplemented
;
}
}
...
@@ -219,6 +229,8 @@ extern "C" Box* floatNe(BoxedFloat* lhs, Box* rhs) {
...
@@ -219,6 +229,8 @@ extern "C" Box* floatNe(BoxedFloat* lhs, Box* rhs) {
return
floatNeInt
(
lhs
,
static_cast
<
BoxedInt
*>
(
rhs
));
return
floatNeInt
(
lhs
,
static_cast
<
BoxedInt
*>
(
rhs
));
}
else
if
(
rhs
->
cls
==
float_cls
)
{
}
else
if
(
rhs
->
cls
==
float_cls
)
{
return
floatNeFloat
(
lhs
,
static_cast
<
BoxedFloat
*>
(
rhs
));
return
floatNeFloat
(
lhs
,
static_cast
<
BoxedFloat
*>
(
rhs
));
}
else
if
(
rhs
->
cls
==
long_cls
)
{
return
boxBool
(
lhs
->
d
!=
PyLong_AsDouble
(
rhs
));
}
else
{
}
else
{
return
NotImplemented
;
return
NotImplemented
;
}
}
...
@@ -242,6 +254,8 @@ extern "C" Box* floatLt(BoxedFloat* lhs, Box* rhs) {
...
@@ -242,6 +254,8 @@ extern "C" Box* floatLt(BoxedFloat* lhs, Box* rhs) {
return
floatLtInt
(
lhs
,
static_cast
<
BoxedInt
*>
(
rhs
));
return
floatLtInt
(
lhs
,
static_cast
<
BoxedInt
*>
(
rhs
));
}
else
if
(
rhs
->
cls
==
float_cls
)
{
}
else
if
(
rhs
->
cls
==
float_cls
)
{
return
floatLtFloat
(
lhs
,
static_cast
<
BoxedFloat
*>
(
rhs
));
return
floatLtFloat
(
lhs
,
static_cast
<
BoxedFloat
*>
(
rhs
));
}
else
if
(
rhs
->
cls
==
long_cls
)
{
return
boxBool
(
lhs
->
d
<
PyLong_AsDouble
(
rhs
));
}
else
{
}
else
{
return
NotImplemented
;
return
NotImplemented
;
}
}
...
@@ -265,6 +279,8 @@ extern "C" Box* floatLe(BoxedFloat* lhs, Box* rhs) {
...
@@ -265,6 +279,8 @@ extern "C" Box* floatLe(BoxedFloat* lhs, Box* rhs) {
return
floatLeInt
(
lhs
,
static_cast
<
BoxedInt
*>
(
rhs
));
return
floatLeInt
(
lhs
,
static_cast
<
BoxedInt
*>
(
rhs
));
}
else
if
(
rhs
->
cls
==
float_cls
)
{
}
else
if
(
rhs
->
cls
==
float_cls
)
{
return
floatLeFloat
(
lhs
,
static_cast
<
BoxedFloat
*>
(
rhs
));
return
floatLeFloat
(
lhs
,
static_cast
<
BoxedFloat
*>
(
rhs
));
}
else
if
(
rhs
->
cls
==
long_cls
)
{
return
boxBool
(
lhs
->
d
<=
PyLong_AsDouble
(
rhs
));
}
else
{
}
else
{
return
NotImplemented
;
return
NotImplemented
;
}
}
...
@@ -288,6 +304,8 @@ extern "C" Box* floatGt(BoxedFloat* lhs, Box* rhs) {
...
@@ -288,6 +304,8 @@ extern "C" Box* floatGt(BoxedFloat* lhs, Box* rhs) {
return
floatGtInt
(
lhs
,
static_cast
<
BoxedInt
*>
(
rhs
));
return
floatGtInt
(
lhs
,
static_cast
<
BoxedInt
*>
(
rhs
));
}
else
if
(
rhs
->
cls
==
float_cls
)
{
}
else
if
(
rhs
->
cls
==
float_cls
)
{
return
floatGtFloat
(
lhs
,
static_cast
<
BoxedFloat
*>
(
rhs
));
return
floatGtFloat
(
lhs
,
static_cast
<
BoxedFloat
*>
(
rhs
));
}
else
if
(
rhs
->
cls
==
long_cls
)
{
return
boxBool
(
lhs
->
d
>
PyLong_AsDouble
(
rhs
));
}
else
{
}
else
{
return
NotImplemented
;
return
NotImplemented
;
}
}
...
@@ -311,6 +329,8 @@ extern "C" Box* floatGe(BoxedFloat* lhs, Box* rhs) {
...
@@ -311,6 +329,8 @@ extern "C" Box* floatGe(BoxedFloat* lhs, Box* rhs) {
return
floatGeInt
(
lhs
,
static_cast
<
BoxedInt
*>
(
rhs
));
return
floatGeInt
(
lhs
,
static_cast
<
BoxedInt
*>
(
rhs
));
}
else
if
(
rhs
->
cls
==
float_cls
)
{
}
else
if
(
rhs
->
cls
==
float_cls
)
{
return
floatGeFloat
(
lhs
,
static_cast
<
BoxedFloat
*>
(
rhs
));
return
floatGeFloat
(
lhs
,
static_cast
<
BoxedFloat
*>
(
rhs
));
}
else
if
(
rhs
->
cls
==
long_cls
)
{
return
boxBool
(
lhs
->
d
>=
PyLong_AsDouble
(
rhs
));
}
else
{
}
else
{
return
NotImplemented
;
return
NotImplemented
;
}
}
...
@@ -334,6 +354,8 @@ extern "C" Box* floatMod(BoxedFloat* lhs, Box* rhs) {
...
@@ -334,6 +354,8 @@ extern "C" Box* floatMod(BoxedFloat* lhs, Box* rhs) {
return
floatModInt
(
lhs
,
static_cast
<
BoxedInt
*>
(
rhs
));
return
floatModInt
(
lhs
,
static_cast
<
BoxedInt
*>
(
rhs
));
}
else
if
(
rhs
->
cls
==
float_cls
)
{
}
else
if
(
rhs
->
cls
==
float_cls
)
{
return
floatModFloat
(
lhs
,
static_cast
<
BoxedFloat
*>
(
rhs
));
return
floatModFloat
(
lhs
,
static_cast
<
BoxedFloat
*>
(
rhs
));
}
else
if
(
rhs
->
cls
==
long_cls
)
{
return
boxFloat
(
mod_float_float
(
lhs
->
d
,
PyLong_AsDouble
(
rhs
)));
}
else
{
}
else
{
return
NotImplemented
;
return
NotImplemented
;
}
}
...
@@ -357,6 +379,8 @@ extern "C" Box* floatRMod(BoxedFloat* lhs, Box* rhs) {
...
@@ -357,6 +379,8 @@ extern "C" Box* floatRMod(BoxedFloat* lhs, Box* rhs) {
return
floatRModInt
(
lhs
,
static_cast
<
BoxedInt
*>
(
rhs
));
return
floatRModInt
(
lhs
,
static_cast
<
BoxedInt
*>
(
rhs
));
}
else
if
(
rhs
->
cls
==
float_cls
)
{
}
else
if
(
rhs
->
cls
==
float_cls
)
{
return
floatRModFloat
(
lhs
,
static_cast
<
BoxedFloat
*>
(
rhs
));
return
floatRModFloat
(
lhs
,
static_cast
<
BoxedFloat
*>
(
rhs
));
}
else
if
(
rhs
->
cls
==
long_cls
)
{
return
boxFloat
(
mod_float_float
(
PyLong_AsDouble
(
rhs
),
lhs
->
d
));
}
else
{
}
else
{
return
NotImplemented
;
return
NotImplemented
;
}
}
...
@@ -380,6 +404,8 @@ extern "C" Box* floatPow(BoxedFloat* lhs, Box* rhs) {
...
@@ -380,6 +404,8 @@ extern "C" Box* floatPow(BoxedFloat* lhs, Box* rhs) {
return
floatPowInt
(
lhs
,
static_cast
<
BoxedInt
*>
(
rhs
));
return
floatPowInt
(
lhs
,
static_cast
<
BoxedInt
*>
(
rhs
));
}
else
if
(
rhs
->
cls
==
float_cls
)
{
}
else
if
(
rhs
->
cls
==
float_cls
)
{
return
floatPowFloat
(
lhs
,
static_cast
<
BoxedFloat
*>
(
rhs
));
return
floatPowFloat
(
lhs
,
static_cast
<
BoxedFloat
*>
(
rhs
));
}
else
if
(
rhs
->
cls
==
long_cls
)
{
return
boxFloat
(
pow
(
lhs
->
d
,
PyLong_AsDouble
(
rhs
)));
}
else
{
}
else
{
return
NotImplemented
;
return
NotImplemented
;
}
}
...
@@ -403,6 +429,8 @@ extern "C" Box* floatMul(BoxedFloat* lhs, Box* rhs) {
...
@@ -403,6 +429,8 @@ extern "C" Box* floatMul(BoxedFloat* lhs, Box* rhs) {
return
floatMulInt
(
lhs
,
static_cast
<
BoxedInt
*>
(
rhs
));
return
floatMulInt
(
lhs
,
static_cast
<
BoxedInt
*>
(
rhs
));
}
else
if
(
rhs
->
cls
==
float_cls
)
{
}
else
if
(
rhs
->
cls
==
float_cls
)
{
return
floatMulFloat
(
lhs
,
static_cast
<
BoxedFloat
*>
(
rhs
));
return
floatMulFloat
(
lhs
,
static_cast
<
BoxedFloat
*>
(
rhs
));
}
else
if
(
rhs
->
cls
==
long_cls
)
{
return
boxFloat
(
lhs
->
d
*
PyLong_AsDouble
(
rhs
));
}
else
{
}
else
{
return
NotImplemented
;
return
NotImplemented
;
}
}
...
@@ -426,6 +454,8 @@ extern "C" Box* floatSub(BoxedFloat* lhs, Box* rhs) {
...
@@ -426,6 +454,8 @@ extern "C" Box* floatSub(BoxedFloat* lhs, Box* rhs) {
return
floatSubInt
(
lhs
,
static_cast
<
BoxedInt
*>
(
rhs
));
return
floatSubInt
(
lhs
,
static_cast
<
BoxedInt
*>
(
rhs
));
}
else
if
(
rhs
->
cls
==
float_cls
)
{
}
else
if
(
rhs
->
cls
==
float_cls
)
{
return
floatSubFloat
(
lhs
,
static_cast
<
BoxedFloat
*>
(
rhs
));
return
floatSubFloat
(
lhs
,
static_cast
<
BoxedFloat
*>
(
rhs
));
}
else
if
(
rhs
->
cls
==
long_cls
)
{
return
boxFloat
(
lhs
->
d
-
PyLong_AsDouble
(
rhs
));
}
else
{
}
else
{
return
NotImplemented
;
return
NotImplemented
;
}
}
...
@@ -449,6 +479,8 @@ extern "C" Box* floatRSub(BoxedFloat* lhs, Box* rhs) {
...
@@ -449,6 +479,8 @@ extern "C" Box* floatRSub(BoxedFloat* lhs, Box* rhs) {
return
floatRSubInt
(
lhs
,
static_cast
<
BoxedInt
*>
(
rhs
));
return
floatRSubInt
(
lhs
,
static_cast
<
BoxedInt
*>
(
rhs
));
}
else
if
(
rhs
->
cls
==
float_cls
)
{
}
else
if
(
rhs
->
cls
==
float_cls
)
{
return
floatRSubFloat
(
lhs
,
static_cast
<
BoxedFloat
*>
(
rhs
));
return
floatRSubFloat
(
lhs
,
static_cast
<
BoxedFloat
*>
(
rhs
));
}
else
if
(
rhs
->
cls
==
long_cls
)
{
return
boxFloat
(
PyLong_AsDouble
(
rhs
)
-
lhs
->
d
);
}
else
{
}
else
{
return
NotImplemented
;
return
NotImplemented
;
}
}
...
@@ -545,6 +577,9 @@ std::string floatFmt(double x, int precision, char code) {
...
@@ -545,6 +577,9 @@ std::string floatFmt(double x, int precision, char code) {
}
}
BoxedFloat
*
_floatNew
(
Box
*
a
)
{
BoxedFloat
*
_floatNew
(
Box
*
a
)
{
// FIXME CPython uses PyUnicode_EncodeDecimal:
a
=
coerceUnicodeToStr
(
a
);
if
(
a
->
cls
==
float_cls
)
{
if
(
a
->
cls
==
float_cls
)
{
return
static_cast
<
BoxedFloat
*>
(
a
);
return
static_cast
<
BoxedFloat
*>
(
a
);
}
else
if
(
isSubclass
(
a
->
cls
,
float_cls
))
{
}
else
if
(
isSubclass
(
a
->
cls
,
float_cls
))
{
...
...
src/runtime/objmodel.cpp
View file @
4480e933
...
@@ -41,6 +41,7 @@
...
@@ -41,6 +41,7 @@
#include "gc/heap.h"
#include "gc/heap.h"
#include "runtime/capi.h"
#include "runtime/capi.h"
#include "runtime/classobj.h"
#include "runtime/classobj.h"
#include "runtime/dict.h"
#include "runtime/file.h"
#include "runtime/file.h"
#include "runtime/float.h"
#include "runtime/float.h"
#include "runtime/generator.h"
#include "runtime/generator.h"
...
@@ -303,6 +304,9 @@ BoxedClass::BoxedClass(BoxedClass* base, gcvisit_func gc_visit, int attrs_offset
...
@@ -303,6 +304,9 @@ BoxedClass::BoxedClass(BoxedClass* base, gcvisit_func gc_visit, int attrs_offset
tp_flags
|=
Py_TPFLAGS_HAVE_GC
;
tp_flags
|=
Py_TPFLAGS_HAVE_GC
;
tp_flags
|=
Py_TPFLAGS_HAVE_WEAKREFS
;
tp_flags
|=
Py_TPFLAGS_HAVE_WEAKREFS
;
if
(
base
&&
(
base
->
tp_flags
&
Py_TPFLAGS_HAVE_NEWBUFFER
))
tp_flags
|=
Py_TPFLAGS_HAVE_NEWBUFFER
;
tp_base
=
base
;
tp_base
=
base
;
if
(
tp_base
)
{
if
(
tp_base
)
{
...
@@ -1940,7 +1944,7 @@ extern "C" BoxedInt* hash(Box* obj) {
...
@@ -1940,7 +1944,7 @@ extern "C" BoxedInt* hash(Box* obj) {
Box
*
hash
=
getclsattr_internal
(
obj
,
"__hash__"
,
NULL
);
Box
*
hash
=
getclsattr_internal
(
obj
,
"__hash__"
,
NULL
);
if
(
hash
==
NULL
)
{
if
(
hash
==
NULL
)
{
ASSERT
(
isUserDefined
(
obj
->
cls
),
"%s.__hash__"
,
getTypeName
(
obj
));
ASSERT
(
isUserDefined
(
obj
->
cls
)
||
obj
->
cls
==
function_cls
,
"%s.__hash__"
,
getTypeName
(
obj
));
// TODO not the best way to handle this...
// TODO not the best way to handle this...
return
static_cast
<
BoxedInt
*>
(
boxInt
((
i64
)
obj
));
return
static_cast
<
BoxedInt
*>
(
boxInt
((
i64
)
obj
));
}
}
...
@@ -2693,7 +2697,13 @@ Box* callFunc(BoxedFunctionBase* func, CallRewriteArgs* rewrite_args, ArgPassSpe
...
@@ -2693,7 +2697,13 @@ Box* callFunc(BoxedFunctionBase* func, CallRewriteArgs* rewrite_args, ArgPassSpe
Box
*
kwargs
Box
*
kwargs
=
getArg
(
argspec
.
num_args
+
argspec
.
num_keywords
+
(
argspec
.
has_starargs
?
1
:
0
),
arg1
,
arg2
,
arg3
,
args
);
=
getArg
(
argspec
.
num_args
+
argspec
.
num_keywords
+
(
argspec
.
has_starargs
?
1
:
0
),
arg1
,
arg2
,
arg3
,
args
);
RELEASE_ASSERT
(
kwargs
->
cls
==
dict_cls
,
"haven't implemented this for non-dicts"
);
if
(
!
isSubclass
(
kwargs
->
cls
,
dict_cls
))
{
BoxedDict
*
d
=
new
BoxedDict
();
dictMerge
(
d
,
kwargs
);
kwargs
=
d
;
}
assert
(
isSubclass
(
kwargs
->
cls
,
dict_cls
));
BoxedDict
*
d_kwargs
=
static_cast
<
BoxedDict
*>
(
kwargs
);
BoxedDict
*
d_kwargs
=
static_cast
<
BoxedDict
*>
(
kwargs
);
for
(
auto
&
p
:
d_kwargs
->
d
)
{
for
(
auto
&
p
:
d_kwargs
->
d
)
{
...
@@ -3288,6 +3298,7 @@ Box* compareInternal(Box* lhs, Box* rhs, int op_type, CompareRewriteArgs* rewrit
...
@@ -3288,6 +3298,7 @@ Box* compareInternal(Box* lhs, Box* rhs, int op_type, CompareRewriteArgs* rewrit
#ifndef NDEBUG
#ifndef NDEBUG
if
((
lhs
->
cls
==
int_cls
||
lhs
->
cls
==
float_cls
||
lhs
->
cls
==
long_cls
)
if
((
lhs
->
cls
==
int_cls
||
lhs
->
cls
==
float_cls
||
lhs
->
cls
==
long_cls
)
&&
(
rhs
->
cls
==
int_cls
||
rhs
->
cls
==
float_cls
||
rhs
->
cls
==
long_cls
))
{
&&
(
rhs
->
cls
==
int_cls
||
rhs
->
cls
==
float_cls
||
rhs
->
cls
==
long_cls
))
{
printf
(
"
\n
%s %s %s
\n
"
,
lhs
->
cls
->
tp_name
,
op_name
.
c_str
(),
rhs
->
cls
->
tp_name
);
Py_FatalError
(
"missing comparison between these classes"
);
Py_FatalError
(
"missing comparison between these classes"
);
}
}
#endif
#endif
...
...
src/runtime/str.cpp
View file @
4480e933
...
@@ -296,7 +296,7 @@ extern "C" PyObject* PyString_FromFormat(const char* format, ...) noexcept {
...
@@ -296,7 +296,7 @@ extern "C" PyObject* PyString_FromFormat(const char* format, ...) noexcept {
}
}
extern
"C"
Box
*
strAdd
(
BoxedString
*
lhs
,
Box
*
_rhs
)
{
extern
"C"
Box
*
strAdd
(
BoxedString
*
lhs
,
Box
*
_rhs
)
{
assert
(
lhs
->
cls
==
str_cls
);
assert
(
isSubclass
(
lhs
->
cls
,
str_cls
)
);
if
(
_rhs
->
cls
==
unicode_cls
)
{
if
(
_rhs
->
cls
==
unicode_cls
)
{
Box
*
rtn
=
PyUnicode_Concat
(
lhs
,
_rhs
);
Box
*
rtn
=
PyUnicode_Concat
(
lhs
,
_rhs
);
...
@@ -934,7 +934,7 @@ extern "C" Box* strMod(BoxedString* lhs, Box* rhs) {
...
@@ -934,7 +934,7 @@ extern "C" Box* strMod(BoxedString* lhs, Box* rhs) {
}
}
extern
"C"
Box
*
strMul
(
BoxedString
*
lhs
,
Box
*
rhs
)
{
extern
"C"
Box
*
strMul
(
BoxedString
*
lhs
,
Box
*
rhs
)
{
assert
(
lhs
->
cls
==
str_cls
);
assert
(
isSubclass
(
lhs
->
cls
,
str_cls
)
);
int
n
;
int
n
;
if
(
isSubclass
(
rhs
->
cls
,
int_cls
))
if
(
isSubclass
(
rhs
->
cls
,
int_cls
))
...
@@ -952,7 +952,7 @@ extern "C" Box* strMul(BoxedString* lhs, Box* rhs) {
...
@@ -952,7 +952,7 @@ extern "C" Box* strMul(BoxedString* lhs, Box* rhs) {
}
}
extern
"C"
Box
*
strLt
(
BoxedString
*
lhs
,
Box
*
rhs
)
{
extern
"C"
Box
*
strLt
(
BoxedString
*
lhs
,
Box
*
rhs
)
{
assert
(
lhs
->
cls
==
str_cls
);
assert
(
isSubclass
(
lhs
->
cls
,
str_cls
)
);
if
(
rhs
->
cls
!=
str_cls
)
if
(
rhs
->
cls
!=
str_cls
)
return
NotImplemented
;
return
NotImplemented
;
...
@@ -962,7 +962,7 @@ extern "C" Box* strLt(BoxedString* lhs, Box* rhs) {
...
@@ -962,7 +962,7 @@ extern "C" Box* strLt(BoxedString* lhs, Box* rhs) {
}
}
extern
"C"
Box
*
strLe
(
BoxedString
*
lhs
,
Box
*
rhs
)
{
extern
"C"
Box
*
strLe
(
BoxedString
*
lhs
,
Box
*
rhs
)
{
assert
(
lhs
->
cls
==
str_cls
);
assert
(
isSubclass
(
lhs
->
cls
,
str_cls
)
);
if
(
rhs
->
cls
!=
str_cls
)
if
(
rhs
->
cls
!=
str_cls
)
return
NotImplemented
;
return
NotImplemented
;
...
@@ -972,7 +972,7 @@ extern "C" Box* strLe(BoxedString* lhs, Box* rhs) {
...
@@ -972,7 +972,7 @@ extern "C" Box* strLe(BoxedString* lhs, Box* rhs) {
}
}
extern
"C"
Box
*
strGt
(
BoxedString
*
lhs
,
Box
*
rhs
)
{
extern
"C"
Box
*
strGt
(
BoxedString
*
lhs
,
Box
*
rhs
)
{
assert
(
lhs
->
cls
==
str_cls
);
assert
(
isSubclass
(
lhs
->
cls
,
str_cls
)
);
if
(
rhs
->
cls
!=
str_cls
)
if
(
rhs
->
cls
!=
str_cls
)
return
NotImplemented
;
return
NotImplemented
;
...
@@ -982,7 +982,7 @@ extern "C" Box* strGt(BoxedString* lhs, Box* rhs) {
...
@@ -982,7 +982,7 @@ extern "C" Box* strGt(BoxedString* lhs, Box* rhs) {
}
}
extern
"C"
Box
*
strGe
(
BoxedString
*
lhs
,
Box
*
rhs
)
{
extern
"C"
Box
*
strGe
(
BoxedString
*
lhs
,
Box
*
rhs
)
{
assert
(
lhs
->
cls
==
str_cls
);
assert
(
isSubclass
(
lhs
->
cls
,
str_cls
)
);
if
(
rhs
->
cls
!=
str_cls
)
if
(
rhs
->
cls
!=
str_cls
)
return
NotImplemented
;
return
NotImplemented
;
...
@@ -992,7 +992,7 @@ extern "C" Box* strGe(BoxedString* lhs, Box* rhs) {
...
@@ -992,7 +992,7 @@ extern "C" Box* strGe(BoxedString* lhs, Box* rhs) {
}
}
extern
"C"
Box
*
strEq
(
BoxedString
*
lhs
,
Box
*
rhs
)
{
extern
"C"
Box
*
strEq
(
BoxedString
*
lhs
,
Box
*
rhs
)
{
assert
(
lhs
->
cls
==
str_cls
);
assert
(
isSubclass
(
lhs
->
cls
,
str_cls
)
);
if
(
rhs
->
cls
!=
str_cls
)
if
(
rhs
->
cls
!=
str_cls
)
return
NotImplemented
;
return
NotImplemented
;
...
@@ -1002,7 +1002,7 @@ extern "C" Box* strEq(BoxedString* lhs, Box* rhs) {
...
@@ -1002,7 +1002,7 @@ extern "C" Box* strEq(BoxedString* lhs, Box* rhs) {
}
}
extern
"C"
Box
*
strNe
(
BoxedString
*
lhs
,
Box
*
rhs
)
{
extern
"C"
Box
*
strNe
(
BoxedString
*
lhs
,
Box
*
rhs
)
{
assert
(
lhs
->
cls
==
str_cls
);
assert
(
isSubclass
(
lhs
->
cls
,
str_cls
)
);
if
(
rhs
->
cls
!=
str_cls
)
if
(
rhs
->
cls
!=
str_cls
)
return
NotImplemented
;
return
NotImplemented
;
...
@@ -1016,7 +1016,7 @@ extern "C" Box* strNe(BoxedString* lhs, Box* rhs) {
...
@@ -1016,7 +1016,7 @@ extern "C" Box* strNe(BoxedString* lhs, Box* rhs) {
#define JUST_CENTER 2
#define JUST_CENTER 2
static
Box
*
pad
(
BoxedString
*
self
,
Box
*
width
,
Box
*
fillchar
,
int
justType
)
{
static
Box
*
pad
(
BoxedString
*
self
,
Box
*
width
,
Box
*
fillchar
,
int
justType
)
{
assert
(
width
->
cls
==
int_cls
);
assert
(
width
->
cls
==
int_cls
);
assert
(
fillchar
->
cls
==
str_cls
);
assert
(
isSubclass
(
fillchar
->
cls
,
str_cls
)
);
assert
(
static_cast
<
BoxedString
*>
(
fillchar
)
->
s
.
size
()
==
1
);
assert
(
static_cast
<
BoxedString
*>
(
fillchar
)
->
s
.
size
()
==
1
);
int64_t
curWidth
=
self
->
s
.
size
();
int64_t
curWidth
=
self
->
s
.
size
();
int64_t
targetWidth
=
static_cast
<
BoxedInt
*>
(
width
)
->
n
;
int64_t
targetWidth
=
static_cast
<
BoxedInt
*>
(
width
)
->
n
;
...
@@ -1067,13 +1067,13 @@ extern "C" Box* strCenter(BoxedString* lhs, Box* width, Box* fillchar) {
...
@@ -1067,13 +1067,13 @@ extern "C" Box* strCenter(BoxedString* lhs, Box* width, Box* fillchar) {
}
}
extern
"C"
Box
*
strLen
(
BoxedString
*
self
)
{
extern
"C"
Box
*
strLen
(
BoxedString
*
self
)
{
assert
(
self
->
cls
==
str_cls
);
assert
(
isSubclass
(
self
->
cls
,
str_cls
)
);
return
boxInt
(
self
->
s
.
size
());
return
boxInt
(
self
->
s
.
size
());
}
}
extern
"C"
Box
*
strStr
(
BoxedString
*
self
)
{
extern
"C"
Box
*
strStr
(
BoxedString
*
self
)
{
assert
(
self
->
cls
==
str_cls
);
assert
(
isSubclass
(
self
->
cls
,
str_cls
)
);
return
self
;
return
self
;
}
}
...
@@ -1099,7 +1099,7 @@ static char _hex[17] = "0123456789abcdef"; // really only needs to be 16 but cla
...
@@ -1099,7 +1099,7 @@ static char _hex[17] = "0123456789abcdef"; // really only needs to be 16 but cla
extern
"C"
PyObject
*
PyString_Repr
(
PyObject
*
obj
,
int
smartquotes
)
noexcept
{
extern
"C"
PyObject
*
PyString_Repr
(
PyObject
*
obj
,
int
smartquotes
)
noexcept
{
BoxedString
*
self
=
(
BoxedString
*
)
obj
;
BoxedString
*
self
=
(
BoxedString
*
)
obj
;
assert
(
self
->
cls
==
str_cls
);
assert
(
isSubclass
(
self
->
cls
,
str_cls
)
);
std
::
ostringstream
os
(
""
);
std
::
ostringstream
os
(
""
);
...
@@ -1333,22 +1333,28 @@ failed:
...
@@ -1333,22 +1333,28 @@ failed:
}
}
extern
"C"
Box
*
strHash
(
BoxedString
*
self
)
{
extern
"C"
Box
*
strHash
(
BoxedString
*
self
)
{
assert
(
self
->
cls
==
str_cls
);
assert
(
isSubclass
(
self
->
cls
,
str_cls
)
);
std
::
hash
<
std
::
string
>
H
;
std
::
hash
<
std
::
string
>
H
;
return
boxInt
(
H
(
self
->
s
));
return
boxInt
(
H
(
self
->
s
));
}
}
extern
"C"
Box
*
strNonzero
(
BoxedString
*
self
)
{
extern
"C"
Box
*
strNonzero
(
BoxedString
*
self
)
{
ASSERT
(
self
->
cls
==
str_cls
,
"%s"
,
self
->
cls
->
tp_name
);
ASSERT
(
isSubclass
(
self
->
cls
,
str_cls
)
,
"%s"
,
self
->
cls
->
tp_name
);
return
boxBool
(
self
->
s
.
size
()
!=
0
);
return
boxBool
(
self
->
s
.
size
()
!=
0
);
}
}
extern
"C"
Box
*
strNew
(
BoxedClass
*
cls
,
Box
*
obj
)
{
extern
"C"
Box
*
strNew
(
BoxedClass
*
cls
,
Box
*
obj
)
{
assert
(
cls
==
str_cls
);
assert
(
isSubclass
(
cls
,
str_cls
)
);
return
str
(
obj
);
Box
*
rtn
=
str
(
obj
);
assert
(
rtn
->
cls
==
str_cls
);
if
(
cls
==
str_cls
)
return
rtn
;
return
new
(
cls
)
BoxedString
(
static_cast
<
BoxedString
*>
(
rtn
)
->
s
);
}
}
extern
"C"
Box
*
basestringNew
(
BoxedClass
*
cls
,
Box
*
args
,
Box
*
kwargs
)
{
extern
"C"
Box
*
basestringNew
(
BoxedClass
*
cls
,
Box
*
args
,
Box
*
kwargs
)
{
...
@@ -1356,7 +1362,7 @@ extern "C" Box* basestringNew(BoxedClass* cls, Box* args, Box* kwargs) {
...
@@ -1356,7 +1362,7 @@ extern "C" Box* basestringNew(BoxedClass* cls, Box* args, Box* kwargs) {
}
}
Box
*
_strSlice
(
BoxedString
*
self
,
i64
start
,
i64
stop
,
i64
step
,
i64
length
)
{
Box
*
_strSlice
(
BoxedString
*
self
,
i64
start
,
i64
stop
,
i64
step
,
i64
length
)
{
assert
(
self
->
cls
==
str_cls
);
assert
(
isSubclass
(
self
->
cls
,
str_cls
)
);
const
std
::
string
&
s
=
self
->
s
;
const
std
::
string
&
s
=
self
->
s
;
...
@@ -1378,7 +1384,7 @@ Box* _strSlice(BoxedString* self, i64 start, i64 stop, i64 step, i64 length) {
...
@@ -1378,7 +1384,7 @@ Box* _strSlice(BoxedString* self, i64 start, i64 stop, i64 step, i64 length) {
}
}
Box
*
strIsAlpha
(
BoxedString
*
self
)
{
Box
*
strIsAlpha
(
BoxedString
*
self
)
{
assert
(
self
->
cls
==
str_cls
);
assert
(
isSubclass
(
self
->
cls
,
str_cls
)
);
const
std
::
string
&
str
(
self
->
s
);
const
std
::
string
&
str
(
self
->
s
);
if
(
str
.
empty
())
if
(
str
.
empty
())
...
@@ -1393,7 +1399,7 @@ Box* strIsAlpha(BoxedString* self) {
...
@@ -1393,7 +1399,7 @@ Box* strIsAlpha(BoxedString* self) {
}
}
Box
*
strIsDigit
(
BoxedString
*
self
)
{
Box
*
strIsDigit
(
BoxedString
*
self
)
{
assert
(
self
->
cls
==
str_cls
);
assert
(
isSubclass
(
self
->
cls
,
str_cls
)
);
const
std
::
string
&
str
(
self
->
s
);
const
std
::
string
&
str
(
self
->
s
);
if
(
str
.
empty
())
if
(
str
.
empty
())
...
@@ -1408,7 +1414,7 @@ Box* strIsDigit(BoxedString* self) {
...
@@ -1408,7 +1414,7 @@ Box* strIsDigit(BoxedString* self) {
}
}
Box
*
strIsAlnum
(
BoxedString
*
self
)
{
Box
*
strIsAlnum
(
BoxedString
*
self
)
{
assert
(
self
->
cls
==
str_cls
);
assert
(
isSubclass
(
self
->
cls
,
str_cls
)
);
const
std
::
string
&
str
(
self
->
s
);
const
std
::
string
&
str
(
self
->
s
);
if
(
str
.
empty
())
if
(
str
.
empty
())
...
@@ -1423,7 +1429,7 @@ Box* strIsAlnum(BoxedString* self) {
...
@@ -1423,7 +1429,7 @@ Box* strIsAlnum(BoxedString* self) {
}
}
Box
*
strIsLower
(
BoxedString
*
self
)
{
Box
*
strIsLower
(
BoxedString
*
self
)
{
assert
(
self
->
cls
==
str_cls
);
assert
(
isSubclass
(
self
->
cls
,
str_cls
)
);
const
std
::
string
&
str
(
self
->
s
);
const
std
::
string
&
str
(
self
->
s
);
bool
lowered
=
false
;
bool
lowered
=
false
;
...
@@ -1445,7 +1451,7 @@ Box* strIsLower(BoxedString* self) {
...
@@ -1445,7 +1451,7 @@ Box* strIsLower(BoxedString* self) {
}
}
Box
*
strIsUpper
(
BoxedString
*
self
)
{
Box
*
strIsUpper
(
BoxedString
*
self
)
{
assert
(
self
->
cls
==
str_cls
);
assert
(
isSubclass
(
self
->
cls
,
str_cls
)
);
const
std
::
string
&
str
(
self
->
s
);
const
std
::
string
&
str
(
self
->
s
);
bool
uppered
=
false
;
bool
uppered
=
false
;
...
@@ -1467,7 +1473,7 @@ Box* strIsUpper(BoxedString* self) {
...
@@ -1467,7 +1473,7 @@ Box* strIsUpper(BoxedString* self) {
}
}
Box
*
strIsSpace
(
BoxedString
*
self
)
{
Box
*
strIsSpace
(
BoxedString
*
self
)
{
assert
(
self
->
cls
==
str_cls
);
assert
(
isSubclass
(
self
->
cls
,
str_cls
)
);
const
std
::
string
&
str
(
self
->
s
);
const
std
::
string
&
str
(
self
->
s
);
if
(
str
.
empty
())
if
(
str
.
empty
())
...
@@ -1482,7 +1488,7 @@ Box* strIsSpace(BoxedString* self) {
...
@@ -1482,7 +1488,7 @@ Box* strIsSpace(BoxedString* self) {
}
}
Box
*
strIsTitle
(
BoxedString
*
self
)
{
Box
*
strIsTitle
(
BoxedString
*
self
)
{
assert
(
self
->
cls
==
str_cls
);
assert
(
isSubclass
(
self
->
cls
,
str_cls
)
);
const
std
::
string
&
str
(
self
->
s
);
const
std
::
string
&
str
(
self
->
s
);
...
@@ -1517,7 +1523,7 @@ Box* strIsTitle(BoxedString* self) {
...
@@ -1517,7 +1523,7 @@ Box* strIsTitle(BoxedString* self) {
}
}
Box
*
strJoin
(
BoxedString
*
self
,
Box
*
rhs
)
{
Box
*
strJoin
(
BoxedString
*
self
,
Box
*
rhs
)
{
assert
(
self
->
cls
==
str_cls
);
assert
(
isSubclass
(
self
->
cls
,
str_cls
)
);
std
::
string
output_str
;
std
::
string
output_str
;
llvm
::
raw_string_ostream
os
(
output_str
);
llvm
::
raw_string_ostream
os
(
output_str
);
...
@@ -1534,7 +1540,7 @@ Box* strJoin(BoxedString* self, Box* rhs) {
...
@@ -1534,7 +1540,7 @@ Box* strJoin(BoxedString* self, Box* rhs) {
extern
"C"
PyObject
*
_PyString_Join
(
PyObject
*
sep
,
PyObject
*
x
)
noexcept
{
extern
"C"
PyObject
*
_PyString_Join
(
PyObject
*
sep
,
PyObject
*
x
)
noexcept
{
try
{
try
{
RELEASE_ASSERT
(
sep
->
cls
==
str_cls
,
""
);
RELEASE_ASSERT
(
isSubclass
(
sep
->
cls
,
str_cls
)
,
""
);
return
strJoin
((
BoxedString
*
)
sep
,
x
);
return
strJoin
((
BoxedString
*
)
sep
,
x
);
}
catch
(
ExcInfo
e
)
{
}
catch
(
ExcInfo
e
)
{
setCAPIException
(
e
);
setCAPIException
(
e
);
...
@@ -1548,6 +1554,11 @@ Box* strReplace(Box* _self, Box* _old, Box* _new, Box** _args) {
...
@@ -1548,6 +1554,11 @@ Box* strReplace(Box* _self, Box* _old, Box* _new, Box** _args) {
getTypeName
(
_self
));
getTypeName
(
_self
));
BoxedString
*
self
=
static_cast
<
BoxedString
*>
(
_self
);
BoxedString
*
self
=
static_cast
<
BoxedString
*>
(
_self
);
#ifdef Py_USING_UNICODE
if
(
PyUnicode_Check
(
_old
)
||
PyUnicode_Check
(
_new
))
return
PyUnicode_Replace
((
PyObject
*
)
self
,
_old
,
_new
,
-
1
/*count*/
);
#endif
if
(
_old
->
cls
!=
str_cls
)
if
(
_old
->
cls
!=
str_cls
)
raiseExcHelper
(
TypeError
,
"expected a character buffer object"
);
raiseExcHelper
(
TypeError
,
"expected a character buffer object"
);
BoxedString
*
old
=
static_cast
<
BoxedString
*>
(
_old
);
BoxedString
*
old
=
static_cast
<
BoxedString
*>
(
_old
);
...
@@ -1574,8 +1585,8 @@ Box* strReplace(Box* _self, Box* _old, Box* _new, Box** _args) {
...
@@ -1574,8 +1585,8 @@ Box* strReplace(Box* _self, Box* _old, Box* _new, Box** _args) {
}
}
Box
*
strPartition
(
BoxedString
*
self
,
BoxedString
*
sep
)
{
Box
*
strPartition
(
BoxedString
*
self
,
BoxedString
*
sep
)
{
RELEASE_ASSERT
(
self
->
cls
==
str_cls
,
""
);
RELEASE_ASSERT
(
isSubclass
(
self
->
cls
,
str_cls
)
,
""
);
RELEASE_ASSERT
(
sep
->
cls
==
str_cls
,
""
);
RELEASE_ASSERT
(
isSubclass
(
sep
->
cls
,
str_cls
)
,
""
);
size_t
found_idx
=
self
->
s
.
find
(
sep
->
s
);
size_t
found_idx
=
self
->
s
.
find
(
sep
->
s
);
if
(
found_idx
==
std
::
string
::
npos
)
if
(
found_idx
==
std
::
string
::
npos
)
...
@@ -1601,11 +1612,11 @@ Box* strFormat(BoxedString* self, BoxedTuple* args, BoxedDict* kwargs) {
...
@@ -1601,11 +1612,11 @@ Box* strFormat(BoxedString* self, BoxedTuple* args, BoxedDict* kwargs) {
}
}
Box
*
strSplit
(
BoxedString
*
self
,
BoxedString
*
sep
,
BoxedInt
*
_max_split
)
{
Box
*
strSplit
(
BoxedString
*
self
,
BoxedString
*
sep
,
BoxedInt
*
_max_split
)
{
assert
(
self
->
cls
==
str_cls
);
assert
(
isSubclass
(
self
->
cls
,
str_cls
)
);
if
(
_max_split
->
cls
!=
int_cls
)
if
(
_max_split
->
cls
!=
int_cls
)
raiseExcHelper
(
TypeError
,
"an integer is required"
);
raiseExcHelper
(
TypeError
,
"an integer is required"
);
if
(
sep
->
cls
==
str_cls
)
{
if
(
isSubclass
(
sep
->
cls
,
str_cls
)
)
{
if
(
!
sep
->
s
.
empty
())
{
if
(
!
sep
->
s
.
empty
())
{
llvm
::
SmallVector
<
llvm
::
StringRef
,
16
>
parts
;
llvm
::
SmallVector
<
llvm
::
StringRef
,
16
>
parts
;
llvm
::
StringRef
(
self
->
s
).
split
(
parts
,
sep
->
s
,
_max_split
->
n
);
llvm
::
StringRef
(
self
->
s
).
split
(
parts
,
sep
->
s
,
_max_split
->
n
);
...
@@ -1642,9 +1653,9 @@ Box* strSplit(BoxedString* self, BoxedString* sep, BoxedInt* _max_split) {
...
@@ -1642,9 +1653,9 @@ Box* strSplit(BoxedString* self, BoxedString* sep, BoxedInt* _max_split) {
}
}
Box
*
strStrip
(
BoxedString
*
self
,
Box
*
chars
)
{
Box
*
strStrip
(
BoxedString
*
self
,
Box
*
chars
)
{
assert
(
self
->
cls
==
str_cls
);
assert
(
isSubclass
(
self
->
cls
,
str_cls
)
);
if
(
chars
->
cls
==
str_cls
)
{
if
(
isSubclass
(
chars
->
cls
,
str_cls
)
)
{
return
new
BoxedString
(
llvm
::
StringRef
(
self
->
s
).
trim
(
static_cast
<
BoxedString
*>
(
chars
)
->
s
));
return
new
BoxedString
(
llvm
::
StringRef
(
self
->
s
).
trim
(
static_cast
<
BoxedString
*>
(
chars
)
->
s
));
}
else
if
(
chars
->
cls
==
none_cls
)
{
}
else
if
(
chars
->
cls
==
none_cls
)
{
return
new
BoxedString
(
llvm
::
StringRef
(
self
->
s
).
trim
(
"
\t\n\r\f\v
"
));
return
new
BoxedString
(
llvm
::
StringRef
(
self
->
s
).
trim
(
"
\t\n\r\f\v
"
));
...
@@ -1654,9 +1665,9 @@ Box* strStrip(BoxedString* self, Box* chars) {
...
@@ -1654,9 +1665,9 @@ Box* strStrip(BoxedString* self, Box* chars) {
}
}
Box
*
strLStrip
(
BoxedString
*
self
,
Box
*
chars
)
{
Box
*
strLStrip
(
BoxedString
*
self
,
Box
*
chars
)
{
assert
(
self
->
cls
==
str_cls
);
assert
(
isSubclass
(
self
->
cls
,
str_cls
)
);
if
(
chars
->
cls
==
str_cls
)
{
if
(
isSubclass
(
chars
->
cls
,
str_cls
)
)
{
return
new
BoxedString
(
llvm
::
StringRef
(
self
->
s
).
ltrim
(
static_cast
<
BoxedString
*>
(
chars
)
->
s
));
return
new
BoxedString
(
llvm
::
StringRef
(
self
->
s
).
ltrim
(
static_cast
<
BoxedString
*>
(
chars
)
->
s
));
}
else
if
(
chars
->
cls
==
none_cls
)
{
}
else
if
(
chars
->
cls
==
none_cls
)
{
return
new
BoxedString
(
llvm
::
StringRef
(
self
->
s
).
ltrim
(
"
\t\n\r\f\v
"
));
return
new
BoxedString
(
llvm
::
StringRef
(
self
->
s
).
ltrim
(
"
\t\n\r\f\v
"
));
...
@@ -1666,9 +1677,9 @@ Box* strLStrip(BoxedString* self, Box* chars) {
...
@@ -1666,9 +1677,9 @@ Box* strLStrip(BoxedString* self, Box* chars) {
}
}
Box
*
strRStrip
(
BoxedString
*
self
,
Box
*
chars
)
{
Box
*
strRStrip
(
BoxedString
*
self
,
Box
*
chars
)
{
assert
(
self
->
cls
==
str_cls
);
assert
(
isSubclass
(
self
->
cls
,
str_cls
)
);
if
(
chars
->
cls
==
str_cls
)
{
if
(
isSubclass
(
chars
->
cls
,
str_cls
)
)
{
return
new
BoxedString
(
llvm
::
StringRef
(
self
->
s
).
rtrim
(
static_cast
<
BoxedString
*>
(
chars
)
->
s
));
return
new
BoxedString
(
llvm
::
StringRef
(
self
->
s
).
rtrim
(
static_cast
<
BoxedString
*>
(
chars
)
->
s
));
}
else
if
(
chars
->
cls
==
none_cls
)
{
}
else
if
(
chars
->
cls
==
none_cls
)
{
return
new
BoxedString
(
llvm
::
StringRef
(
self
->
s
).
rtrim
(
"
\t\n\r\f\v
"
));
return
new
BoxedString
(
llvm
::
StringRef
(
self
->
s
).
rtrim
(
"
\t\n\r\f\v
"
));
...
@@ -1678,7 +1689,7 @@ Box* strRStrip(BoxedString* self, Box* chars) {
...
@@ -1678,7 +1689,7 @@ Box* strRStrip(BoxedString* self, Box* chars) {
}
}
Box
*
strCapitalize
(
BoxedString
*
self
)
{
Box
*
strCapitalize
(
BoxedString
*
self
)
{
assert
(
self
->
cls
==
str_cls
);
assert
(
isSubclass
(
self
->
cls
,
str_cls
)
);
std
::
string
s
(
self
->
s
);
std
::
string
s
(
self
->
s
);
...
@@ -1694,7 +1705,7 @@ Box* strCapitalize(BoxedString* self) {
...
@@ -1694,7 +1705,7 @@ Box* strCapitalize(BoxedString* self) {
}
}
Box
*
strTitle
(
BoxedString
*
self
)
{
Box
*
strTitle
(
BoxedString
*
self
)
{
assert
(
self
->
cls
==
str_cls
);
assert
(
isSubclass
(
self
->
cls
,
str_cls
)
);
std
::
string
s
(
self
->
s
);
std
::
string
s
(
self
->
s
);
bool
start_of_word
=
false
;
bool
start_of_word
=
false
;
...
@@ -1746,12 +1757,12 @@ Box* strTranslate(BoxedString* self, BoxedString* table, BoxedString* delete_cha
...
@@ -1746,12 +1757,12 @@ Box* strTranslate(BoxedString* self, BoxedString* table, BoxedString* delete_cha
}
}
Box
*
strLower
(
BoxedString
*
self
)
{
Box
*
strLower
(
BoxedString
*
self
)
{
assert
(
self
->
cls
==
str_cls
);
assert
(
isSubclass
(
self
->
cls
,
str_cls
)
);
return
boxString
(
llvm
::
StringRef
(
self
->
s
).
lower
());
return
boxString
(
llvm
::
StringRef
(
self
->
s
).
lower
());
}
}
Box
*
strUpper
(
BoxedString
*
self
)
{
Box
*
strUpper
(
BoxedString
*
self
)
{
assert
(
self
->
cls
==
str_cls
);
assert
(
isSubclass
(
self
->
cls
,
str_cls
)
);
return
boxString
(
llvm
::
StringRef
(
self
->
s
).
upper
());
return
boxString
(
llvm
::
StringRef
(
self
->
s
).
upper
());
}
}
...
@@ -1769,7 +1780,7 @@ Box* strSwapcase(BoxedString* self) {
...
@@ -1769,7 +1780,7 @@ Box* strSwapcase(BoxedString* self) {
}
}
Box
*
strContains
(
BoxedString
*
self
,
Box
*
elt
)
{
Box
*
strContains
(
BoxedString
*
self
,
Box
*
elt
)
{
assert
(
self
->
cls
==
str_cls
);
assert
(
isSubclass
(
self
->
cls
,
str_cls
)
);
if
(
PyUnicode_Check
(
elt
))
{
if
(
PyUnicode_Check
(
elt
))
{
int
r
=
PyUnicode_Contains
(
self
,
elt
);
int
r
=
PyUnicode_Contains
(
self
,
elt
);
...
@@ -1796,9 +1807,6 @@ Box* strStartswith(BoxedString* self, Box* elt, Box* start, Box** _args) {
...
@@ -1796,9 +1807,6 @@ Box* strStartswith(BoxedString* self, Box* elt, Box* start, Box** _args) {
raiseExcHelper
(
TypeError
,
"descriptor 'startswith' requires a 'str' object but received a '%s'"
,
raiseExcHelper
(
TypeError
,
"descriptor 'startswith' requires a 'str' object but received a '%s'"
,
getTypeName
(
self
));
getTypeName
(
self
));
if
(
elt
->
cls
!=
str_cls
)
raiseExcHelper
(
TypeError
,
"expected a character buffer object"
);
Py_ssize_t
istart
=
0
,
iend
=
PY_SSIZE_T_MAX
;
Py_ssize_t
istart
=
0
,
iend
=
PY_SSIZE_T_MAX
;
if
(
start
)
{
if
(
start
)
{
int
r
=
_PyEval_SliceIndex
(
start
,
&
istart
);
int
r
=
_PyEval_SliceIndex
(
start
,
&
istart
);
...
@@ -1812,6 +1820,27 @@ Box* strStartswith(BoxedString* self, Box* elt, Box* start, Box** _args) {
...
@@ -1812,6 +1820,27 @@ Box* strStartswith(BoxedString* self, Box* elt, Box* start, Box** _args) {
throwCAPIException
();
throwCAPIException
();
}
}
if
(
isSubclass
(
elt
->
cls
,
tuple_cls
))
{
for
(
auto
e
:
static_cast
<
BoxedTuple
*>
(
elt
)
->
elts
)
{
auto
b
=
strStartswith
(
self
,
e
,
start
,
_args
);
assert
(
b
->
cls
==
bool_cls
);
if
(
b
==
True
)
return
True
;
}
return
False
;
}
if
(
isSubclass
(
elt
->
cls
,
unicode_cls
))
{
int
r
=
PyUnicode_Tailmatch
(
self
,
elt
,
istart
,
iend
,
-
1
);
if
(
r
<
0
)
throwCAPIException
();
assert
(
r
==
0
||
r
==
1
);
return
boxBool
(
r
);
}
if
(
elt
->
cls
!=
str_cls
)
raiseExcHelper
(
TypeError
,
"expected a character buffer object"
);
BoxedString
*
sub
=
static_cast
<
BoxedString
*>
(
elt
);
BoxedString
*
sub
=
static_cast
<
BoxedString
*>
(
elt
);
Py_ssize_t
n
=
self
->
s
.
size
();
Py_ssize_t
n
=
self
->
s
.
size
();
...
@@ -1841,9 +1870,6 @@ Box* strEndswith(BoxedString* self, Box* elt, Box* start, Box** _args) {
...
@@ -1841,9 +1870,6 @@ Box* strEndswith(BoxedString* self, Box* elt, Box* start, Box** _args) {
raiseExcHelper
(
TypeError
,
"descriptor 'endswith' requires a 'str' object but received a '%s'"
,
raiseExcHelper
(
TypeError
,
"descriptor 'endswith' requires a 'str' object but received a '%s'"
,
getTypeName
(
self
));
getTypeName
(
self
));
if
(
elt
->
cls
!=
str_cls
)
raiseExcHelper
(
TypeError
,
"expected a character buffer object"
);
Py_ssize_t
istart
=
0
,
iend
=
PY_SSIZE_T_MAX
;
Py_ssize_t
istart
=
0
,
iend
=
PY_SSIZE_T_MAX
;
if
(
start
)
{
if
(
start
)
{
int
r
=
_PyEval_SliceIndex
(
start
,
&
istart
);
int
r
=
_PyEval_SliceIndex
(
start
,
&
istart
);
...
@@ -1857,6 +1883,27 @@ Box* strEndswith(BoxedString* self, Box* elt, Box* start, Box** _args) {
...
@@ -1857,6 +1883,27 @@ Box* strEndswith(BoxedString* self, Box* elt, Box* start, Box** _args) {
throwCAPIException
();
throwCAPIException
();
}
}
if
(
isSubclass
(
elt
->
cls
,
unicode_cls
))
{
int
r
=
PyUnicode_Tailmatch
(
self
,
elt
,
istart
,
iend
,
+
1
);
if
(
r
<
0
)
throwCAPIException
();
assert
(
r
==
0
||
r
==
1
);
return
boxBool
(
r
);
}
if
(
isSubclass
(
elt
->
cls
,
tuple_cls
))
{
for
(
auto
e
:
static_cast
<
BoxedTuple
*>
(
elt
)
->
elts
)
{
auto
b
=
strEndswith
(
self
,
e
,
start
,
_args
);
assert
(
b
->
cls
==
bool_cls
);
if
(
b
==
True
)
return
True
;
}
return
False
;
}
if
(
elt
->
cls
!=
str_cls
)
raiseExcHelper
(
TypeError
,
"expected a character buffer object"
);
BoxedString
*
sub
=
static_cast
<
BoxedString
*>
(
elt
);
BoxedString
*
sub
=
static_cast
<
BoxedString
*>
(
elt
);
Py_ssize_t
n
=
self
->
s
.
size
();
Py_ssize_t
n
=
self
->
s
.
size
();
...
@@ -1920,7 +1967,7 @@ Box* strEncode(BoxedString* self, Box* encoding, Box* error) {
...
@@ -1920,7 +1967,7 @@ Box* strEncode(BoxedString* self, Box* encoding, Box* error) {
}
}
extern
"C"
Box
*
strGetitem
(
BoxedString
*
self
,
Box
*
slice
)
{
extern
"C"
Box
*
strGetitem
(
BoxedString
*
self
,
Box
*
slice
)
{
assert
(
self
->
cls
==
str_cls
);
assert
(
isSubclass
(
self
->
cls
,
str_cls
)
);
if
(
isSubclass
(
slice
->
cls
,
int_cls
))
{
if
(
isSubclass
(
slice
->
cls
,
int_cls
))
{
BoxedInt
*
islice
=
static_cast
<
BoxedInt
*>
(
slice
);
BoxedInt
*
islice
=
static_cast
<
BoxedInt
*>
(
slice
);
...
@@ -1989,12 +2036,12 @@ extern "C" void strIteratorGCHandler(GCVisitor* v, Box* b) {
...
@@ -1989,12 +2036,12 @@ extern "C" void strIteratorGCHandler(GCVisitor* v, Box* b) {
}
}
Box
*
strIter
(
BoxedString
*
self
)
{
Box
*
strIter
(
BoxedString
*
self
)
{
assert
(
self
->
cls
==
str_cls
);
assert
(
isSubclass
(
self
->
cls
,
str_cls
)
);
return
new
BoxedStringIterator
(
self
);
return
new
BoxedStringIterator
(
self
);
}
}
int64_t
strCount2Unboxed
(
BoxedString
*
self
,
Box
*
elt
)
{
int64_t
strCount2Unboxed
(
BoxedString
*
self
,
Box
*
elt
)
{
assert
(
self
->
cls
==
str_cls
);
assert
(
isSubclass
(
self
->
cls
,
str_cls
)
);
if
(
elt
->
cls
!=
str_cls
)
if
(
elt
->
cls
!=
str_cls
)
raiseExcHelper
(
TypeError
,
"expected a character buffer object"
);
raiseExcHelper
(
TypeError
,
"expected a character buffer object"
);
...
@@ -2020,7 +2067,7 @@ Box* strCount2(BoxedString* self, Box* elt) {
...
@@ -2020,7 +2067,7 @@ Box* strCount2(BoxedString* self, Box* elt) {
}
}
Box
*
strIndex
(
BoxedString
*
self
,
Box
*
elt
)
{
Box
*
strIndex
(
BoxedString
*
self
,
Box
*
elt
)
{
assert
(
self
->
cls
==
str_cls
);
assert
(
isSubclass
(
self
->
cls
,
str_cls
)
);
if
(
elt
->
cls
!=
str_cls
)
if
(
elt
->
cls
!=
str_cls
)
raiseExcHelper
(
TypeError
,
"expected a character buffer object"
);
raiseExcHelper
(
TypeError
,
"expected a character buffer object"
);
...
@@ -2094,14 +2141,14 @@ extern "C" PyObject* PyString_FromStringAndSize(const char* s, ssize_t n) noexce
...
@@ -2094,14 +2141,14 @@ extern "C" PyObject* PyString_FromStringAndSize(const char* s, ssize_t n) noexce
}
}
extern
"C"
char
*
PyString_AsString
(
PyObject
*
o
)
noexcept
{
extern
"C"
char
*
PyString_AsString
(
PyObject
*
o
)
noexcept
{
RELEASE_ASSERT
(
o
->
cls
==
str_cls
,
""
);
RELEASE_ASSERT
(
isSubclass
(
o
->
cls
,
str_cls
)
,
""
);
BoxedString
*
s
=
static_cast
<
BoxedString
*>
(
o
);
BoxedString
*
s
=
static_cast
<
BoxedString
*>
(
o
);
return
getWriteableStringContents
(
s
);
return
getWriteableStringContents
(
s
);
}
}
extern
"C"
Py_ssize_t
PyString_Size
(
PyObject
*
op
)
noexcept
{
extern
"C"
Py_ssize_t
PyString_Size
(
PyObject
*
op
)
noexcept
{
if
(
op
->
cls
==
str_cls
)
if
(
isSubclass
(
op
->
cls
,
str_cls
)
)
return
static_cast
<
BoxedString
*>
(
op
)
->
s
.
size
();
return
static_cast
<
BoxedString
*>
(
op
)
->
s
.
size
();
char
*
_s
;
char
*
_s
;
...
@@ -2115,7 +2162,7 @@ extern "C" int _PyString_Resize(PyObject** pv, Py_ssize_t newsize) noexcept {
...
@@ -2115,7 +2162,7 @@ extern "C" int _PyString_Resize(PyObject** pv, Py_ssize_t newsize) noexcept {
// This is only allowed to be called when there is only one user of the string (ie a refcount of 1 in CPython)
// This is only allowed to be called when there is only one user of the string (ie a refcount of 1 in CPython)
assert
(
pv
);
assert
(
pv
);
assert
(
(
*
pv
)
->
cls
==
str_cls
);
assert
(
isSubclass
((
*
pv
)
->
cls
,
str_cls
)
);
BoxedString
*
s
=
static_cast
<
BoxedString
*>
(
*
pv
);
BoxedString
*
s
=
static_cast
<
BoxedString
*>
(
*
pv
);
s
->
s
.
resize
(
newsize
,
'\0'
);
s
->
s
.
resize
(
newsize
,
'\0'
);
return
0
;
return
0
;
...
@@ -2223,7 +2270,7 @@ static Py_ssize_t string_buffer_getreadbuf(PyObject* self, Py_ssize_t index, con
...
@@ -2223,7 +2270,7 @@ static Py_ssize_t string_buffer_getreadbuf(PyObject* self, Py_ssize_t index, con
RELEASE_ASSERT
(
index
==
0
,
""
);
RELEASE_ASSERT
(
index
==
0
,
""
);
// I think maybe this can just be a non-release assert? shouldn't be able to call this with
// I think maybe this can just be a non-release assert? shouldn't be able to call this with
// the wrong type
// the wrong type
RELEASE_ASSERT
(
self
->
cls
==
str_cls
,
""
);
RELEASE_ASSERT
(
isSubclass
(
self
->
cls
,
str_cls
)
,
""
);
auto
s
=
static_cast
<
BoxedString
*>
(
self
);
auto
s
=
static_cast
<
BoxedString
*>
(
self
);
*
ptr
=
s
->
s
.
c_str
();
*
ptr
=
s
->
s
.
c_str
();
...
@@ -2232,7 +2279,7 @@ static Py_ssize_t string_buffer_getreadbuf(PyObject* self, Py_ssize_t index, con
...
@@ -2232,7 +2279,7 @@ static Py_ssize_t string_buffer_getreadbuf(PyObject* self, Py_ssize_t index, con
static
Py_ssize_t
string_buffer_getsegcount
(
PyObject
*
o
,
Py_ssize_t
*
lenp
)
noexcept
{
static
Py_ssize_t
string_buffer_getsegcount
(
PyObject
*
o
,
Py_ssize_t
*
lenp
)
noexcept
{
RELEASE_ASSERT
(
lenp
==
NULL
,
""
);
RELEASE_ASSERT
(
lenp
==
NULL
,
""
);
RELEASE_ASSERT
(
o
->
cls
==
str_cls
,
""
);
RELEASE_ASSERT
(
isSubclass
(
o
->
cls
,
str_cls
)
,
""
);
return
1
;
return
1
;
}
}
...
@@ -2246,7 +2293,7 @@ static Py_ssize_t string_buffer_getcharbuf(PyStringObject* self, Py_ssize_t inde
...
@@ -2246,7 +2293,7 @@ static Py_ssize_t string_buffer_getcharbuf(PyStringObject* self, Py_ssize_t inde
}
}
static
int
string_buffer_getbuffer
(
BoxedString
*
self
,
Py_buffer
*
view
,
int
flags
)
noexcept
{
static
int
string_buffer_getbuffer
(
BoxedString
*
self
,
Py_buffer
*
view
,
int
flags
)
noexcept
{
assert
(
self
->
cls
==
str_cls
);
assert
(
isSubclass
(
self
->
cls
,
str_cls
)
);
return
PyBuffer_FillInfo
(
view
,
(
PyObject
*
)
self
,
&
self
->
s
[
0
],
self
->
s
.
size
(),
1
,
flags
);
return
PyBuffer_FillInfo
(
view
,
(
PyObject
*
)
self
,
&
self
->
s
[
0
],
self
->
s
.
size
(),
1
,
flags
);
}
}
...
@@ -2358,7 +2405,7 @@ void setupStr() {
...
@@ -2358,7 +2405,7 @@ void setupStr() {
str_cls
->
giveAttr
(
"join"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
strJoin
,
STR
,
2
)));
str_cls
->
giveAttr
(
"join"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
strJoin
,
STR
,
2
)));
str_cls
->
giveAttr
(
"replace"
,
str_cls
->
giveAttr
(
"replace"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
strReplace
,
STR
,
4
,
1
,
false
,
false
),
{
boxInt
(
-
1
)
}));
new
BoxedFunction
(
boxRTFunction
((
void
*
)
strReplace
,
UNKNOWN
,
4
,
1
,
false
,
false
),
{
boxInt
(
-
1
)
}));
str_cls
->
giveAttr
(
str_cls
->
giveAttr
(
"split"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
strSplit
,
LIST
,
3
,
2
,
false
,
false
),
{
None
,
boxInt
(
-
1
)
}));
"split"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
strSplit
,
LIST
,
3
,
2
,
false
,
false
),
{
None
,
boxInt
(
-
1
)
}));
...
...
src/runtime/types.cpp
View file @
4480e933
...
@@ -1159,10 +1159,9 @@ Box* objectStr(Box* obj) {
...
@@ -1159,10 +1159,9 @@ Box* objectStr(Box* obj) {
}
}
static
Box
*
typeName
(
Box
*
b
,
void
*
)
{
static
Box
*
typeName
(
Box
*
b
,
void
*
)
{
assert
(
b
->
cls
==
type_cls
);
RELEASE_ASSERT
(
isSubclass
(
b
->
cls
,
type_cls
),
""
);
BoxedClass
*
type
=
static_cast
<
BoxedClass
*>
(
b
);
BoxedClass
*
type
=
static_cast
<
BoxedClass
*>
(
b
);
// TODO is this predicate right?
if
(
type
->
tp_flags
&
Py_TPFLAGS_HEAPTYPE
)
{
if
(
type
->
tp_flags
&
Py_TPFLAGS_HEAPTYPE
)
{
BoxedHeapClass
*
et
=
static_cast
<
BoxedHeapClass
*>
(
type
);
BoxedHeapClass
*
et
=
static_cast
<
BoxedHeapClass
*>
(
type
);
return
et
->
ht_name
;
return
et
->
ht_name
;
...
@@ -1321,6 +1320,8 @@ void setupRuntime() {
...
@@ -1321,6 +1320,8 @@ void setupRuntime() {
tuple_cls
->
finishInitialization
();
tuple_cls
->
finishInitialization
();
list_cls
->
finishInitialization
();
list_cls
->
finishInitialization
();
str_cls
->
tp_flags
|=
Py_TPFLAGS_HAVE_NEWBUFFER
;
module_cls
=
BoxedHeapClass
::
create
(
type_cls
,
object_cls
,
NULL
,
offsetof
(
BoxedModule
,
attrs
),
0
,
module_cls
=
BoxedHeapClass
::
create
(
type_cls
,
object_cls
,
NULL
,
offsetof
(
BoxedModule
,
attrs
),
0
,
...
@@ -1516,6 +1517,7 @@ void setupRuntime() {
...
@@ -1516,6 +1517,7 @@ void setupRuntime() {
setupPyston
();
setupPyston
();
PyType_Ready
(
&
PyCapsule_Type
);
PyType_Ready
(
&
PyCapsule_Type
);
PyType_Ready
(
&
PyCallIter_Type
);
initerrno
();
initerrno
();
init_sha
();
init_sha
();
...
...
test/tests/genexps.py
View file @
4480e933
...
@@ -15,3 +15,10 @@ def f2():
...
@@ -15,3 +15,10 @@ def f2():
print
list
(
g2
)
print
list
(
g2
)
f2
()
f2
()
# Make sure that the 'ifs' part gets scoped properly
def
f3
():
b
=
True
print
list
(
x
for
x
in
range
(
5
)
if
b
)
print
list
(
x
for
x
in
range
(
5
)
if
[
b
for
b
in
xrange
(
4
)])
print
b
print
f3
()
test/tests/gzip_test.py
View file @
4480e933
# allow-warning: import level 0 will be treated as -1
import
gzip
import
gzip
import
io
import
io
...
...
test/tests/io_test.py
View file @
4480e933
# allow-warning: import level 0 will be treated as -1
import
io
import
io
filename
=
"io_test_.txt"
filename
=
"io_test_.txt"
...
...
test/tests/kwargs_protocol.py
View file @
4480e933
# expected: fail
# - not supported yet
class
C
(
object
):
class
C
(
object
):
def
__len__
(
self
):
def
__len__
(
self
):
print
"__len__"
print
"__len__"
...
@@ -26,3 +23,20 @@ def f(a, b, c):
...
@@ -26,3 +23,20 @@ def f(a, b, c):
print
a
,
b
,
c
print
a
,
b
,
c
f
(
**
C
())
f
(
**
C
())
class
MyDict
(
dict
):
pass
d
=
MyDict
(
a
=
1
,
b
=
2
,
c
=
3
)
print
f
(
**
d
)
# Django does this:
class
C
(
object
):
pass
c
=
C
()
c
.
a
=
1
c
.
b
=
3
c
.
c
=
7
print
f
(
**
c
.
__dict__
)
test/tests/long.py
View file @
4480e933
...
@@ -8,7 +8,7 @@ for i in xrange(150):
...
@@ -8,7 +8,7 @@ for i in xrange(150):
print
t
,
repr
(
t
)
print
t
,
repr
(
t
)
def
test
(
a
,
b
):
def
test
(
a
,
b
):
print
a
,
b
print
repr
(
a
),
repr
(
b
)
print
a
+
b
,
b
+
a
,
a
.
__add__
(
b
),
b
.
__add__
(
a
)
print
a
+
b
,
b
+
a
,
a
.
__add__
(
b
),
b
.
__add__
(
a
)
print
a
-
b
,
b
-
a
,
a
.
__sub__
(
b
),
b
.
__sub__
(
a
)
print
a
-
b
,
b
-
a
,
a
.
__sub__
(
b
),
b
.
__sub__
(
a
)
print
a
*
b
,
b
*
a
,
a
.
__mul__
(
b
),
b
.
__mul__
(
a
)
print
a
*
b
,
b
*
a
,
a
.
__mul__
(
b
),
b
.
__mul__
(
a
)
...
@@ -26,6 +26,9 @@ for a in [-5, -1, 1, 5, -2L, -1L, 1L, 2L]:
...
@@ -26,6 +26,9 @@ for a in [-5, -1, 1, 5, -2L, -1L, 1L, 2L]:
for
b
in
[
-
5
,
-
1
,
1
,
5
,
-
2L
,
-
1L
,
1L
,
2L
]:
for
b
in
[
-
5
,
-
1
,
1
,
5
,
-
2L
,
-
1L
,
1L
,
2L
]:
test
(
a
,
b
)
test
(
a
,
b
)
test
(
1L
,
2.0
)
test
(
3.0
,
2L
)
print
(
2L
).
__rdiv__
(
-
1
)
print
(
2L
).
__rdiv__
(
-
1
)
print
(
2L
).
__rdiv__
(
-
1L
)
print
(
2L
).
__rdiv__
(
-
1L
)
print
(
-
2L
).
__rdiv__
(
1L
)
print
(
-
2L
).
__rdiv__
(
1L
)
...
...
test/tests/optparse_test.py
View file @
4480e933
# allow-warning: import level 0 will be treated as -1
# Simple optparse test, taken from the optparse.py docstring:
# Simple optparse test, taken from the optparse.py docstring:
from
optparse
import
OptionParser
from
optparse
import
OptionParser
...
...
test/tests/pickle_test.py
View file @
4480e933
# allow-warning: import level 0 will be treated as -1
import
pickle
import
pickle
l
=
[[],
(
123
,)]
l
=
[[],
(
123
,)]
...
...
test/tests/prevent_nonascii_attrs.py
View file @
4480e933
# allow-warning: import level 0 will be treated as -1
# skip-if: '-x' in EXTRA_JIT_ARGS
# skip-if: '-x' in EXTRA_JIT_ARGS
def
f
(
a
):
def
f
(
a
):
...
...
test/tests/str_encode_decode.py
View file @
4480e933
# allow-warning: import level 0 will be treated as -1!
def
test
(
string
,
encoding
):
def
test
(
string
,
encoding
):
s
=
string
.
encode
(
encoding
)
s
=
string
.
encode
(
encoding
)
print
encoding
,
s
print
encoding
,
s
...
...
test/tests/str_functions.py
View file @
4480e933
...
@@ -139,3 +139,6 @@ except:
...
@@ -139,3 +139,6 @@ except:
print
repr
(
"hello
\
t
world
\
t
"
.
expandtabs
())
print
repr
(
"hello
\
t
world
\
t
"
.
expandtabs
())
print
repr
(
"hello
\
t
world
\
t
"
.
expandtabs
(
12
))
print
repr
(
"hello
\
t
world
\
t
"
.
expandtabs
(
12
))
print
"hello world"
.
startswith
((
"x"
,
"h"
))
print
"hello world"
.
endswith
((
"x"
,
"h"
))
test/tests/str_subclassing.py
0 → 100644
View file @
4480e933
class
MyStr
(
str
):
pass
s
=
MyStr
(
1
)
print
repr
(
s
)
import
sys
sys
.
stdout
.
write
(
s
)
test/tests/sys_exit_none.py
0 → 100644
View file @
4480e933
# no-collect-stats
import
sys
sys
.
exit
(
None
)
test/tests/unicode_test.py
View file @
4480e933
# skip-if: '-x' in EXTRA_JIT_ARGS
# skip-if: '-x' in EXTRA_JIT_ARGS
# allow-warning: import level 0 will be treated as -1
print
repr
(
unicode
())
print
repr
(
unicode
())
print
repr
(
unicode
(
'hello world'
))
print
repr
(
unicode
(
'hello world'
))
...
@@ -81,3 +80,12 @@ f(**{'a':2})
...
@@ -81,3 +80,12 @@ f(**{'a':2})
f
(
**
{
u'a'
:
3
})
f
(
**
{
u'a'
:
3
})
print
repr
(
'%s'
%
u''
)
# this gives a unicode object!
print
repr
(
'%s'
%
u''
)
# this gives a unicode object!
print
repr
(
'hello world'
.
replace
(
u'hello'
,
u'hi'
))
print
"hello world"
.
endswith
(
u'hello'
)
print
"hello world"
.
endswith
(
u'world'
)
print
"hello world"
.
startswith
(
u'hello'
)
print
"hello world"
.
startswith
(
u'world'
)
print
float
(
u'1.0'
)
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