에서 최종 클래스 생성자를 호출 : 난 그냥 추가 한다음과 같이 내가 예외 클래스가 기본 클래스
class ExtensionExceptionType;
class Object;
class Exception
{
public:
explicit Exception() { }
Exception( const std::string &reason) { PyErr_SetString(_Exc_RuntimeError(), reason.c_str()); }
Exception(PyObject* exception, const std::string &reason) { PyErr_SetString(exception, reason.c_str()); }
Exception(PyObject* exception, Object& reason);
Exception(ExtensionExceptionType& exception, const std::string& reason);
Exception(ExtensionExceptionType& exception, Object& reason);
void clear() { PyErr_Clear(); } // clear the error -- technically but not philosophically const
static Object err_type();
static Object err_value();
static Object err_trace();
static Object err_stats(uint32_t i); // 0 1 2 for {type, value, trace}
static void wrap(int condition) {
if(condition == -1)
throw Exception{};
}
};
// Abstract
class StandardError : public Exception { protected: explicit StandardError() {} };
class LookupError : public StandardError { protected: explicit LookupError() {} };
class ArithmeticError : public StandardError { protected: explicit ArithmeticError() {} };
class EnvironmentError : public StandardError { protected: explicit EnvironmentError() {} };
// Concrete (π)
// e.g.
// class TypeError: public StandardError
// {
// public:
// TypeError (const std::string& reason)
// : StandardError()
// {
// PyErr_SetString(Py::_Exc_TypeError(),reason.c_str());
// }
// };
#define CONCRETE(CLASS, BASE) \
class CLASS: public BASE \
{ \
public: \
CLASS (const std::string& reason) \
{ \
std::cout << "(Exception.hxx) " #CLASS " from PyCXX (" << reason.c_str() << ") \n"; \
PyErr_SetString(_Exc_##CLASS(), reason.c_str()); \
} \
};
// it appears that these classes are only for manually RAISING Python errors
// i.e. Raising an exception in the Python runtime
// because if I type something in to the Python console, I can make (e.g.) a KeyError occur, but these classes don't get hit.
CONCRETE(TypeError, StandardError )
CONCRETE(IndexError, LookupError )
CONCRETE(AttributeError, StandardError )
CONCRETE(NameError, StandardError )
CONCRETE(RuntimeError, StandardError )
CONCRETE(NotImplementedError, StandardError )
CONCRETE(SystemError, StandardError )
CONCRETE(KeyError, LookupError )
CONCRETE(ValueError, StandardError )
CONCRETE(OverflowError, ArithmeticError)
CONCRETE(ZeroDivisionError, ArithmeticError)
CONCRETE(FloatingPointError, ArithmeticError)
CONCRETE(MemoryError, StandardError )
CONCRETE(SystemExit, StandardError )
:
static void wrap(int condition) {
if(condition == -1)
throw Exception{};
}
을 다른 곳에서의 많은 경우가 있었기 때문에 ... ..
:.들로 정돈 된if(SomePythonFunc(...) == -1) throw Exception{};
... 의도하지만
Exception.wrap(SomePythonFunc(...)); // much nicer, I think
,이 경우 :
if(SomePythonFunc(...) == -1) throw TypeError{ "foo" };
... 내가 동등한 포장을 수행하는 방법을 볼 수 없습니다.
즉, 쓰기 :
TypeError.wrap(SomePythonFunc(...), "foo");
형식 오류로 : 예외 및 예외 :: 랩 공개, 난 그냥 랩에 대한 선택적인 두 번째 매개 변수를 만들 수 있습니다
static void wrap(int condition, string err="default-err") {
if(condition == -1)
throw FinalClassConstructor{ err }; // <-- how to do this?
}
을 ...하지만 어떻게 :: 랩이 막 히트 된 최종 클래스의 생성자를 호출합니까?