@@ -62,9 +62,30 @@ object CCachedProperty::_callable_check(object function, const char *szName)
6262
6363object CCachedProperty::_prepare_value (object value)
6464{
65- if (PyGen_Check (value.ptr ()))
66- value = object (CCachedGenerator (value));
67- return value;
65+ if (!PyGen_Check (value.ptr ()))
66+ return value;
67+
68+ if (getattr (value, " gi_frame" ).is_none ())
69+ BOOST_RAISE_EXCEPTION (
70+ PyExc_ValueError,
71+ " The given generator is exhausted."
72+ );
73+
74+ list values;
75+ while (true )
76+ {
77+ try
78+ {
79+ values.append (value.attr (" __next__" )());
80+ }
81+ catch (...)
82+ {
83+ PyErr_Clear ();
84+ break ;
85+ }
86+ }
87+
88+ return values;
6889}
6990
7091
@@ -76,7 +97,7 @@ object CCachedProperty::get_getter()
7697object CCachedProperty::set_getter (object fget)
7798{
7899 m_fget = _callable_check (fget, " getter" );
79- return object ( ptr ( this )) ;
100+ return fget ;
80101}
81102
82103
@@ -88,7 +109,7 @@ object CCachedProperty::get_setter()
88109object CCachedProperty::set_setter (object fset)
89110{
90111 m_fset = _callable_check (fset, " setter" );
91- return object ( ptr ( this )) ;
112+ return fset ;
92113}
93114
94115
@@ -100,7 +121,7 @@ object CCachedProperty::get_deleter()
100121object CCachedProperty::set_deleter (object fdel)
101122{
102123 m_fdel = _callable_check (fdel, " deleter" );
103- return object ( ptr ( this )) ;
124+ return fdel ;
104125}
105126
106127
@@ -121,44 +142,43 @@ void CCachedProperty::__set_name__(object owner, str name)
121142 m_name = name;
122143}
123144
124-
125145object CCachedProperty::__get__ (object instance, object owner=object())
126146{
127147 if (instance.is_none ())
128148 return object (ptr (this ));
129149
130- if (! m_name)
150+ if (m_name. is_none () )
131151 BOOST_RAISE_EXCEPTION (
132152 PyExc_AttributeError,
133153 " Unable to retrieve the value of an unbound property."
134154 );
135155
136- PyObject *pCache = PyObject_GetAttrString (instance.ptr (), " __dict__" );
156+ object cache = extract<dict> (instance.attr ( " __dict__" ) );
137157
138- if (!PyDict_Check (pCache))
139- BOOST_RAISE_EXCEPTION (
140- PyExc_ValueError,
141- " Cache dictionary is invalid."
142- );
143-
144- Py_DECREF (pCache);
145- PyObject *pValue = PyDict_GetItemString (pCache, extract<const char *>(m_name));
146- if (pValue)
147- return object (handle<>(borrowed (pValue)));
148-
149- if (m_fget.is_none ())
150- BOOST_RAISE_EXCEPTION (
151- PyExc_AttributeError,
152- " Unable to retrieve the value of a property that have no getter function."
158+ try
159+ {
160+ return cache[m_name];
161+ }
162+ catch (...)
163+ {
164+ if (!PyErr_ExceptionMatches (PyExc_KeyError))
165+ throw_error_already_set ();
166+
167+ PyErr_Clear ();
168+
169+ if (m_fget.is_none ())
170+ BOOST_RAISE_EXCEPTION (
171+ PyExc_AttributeError,
172+ " Unable to retrieve the value of a property that have no getter function."
173+ );
174+
175+ cache[m_name] = _prepare_value (
176+ m_fget (
177+ *(make_tuple (handle<>(borrowed (instance.ptr ()))) + m_args),
178+ **m_kwargs
179+ )
153180 );
154-
155- dict cache = extract<dict>(pCache);
156- cache[m_name] = _prepare_value (
157- m_fget (
158- *(make_tuple (handle<>(borrowed (instance.ptr ()))) + m_args),
159- **m_kwargs
160- )
161- );
181+ }
162182
163183 return cache[m_name];
164184}
@@ -181,7 +201,7 @@ void CCachedProperty::__set__(object instance, object value)
181201 if (!result.is_none ())
182202 cache[m_name] = _prepare_value (result);
183203 else
184- PyDict_DelItemString ( cache. ptr (), extract< const char *>(m_name) );
204+ cache[m_name]. del ( );
185205}
186206
187207void CCachedProperty::__delete__ (object instance)
@@ -193,7 +213,13 @@ void CCachedProperty::__delete__(object instance)
193213 );
194214
195215 dict cache = extract<dict>(instance.attr (" __dict__" ));
196- PyDict_DelItemString (cache.ptr (), extract<const char *>(m_name));
216+ cache[m_name].del ();
217+ }
218+
219+ object CCachedProperty::__call__ (object fget)
220+ {
221+ m_fget = _callable_check (fget, " getter" );
222+ return object (ptr (this ));
197223}
198224
199225object CCachedProperty::__getitem__ (str item)
@@ -218,49 +244,3 @@ CCachedProperty *CCachedProperty::wrap_descriptor(object descriptor, object owne
218244
219245 return pProperty;
220246}
221-
222-
223- // -----------------------------------------------------------------------------
224- // CCachedGenerator class.
225- // -----------------------------------------------------------------------------
226- CCachedGenerator::CCachedGenerator (object generator)
227- {
228- if (!PyGen_Check (generator.ptr ()))
229- BOOST_RAISE_EXCEPTION (
230- PyExc_TypeError,
231- " The given generator is invalid."
232- );
233-
234- object frame = generator.attr (" gi_frame" );
235- if (frame.is_none ())
236- BOOST_RAISE_EXCEPTION (
237- PyExc_ValueError,
238- " The given generator is exhausted."
239- );
240-
241- m_generator = generator;
242- }
243-
244-
245- object CCachedGenerator::get_generator ()
246- {
247- return m_generator;
248- }
249-
250-
251- object CCachedGenerator::__iter__ ()
252- {
253- while (!m_generator.is_none ())
254- {
255- try
256- {
257- m_generated_values.append (m_generator.attr (" __next__" )());
258- }
259- catch (...)
260- {
261- m_generator = object ();
262- PyErr_Clear ();
263- }
264- }
265- return m_generated_values.attr (" __iter__" )();
266- }
0 commit comments