Update of /cvsroot/boost/boost/libs/python/example/quickstart
In directory sc8-pr-cvs3.sourceforge.net:/tmp/cvs-serv15408/example/quickstart

Added Files:
      Tag: RC_1_34_0
        test_extending.py script.py extending.cpp embedding.cpp 
        boost-build.jam Jamroot 
Log Message:
Updated build-and-test howto


--- NEW FILE: test_extending.py ---
# Copyright Ralf W. Grosse-Kunstleve 2006. Distributed under the Boost
# Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

# Using the doctest module here to ensure that the results are as expected.
r'''>>> from extending import *
    >>> hi = hello('California')
    >>> hi.greet()
    'Hello from California'
    >>> invite(hi)
    'Hello from California! Please come soon!'
    >>> hi.invite()
    'Hello from California! Please come soon!'

    >>> class wordy(hello):
    ...     def greet(self):
    ...         return hello.greet(self) + ', where the weather is fine'
    ...
    >>> hi2 = wordy('Florida')
    >>> hi2.greet()
    'Hello from Florida, where the weather is fine'
    >>> invite(hi2)
    'Hello from Florida! Please come soon!'
'''

def run(args = None):
    if args is not None:
        import sys
        sys.argv = args
    import doctest, test_extending
    return doctest.testmod(test_extending, verbose=True)

if __name__ == '__main__':
    import sys
    sys.exit(run()[0])


--- NEW FILE: script.py ---
# Copyright Stefan Seefeld 2006. Distributed under the Boost
# Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

print 'Hello World !'
number = 42

--- NEW FILE: extending.cpp ---
// Copyright Ralf W. Grosse-Kunstleve 2002-2004. Distributed under the Boost
// Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

#include <boost/python/class.hpp>
#include <boost/python/module.hpp>
#include <boost/python/def.hpp>
#include <iostream>
#include <string>

namespace { // Avoid cluttering the global namespace.

  // A friendly class.
  class hello
  {
    public:
      hello(const std::string& country) { this->country = country; }
      std::string greet() const { return "Hello from " + country; }
    private:
      std::string country;
  };

  // A function taking a hello object as an argument.
  std::string invite(const hello& w) {
    return w.greet() + "! Please come soon!";
  }
}

BOOST_PYTHON_MODULE(extending)
{
    using namespace boost::python;
    class_<hello>("hello", init<std::string>())
        // Add a regular member function.
        .def("greet", &hello::greet)
        // Add invite() as a member of hello!
        .def("invite", invite)
        ;
    
    // Also add invite() as a regular function to the module.
    def("invite", invite);
}

--- NEW FILE: embedding.cpp ---
// Copyright Stefan Seefeld 2005.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)

#include <boost/python.hpp>

#include <boost/detail/lightweight_test.hpp>
#include <iostream>

namespace python = boost::python;

// An abstract base class
class Base : public boost::noncopyable
{
public:
  virtual ~Base() {};
  virtual std::string hello() = 0;
};

// C++ derived class
class CppDerived : public Base
{
public:
  virtual ~CppDerived() {}
  virtual std::string hello() { return "Hello from C++!";}
};

// Familiar Boost.Python wrapper class for Base
struct BaseWrap : Base, python::wrapper<Base>
{
  virtual std::string hello() 
  {
#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
    // workaround for VC++ 6.x or 7.0, see
    // 
http://boost.org/libs/python/doc/tutorial/doc/html/python/exposing.html#python.class_virtual_functions
    return python::call<std::string>(this->get_override("hello").ptr());
#else
    return this->get_override("hello")();
#endif
  }
};

// Pack the Base class wrapper into a module
BOOST_PYTHON_MODULE(embedded_hello)
{
  python::class_<BaseWrap, boost::noncopyable> base("Base");
}


