From dfd85da9d791984e1b8402340721ba2bde4f0ebe Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Thu, 18 Jul 2002 15:17:08 +0000 Subject: [PATCH] str, dict, and tuple! [SVN r14517] --- Jamfile | 4 + include/boost/python/dict.hpp | 130 ++++++++++ include/boost/python/objects.hpp | 3 +- include/boost/python/objects2.hpp | 252 -------------------- include/boost/python/str.hpp | 365 ++++++++++++++++++++++++++++ include/boost/python/tuple.hpp | 47 ++++ src/dict.cpp | 172 ++++++++++++++ src/object/function.cpp | 8 +- src/objects2.cpp | 279 ---------------------- src/str.cpp | 380 ++++++++++++++++++++++++++++++ src/tuple.cpp | 20 ++ test/Jamfile | 5 + test/dict.cpp | 82 +++++++ test/dict.py | 40 ++++ test/str.cpp | 68 ++++++ test/str.py | 52 ++++ test/tuple.cpp | 23 ++ test/tuple.py | 26 ++ 18 files changed, 1419 insertions(+), 537 deletions(-) create mode 100644 include/boost/python/dict.hpp delete mode 100755 include/boost/python/objects2.hpp create mode 100644 include/boost/python/str.hpp create mode 100644 include/boost/python/tuple.hpp create mode 100644 src/dict.cpp delete mode 100755 src/objects2.cpp create mode 100644 src/str.cpp create mode 100644 src/tuple.cpp create mode 100644 test/dict.cpp create mode 100644 test/dict.py create mode 100644 test/str.cpp create mode 100644 test/str.py create mode 100644 test/tuple.cpp create mode 100644 test/tuple.py diff --git a/Jamfile b/Jamfile index 192982f6..81789b85 100644 --- a/Jamfile +++ b/Jamfile @@ -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 diff --git a/include/boost/python/dict.hpp b/include/boost/python/dict.hpp new file mode 100644 index 00000000..2f90344e --- /dev/null +++ b/include/boost/python/dict.hpp @@ -0,0 +1,130 @@ +#ifndef DICT_20020706_HPP +#define DICT_20020706_HPP + +#include +#include +#include +#include + +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 + 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 + object get(T const& k) const + { + return this->get(object(k)); + } + + BOOST_PYTHON_DECL object get(object_cref k, object_cref d) const; + + template + 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 + 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 + object setdefault(T const& k) + { + return this->setdefault(object(k)); + } + + BOOST_PYTHON_DECL object setdefault(object_cref k, object_cref d); + + template + 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 + 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 + : pytype_object_manager_traits<&PyDict_Type,dict> + { + }; +} + +}} // namespace boost::python + +#endif + diff --git a/include/boost/python/objects.hpp b/include/boost/python/objects.hpp index cab5f720..f2adb65b 100644 --- a/include/boost/python/objects.hpp +++ b/include/boost/python/objects.hpp @@ -10,8 +10,7 @@ # define OBJECTS_DWA051100_H_ # ifdef BOOST_PYTHON_V2 -# include -# include +# error obsolete # else # include # include diff --git a/include/boost/python/objects2.hpp b/include/boost/python/objects2.hpp deleted file mode 100755 index a66a422e..00000000 --- a/include/boost/python/objects2.hpp +++ /dev/null @@ -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 -# include -# include -# include "boost/operators.hpp" -# include - -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 - tuple(const std::pair& x) - : tuple_base(handle<>(PyTuple_New(2))) - { - set_item(0, x.first); - set_item(1, x.second); - } - - template - tuple(const First& first, const Second& second) - : tuple_base(handle<>(PyTuple_New(2))) - { - set_item(0, first); - set_item(1, second); - } - - template - 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 - 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 -{ - 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 - 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 - proxy operator[](const Key& key) - { return this->operator[](make_ref(key)); } - proxy operator[](handle<> key) - { return dictionary_base::operator[](key); } - - template - handle<> operator[](const Key& key) const - { return this->operator[](make_ref(key)); } - handle<> operator[](handle<> key) const - { return dictionary_base::operator[](key); } - - template - 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 - 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 - 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 - 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 diff --git a/include/boost/python/str.hpp b/include/boost/python/str.hpp new file mode 100644 index 00000000..53d7f321 --- /dev/null +++ b/include/boost/python/str.hpp @@ -0,0 +1,365 @@ +#ifndef STR_20020703_HPP +#define STR_20020703_HPP + +#include +#include +#include + +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 + 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 + str center(T const& width) const + { + return this->center(object(width)); + } + + BOOST_PYTHON_DECL long count(object_cref sub) const; + + template + long count(T const& sub) const + { + return this->count(object(sub)); + } + + BOOST_PYTHON_DECL long count(object_cref sub, object_cref start) const; + + template + 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 + 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 + str decode(T const& encoding) const + { + return this->decode(object(encoding)); + } + + BOOST_PYTHON_DECL str decode(object_cref encoding, object_cref errors) const; + + template + 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 + str encode(T const& encoding) const + { + return this->encode(object(encoding)); + } + + BOOST_PYTHON_DECL str encode(object_cref encoding, object_cref errors) const; + + template + 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 + bool endswith(T const& suffix) const + { + return this->endswith(object(suffix)); + } + + BOOST_PYTHON_DECL bool endswith(object_cref suffix, object_cref start) const; + + template + 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 + 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 + str expandtabs(T const& tabsize) const + { + return this->expandtabs(object(tabsize)); + } + + BOOST_PYTHON_DECL long find(object_cref sub) const; + + template + long find(T const& sub) const + { + return this->find(object(sub)); + } + + BOOST_PYTHON_DECL long find(object_cref sub, object_cref start) const; + + template + 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 + 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 + long index(T const& sub) const + { + return this->index(object(sub)); + } + + BOOST_PYTHON_DECL long index(object_cref sub, object_cref start) const; + + template + 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 + 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 + str join(T const& sequence) const + { + return this->join(object(sequence)); + } + + BOOST_PYTHON_DECL str ljust(object_cref width) const; + + template + 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 + 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 + 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 + long rfind(T const& sub) const + { + return this->rfind(object(sub)); + } + + BOOST_PYTHON_DECL long rfind(object_cref sub, object_cref start) const; + + template + 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 + 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 + long rindex(T const& sub) const + { + return this->rindex(object(sub)); + } + + BOOST_PYTHON_DECL long rindex(object_cref sub, object_cref start) const; + + template + 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 + 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 + 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 + list split(T const& sep) const + { + return this->split(object(sep)); + } + + BOOST_PYTHON_DECL list split(object_cref sep, object_cref maxsplit) const; + + template + 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 + list splitlines(T const& keepends) const + { + return this->splitlines(object(keepends)); + } + + BOOST_PYTHON_DECL bool startswith(object_cref prefix) const ; + + template + bool startswith(T const& prefix) const + { + return this->startswith(object(prefix)); + } + + BOOST_PYTHON_DECL bool startswith(object_cref prefix, object_cref start) const ; + + template + 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 + 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 + str translate(T const& table) const + { + return this->translate(object(table)); + } + + BOOST_PYTHON_DECL str translate(object_cref table, object_cref deletechars) const; + + template + 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 + : pytype_object_manager_traits<&PyString_Type,str> + { + }; +} + +}} // namespace boost::python + +#endif // STR_20020703_HPP diff --git a/include/boost/python/tuple.hpp b/include/boost/python/tuple.hpp new file mode 100644 index 00000000..75e2eb4a --- /dev/null +++ b/include/boost/python/tuple.hpp @@ -0,0 +1,47 @@ +#ifndef TUPLE_20020706_HPP +#define TUPLE_20020706_HPP + +#include +#include + +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 + 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 + : pytype_object_manager_traits<&PyTuple_Type,tuple> + { + }; +} + +}} // namespace boost::python + +#endif + diff --git a/src/dict.cpp b/src/dict.cpp new file mode 100644 index 00000000..c8829505 --- /dev/null +++ b/src/dict.cpp @@ -0,0 +1,172 @@ +#include +#include + +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(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 diff --git a/src/object/function.cpp b/src/object/function.cpp index 4e237e4e..4fc6a141 100644 --- a/src/object/function.cpp +++ b/src/object/function.cpp @@ -7,7 +7,7 @@ #include #include #include -#include +#include #include #include @@ -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(); } diff --git a/src/objects2.cpp b/src/objects2.cpp deleted file mode 100755 index 462535e2..00000000 --- a/src/objects2.cpp +++ /dev/null @@ -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 -#include - -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(pos)))); -} - -void tuple_base::set_item(std::size_t pos, const handle<>& rhs) -{ - int failed = PyTuple_SetItem( - get() - , static_cast(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(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(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 diff --git a/src/str.cpp b/src/str.cpp new file mode 100644 index 00000000..dd8ce0a7 --- /dev/null +++ b/src/str.cpp @@ -0,0 +1,380 @@ +#include +#include + +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(this->attr("count")(sub)); +} + +BOOST_PYTHON_DECL long str::count(object_cref sub, object_cref start) const +{ + return extract(this->attr("count")(sub,start)); +} + +BOOST_PYTHON_DECL long str::count(object_cref sub, object_cref start, object_cref end) const +{ + return extract(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 diff --git a/src/tuple.cpp b/src/tuple.cpp new file mode 100644 index 00000000..92e0df92 --- /dev/null +++ b/src/tuple.cpp @@ -0,0 +1,20 @@ +#include + +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 diff --git a/test/Jamfile b/test/Jamfile index 1a73da53..5fb0eff4 100644 --- a/test/Jamfile +++ b/test/Jamfile @@ -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 ; diff --git a/test/dict.cpp b/test/dict.cpp new file mode 100644 index 00000000..d693658c --- /dev/null +++ b/test/dict.cpp @@ -0,0 +1,82 @@ +#include +#include +#include +#include +#include + +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) + ; +} diff --git a/test/dict.py b/test/dict.py new file mode 100644 index 00000000..fdabf2c9 --- /dev/null +++ b/test/dict.py @@ -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]) diff --git a/test/str.cpp b/test/str.cpp new file mode 100644 index 00000000..d9af0478 --- /dev/null +++ b/test/str.cpp @@ -0,0 +1,68 @@ +#include +#include +#include + +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) + ; +} + diff --git a/test/str.py b/test/str.py new file mode 100644 index 00000000..666096b1 --- /dev/null +++ b/test/str.py @@ -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]) diff --git a/test/tuple.cpp b/test/tuple.cpp new file mode 100644 index 00000000..38494b76 --- /dev/null +++ b/test/tuple.cpp @@ -0,0 +1,23 @@ +#include +#include +#include + +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) + ; +} diff --git a/test/tuple.py b/test/tuple.py new file mode 100644 index 00000000..74a6e9d8 --- /dev/null +++ b/test/tuple.py @@ -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])