Added extract_traceback function

Create a C++ traceback from a boost::python object. Refactored get_exception_info() to return a struct of boost::python::objects instead of a tuple with magic knowledge in it. Also refactored and modularized tests some more.
By making them const, we know (in any sane use case) that they can't change. More importantly, so does the compiler, so it can optimize with that in mind. I'm not arguing that it's a huge performance gain or anything, but given that we have no reason to expect the users to ever want to change them, it's the deciding factor for the issue.

Likewise, from an API perspective, it's much easier to add mutability later than it is to take it away. Just like taking functions away from a public API is difficult. So if users *do* complain about wanting to modify these things, we can consider it. But I consider that utterly unlikely.

In my experience, mutability should be treated just as cautiously as any other element of the language that the client will see. If you don't have a good reason to make something mutable, generally you shouldn't. This is where languages like clojure and rust get it right, in my opinion.

Ultimately I think it's just good hygiene. Fewer moving parts means lower complexity, and managing complexity is at the heart of writing good software.