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;
94
{ std::cout << "OK: T1: True" << std::endl; }
96
{ std::cout << "Bad: T1: False" << std::endl; passed = false; }
100
{ std::cout << "OK: T2: True" << std::endl; }
102
{ std::cout << "Bad: T2: False" << std::endl; passed = false; }
106
{ std::cout << "OK: T3: True" << std::endl; }
108
{ std::cout << "Bad: T3: False" << std::endl; passed = false; }
112
{ std::cout << "OK: T4: True" << std::endl; }
114
{ std::cout << "Bad: T4: False" << std::endl; passed = false; }
118
{ std::cout << "OK: T5: True" << std::endl; }
120
{ std::cout << "Bad: T5: False" << std::endl; passed = false; }
125
{ std::cout << "Bad: F1: True" << std::endl; passed = false; }
127
{ std::cout << "OK: F1: False" << std::endl; }
131
{ std::cout << "Bad: F2: True" << std::endl; passed = false; }
133
{ std::cout << "OK: F2: False" << std::endl; }
137
{ std::cout << "Bad: F3: True" << std::endl; passed = false; }
139
{ std::cout << "OK: F3: False" << std::endl; }
143
{ std::cout << "Bad: F4: True" << std::endl; passed = false; }
145
{ std::cout << "OK: F4: False" << std::endl; }
149
{ std::cout << "Bad: F5: True" << std::endl; passed = false; }
151
{ std::cout << "OK: F5: False" << std::endl; }
162
// test the basic numerical classes
165
Py::Int k = Py::Int(3);
167
if (! (j < k)) return "failed (1)";
168
if (! (j == j)) return "failed (2)" ;
169
if (! (j != k)) return "failed (3)";
170
if (! (j <= k)) return "failed (4)";
171
if (! (k >= j)) return "failed (5)";
172
if (! (k > j)) return "failed (6)";
173
if (! (j <= j)) return "failed (7)";
174
if (! (j >= Py::Int(2))) return "failed (8)";
180
a = (1.0 + 2*a + (b*3.0)/2.0 + k)/Py::Float(5); // 4.0
191
test_List_iterators (const Py::List& x, Py::List& y)
193
std::vector<Py::Object> v;
194
Py::Sequence::iterator j;
196
for(Py::Sequence::const_iterator i = x.begin(); i != x.end(); ++i)
204
return "failed List iterators (1)";
207
for(j = y.begin(); j != y.end(); ++j)
214
for(j = y.begin(); j != y.end(); j++)
217
return "failed List iterators (2)";
218
if(v[k] != Py::Int(k))
219
return "failed List iterators (3)";
222
Py::String o1("Howdy");
229
catch (Py::Exception& e)
235
return "failed exception catch (4).";
240
test_List_references (Py::List& x)
243
for(Py::List::size_type i=0; i < x.length(); ++i)
256
// test the Py::List class
259
aux.append(Py::Int(3));
260
aux.append(Py::Float(6.0));
265
Py::Float c(10.0), d(20.0);
268
a.append(Py::Float(0.0));
273
// a is now [3, 6.0, 3, 30.0, aux]
275
ans.append(Py::Int(3));
276
ans.append(Py::Float(6.0));
277
ans.append(Py::Int(3));
278
ans.append(Py::Float(30.0));
281
Py::List::iterator l1, l2;
282
for(l1= a.begin(), l2 = ans.begin();
283
l1 != a.end() && l2 != ans.end();
286
if(*l1 != *l2) return "failed 1" + a.as_string();
289
if (test_List_references (a)!= aux)
291
return "failed 2" + test_List_references(a).as_string();
293
return test_List_iterators(ans, a);
299
// test the Dict class
303
a["one"] = Py::Int(1);
305
a["three"] = Py::Int(3);
306
if(Py::Int(a["one"]) != Py::Int(1))
307
return "failed 1a " + a.as_string();
308
if(Py::Int(a[s]) != Py::Int(2))
309
return "failed 1b " + a.as_string();
314
std::sort(v.begin(), v.end());
316
for(int k = 1; k < 4; ++k)
318
if(v[k-1] != Py::Int(k))
319
return "failed 2 " + v.as_string();
325
if(b.keys().length() != 0)
327
return "failed 3 " + b.as_string();
335
// test the Tuple class
338
Py::Float f1(1.0), f2(2.0), f3(3.0);
339
a[0] = f1; // should be ok since no other reference owned
344
for(Py::Tuple::iterator i = b.begin(); i != b.end(); ++i)
346
if(*i != Py::Float(++k)) return "failed 1 " + b.as_string();
352
t1[0] = Py::Int(1); // should fail, tuple has multiple references
355
catch (Py::Exception& e)
368
wans.append(Py::Int(1));
369
wans.append(Py::Int(1));
370
wans.append(Py::Int(2));
371
wans.append(Py::Int(3));
372
wans.append(Py::Int(4));
373
wans.append(Py::Int(5));
374
w.append(Py::Int(5));
375
w.append(Py::Int(1));
376
w.append(Py::Int(4));
377
w.append(Py::Int(2));
378
w.append(Py::Int(3));
379
w.append(Py::Int(1));
380
ans1 = std::count(w.begin(), w.end(), Py::Float(1.0));
383
return "failed count test";
388
std::sort(w.begin(), w.end());
391
return "failed sort test";
396
Py::String s1("blah");
397
Py::String s2("gorf");
403
Py::Dict::iterator it = d.begin();
404
for( ; it != d.end(); ++it )
406
Py::Dict::value_type vt( *it );
407
Py::String rs = vt.second.repr();
408
std::string ls = rs.operator std::string();
409
std::cout << "dict value " << ls.c_str() << std::endl;
415
void debug_check_ref_queue()
419
// create an element to find the queue
420
Py::Int list_element;
422
PyObject *p_slow = list_element.ptr();
423
PyObject *p_fast = p_slow;
427
assert( p_slow->_ob_next->_ob_prev == p_slow );
428
assert( p_slow->_ob_prev->_ob_next == p_slow );
431
p_slow = p_slow->_ob_next;
432
p_fast = p_slow->_ob_next->_ob_next;
434
assert( p_slow != p_fast );
436
while( p_slow != list_element.ptr() );
442
class example_module : public Py::ExtensionModule<example_module>
446
: Py::ExtensionModule<example_module>( "example" )
450
add_varargs_method("string", &example_module::ex_string, "string( s ) = return string");
451
add_varargs_method("sum", &example_module::ex_sum, "sum(arglist) = sum of arguments");
452
add_varargs_method("test", &example_module::ex_test, "test(arglist) runs a test suite");
453
add_varargs_method("range", &example_module::new_r, "range(start,stop,stride)");
454
add_keyword_method("kw", &example_module::ex_keyword, "kw()");
456
initialize( "documentation for the example module" );
458
Py::Dict d( moduleDictionary() );
460
Py::Object b(Py::asObject(new range(1,10,2)));
462
d["a_constant"] = b.getAttr("c");
465
virtual ~example_module()
469
Py::Object ex_keyword( const Py::Tuple &args, const Py::Dict &kws )
471
std::cout << "Called with " << args.length() << " normal arguments." << std::endl;
472
Py::List names( kws.keys() );
473
std::cout << "and with " << names.length() << " keyword arguments:" << std::endl;
474
for( Py::List::size_type i=0; i< names.length(); i++ )
476
Py::String name( names[i] );
477
std::cout << " " << name << std::endl;
483
Py::Object new_r (const Py::Tuple &rargs)
485
if (rargs.length() < 2 || rargs.length() > 3)
487
throw Py::RuntimeError("Incorrect # of args to range(start,stop [,step]).");
490
Py::Int start(rargs[0]);
491
Py::Int stop(rargs[1]);
493
if (rargs.length() == 3)
497
if (long(start) > long(stop) + 1 || long(step) == 0)
499
throw Py::RuntimeError("Bad arguments to range(start,stop [,step]).");
501
return Py::asObject(new range(start, stop, step));
504
Py::Object ex_string (const Py::Tuple &a)
506
std::cout << "ex_std::string: s1 is first arg" << std::endl;
507
Py::String s1( a[0] );
508
std::cout << "ex_string: s1.isString() " << s1.isString() << std::endl;
509
std::cout << "ex_string: s1.isUnicode() " << s1.isUnicode() << std::endl;
510
std::cout << "ex_string: s1.size() " << s1.size() << std::endl;
514
std::cout << "ex_string: s2 is s1.encode( utf-8 )" << std::endl;
515
Py::String s2( s1.encode( "utf-8" ) );
516
std::cout << "ex_string: s2.isString() " << s2.isString() << std::endl;
517
std::cout << "ex_string: s2.isUnicode() " << s2.isUnicode() << std::endl;
518
std::cout << "ex_string: s2.size() " << s2.size() << std::endl;
523
std::cout << "ex_string: s2 is s1.decode( utf-8 )" << std::endl;
524
Py::String s2( s1.decode( "utf-8" ) );
525
std::cout << "ex_string: s2.isString() " << s2.isString() << std::endl;
526
std::cout << "ex_string: s2.isUnicode() " << s2.isUnicode() << std::endl;
527
std::cout << "ex_string: s2.size() " << s2.size() << std::endl;
532
Py::Object ex_sum (const Py::Tuple &a)
534
// this is just to test the function verify_length:
538
std::cout << "I see that you refuse to give me any work to do." << std::endl;
540
catch (Py::Exception& e)
543
std::cout << "I will now add up your elements, oh great one." << std::endl;
548
for( Py::Sequence::size_type i = 0; i < a.length(); i++ )
557
Py::Object ex_test( const Py::Tuple &a)
559
debug_check_ref_queue();
561
std::cout << "Example Test starting" << std::endl;
565
std::cout << "Trying to convert a NULL to an Py::Int" << std::endl;
567
std::cout << "Failed to raise error" << std::endl;
569
catch (Py::TypeError& e)
571
std::cout << "Correctly caught " << Py::type(e) << std::endl;
572
std::cout << " Py::Exception value: " << Py::value(e) << std::endl;
573
std::cout << " Py::Exception traceback: " << Py::trace(e) << std::endl;
579
Py::String s("this should fail");
580
PyObject *p = s.ptr();
581
std::cout << "Trying to convert a Py::String to an Py::Int" << std::endl;
583
std::cout << "Failed to raise error" << std::endl;
585
catch (Py::TypeError& e)
587
std::cout << "Correctly caught " << Py::type(e) << std::endl;
588
std::cout << " Py::Exception value: " << Py::value(e) << std::endl;
589
std::cout << " Py::Exception traceback: " << Py::trace(e) << std::endl;
593
debug_check_ref_queue();
595
std::string result = test_boolean();
596
std::cout << "Py::Boolean: " << result << std::endl;
597
debug_check_ref_queue();
598
std::cout << "Numbers: " << test_numbers() << std::endl;
599
debug_check_ref_queue();
600
std::cout << "Py::String: " << test_String() << std::endl;
601
debug_check_ref_queue();
602
std::cout << "Py::List: " << test_List() << std::endl;
603
debug_check_ref_queue();
604
std::cout << "Py::Dict: " << test_Dict() << std::endl;
605
debug_check_ref_queue();
606
std::cout << "Py::Tuple: " << test_Tuple() << std::endl;
607
debug_check_ref_queue();
608
std::cout << "STL test: " << test_STL() << std::endl;
609
debug_check_ref_queue();
610
std::cout << "Extension object test: " << test_extension_object() << std::endl;
611
debug_check_ref_queue();
617
std::cout << "Py::Tuple/list conversion failed.\n";
621
Py::Object s = m.getAttr("stdout");
623
nun = PyObject_CallMethod(s.ptr(), "write", "s", "Module test ok.\n");
628
extern "C" void initexample()
630
#if defined(PY_WIN32_DELAYLOAD_PYTHON_DLL)
631
Py::InitialisePythonIndirectPy::Interface();
634
static example_module* example = new example_module;
637
// symbol required for the debug version
638
extern "C" void initexample_d()