-
Notifications
You must be signed in to change notification settings - Fork 851
Expand file tree
/
Copy pathPyIBase.cpp
More file actions
89 lines (76 loc) · 2.68 KB
/
PyIBase.cpp
File metadata and controls
89 lines (76 loc) · 2.68 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
#include "stdafx.h"
#include "PythonCOM.h"
static PyComTypeObject type("PyIBase", NULL, sizeof(PyIBase), NULL, NULL);
PyIBase::PyIBase()
{
// ob_type will be overridden to the real type once the subclasses
// constructor body runs, however, _Py_NewReference() sometimes wants
// ob_type to be valid (particularly when tracemalloc is enabled!)
ob_type = &type;
_Py_NewReference(this);
}
PyIBase::~PyIBase() {}
/*static*/ BOOL PyIBase::is_object(PyObject *ob, PyComTypeObject *which)
{
return PyObject_IsInstance(ob, (PyObject *)which);
}
BOOL PyIBase::is_object(PyComTypeObject *which) { return is_object(this, which); }
/*static*/ PyObject *PyIBase::getattro(PyObject *self, PyObject *name)
{
// Using PyObject_GenericGetAttr allows some special type magic
// (ie,
return PyObject_GenericGetAttr(self, name);
}
PyObject *PyIBase::getattr(char *name) { return PyObject_GetAttrString(this, name); }
/*static*/ int PyIBase::setattro(PyObject *op, PyObject *obname, PyObject *v)
{
const char *name = PyUnicode_AsUTF8(obname);
if (name == NULL)
return -1;
PyIBase *bc = (PyIBase *)op;
return bc->setattr(name, v);
}
int PyIBase::setattr(const char *name, PyObject *v)
{
char buf[128];
sprintf(buf, "%s has read-only attributes", ob_type->tp_name);
PyErr_SetString(PyExc_TypeError, buf);
return -1;
}
/*static*/ PyObject *PyIBase::repr(PyObject *ob) { return ((PyIBase *)ob)->repr(); }
PyObject *PyIBase::repr()
{
TCHAR buf[80];
wsprintf(buf, _T("<%hs at %p>"), ob_type->tp_name, (PyObject *)this);
return PyWinCoreString_FromString(buf);
}
/*static*/ void PyIBase::dealloc(PyObject *ob) { delete (PyIBase *)ob; }
/*static*/ int PyIBase::cmp(PyObject *ob1, PyObject *ob2) { return ((PyIBase *)ob1)->compare(ob2); }
/*static*/ PyObject *PyIBase::richcmp(PyObject *ob1, PyObject *ob2, int op)
{
// our 'compare' implementations don't assume ob2 is our type, so
// no additional checks are needed.
int c = cmp(ob1, ob2);
// BUT - it doesn't propogate exceptions correctly.
if (c == -1 && PyErr_Occurred()) {
// if the error related to the type of the object,
// rich-compare wants Py_NotImplemented returned.
if (PyErr_ExceptionMatches(PyExc_TypeError)) {
PyErr_Clear();
Py_INCREF(Py_NotImplemented);
return Py_NotImplemented;
}
return NULL;
}
assert(!PyErr_Occurred()); // should always have returned -1 on error.
BOOL ret;
if (op == Py_EQ)
ret = c == 0;
else if (op == Py_NE)
ret = c != 0;
else {
Py_INCREF(Py_NotImplemented);
return Py_NotImplemented;
}
return PyBool_FromLong(ret);
}