{"action":"created","issue":{"url":"https://api.github.com/repos/cython/cython/issues/2737","repository_url":"https://api.github.com/repos/cython/cython","labels_url":"https://api.github.com/repos/cython/cython/issues/2737/labels{/name}","comments_url":"https://api.github.com/repos/cython/cython/issues/2737/comments","events_url":"https://api.github.com/repos/cython/cython/issues/2737/events","html_url":"https://github.com/cython/cython/issues/2737","id":385107764,"node_id":"MDU6SXNzdWUzODUxMDc3NjQ=","number":2737,"title":"add custom code to tp_traverse and tp_clear?","user":{"login":"mdavidsaver","id":4429215,"node_id":"MDQ6VXNlcjQ0MjkyMTU=","avatar_url":"https://avatars2.githubusercontent.com/u/4429215?v=4","gravatar_id":"","url":"https://api.github.com/users/mdavidsaver","html_url":"https://github.com/mdavidsaver","followers_url":"https://api.github.com/users/mdavidsaver/followers","following_url":"https://api.github.com/users/mdavidsaver/following{/other_user}","gists_url":"https://api.github.com/users/mdavidsaver/gists{/gist_id}","starred_url":"https://api.github.com/users/mdavidsaver/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mdavidsaver/subscriptions","organizations_url":"https://api.github.com/users/mdavidsaver/orgs","repos_url":"https://api.github.com/users/mdavidsaver/repos","events_url":"https://api.github.com/users/mdavidsaver/events{/privacy}","received_events_url":"https://api.github.com/users/mdavidsaver/received_events","type":"User","site_admin":false},"labels":[{"id":425559948,"node_id":"MDU6TGFiZWw0MjU1NTk5NDg=","url":"https://api.github.com/repos/cython/cython/labels/Cython%20Language%20Feature","name":"Cython Language Feature","color":"444444","default":false},{"id":414805463,"node_id":"MDU6TGFiZWw0MTQ4MDU0NjM=","url":"https://api.github.com/repos/cython/cython/labels/feature","name":"feature","color":"c2e0c6","default":false}],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":1,"created_at":"2018-11-28T05:27:37Z","updated_at":"2018-12-06T19:17:41Z","closed_at":null,"author_association":"NONE","body":"I've been looking at Cython with an eye toward replacing some hand written\r\ncpython extension code binding a C++ library.  This library is for a network\r\nclient and server, and includes a number of callbacks from C++ into python code.\r\nIt also makes heavy use of std::shared_ptr.\r\n\r\nI find myself wanting the ability to add custom code to tp_traverse and tp_clear\r\nto find additional python objects referenced indirectly through c++ objects.\r\n\r\nI don't think this is presently possible?\r\n\r\nA strawman example of the situation is as follows.\r\nThe reference cycles to be broken would include.\r\n\r\nHolder.iface -> PyImpl.held -> Held -> ... -> Holder\r\n\r\n```py\r\ncdef extern from \"foo.h\":\r\n    cdef cppclass Interface:\r\n        ...\r\n        void callback() # pure virtual\r\n    cdef cppclass PyImpl(Interface):\r\n        ...\r\n        void callback() # calls held.callback()\r\n        object held\r\n\r\n    ctypedef Interface* pInterface\r\n\r\ncdef class Held:\r\n    def callback(self, arg):\r\n        pass\r\n\r\ncdef class Holder:\r\n    cdef shared_ptr[Interface] iface\r\n\r\n    # I would like to be able to do something like this:\r\n    def tp_traverse(self, visit):\r\n        cdef PyImpl* impl\r\n        if self.iface:\r\n            impl = dynamic_cast[pInterface](self.iface.get())\r\n            if impl:\r\n                visit(impl.held)\r\n```\r\n"},"comment":{"url":"https://api.github.com/repos/cython/cython/issues/comments/444995009","html_url":"https://github.com/cython/cython/issues/2737#issuecomment-444995009","issue_url":"https://api.github.com/repos/cython/cython/issues/2737","id":444995009,"node_id":"MDEyOklzc3VlQ29tbWVudDQ0NDk5NTAwOQ==","user":{"login":"mdavidsaver","id":4429215,"node_id":"MDQ6VXNlcjQ0MjkyMTU=","avatar_url":"https://avatars2.githubusercontent.com/u/4429215?v=4","gravatar_id":"","url":"https://api.github.com/users/mdavidsaver","html_url":"https://github.com/mdavidsaver","followers_url":"https://api.github.com/users/mdavidsaver/followers","following_url":"https://api.github.com/users/mdavidsaver/following{/other_user}","gists_url":"https://api.github.com/users/mdavidsaver/gists{/gist_id}","starred_url":"https://api.github.com/users/mdavidsaver/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mdavidsaver/subscriptions","organizations_url":"https://api.github.com/users/mdavidsaver/orgs","repos_url":"https://api.github.com/users/mdavidsaver/repos","events_url":"https://api.github.com/users/mdavidsaver/events{/privacy}","received_events_url":"https://api.github.com/users/mdavidsaver/received_events","type":"User","site_admin":false},"created_at":"2018-12-06T19:17:41Z","updated_at":"2018-12-06T19:17:41Z","author_association":"NONE","body":"As advertised, it is possible to replace tp_traverse.  A working example: https://github.com/mdavidsaver/cython-c--demo\r\n\r\nI found that the definition of `cpython.traverseproc` changed at some point to include \"except -1\".  In exploring ways to handle with this sort of API change I was surprised to find that eg. `IF CYTHON_HEX_VERSION>=0x001D01F0` isn't possible."}}
{"actor":{"display_login":"mdavidsaver"}}