str, dict, and tuple!

[SVN r14517]
This commit is contained in:
Dave Abrahams 2002-07-18 15:17:08 +00:00
parent 94edc13393
commit dfd85da9d7
18 changed files with 1419 additions and 537 deletions

View File

@ -15,6 +15,10 @@ dll bpl
:
src/list.cpp
src/long.cpp
src/dict.cpp
src/tuple.cpp
src/str.cpp
src/aix_init_module.cpp
src/converter/from_python.cpp
src/converter/registry.cpp

View File

@ -0,0 +1,130 @@
#ifndef DICT_20020706_HPP
#define DICT_20020706_HPP
#include <boost/python/object.hpp>
#include <boost/python/list.hpp>
#include <boost/python/tuple.hpp>
#include <boost/python/converter/pytype_object_manager_traits.hpp>
namespace boost { namespace python {
class dict : public object
{
public:
// dict() -> new empty dictionary.
// dict(mapping) -> new dictionary initialized from a mapping object's
// (key, value) pairs.
// dict(seq) -> new dictionary initialized as if via:
BOOST_PYTHON_DECL dict(); // new dict
explicit BOOST_PYTHON_DECL dict(object_cref data);
template <class T>
explicit dict(T const& data)
: object(dict::call(object(data)))
{
}
// D.clear() -> None. Remove all items from D.
BOOST_PYTHON_DECL void clear();
// D.copy() -> a shallow copy of D
BOOST_PYTHON_DECL dict copy();
// D.get(k[,d]) -> D[k] if D.has_key(k), else d. d defaults to None.
BOOST_PYTHON_DECL object get(object_cref k) const;
template<class T>
object get(T const& k) const
{
return this->get(object(k));
}
BOOST_PYTHON_DECL object get(object_cref k, object_cref d) const;
template<class T1, class T2>
object get(T1 const& k, T2 const& d) const
{
return this->get(object(k),object(d));
}
// D.has_key(k) -> 1 if D has a key k, else 0
BOOST_PYTHON_DECL bool has_key(object_cref k) const;
template<class T>
bool has_key(T const& k) const
{
return this->has_key(object(k));
}
// D.items() -> list of D's (key, value) pairs, as 2-tuples
BOOST_PYTHON_DECL list items() const;
// D.iteritems() -> an iterator over the (key, value) items of D
BOOST_PYTHON_DECL object iteritems() const;
// D.iterkeys() -> an iterator over the keys of D
BOOST_PYTHON_DECL object iterkeys() const;
// D.itervalues() -> an iterator over the values of D
BOOST_PYTHON_DECL object itervalues() const;
// D.keys() -> list of D's keys
BOOST_PYTHON_DECL list keys() const;
// D.popitem() -> (k, v), remove and return some (key, value) pair as a
// 2-tuple; but raise KeyError if D is empty
BOOST_PYTHON_DECL tuple popitem();
// D.setdefault(k[,d]) -> D.get(k,d), also set D[k]=d if not D.has_key(k)
BOOST_PYTHON_DECL object setdefault(object_cref k);
template<class T>
object setdefault(T const& k)
{
return this->setdefault(object(k));
}
BOOST_PYTHON_DECL object setdefault(object_cref k, object_cref d);
template<class T1, class T2>
object setdefault(T1 const& k, T2 const& d)
{
return this->setdefault(object(k),object(d));
}
// D.update(E) -> None. Update D from E: for k in E.keys(): D[k] = E[k]
BOOST_PYTHON_DECL void update(object_cref E);
template<class T>
void update(T const& E)
{
this->update(object(E));
}
// D.values() -> list of D's values
BOOST_PYTHON_DECL list values() const;
public: // implementation detail -- for internal use only
BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS(dict)
private:
static BOOST_PYTHON_DECL detail::new_reference call(object const&);
};
//
// Converter Specializations
//
namespace converter
{
template <>
struct object_manager_traits<dict>
: pytype_object_manager_traits<&PyDict_Type,dict>
{
};
}
}} // namespace boost::python
#endif

View File

@ -10,8 +10,7 @@
# define OBJECTS_DWA051100_H_
# ifdef BOOST_PYTHON_V2
# include <boost/python/objects2.hpp>
# include <boost/python/list.hpp>
# error obsolete
# else
# include <boost/python/detail/wrap_python.hpp>
# include <boost/python/detail/config.hpp>

View File

