PyObject* NodeProxy::getAttr(std::string name) { Datum* datum = node->getDatum(QString::fromStdString(name)); if (!datum) throw proxy::ProxyException("Nonexistent datum lookup."); // If we have a known caller, then mark that this datum is an upstream node // for the caller. if (caller) { // Try to connect this datum as an upstream datum of the caller if (!caller->connectUpstream(datum)) throw proxy::ProxyException("Recursive loop in lookup."); // Also connect the node's name as an upstream datum // (since if the name changes, the expression may become invalid) Q_ASSERT(dynamic_cast<Node*>(datum->parent())); Node* n = static_cast<Node*>(datum->parent()); auto name = n->getDatum("__name"); Q_ASSERT(name); caller->connectUpstream(name); } if (!datum->getValid()) throw proxy::ProxyException("Invalid datum lookup."); PyObject* value = datum->getValue(); Py_INCREF(value); return value; }