void exec_test()
{
    std::cout << "registering extension module embedded_hello..." << std::endl;
    
  // Register the module with the interpreter
  if (PyImport_AppendInittab("embedded_hello", initembedded_hello) == -1)
    throw std::runtime_error("Failed to add embedded_hello to the interpreter's 
"
                 "builtin modules");

  std::cout << "defining Python class derived from Base..." << std::endl;
  
  // Retrieve the main module
  python::object main = python::import("__main__");
  
  // Retrieve the main module's namespace
  python::object global(main.attr("__dict__"));

  // Define the derived class in Python.
  python::object result = python::exec(
    "from embedded_hello import *        \n"
    "class PythonDerived(Base):          \n"
    "    def hello(self):                \n"
    "        return 'Hello from Python!' \n",
    global, global);

  python::object PythonDerived = global["PythonDerived"];

  // Creating and using instances of the C++ class is as easy as always.
  CppDerived cpp;
  BOOST_TEST(cpp.hello() == "Hello from C++!");

  std::cout << "testing derived class from C++..." << std::endl;
  
  // But now creating and using instances of the Python class is almost
  // as easy!
  python::object py_base = PythonDerived();
  Base& py = python::extract<Base&>(py_base) BOOST_EXTRACT_WORKAROUND;

  // Make sure the right 'hello' method is called.
  BOOST_TEST(py.hello() == "Hello from Python!");

  std::cout << "success!" << std::endl;
}

void exec_file_test(std::string const &script)
{
    std::cout << "running file " << script << "..." << std::endl;
    
    // Run a python script in an empty environment.
    python::dict global;
    python::object result = python::exec_file(script.c_str(), global, global);

    // Extract an object the script stored in the global dictionary.
    BOOST_TEST(python::extract<int>(global["number"]) ==  42);
    
    std::cout << "success!" << std::endl;
}

void exec_test_error()
{
    std::cout << "intentionally causing a python exception..." << std::endl;
    
    // Execute a statement that raises a python exception.
    python::dict global;
    python::object result = python::exec("print unknown \n", global, global);

    std::cout << "Oops! This statement should be skipped due to an exception" 
<< std::endl;
}

int main(int argc, char **argv)
{
  BOOST_TEST(argc == 2);
  std::string script = argv[1];
  // Initialize the interpreter
  Py_Initialize();

  bool error_expected = false;
  
  if (
      python::handle_exception(exec_test)
      || python::handle_exception(boost::bind(exec_file_test, script))
      || (
          (error_expected = true)
          && python::handle_exception(exec_test_error)
      )

  )
  {
    if (PyErr_Occurred())
    {
        if (!error_expected)
            BOOST_ERROR("Python Error detected");
        PyErr_Print();
    }
    else
    {
        BOOST_ERROR("A C++ exception was thrown  for which "
                    "there was no exception translator registered.");
    }
  }
  
  // Boost.Python doesn't support Py_Finalize yet, so don't call it!
  return boost::report_errors();
}

--- NEW FILE: boost-build.jam ---
# Copyright David Abrahams 2006. Distributed under the Boost
# Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

# Edit this path to point at the tools/build/v2 subdirectory of your
# Boost installation.  Absolute paths work, too.
boost-build ../../../../tools/build/v2 ;

--- NEW FILE: Jamroot ---
# Copyright David Abrahams 2006. Distributed under the Boost
# Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

# Specify the path to the Boost project.  If you move this project,
# adjust the path to refer to the Boost root directory.
use-project boost 
  : ../../../.. ;

# Set up the project-wide requirements that everything uses the
# boost_python library defined in the project whose global ID is
# /boost/python.
project
  : requirements <library>/boost/python//boost_python ;

# Declare a Python extension called hello.
python-extension extending : extending.cpp ;

# Declare an executable called embedding that embeds Python
exe embedding : embedding.cpp /python//python ;

import testing ;

# Declare a test of the extension module
testing.make-test run-pyd : extending test_extending.py : : test_ext ;

# Declare a test of the embedding application
testing.run embedding 
  :              # any ordinary arguments
  : script.py    # any arguments that should be treated as relative paths
  :              # requirements
  : test_embed ; # name of test



-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
_______________________________________________
Boost-cvs mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/boost-cvs

Reply via email to