@ -1,252 +0,0 @@
// (C) Copyright David Abrahams 2002. Permission to copy, use, modify, sell and
// distribute this software is granted provided this copyright notice appears
// in all copies. This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
#ifndef OBJECTS_DWA20020611_H
# define OBJECTS_DWA20020611_H
# include <boost/python/detail/wrap_python.hpp>
# include <boost/python/detail/config.hpp>
# include <boost/python/handle.hpp>
# include "boost/operators.hpp"
# include <utility>
namespace boost { namespace python {
class list;
class BOOST_PYTHON_DECL objects_base
{
public:
explicit objects_base(handle<> const& p);
// Return a reference to the held object
handle<> reference() const;
// Return a raw pointer to the held object
PyObject* get() const;
private:
handle<> m_p;
};
class tuple;
class BOOST_PYTHON_DECL tuple_base : public objects_base
{
public:
explicit tuple_base(std::size_t n = 0);
explicit tuple_base(handle<> p);
static PyTypeObject* type_obj();
static bool accepts(handle<> p);
std::size_t size() const;
handle<> operator[](std::size_t pos) const;
void set_item(std::size_t pos, const handle<>& rhs);
tuple slice(int low, int high) const;
friend BOOST_PYTHON_DECL tuple operator+(const tuple&, const tuple&);
friend BOOST_PYTHON_DECL tuple& operator+=(tuple&, const tuple&);
};
class tuple : public tuple_base
{
public:
explicit tuple(std::size_t n = 0) : tuple_base(n) {}
explicit tuple(handle<> p) : tuple_base(p) {}
template <class First, class Second>
tuple(const std::pair<First,Second>& x)
: tuple_base(handle<>(PyTuple_New(2)))
{
set_item(0, x.first);
set_item(1, x.second);
}
template <class First, class Second>
tuple(const First& first, const Second& second)
: tuple_base(handle<>(PyTuple_New(2)))
{
set_item(0, first);
set_item(1, second);
}
template <class First, class Second, class Third>
tuple(const First& first, const Second& second, const Third& third)
: tuple_base(handle<>(PyTuple_New(3)))
{
set_item(0, first);
set_item(1, second);
set_item(2, third);
}
template <class First, class Second, class Third, class Fourth>
tuple(const First& first, const Second& second, const Third& third, const Fourth& fourth)
: tuple_base(handle<>(PyTuple_New(4)))
{
set_item(0, first);
set_item(1, second);
set_item(2, third);
set_item(3, fourth);
}
void set_item(std::size_t pos, const handle<>& rhs)
{
tuple_base::set_item(pos, rhs);
}
};
class BOOST_PYTHON_DECL string
: public objects_base, public boost::multipliable2<string, unsigned int>
{
public:
// Construct from an owned PyObject*.
// Precondition: p must point to a python string.
explicit string(handle<> p);
explicit string(const char* s);
string(const char* s, std::size_t length);
string(const string& rhs);
enum interned_t { interned };
string(const char* s, interned_t);
// Get the type object for Strings
static PyTypeObject* type_obj();
// Return true if the given object is a python string
static bool accepts(handle<> o);
// Return the length of the string.
std::size_t size() const;
// Returns a null-terminated representation of the contents of string.
// The pointer refers to the internal buffer of string, not a copy.
// The data must not be modified in any way. It must not be de-allocated.
const char* c_str() const;
string& operator*=(unsigned int repeat_count);
string& operator+=(const string& rhs);
friend string operator+(string x, string y);
string& operator+=(const char* rhs);
friend string operator+(string x, const char* y);
friend string operator+(const char* x, string y);
void intern();
friend string operator%(const string& format, const tuple& args);
};
class dictionary;
struct BOOST_PYTHON_DECL dictionary_proxy;
class BOOST_PYTHON_DECL dictionary_base : public objects_base
{
protected:
typedef dictionary_proxy proxy;
public:
explicit dictionary_base(handle<> p);
dictionary_base();
void clear();
static PyTypeObject* type_obj();
static bool accepts(handle<> p);
public:
proxy operator[](handle<> key);
handle<> operator[](handle<> key) const;
handle<> get_item(const handle<>& key) const;
handle<> get_item(const handle<>& key, const handle<>& default_) const;
void set_item(const handle<>& key, const handle<>& value);
void erase(handle<> key);
// proxy operator[](const object& key);
// ref operator[](const object& key) const;
// ref get_item(const object& key, ref default_ = ref()) const;
// void set_item(const object& key, const ref& value);
// void erase(const object& key);
list items() const;
list keys() const;
list values() const;
std::size_t size() const;
// TODO: iterator support
};
struct BOOST_PYTHON_DECL dictionary_proxy
{
template <class T>
const handle<>& operator=(const T& rhs)
{ return (*this) = make_ref(rhs); }
const handle<>& operator=(const handle<>& rhs);
operator handle<>() const;
private:
friend class dictionary_base;
dictionary_proxy(const handle<>& dict, const handle<>& key);
// This is needed to work around the very strange MSVC error report that the
// return type of the built-in operator= differs from that of the ones
// defined above. Couldn't hurt to make these un-assignable anyway, though.
const handle<>& operator=(const dictionary_proxy&); // Not actually implemented
private:
handle<> m_dict;
handle<> m_key;
};
class dictionary : public dictionary_base
{
typedef dictionary_proxy proxy;
public:
explicit dictionary(handle<> p) : dictionary_base(p) {}
dictionary() : dictionary_base() {}
template <class Key>
proxy operator[](const Key& key)
{ return this->operator[](make_ref(key)); }
proxy operator[](handle<> key)
{ return dictionary_base::operator[](key); }
template <class Key>
handle<> operator[](const Key& key) const
{ return this->operator[](make_ref(key)); }
handle<> operator[](handle<> key) const
{ return dictionary_base::operator[](key); }
template <class Key>
handle<> get_item(const Key& key) const
{ return this->get_item(make_ref(key)); }
handle<> get_item(const handle<>& key) const
{ return dictionary_base::get_item(key); }
template <class Key, class Default>
handle<> get_item(const Key& key, const Default& default_) const
{ return this->get_item(make_ref(key), make_ref(default_)); }
handle<> get_item(const handle<>& key, const handle<>& default_) const
{ return dictionary_base::get_item(key, default_); }
template <class Key, class Value>
void set_item(const Key& key, const Value& value)
{ this->set_item(make_ref(key), make_ref(value)); }
void set_item(const handle<>& key, const handle<>& value)
{ dictionary_base::set_item(key, value); }
template <class Key>
void erase(const Key& key)
{ this->erase(make_ref(key)); }
void erase(handle<> key)
{ dictionary_base::erase(key); }
};
}} // namespace boost::python
#endif // OBJECTS_DWA20020611_H

View File

