1
//-----------------------------------------------------------------------------
3
// Copyright (c) 1998 - 2007, The Regents of the University of California
4
// Produced at the Lawrence Livermore National Laboratory
5
// All rights reserved.
7
// This file is part of PyCXX. For details, see http://cxx.sourceforge.net. The
8
// full copyright notice is contained in the file COPYRIGHT located at the root
9
// of the PyCXX distribution.
11
// Redistribution and use in source and binary forms, with or without
12
// modification, are permitted provided that the following conditions are met:
14
// - Redistributions of source code must retain the above copyright notice,
15
// this list of conditions and the disclaimer below.
16
// - Redistributions in binary form must reproduce the above copyright notice,
17
// this list of conditions and the disclaimer (as noted below) in the
18
// documentation and/or materials provided with the distribution.
19
// - Neither the name of the UC/LLNL nor the names of its contributors may be
20
// used to endorse or promote products derived from this software without
21
// specific prior written permission.
23
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
24
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26
// ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OF THE UNIVERSITY OF
27
// CALIFORNIA, THE U.S. DEPARTMENT OF ENERGY OR CONTRIBUTORS BE LIABLE FOR
28
// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
30
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
31
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33
// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
36
//-----------------------------------------------------------------------------
39
// disable warning C4786: symbol greater than 255 character,
40
// nessesary to ignore as <map> causes lots of warning
41
#pragma warning(disable: 4786)
44
#include "CXX/Objects.hxx"
45
#include "CXX/Extensions.hxx"
49
#include "range.hxx" // Extension object
50
extern std::string test_extension_object();
54
static std::string test_String()
56
Py::String s("hello");
58
Py::String r1("world in brief", 5);
61
if(std::string(s) != "hello worldhello world")
63
return "failed (1) '" + std::string(s) + "'";
66
std::string w = static_cast<std::string>(s);
67
std::string w2 = (std::string) s;
72
Py::String r2("12345 789");
76
std::cout << "|" << c6 << "|" << std::endl;
80
Py::Char c7 = r2.front();
81
Py::Char c8 = r2.back();
98
{ std::cout << "OK: T1: True" << std::endl; }
100
{ std::cout << "Bad: T1: False" << std::endl; passed = false; }
104
{ std::cout << "OK: T2: True" << std::endl; }
106
{ std::cout << "Bad: T2: False" << std::endl; passed = false; }
110
{ std::cout << "OK: T3: True" << std::endl; }
112
{ std::cout << "Bad: T3: False" << std::endl; passed = false; }
116
{ std::cout << "OK: T4: True" << std::endl; }
118
{ std::cout << "Bad: T4: False" << std::endl; passed = false; }
122
{ std::cout << "OK: T5: True" << std::endl; }
124
{ std::cout << "Bad: T5: False" << std::endl; passed = false; }
129
{ std::cout << "Bad: F1: True" << std::endl; passed = false; }
131
{ std::cout << "OK: F1: False" << std::endl; }
135
{ std::cout << "Bad: F2: True" << std::endl; passed = false; }
137
{ std::cout << "OK: F2: False" << std::endl; }
141
{ std::cout << "Bad: F3: True" << std::endl; passed = false; }
143
{ std::cout << "OK: F3: False" << std::endl; }
147
{ std::cout << "Bad: F4: True" << std::endl; passed = false; }
149
{ std::cout << "OK: F4: False" << std::endl; }
153
{ std::cout << "Bad: F5: True" << std::endl; passed = false; }
155
{ std::cout << "OK: F5: False" << std::endl; }
166
// test the basic numerical classes
169
Py::Int k = Py::Int(3);
171
if (! (j < k)) return "failed (1)";
172
if (! (j == j)) return "failed (2)" ;
173
if (! (j != k)) return "failed (3)";
174
if (! (j <= k)) return "failed (4)";
175
if (! (k >= j)) return "failed (5)";
176
if (! (k > j)) return "failed (6)";
177
if (! (j <= j)) return "failed (7)";
178
if (! (j >= Py::Int(2))) return "failed (8)";
184
a = (1.0 + 2*a + (b*3.0)/2.0 + k)/Py::Float(5); // 4.0
195
test_List_iterators (const Py::List& x, Py::List& y)
197
std::vector<Py::Object> v;
198
Py::Sequence::iterator j;
200
for(Py::Sequence::const_iterator i = x.begin(); i != x.end(); ++i)
208
return "failed List iterators (1)";
211
for(j = y.begin(); j != y.end(); ++j)
218
for(j = y.begin(); j != y.end(); j++)
221
return "failed List iterators (2)";
222
if(v[k] != Py::Int(k))
223
return "failed List iterators (3)";
226
Py::String o1("Howdy");
233
catch (Py::Exception& e)
239
return "failed exception catch (4).";
244
test_List_references (Py::List& x)
247
for(Py::List::size_type i=0; i < x.length(); ++i)
260
// test the Py::List class
263
aux.append(Py::Int(3));
264
aux.append(Py::Float(6.0));
269
Py::Float c(10.0), d(20.0);
272
a.append(Py::Float(0.0));
277
// a is now [3, 6.0, 3, 30.0, aux]
279
ans.append(Py::Int(3));
280
ans.append(Py::Float(6.0));
281
ans.append(Py::Int(3));
282
ans.append(Py::Float(30.0));
285
Py::List::iterator l1, l2;
286
for(l1= a.begin(), l2 = ans.begin();
287
l1 != a.end() && l2 != ans.end();
290
if(*l1 != *l2) return "failed 1" + a.as_string();
293
if (test_List_references (a)!= aux)
295
return "failed 2" + test_List_references(a).as_string();
297
return test_List_iterators(ans, a);
303
// test the Dict class
307
a["one"] = Py::Int(1);
309
a["three"] = Py::Int(3);
310
if(Py::Int(a["one"]) != Py::Int(1))
311
return "failed 1a " + a.as_string();
312
if(Py::Int(a[s]) != Py::Int(2))
313
return "failed 1b " + a.as_string();
318
std::sort(v.begin(), v.end());
320
for(int k = 1; k < 4; ++k)
322
if(v[k-1] != Py::Int(k))
323
return "failed 2 " + v.as_string();
329
if(b.keys().length() != 0)
331
return "failed 3 " + b.as_string();
335
for (Py::Dict::const_iterator it = c.begin(); it != c.end(); ++it)
345
// test the Tuple class
348
Py::Float f1(1.0), f2(2.0), f3(3.0);
349
a[0] = f1; // should be ok since no other reference owned
354
for(Py::Tuple::iterator i = b.begin(); i != b.end(); ++i)
356
if(*i != Py::Float(++k)) return "failed 1 " + b.as_string();
362
t1[0] = Py::Int(1); // should fail, tuple has multiple references
365
catch (Py::Exception& e)
378
wans.append(Py::Int(1));
379
wans.append(Py::Int(1));
380
wans.append(Py::Int(2));
381
wans.append(Py::Int(3));
382
wans.append(Py::Int(4));
383
wans.append(Py::Int(5));
384
w.append(Py::Int(5));
385
w.append(Py::Int(1));
386
w.append(Py::Int(4));
387
w.append(Py::Int(2));
388
w.append(Py::Int(3));
389
w.append(Py::Int(1));
390
ans1 = std::count(w.begin(), w.end(), Py::Float(1.0));
393
return "failed count test";
398
std::sort(w.begin(), w.end());
401
return "failed sort test";
406
Py::String s1("blah");
407
Py::String s2("gorf");
413
Py::Dict::iterator it = d.begin();
414
for( ; it != d.end(); ++it )
416
Py::Dict::value_type vt( *it );
417
Py::String rs = vt.second.repr();
418
std::string ls = rs.operator std::string();
419
std::cout << "dict value " << ls.c_str() << std::endl;
425
void debug_check_ref_queue()
429
// create an element to find the queue
430
Py::Int list_element;
432
PyObject *p_slow = list_element.ptr();
433
PyObject *p_fast = p_slow;
437
assert( p_slow->_ob_next->_ob_prev == p_slow );
438
assert( p_slow->_ob_prev->_ob_next == p_slow );
441
p_slow = p_slow->_ob_next;
442
p_fast = p_slow->_ob_next->_ob_next;
444
assert( p_slow != p_fast );
446
while( p_slow != list_element.ptr() );
452
class example_module : public Py::ExtensionModule<example_module>
456
: Py::ExtensionModule<example_module>( "example" )
460
add_varargs_method("string", &example_module::ex_string, "string( s ) = return string");
461
add_varargs_method("sum", &example_module::ex_sum, "sum(arglist) = sum of arguments");
462
add_varargs_method("test", &example_module::ex_test, "test(arglist) runs a test suite");
463
add_varargs_method("range", &example_module::new_r, "range(start,stop,stride)");
464
add_keyword_method("kw", &example_module::ex_keyword, "kw()");
466
initialize( "documentation for the example module" );
468
Py::Dict d( moduleDictionary() );
470
Py::Object b(Py::asObject(new range(1,10,2)));
472
d["a_constant"] = b.getAttr("c");
475
virtual ~example_module()
479
Py::Object ex_keyword( const Py::Tuple &args, const Py::Dict &kws )
481
std::cout << "Called with " << args.length() << " normal arguments." << std::endl;
482
Py::List names( kws.keys() );
483
std::cout << "and with " << names.length() << " keyword arguments:" << std::endl;
484
for( Py::List::size_type i=0; i< names.length(); i++ )
486
Py::String name( names[i] );
487
std::cout << " " << name << std::endl;
493
Py::Object new_r (const Py::Tuple &rargs)
495
if (rargs.length() < 2 || rargs.length() > 3)
497
throw Py::RuntimeError("Incorrect # of args to range(start,stop [,step]).");
500
Py::Int start(rargs[0]);
501
Py::Int stop(rargs[1]);
503
if (rargs.length() == 3)
507
if (long(start) > long(stop) + 1 || long(step) == 0)
509
throw Py::RuntimeError("Bad arguments to range(start,stop [,step]).");
511
return Py::asObject(new range(start, stop, step));
514
Py::Object ex_string (const Py::Tuple &a)
516
std::cout << "ex_std::string: s1 is first arg" << std::endl;
517
Py::String s1( a[0] );
518
std::cout << "ex_string: s1.isString() " << s1.isString() << std::endl;
519
std::cout << "ex_string: s1.isUnicode() " << s1.isUnicode() << std::endl;
520
std::cout << "ex_string: s1.size() " << s1.size() << std::endl;
524
std::cout << "ex_string: s2 is s1.encode( utf-8 )" << std::endl;
525
Py::String s2( s1.encode( "utf-8" ) );
526
std::cout << "ex_string: s2.isString() " << s2.isString() << std::endl;
527
std::cout << "ex_string: s2.isUnicode() " << s2.isUnicode() << std::endl;
528
std::cout << "ex_string: s2.size() " << s2.size() << std::endl;
533
std::cout << "ex_string: s2 is s1.decode( utf-8 )" << std::endl;
534
Py::String s2( s1.decode( "utf-8" ) );
535
std::cout << "ex_string: s2.isString() " << s2.isString() << std::endl;
536
std::cout << "ex_string: s2.isUnicode() " << s2.isUnicode() << std::endl;
537
std::cout << "ex_string: s2.size() " << s2.size() << std::endl;
542
Py::Object ex_sum (const Py::Tuple &a)
544
// this is just to test the function verify_length:
548
std::cout << "I see that you refuse to give me any work to do." << std::endl;
550
catch (Py::Exception& e)
553
std::cout << "I will now add up your elements, oh great one." << std::endl;
558
for( Py::Sequence::size_type i = 0; i < a.length(); i++ )
567
Py::Object ex_test( const Py::Tuple &a)
569
debug_check_ref_queue();
571
std::cout << "Example Test starting" << std::endl;
575
std::cout << "Trying to convert a NULL to an Py::Int" << std::endl;
577
std::cout << "Failed to raise error" << std::endl;
579
catch (Py::TypeError& e)
581
std::cout << "Correctly caught " << Py::type(e) << std::endl;
582
std::cout << " Py::Exception value: " << Py::value(e) << std::endl;
583
std::cout << " Py::Exception traceback: " << Py::trace(e) << std::endl;
589
Py::String s("this should fail");
590
PyObject *p = s.ptr();
591
std::cout << "Trying to convert a Py::String to an Py::Int" << std::endl;
593
std::cout << "Failed to raise error" << std::endl;
595
catch (Py::TypeError& e)
597
std::cout << "Correctly caught " << Py::type(e) << std::endl;
598
std::cout << " Py::Exception value: " << Py::value(e) << std::endl;
599
std::cout << " Py::Exception traceback: " << Py::trace(e) << std::endl;
603
debug_check_ref_queue();
605
std::string result = test_boolean();
606
std::cout << "Py::Boolean: " << result << std::endl;
607
debug_check_ref_queue();
608
std::cout << "Numbers: " << test_numbers() << std::endl;
609
debug_check_ref_queue();
610
std::cout << "Py::String: " << test_String() << std::endl;
611
debug_check_ref_queue();
612
std::cout << "Py::List: " << test_List() << std::endl;
613
debug_check_ref_queue();
614
std::cout << "Py::Dict: " << test_Dict() << std::endl;
615
debug_check_ref_queue();
616
std::cout << "Py::Tuple: " << test_Tuple() << std::endl;
617
debug_check_ref_queue();
618
std::cout << "STL test: " << test_STL() << std::endl;
619
debug_check_ref_queue();
620
std::cout << "Extension object test: " << test_extension_object() << std::endl;
621
debug_check_ref_queue();
627
std::cout << "Py::Tuple/list conversion failed.\n";
631
Py::Object s = m.getAttr("stdout");
633
nun = PyObject_CallMethod(s.ptr(), "write", "s", "Module test ok.\n");
638
extern "C" void initexample()
640
#if defined(PY_WIN32_DELAYLOAD_PYTHON_DLL)
641
Py::InitialisePythonIndirectPy::Interface();
644
static example_module* example = new example_module;
647
// symbol required for the debug version
648
extern "C" void initexample_d()