-
Notifications
You must be signed in to change notification settings - Fork 0
/
notes.txt
231 lines (185 loc) · 8.11 KB
/
notes.txt
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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
Questions:
1. sequences (tuples and lists) are empty (full of NULL values)
on creation. On return to Python, nothing is done to check
whether a sequence has NULL values in it. NULL values in
Python will cause problems. An alternative is to fill created
sequences with PyNone. This is slower, but maybe safer. I
believe this is what CXX does. I need to ask others what they
think about this.
2. operator[] presents the biggest problems for C++ Python library
as far as I can tell. The problem is we need a different function
called in the following two cases:
dict_obj["a"] = 1;
obj = dict_obj["a"];
In the first case, no KeyError should be thrown. In the 2nd,
the KeyError should be thrown. Unfortunately, this is not
possible with simple C++. It may be possible with template
expressions, but we aren't using those. So, for now, we will
have to deal with KeyErrors not occurring on the RHS of equations.
A secondary option here is to have a second argument have a
special function for RHS access to values. This is likely
what we will do in auto generated code.
In the case that IndexErrors occur, these should always be
thrown.
For release:
1. Change return_val to be an py::object. This will get rid of
of the need to handle incref/decref on your own most of the time.
DONE
2. Flesh out object to handle all types of values in a generic way:
a. sequence access.
DONE
b. casting from/to standard types
int, float, double, std::complex, char*, std::string.
DONE
c. attr should return a reference? Not sure about this.
I DONT THINK SO
3. Tests that always thrown exceptions aren't getting cataloged.
This isn't a big deal in practice, but it needs to be cleaned up.
4. Test file conversion for ref counts
5. Examine all examples and make sure they make sense (and work).
6. Add iter() and next() to objects.
7. check comparisons
DONE.
8. clean up dict objects.
DONE.
9. test dict object.
DONE
9. test get_item_operator for object, list, tuples, dicts.
DONE -- but I don't really like the operator[] behavior.
base package
scipy_base
scipy_distutils
scipy_test
gui_thread
scipy
weave
chaco
weave
Note on ref counts:
There is some ref count strangness in inline() *if it is called from
a function*. When called from the command line, the ref counts behave
correctly. When called from a function, the first call to a
inline() causes the ref count goes up an extra count. However,
subsequent calls don't cause any further refcount increases. Checks
put in py::object creation and destruction look like the C++ code is
not losing a ref count. I'm thinking that some of the stack frame
limbo played in inline() might be to blame??? Anyway, this needs
further investigation. I'm not sure if the issue is leading to leaks
or not.
Proposed changes to weave:
* change return_val to a py::object
This could remove almost all of the need of handling PyObject*.
* document changes.
* review directory structure.
* outline method of aggregating functions into a single file.
EVERYTHING BELOW HERE IS DONE.
* all classes moved to py:: namespace
* made tuples mutable with indexing notation. (handy in weave)
* converted camel case names (setItem -> set_item)
* change class names to reflect boost like names and put each
exposed class in its own header file.
PWOBase -> py::object -- object.h
PWOList -> py::list -- list.h
PWOTuple -> py::tuple -- tuple.h
PWOMapping -> py::dict -- dict.h
PWOCallable -> py::callable -- callable.h
PWOString -> py::str -- str.h
PWONumber -> py::number -- number.h
py::object public methods:
int print(FILE *f, int flags) const DONE
bool hasattr(const char* nm) const DONE
py::object_attr attr(const char* nm) const
py::object_attr attr(const py::object& nm) const
??
int set_attr(const char* nm, py::object& val)
int set_attr(PyObject* nm, py::object& val)
int del(const char* nm)
int del(const py::object& nm)
int cmp(const py::object& other) const
bool operator == (const py::object& other) const
bool operator != (const py::object& other) const
bool operator > (const py::object& other) const
bool operator < (const py::object& other) const
bool operator >= (const py::object& other) const
bool operator <= (const py::object& other) const
PyObject* repr() const
/*PyObject* str() const*/ // conflicts with class named str
PyObject* type() const
int hash() const
bool is_true() const
bool is_callable() const
PyObject* disown()
py::sequence public methods:
PWOSequence operator+(const PWOSequence& rhs) const
//count
int count(const py::object& value) const
int count(int value) const;
int count(double value) const;
int count(char* value) const;
int count(std::string value) const;
py::object operator [] (int i) const
py::sequence get_slice(int lo, int hi) const
bool in(const py::object& value) const
bool in(int value);
bool in(double value);
bool in(char* value);
bool in(std::string value);
int index(const py::object& value) const
int index(int value) const;
int index(double value) const;
int index(char* value) const;
int index(std::string value) const;
int len() const
int length() const // compatible with std::string
py::sequence operator * (int count) const //repeat
class py::tuple
void set_item(int ndx, py::object& val)
void set_item(int ndx, int val)
void set_item(int ndx, double val)
void set_item(int ndx, char* val)
void set_item(int ndx, std::string val)
// make tuples mutable like lists
// much easier to set up call lists, etc.
py::tuple_member operator [] (int i)
class py::list
bool del(int i)
bool del(int lo, int hi)
py::list_member operator [] (int i)
void set_item(int ndx, py::object& val)
void set_item(int ndx, int val)
void set_item(int ndx, double val)
void set_item(int ndx, char* val)
void set_item(int ndx, std::string val)
void set_slice(int lo, int hi, const py::sequence& slice)
py::list& append(const py::object& other)
py::list& append(int other)
py::list& append(double other)
py::list& append(char* other)
py::list& append(std::string other)
py::list& insert(int ndx, py::object& other)
py::list& insert(int ndx, int other);
py::list& insert(int ndx, double other);
py::list& insert(int ndx, char* other);
py::list& insert(int ndx, std::string other);
py::list& reverse()
py::list& sort()
class py::dict
py::dict_member operator [] (const char* key)
py::dict_member operator [] (std::string key)
py::dict_member operator [] (PyObject* key)
py::dict_member operator [] (int key)
py::dict_member operator [] (double key)
bool has_key(PyObject* key) const
bool has_key(const char* key) const
// needs int, std::string, and double versions
int len() const
int length() const
void set_item(const char* key, PyObject* val)
void set_item(PyObject* key, PyObject* val) const
// need int, std::string and double versions
void clear()
void del(PyObject* key)
void del(const char* key)
// need int, std::string, and double versions
py::list items() const
py::list keys() const