@ -0,0 +1,365 @@
#ifndef STR_20020703_HPP
#define STR_20020703_HPP
#include <boost/python/object.hpp>
#include <boost/python/list.hpp>
#include <boost/python/converter/pytype_object_manager_traits.hpp>
namespace boost { namespace python {
class str : public object
{
public:
BOOST_PYTHON_DECL str(const char* s); // new str
explicit BOOST_PYTHON_DECL str(object_cref other);
template <class T>
explicit str(T const& other)
: object(str::call(object(other)))
{
}
BOOST_PYTHON_DECL str capitalize() const ;
BOOST_PYTHON_DECL str center(object_cref width) const ;
template <class T>
str center(T const& width) const
{
return this->center(object(width));
}
BOOST_PYTHON_DECL long count(object_cref sub) const;
template<class T>
long count(T const& sub) const
{
return this->count(object(sub));
}
BOOST_PYTHON_DECL long count(object_cref sub, object_cref start) const;
template<class T1, class T2>
str count(T1 const& sub,T2 const& start) const
{
return this->count(object(sub), object(start));
}
BOOST_PYTHON_DECL long count(object_cref sub, object_cref start, object_cref end) const;
template<class T1, class T2, class T3>
str count(T1 const& sub,T2 const& start, T3 const& end) const
{
return this->count(object(sub), object(start));
}
BOOST_PYTHON_DECL str decode() const;
BOOST_PYTHON_DECL str decode(object_cref encoding) const;
template<class T>
str decode(T const& encoding) const
{
return this->decode(object(encoding));
}
BOOST_PYTHON_DECL str decode(object_cref encoding, object_cref errors) const;
template<class T1, class T2>
str decode(T1 const& encoding, T2 const& errors) const
{
return this->decode(object(encoding),object(errors));
}
BOOST_PYTHON_DECL str encode() const;
BOOST_PYTHON_DECL str encode(object_cref encoding) const;
template <class T>
str encode(T const& encoding) const
{
return this->encode(object(encoding));
}
BOOST_PYTHON_DECL str encode(object_cref encoding, object_cref errors) const;
template <class T1, class T2>
str encode(T1 const& encoding, T2 const& errors) const
{
return this->encode(object(encoding),object(errors));
}
BOOST_PYTHON_DECL bool endswith(object_cref suffix) const;
template <class T>
bool endswith(T const& suffix) const
{
return this->endswith(object(suffix));
}
BOOST_PYTHON_DECL bool endswith(object_cref suffix, object_cref start) const;
template <class T1, class T2>
bool endswith(T1 const& suffix, T2 const& start) const
{
return this->endswith(object(suffix), object(start));
}
BOOST_PYTHON_DECL bool endswith(object_cref suffix, object_cref start, object_cref end) const;
template <class T1, class T2, class T3>
bool endswith(T1 const& suffix, T2 const& start, T3 const& end) const
{
return this->endswith(object(suffix), object(start), object(end));
}
BOOST_PYTHON_DECL str expandtabs() const;
BOOST_PYTHON_DECL str expandtabs(object_cref tabsize) const;
template <class T>
str expandtabs(T const& tabsize) const
{
return this->expandtabs(object(tabsize));
}
BOOST_PYTHON_DECL long find(object_cref sub) const;
template <class T>
long find(T const& sub) const
{
return this->find(object(sub));
}
BOOST_PYTHON_DECL long find(object_cref sub, object_cref start) const;
template <class T1, class T2>
long find(T1 const& sub, T2 const& start) const
{
return this->find(object(sub), object(start));
}
BOOST_PYTHON_DECL long find(object_cref sub, object_cref start, object_cref end) const;
template <class T1, class T2, class T3>
long find(T1 const& sub, T2 const& start, T3 const& end) const
{
return this->find(object(sub), object(start), object(end));
}
BOOST_PYTHON_DECL long index(object_cref sub) const;
template <class T>
long index(T const& sub) const
{
return this->index(object(sub));
}
BOOST_PYTHON_DECL long index(object_cref sub, object_cref start) const;
template <class T1, class T2>
long index(T1 const& sub, T2 const& start) const
{
return this->index(object(sub), object(start));
}
BOOST_PYTHON_DECL long index(object_cref sub, object_cref start, object_cref end) const;
template <class T1, class T2, class T3>
long index(T1 const& sub, T2 const& start, T3 const& end) const
{
return this->index(object(sub), object(start), object(end));
}
BOOST_PYTHON_DECL bool isalnum() const;
BOOST_PYTHON_DECL bool isalpha() const;
BOOST_PYTHON_DECL bool isdigit() const;
BOOST_PYTHON_DECL bool islower() const;
BOOST_PYTHON_DECL bool isspace() const;
BOOST_PYTHON_DECL bool istitle() const;
BOOST_PYTHON_DECL bool isupper() const;
BOOST_PYTHON_DECL str join(object_cref sequence) const;
template <class T>
str join(T const& sequence) const
{
return this->join(object(sequence));
}
BOOST_PYTHON_DECL str ljust(object_cref width) const;
template <class T>
str ljust(T const& width) const
{
return this->ljust(object(width));
}
BOOST_PYTHON_DECL str lower() const;
BOOST_PYTHON_DECL str lstrip() const;
BOOST_PYTHON_DECL str replace(object_cref old, object_cref new_) const ;
template <class T1, class T2>
str replace(T1 const& old, T2 const& new_) const
{
return this->replace(object(old),object(new_));
}
BOOST_PYTHON_DECL str replace(object_cref old, object_cref new_, object_cref maxsplit) const ;
template <class T1, class T2, class T3>
str replace(T1 const& old, T2 const& new_, T3 const& maxsplit) const
{
return this->replace(object(old),object(new_),object(maxsplit));
}
BOOST_PYTHON_DECL long rfind(object_cref sub) const;
template <class T>
long rfind(T const& sub) const
{
return this->rfind(object(sub));
}
BOOST_PYTHON_DECL long rfind(object_cref sub, object_cref start) const;
template <class T1, class T2>
long rfind(T1 const& sub, T2 const& start) const
{
return this->rfind(object(sub), object(start));
}
BOOST_PYTHON_DECL long rfind(object_cref sub, object_cref start, object_cref end) const;
template <class T1, class T2, class T3>
long rfind(T1 const& sub, T2 const& start, T3 const& end) const
{
return this->rfind(object(sub), object(start), object(end));
}
BOOST_PYTHON_DECL long rindex(object_cref sub) const;
template <class T>
long rindex(T const& sub) const
{
return this->rindex(object(sub));
}
BOOST_PYTHON_DECL long rindex(object_cref sub, object_cref start) const;
template <class T1, class T2>
long rindex(T1 const& sub, T2 const& start) const
{
return this->rindex(object(sub), object(start));
}
BOOST_PYTHON_DECL long rindex(object_cref sub, object_cref start, object_cref end) const;
template <class T1, class T2, class T3>
long rindex(T1 const& sub, T2 const& start, T3 const& end) const
{
return this->rindex(object(sub), object(start), object(end));
}
BOOST_PYTHON_DECL str rjust(object_cref width) const;
template <class T>
str rjust(T const& width) const
{
return this->rjust(object(width));
}
BOOST_PYTHON_DECL str rstrip() const;
BOOST_PYTHON_DECL list split() const;
BOOST_PYTHON_DECL list split(object_cref sep) const;
template <class T>
list split(T const& sep) const
{
return this->split(object(sep));
}
BOOST_PYTHON_DECL list split(object_cref sep, object_cref maxsplit) const;
template <class T1, class T2>
list split(T1 const& sep, T2 const& maxsplit) const
{
return this->split(object(sep), object(maxsplit));
}
BOOST_PYTHON_DECL list splitlines() const;
BOOST_PYTHON_DECL list splitlines(object_cref keepends) const;
template <class T>
list splitlines(T const& keepends) const
{
return this->splitlines(object(keepends));
}
BOOST_PYTHON_DECL bool startswith(object_cref prefix) const ;
template <class T>
bool startswith(T const& prefix) const
{
return this->startswith(object(prefix));
}
BOOST_PYTHON_DECL bool startswith(object_cref prefix, object_cref start) const ;
template <class T1, class T2>
bool startswidth(T1 const& prefix, T2 const& start) const
{
return this->startswidth(object(prefix), object(start));
}
BOOST_PYTHON_DECL bool startswith(object_cref prefix, object_cref start, object_cref end) const ;
template <class T1, class T2, class T3>
bool startswidth(T1 const& prefix, T2 const& start, T3 const& end) const
{
return this->startswidth(object(prefix), object(start), object(end));
}
BOOST_PYTHON_DECL str strip() const ;
BOOST_PYTHON_DECL str swapcase() const ;
BOOST_PYTHON_DECL str title() const ;
BOOST_PYTHON_DECL str translate(object_cref table) const;
template <class T>
str translate(T const& table) const
{
return this->translate(object(table));
}
BOOST_PYTHON_DECL str translate(object_cref table, object_cref deletechars) const;
template <class T1, class T2>
str translate(T1 const& table, T2 const& deletechars) const
{
return this->translate(object(table), object(deletechars));
}
BOOST_PYTHON_DECL str upper() const;
public: // implementation detail -- for internal use only
BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS(str)
private:
static BOOST_PYTHON_DECL detail::new_reference call(object const&);
};
//
// Converter Specializations
//
namespace converter
{
template <>
struct object_manager_traits<str>
: pytype_object_manager_traits<&PyString_Type,str>
{
};
}
}} // namespace boost::python
#endif // STR_20020703_HPP

View File

@ -0,0 +1,47 @@
#ifndef TUPLE_20020706_HPP
#define TUPLE_20020706_HPP
#include <boost/python/object.hpp>
#include <boost/python/converter/pytype_object_manager_traits.hpp>
namespace boost { namespace python {
class tuple : public object
{
public:
// tuple() -> an empty tuple
BOOST_PYTHON_DECL tuple();
// tuple(sequence) -> tuple initialized from sequence's items
BOOST_PYTHON_DECL tuple(object_cref sequence);
template <class T>
explicit tuple(T const& sequence)
: object(tuple::call(object(sequence)))
{
}
public: // implementation detail -- for internal use only
BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS(tuple)
private:
static BOOST_PYTHON_DECL detail::new_reference call(object const&);
};
//
// Converter Specializations
//
namespace converter
{
template <>
struct object_manager_traits<tuple>
: pytype_object_manager_traits<&PyTuple_Type,tuple>
{
};
}
}} // namespace boost::python
#endif

172
src/dict.cpp Normal file
View File

@ -0,0 +1,172 @@
#include <boost/python/dict.hpp>
#include <boost/python/extract.hpp>
namespace boost { namespace python {
namespace
{
// When returning list objects from methods, it may turn out that the
// derived class is returning something else, perhaps something not
// even derived from list. Since it is generally harmless for a
// Boost.Python wrapper object to hold an object of a different
// type, and because calling list() with an object may in fact
// perform a conversion, the least-bad alternative is to assume that
// we have a Python list object and stuff it into the list result.
list assume_list(object const& o)
{
return list(detail::borrowed_reference(o.ptr()));
}
// No PyDict_CheckExact; roll our own.
inline bool check_exact(dict const* p)
{
return p->ptr()->ob_type == &PyDict_Type;
}
}
BOOST_PYTHON_DECL detail::new_reference dict::call(object const& arg)
{
return (detail::new_reference)PyObject_CallFunction(
(PyObject*)&PyDict_Type, "(O)",
arg.ptr());
}
BOOST_PYTHON_DECL dict::dict()
: object(detail::new_reference(PyDict_New()))
{}
BOOST_PYTHON_DECL dict::dict(object_cref data)
: object(dict::call(data))
{}
BOOST_PYTHON_DECL void dict::clear()
{
if (check_exact(this))
PyDict_Clear(this->ptr());
else
this->attr("clear")();
}
BOOST_PYTHON_DECL dict dict::copy()
{
if (check_exact(this))
{
return dict(detail::new_reference(
PyDict_Copy(this->ptr())));
}
else
{
return dict(detail::borrowed_reference(
this->attr("copy")().ptr()
));
}
}
BOOST_PYTHON_DECL object dict::get(object_cref k) const
{
if (check_exact(this))
{
return object(detail::borrowed_reference(
PyDict_GetItem(this->ptr(),k.ptr())));
}
else
{
return this->attr("get")(k);
}
}
BOOST_PYTHON_DECL object dict::get(object_cref k, object_cref d) const
{
return this->attr("get")(k,d);
}
BOOST_PYTHON_DECL bool dict::has_key(object_cref k) const
{
return extract<bool>(this->attr("has_key")(k));
}
BOOST_PYTHON_DECL list dict::items() const
{
if (check_exact(this))
{
return list(detail::new_reference(
PyDict_Items(this->ptr())));
}
else
{
return assume_list(this->attr("items")());
}
}
BOOST_PYTHON_DECL object dict::iteritems() const
{
return this->attr("iteritems")();
}
BOOST_PYTHON_DECL object dict::iterkeys() const
{
return this->attr("iterkeys")();
}
BOOST_PYTHON_DECL object dict::itervalues() const
{
return this->attr("itervalues")();
}
BOOST_PYTHON_DECL list dict::keys() const
{
if (check_exact(this))
{
return list(detail::new_reference(
PyDict_Keys(this->ptr())));
}
else
{
return assume_list(this->attr("keys")());
}
}
BOOST_PYTHON_DECL tuple dict::popitem()
{
return tuple(detail::borrowed_reference(
this->attr("popitem")().ptr()
));
}
BOOST_PYTHON_DECL object dict::setdefault(object_cref k)
{
return this->attr("setdefault")(k);
}
BOOST_PYTHON_DECL object dict::setdefault(object_cref k, object_cref d)
{
return this->attr("setdefault")(k,d);
}
BOOST_PYTHON_DECL void dict::update(object_cref other)
{
if (check_exact(this))
{
if (PyDict_Update(this->ptr(),other.ptr()) == -1)
throw_error_already_set();
}
else
{
this->attr("update")(other);
}
}
BOOST_PYTHON_DECL list dict::values() const
{
if (check_exact(this))
{
return list(detail::new_reference(
PyDict_Values(this->ptr())));
}
else
{
return assume_list(this->attr("values")());
}
}
}} // namespace boost::python

View File

@ -7,7 +7,7 @@
#include <boost/python/object/function.hpp>
#include <numeric>
#include <boost/python/errors.hpp>
#include <boost/python/objects2.hpp>
#include <boost/python/str.hpp>
#include <algorithm>
#include <cstring>
@ -158,7 +158,7 @@ namespace
void function::add_to_namespace(
handle<> const& name_space, char const* name_, handle<> const& attribute)
{
string const name(name_);
str const name(name_);
PyObject* const ns = name_space.get();
if (attribute->ob_type == &function_type)
@ -175,7 +175,7 @@ void function::add_to_namespace(
if (dict == 0)
throw_error_already_set();
handle<> existing( allow_null(PyObject_GetItem(dict, name.get())) );
handle<> existing( allow_null(PyObject_GetItem(dict, name.ptr())) );
if (existing.get())
{
@ -195,7 +195,7 @@ void function::add_to_namespace(
// The PyObject_GetAttrString() call above left an active error
PyErr_Clear();
if (PyObject_SetAttr(ns, name.get(), attribute.get()) < 0)
if (PyObject_SetAttr(ns, name.ptr(), attribute.get()) < 0)
throw_error_already_set();
}

View File

@ -1,279 +0,0 @@
// (C) Copyright David Abrahams 2000. Permission to copy, use, modify, sell and
// distribute this software is granted provided this copyright notice appears
// in all copies. This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
//
// The author gratefully acknowleges the support of Dragon Systems, Inc., in
// producing this work.
// TODO: Move inline implementations from objects.cpp here
#ifndef BOOST_PYTHON_SOURCE
# define BOOST_PYTHON_SOURCE
#endif
#include <boost/python/objects.hpp>
#include <boost/python/detail/none.hpp>
namespace boost { namespace python {
objects_base::objects_base(handle<> const& p)
: m_p(borrowed(p.get())) // Do the null check here
{}
// Return a reference to the held object
handle<> objects_base::reference() const
{
return m_p;
}
// Return a raw pointer to the held object
PyObject* objects_base::get() const
{
return m_p.get();
}
}} // namespace boost::python
namespace boost { namespace python {
tuple_base::tuple_base(std::size_t n)
: objects_base(handle<>(PyTuple_New(n)))
{
for (std::size_t i = 0; i < n; ++i)
PyTuple_SET_ITEM(get(), i, detail::none());
}
tuple_base::tuple_base(handle<> p)
: objects_base(p)
{
assert(accepts(p));
if (!accepts(p))
{
PyErr_SetString(PyExc_TypeError, p->ob_type->tp_name);
throw_error_already_set();
}
}
PyTypeObject* tuple_base::type_obj()
{
return &PyTuple_Type;
}
bool tuple_base::accepts(handle<> p)
{
return PyTuple_Check(p.get());
}
std::size_t tuple_base::size() const
{
return PyTuple_Size(get());
}
handle<> tuple_base::operator[](std::size_t pos) const
{
return handle<>(borrowed(PyTuple_GetItem(get(), static_cast<int>(pos))));
}
void tuple_base::set_item(std::size_t pos, const handle<>& rhs)
{
int failed = PyTuple_SetItem(
get()
, static_cast<int>(pos)
, incref(expect_non_null(rhs.get()))
);
(void)failed;
assert(failed == 0);
}
tuple tuple_base::slice(int low, int high) const
{
return tuple(handle<>(PyTuple_GetSlice(get(), low, high)));
}
BOOST_PYTHON_DECL tuple& operator+=(tuple& self, const tuple& rhs)
{
return self = self + rhs;
}
// Construct from an owned PyObject*.
// Precondition: p must point to a python string.
string::string(handle<> p)
: objects_base(p)
{
assert(accepts(p));
if (!accepts(p))
{
PyErr_SetString(PyExc_TypeError, p->ob_type->tp_name);
throw_error_already_set();
}
}
string::string(const char* s)
: objects_base(handle<>(PyString_FromString(s))) {}
string::string(const char* s, std::size_t length)
: objects_base(handle<>(PyString_FromStringAndSize(s, length))) {}
string::string(const char* s, interned_t)
: objects_base(handle<>(PyString_InternFromString(s))) {}
string::string(const string& rhs)
: objects_base(rhs.reference()) {}
// Get the type object for Strings
PyTypeObject* string::type_obj()
{ return &PyString_Type; }
// Return true if the given object is a python string
bool string::accepts(handle<> o)
{ return PyString_Check(o.get()); }
// Return the length of the string.
std::size_t string::size() const
{
int size = PyString_GET_SIZE(get());
assert(size >= 0);
return static_cast<std::size_t>(size);
}
// Returns a null-terminated representation of the contents of string.
// The pointer refers to the internal buffer of string, not a copy.
// The data must not be modified in any way. It must not be de-allocated.
const char* string::c_str() const
{ return PyString_AS_STRING(get()); }
void string::intern()
{ // UNTESTED!!
*this = string(handle<>(borrowed(PyString_InternFromString(c_str()))));
}
string& string::operator*=(unsigned int repeat_count)
{
*this = string(handle<>(PySequence_Repeat(get(), repeat_count)));
return *this;
}
dictionary_base::dictionary_base(handle<> p)
: objects_base(p)
{
assert(accepts(p));
if (!accepts(p))
{
PyErr_SetString(PyExc_TypeError, p->ob_type->tp_name);
throw_error_already_set();
}
}
dictionary_base::dictionary_base()
: objects_base(handle<>(PyDict_New())) {}
PyTypeObject* dictionary_base::type_obj()
{ return &PyDict_Type; }
bool dictionary_base::accepts(handle<> p)
{ return PyDict_Check(p.get()); }
void dictionary_base::clear()
{ PyDict_Clear(get()); }
const handle<>& dictionary_proxy::operator=(const handle<>& rhs)
{
if (PyDict_SetItem(m_dict.get(), m_key.get(), rhs.get()) == -1)
throw_error_already_set();
return rhs;
}
dictionary_proxy::operator handle<>() const
{
return handle<>(
m_dict->ob_type->tp_as_mapping->mp_subscript(m_dict.get(), m_key.get()));
}
dictionary_proxy::dictionary_proxy(const handle<>& dict, const handle<>& key)
: m_dict(dict), m_key(key) {}
dictionary_proxy dictionary_base::operator[](handle<> key)
{ return proxy(reference(), key); }
handle<> dictionary_base::operator[](handle<> key) const {
// An odd MSVC bug causes the ".operator Ptr()" to be needed
return proxy(reference(), key).operator handle<>();
}
handle<> dictionary_base::get_item(const handle<>& key) const
{
return get_item(key, handle<>());
}
handle<> dictionary_base::get_item(const handle<>& key, const handle<>& default_) const
{
PyObject* value_or_null = PyDict_GetItem(get(), key.get());
if (value_or_null == 0 && !PyErr_Occurred())
return default_;
else
return handle<>(borrowed(value_or_null)); // Will throw if there was another error
}
void dictionary_base::set_item(const handle<>& key, const handle<>& value)
{
if (PyDict_SetItem(get(), key.get(), value.get()) == -1)
throw_error_already_set();
}
void dictionary_base::erase(handle<> key) {
if (PyDict_DelItem(get(), key.get()) == -1)
throw_error_already_set();
}
list dictionary_base::items() const { return list(handle<>(PyDict_Items(get()))); }
list dictionary_base::keys() const { return list(handle<>(PyDict_Keys(get()))); }
list dictionary_base::values() const { return list(handle<>(PyDict_Values(get()))); }
std::size_t dictionary_base::size() const { return static_cast<std::size_t>(PyDict_Size(get())); }
string operator+(string x, string y)
{
PyObject* io_string = incref(x.get());
PyString_Concat(&io_string, y.get());
return string(handle<>(io_string));
}
string& string::operator+=(const string& rhs)
{
return *this = *this + rhs;
}
string& string::operator+=(const char* y)
{
return *this += string(y);
}
string operator%(const string& format, const tuple& args)
{
return string(handle<>(PyString_Format(format.get(), args.reference().get())));
}
string operator+(string x, const char* y)
{
return x + string(y);
}
string operator+(const char* x, string y)
{
return string(x) + y;
}
tuple operator+(const tuple& x, const tuple& y)
{
tuple result(x.size() + y.size());
for (std::size_t xi = 0; xi < x.size(); ++xi)
result.set_item(xi, x[xi]);
for (std::size_t yi = 0; yi < y.size(); ++yi)
result.set_item(yi + x.size(), y[yi]);
return result;
}
}} // namespace boost::python

380
src/str.cpp Normal file
View File

@ -0,0 +1,380 @@
#include <boost/python/str.hpp>
#include <boost/python/extract.hpp>
namespace boost { namespace python {
BOOST_PYTHON_DECL detail::new_reference str::call(object const& arg)
{
return (detail::new_reference)PyObject_CallFunction(
(PyObject*)&PyString_Type, "(O)",
arg.ptr());
}
BOOST_PYTHON_DECL str::str(const char* s)
: object(detail::new_reference(PyString_FromString(s)))
{}
BOOST_PYTHON_DECL str::str(object_cref other)
: object(str::call(other))
{}
namespace
{
// When returning str objects from methods, it may turn out that the
// derived class is returning something else, perhaps something not
// even derived from str. Since it is generally harmless for a
// Boost.Python wrapper object to hold an object of a different
// type, and because calling str() with an object may in fact
// perform a conversion, the least-bad alternative is to assume that
// we have a Python str object and stuff it into the str result.
str assume_str(object const& o)
{
return str(detail::borrowed_reference(o.ptr()));
}
}
BOOST_PYTHON_DECL str str::capitalize() const
{
return assume_str(this->attr("capitalize")());
}
BOOST_PYTHON_DECL str str::center(object_cref width) const
{
return assume_str(
this->attr("center")(width)
);
}
BOOST_PYTHON_DECL long str::count(object_cref sub) const
{
return extract<long>(this->attr("count")(sub));
}
BOOST_PYTHON_DECL long str::count(object_cref sub, object_cref start) const
{
return extract<long>(this->attr("count")(sub,start));
}
BOOST_PYTHON_DECL long str::count(object_cref sub, object_cref start, object_cref end) const
{
return extract<long>(this->attr("count")(sub,start,end));
}
BOOST_PYTHON_DECL str str::decode() const
{
return assume_str(this->attr("decode")());
}
BOOST_PYTHON_DECL str str::decode(object_cref encoding) const
{
return assume_str(this->attr("decode")(encoding));
}
BOOST_PYTHON_DECL str str::decode(object_cref encoding, object_cref errors) const
{
return assume_str(this->attr("decode")(encoding,errors));
}
BOOST_PYTHON_DECL str str::encode() const
{
return assume_str(this->attr("encode")());
}
BOOST_PYTHON_DECL str str::encode(object_cref encoding) const
{
return assume_str(this->attr("encode")(encoding));
}
BOOST_PYTHON_DECL str str::encode(object_cref encoding, object_cref errors) const
{
return assume_str(this->attr("encode")(encoding,errors));
}
BOOST_PYTHON_DECL bool str::endswith(object_cref suffix) const
{
bool result = PyInt_AsLong(this->attr("endswith")(suffix).ptr());
if (PyErr_Occurred())
throw_error_already_set();
return result;
}
BOOST_PYTHON_DECL str str::expandtabs() const
{
return assume_str(this->attr("expandtabs")());
}
BOOST_PYTHON_DECL str str::expandtabs(object_cref tabsize) const
{
return assume_str(this->attr("expandtabs")(tabsize));
}
BOOST_PYTHON_DECL long str::find(object_cref sub) const
{
long result = PyInt_AsLong(this->attr("find")(sub).ptr());
if (PyErr_Occurred())
throw_error_already_set();
return result;
}
BOOST_PYTHON_DECL long str::find(object_cref sub, object_cref start) const
{
long result = PyInt_AsLong(this->attr("find")(sub,start).ptr());
if (PyErr_Occurred())
throw_error_already_set();
return result;
}
BOOST_PYTHON_DECL long str::find(object_cref sub, object_cref start, object_cref end) const
{
long result = PyInt_AsLong(this->attr("find")(sub,start,end).ptr());
if (PyErr_Occurred())
throw_error_already_set();
return result;
}
BOOST_PYTHON_DECL long str::index(object_cref sub) const
{
long result = PyInt_AsLong(this->attr("index")(sub).ptr());
if (PyErr_Occurred())
throw_error_already_set();
return result;
}
BOOST_PYTHON_DECL long str::index(object_cref sub, object_cref start) const
{
long result = PyInt_AsLong(this->attr("index")(sub,start).ptr());
if (PyErr_Occurred())
throw_error_already_set();
return result;
}
BOOST_PYTHON_DECL long str::index(object_cref sub, object_cref start, object_cref end) const
{
long result = PyInt_AsLong(this->attr("index")(sub,start,end).ptr());
if (PyErr_Occurred())
throw_error_already_set();
return result;
}
BOOST_PYTHON_DECL bool str::isalnum() const
{
bool result = PyInt_AsLong(this->attr("isalnum")().ptr());
if (PyErr_Occurred())
throw_error_already_set();
return result;
}
BOOST_PYTHON_DECL bool str::isalpha() const
{
bool result = PyInt_AsLong(this->attr("isalpha")().ptr());
if (PyErr_Occurred())
throw_error_already_set();
return result;
}
BOOST_PYTHON_DECL bool str::isdigit() const
{
bool result = PyInt_AsLong(this->attr("isdigit")().ptr());
if (PyErr_Occurred())
throw_error_already_set();
return result;
}
BOOST_PYTHON_DECL bool str::islower() const
{
bool result = PyInt_AsLong(this->attr("islower")().ptr());
if (PyErr_Occurred())
throw_error_already_set();
return result;
}
BOOST_PYTHON_DECL bool str::isspace() const
{
bool result = PyInt_AsLong(this->attr("isspace")().ptr());
if (PyErr_Occurred())
throw_error_already_set();
return result;
}
BOOST_PYTHON_DECL bool str::istitle() const
{
bool result = PyInt_AsLong(this->attr("istitle")().ptr());
if (PyErr_Occurred())
throw_error_already_set();
return result;
}
BOOST_PYTHON_DECL bool str::isupper() const
{
bool result = PyInt_AsLong(this->attr("isupper")().ptr());
if (PyErr_Occurred())
throw_error_already_set();
return result;
}
BOOST_PYTHON_DECL str str::join(object_cref sequence) const
{
return assume_str(this->attr("join")(sequence));
}
BOOST_PYTHON_DECL str str::ljust(object_cref width) const
{
return assume_str(this->attr("ljust")(width));
}
BOOST_PYTHON_DECL str str::lower() const
{
return assume_str(this->attr("lower")());
}
BOOST_PYTHON_DECL str str::lstrip() const
{
return assume_str(this->attr("lstrip")());
}
BOOST_PYTHON_DECL str str::replace(object_cref old, object_cref new_) const
{
return assume_str(this->attr("replace")(old,new_));
}
BOOST_PYTHON_DECL str str::replace(object_cref old, object_cref new_, object_cref maxsplit) const {
return assume_str(this->attr("replace")(old,new_,maxsplit));
}
BOOST_PYTHON_DECL long str::rfind(object_cref sub) const
{
long result = PyInt_AsLong(this->attr("rfind")(sub).ptr());
if (PyErr_Occurred())
throw_error_already_set();
return result;
}
BOOST_PYTHON_DECL long str::rfind(object_cref sub, object_cref start) const
{
long result = PyInt_AsLong(this->attr("rfind")(sub,start).ptr());
if (PyErr_Occurred())
throw_error_already_set();
return result;
}
BOOST_PYTHON_DECL long str::rfind(object_cref sub, object_cref start, object_cref end) const
{
long result = PyInt_AsLong(this->attr("rfind")(sub,start,end).ptr());
if (PyErr_Occurred())
throw_error_already_set();
return result;
}
BOOST_PYTHON_DECL long str::rindex(object_cref sub) const
{
long result = PyInt_AsLong(this->attr("rindex")(sub).ptr());
if (PyErr_Occurred())
throw_error_already_set();
return result;
}
BOOST_PYTHON_DECL long str::rindex(object_cref sub, object_cref start) const
{
long result = PyInt_AsLong(this->attr("rindex")(sub,start).ptr());
if (PyErr_Occurred())
throw_error_already_set();
return result;
}
BOOST_PYTHON_DECL long str::rindex(object_cref sub, object_cref start, object_cref end) const
{
long result = PyInt_AsLong(this->attr("rindex")(sub,start,end).ptr());
if (PyErr_Occurred())
throw_error_already_set();
return result;
}
BOOST_PYTHON_DECL str str::rjust(object_cref width) const
{
return assume_str(this->attr("rjust")(width));
}
BOOST_PYTHON_DECL str str::rstrip() const
{
return assume_str(this->attr("rstrip")());
}
BOOST_PYTHON_DECL list str::split() const
{
return list(this->attr("split")());
}
BOOST_PYTHON_DECL list str::split(object_cref sep) const
{
return list(this->attr("split")(sep));
}
BOOST_PYTHON_DECL list str::split(object_cref sep, object_cref maxsplit) const
{
return list(this->attr("split")(sep,maxsplit));
}
BOOST_PYTHON_DECL list str::splitlines() const
{
return list(this->attr("splitlines")());
}
BOOST_PYTHON_DECL list str::splitlines(object_cref keepends) const
{
return list(this->attr("splitlines")(keepends));
}
BOOST_PYTHON_DECL bool str::startswith(object_cref prefix) const
{
bool result = PyInt_AsLong(this->attr("startswith")(prefix).ptr());
if (PyErr_Occurred())
throw_error_already_set();
return result;
}
BOOST_PYTHON_DECL bool str::startswith(object_cref prefix, object_cref start) const
{
bool result = PyInt_AsLong(this->attr("startswith")(prefix,start).ptr());
if (PyErr_Occurred())
throw_error_already_set();
return result;
}
BOOST_PYTHON_DECL bool str::startswith(object_cref prefix, object_cref start, object_cref end) const
{
bool result = PyInt_AsLong(this->attr("startswith")(prefix,start,end).ptr());
if (PyErr_Occurred())
throw_error_already_set();
return result;
}
BOOST_PYTHON_DECL str str::strip() const
{
return assume_str(this->attr("strip")());
}
BOOST_PYTHON_DECL str str::swapcase() const
{
return assume_str(this->attr("swapcase")());
}
BOOST_PYTHON_DECL str str::title() const
{
return assume_str(this->attr("title")());
}
BOOST_PYTHON_DECL str str::translate(object_cref table) const
{
return assume_str(this->attr("translate")(table));
}
BOOST_PYTHON_DECL str str::translate(object_cref table, object_cref deletechars) const
{
return assume_str(this->attr("translate")(table,deletechars));
}
BOOST_PYTHON_DECL str str::upper() const
{
return assume_str(this->attr("upper")());
}
}} // namespace boost::python

20
src/tuple.cpp Normal file
View File

@ -0,0 +1,20 @@
#include <boost/python/tuple.hpp>
namespace boost { namespace python {
BOOST_PYTHON_DECL detail::new_reference tuple::call(object const& arg)
{
return (detail::new_reference)PyObject_CallFunction(
(PyObject*)&PyTuple_Type, "(O)",
arg.ptr());
}
BOOST_PYTHON_DECL tuple::tuple()
: object(detail::new_reference(PyTuple_New(0)))
{}
BOOST_PYTHON_DECL tuple::tuple(object_cref sequence)
: object(tuple::call(sequence))
{}
}} // namespace boost::python

View File

@ -61,9 +61,14 @@ bpl-test builtin_converters : test_builtin_converters.py test_builtin_converters
bpl-test test_pointer_adoption ;
bpl-test operators ;
bpl-test callbacks ;
bpl-test object ;
bpl-test list ;
bpl-test long ;
bpl-test dict ;
bpl-test tuple ;
bpl-test str ;
bpl-test virtual_functions ;
bpl-test back_reference ;
bpl-test implicit ;

82
test/dict.cpp Normal file
View File

@ -0,0 +1,82 @@
#include <boost/python/module.hpp>
#include <boost/python/class.hpp>
#include <boost/python/dict.hpp>
#include <exception>
#include <string>
using namespace boost::python;
object new_dict()
{
return dict();
}
object data_dict()
{
dict tmp1;
tmp1["key1"] = "value1";
dict tmp2;
tmp2["key2"] = "value2";
tmp1[1] = tmp2;
return tmp1;
}
object dict_from_sequence(object sequence)
{
return dict(sequence);
}
object dict_keys(dict data)
{
return data.keys();
}
object dict_values(dict data)
{
return data.values();
}
object dict_items(dict data)
{
return data.items();
}
void work_with_dict(dict data1, dict data2)
{
if (!data1.has_key("k1")) {
throw std::runtime_error("dict does not have key 'k1'");
}
data1.update(data2);
}
void test_templates(object print)
{
std::string key = "key";
dict tmp;
tmp[1] = "a test string";
print(tmp.get(1));
//print(tmp[1]);
tmp[1.5] = 13;
print(tmp.get(1.5));
print(tmp);
print(tmp.get(2,"default"));
print(tmp.has_key(key));
print(tmp.setdefault(3,"default"));
//print(tmp[3]);
}
BOOST_PYTHON_MODULE_INIT(dict_ext)
{
module("dict_ext")
.def("new_dict", new_dict)
.def("data_dict", data_dict)
.def("dict_keys", dict_keys)
.def("dict_values", dict_values)
.def("dict_items", dict_items)
.def("dict_from_sequence", dict_from_sequence)
.def("work_with_dict", work_with_dict)
.def("test_templates", test_templates)
;
}

40
test/dict.py Normal file
View File

@ -0,0 +1,40 @@
"""
>>> from dict_ext import *
>>> def printer(*args):
... for x in args: print x,
... print
...
>>> print new_dict()
{}
>>> print data_dict()
{1: {'key2': 'value2'}, 'key1': 'value1'}
>>> tmp = data_dict()
>>> print dict_keys(tmp)
[1, 'key1']
>>> print dict_values(tmp)
[{'key2': 'value2'}, 'value1']
>>> print dict_items(tmp)
[(1, {'key2': 'value2'}), ('key1', 'value1')]
>>> print dict_from_sequence([(1,1),(2,2),(3,3)])
{1: 1, 2: 2, 3: 3}
>>> test_templates(printer)
a test string
13
{1.5: 13, 1: 'a test string'}
default
0
default
"""
def run(args = None):
import sys
import doctest
if args is not None:
sys.argv = args
return doctest.testmod(sys.modules.get(__name__))
if __name__ == '__main__':
print "running..."
import sys
sys.exit(run()[0])

68
test/str.cpp Normal file
View File

@ -0,0 +1,68 @@
#include <boost/python/module.hpp>
#include <boost/python/class.hpp>
#include <boost/python/str.hpp>
using namespace boost::python;
object convert_to_string(object data)
{
return str(data);
}
void work_with_string(object print)
{
str data("this is a demo string");
print(data.split(" "));
print(data.split(" ",3));
print(str("<->").join(data.split(" ")));
print(data.capitalize());
print('[' + data.center(30) + ']');
print(data.count("t"));
print(data.encode("utf-8"));
print(data.decode("utf-8"));
print(data.endswith("xx"));
print(data.startswith("test"));
print(data.splitlines());
print(data.strip());
print(data.swapcase());
print(data.title());
print("find");
print(data.find("demo"));
print(data.find("demo"),3,5);
print(data.find(std::string("demo")));
print(data.find(std::string("demo"),9));
print("expandtabs");
str tabstr("\t\ttab\tdemo\t!");
print(tabstr.expandtabs());
print(tabstr.expandtabs(4));
print(tabstr.expandtabs(7.9));
print("operators");
print( str("part1") + str("part2") );
// print( str("a test string").slice(3,_) );
// print( str("another test")[5] );
print(data.replace("demo",std::string("blabla")));
print(data.rfind("i",5));
print(data.rindex("i",5));
print(data.startswith("asdf"));
print(data.endswith("asdf"));
print(data.translate(str('a')*256));
bool tmp = data.isalnum() || data.isalpha() || data.isdigit() || data.islower() ||
data.isspace() || data.istitle() || data.isupper();
(void)tmp; // ignored.
}
BOOST_PYTHON_MODULE_INIT(str_ext)
{
module("str_ext")
.def("convert_to_string",convert_to_string)
.def("work_with_string",work_with_string)
;
}

52
test/str.py Normal file
View File

@ -0,0 +1,52 @@
"""
>>> from str_ext import *
>>> def printer(*args):
... for x in args: print x,
... print
...
>>> work_with_string(printer)
['this', 'is', 'a', 'demo', 'string']
['this', 'is', 'a', 'demo string']
this<->is<->a<->demo<->string
This is a demo string
[ this is a demo string ]
2
this is a demo string
this is a demo string
0
0
['this is a demo string']
this is a demo string
THIS IS A DEMO STRING
This Is A Demo String
find
10
10 3 5
10
10
expandtabs
tab demo !
tab demo !
tab demo !
operators
part1part2
this is a blabla string
18
18
0
0
aaaaaaaaaaaaaaaaaaaaa
"""
def run(args = None):
import sys
import doctest
if args is not None:
sys.argv = args
return doctest.testmod(sys.modules.get(__name__))
if __name__ == '__main__':
print "running..."
import sys
sys.exit(run()[0])

23
test/tuple.cpp Normal file
View File

@ -0,0 +1,23 @@
#include <boost/python/module.hpp>
#include <boost/python/class.hpp>
#include <boost/python/tuple.hpp>
using namespace boost::python;
object convert_to_tuple(object data)
{
return tuple(data);
}
void test_operators(tuple t1, tuple t2, object print)
{
print(t1 + t2);
}
BOOST_PYTHON_MODULE_INIT(tuple_ext)
{
module("tuple_ext")
.def("convert_to_tuple",convert_to_tuple)
.def("test_operators",test_operators)
;
}

26
test/tuple.py Normal file
View File

@ -0,0 +1,26 @@
"""
>>> from tuple_ext import *
>>> def printer(*args):
... for x in args: print x,
... print
...
>>> print convert_to_tuple("this is a test string")
('t', 'h', 'i', 's', ' ', 'i', 's', ' ', 'a', ' ', 't', 'e', 's', 't', ' ', 's', 't', 'r', 'i', 'n', 'g')
>>> t1 = convert_to_tuple("this is")
>>> t2 = (1,2,3,4)
>>> test_operators(t1,t2,printer)
('t', 'h', 'i', 's', ' ', 'i', 's', 1, 2, 3, 4)
"""
def run(args = None):
import sys
import doctest
if args is not None:
sys.argv = args
return doctest.testmod(sys.modules.get(__name__))
if __name__ == '__main__':
print "running..."
import sys
sys.exit(run()[0])