<div dir="ltr"><div class="gmail_quote"><div dir="ltr">[Radim Řehůřek <<a href="mailto:radim@rare-technologies.com">radim@rare-technologies.com</a>>]</div><div dir="ltr"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">one of our Python projects calls for pretty heavy, low-level optimizations.</blockquote></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div><br></div><div>We went down the rabbit hole and determined that having access to PyList_GET_ITEM(list), PyInt_AS_LONG(int) and PyDict_GetItem(dict, unicode) on Python objects **outside of GIL** might be a good-enough solution. The Python objects in question are guaranteed to live and not be mutated externally in any way. They're "frozen" and read-only.</div><div><br></div><div>Under what conditions is it OK to call these 3 functions on such objects?</div></div></blockquote><div><br>          <span>From the "initialization, Finalization, and Threads" section of the Python/C API Reference Manual:<br><br></span><div class="gmail-document"><div class="gmail-documentwrapper"><div class="gmail-body"><div class="gmail-section" id="gmail-initialization-finalization-and-threads"><div class="gmail-section" id="gmail-thread-state-and-the-global-interpreter-lock"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Therefore, the rule exists that only the thread that has acquired the <a class="gmail-reference gmail-internal"><span class="gmail-xref gmail-std gmail-std-term">GIL</span></a> may operate on Python objects or call Python/C API functions.</blockquote></div></div></div></div></div><br>Under protection of the GIL is the only documented - or intended - way to do anything with Python objects, or to call virtually any Python/C API function.</div><div><br> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div></div><div>More generally, what is the CPython 2.7/3.5 contract regarding (lack of) object mutation, and the need for reference counting and synchronization via GIL?</div></div></blockquote><div><br>There is no intention to support GIL-free access to any Python objects.  So that's the contract:  "All warranties are null & void if you do just about anything while not holding the GIL".<br> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div>Which C API functions are safe to call on "const" objects?</div></div></blockquote><div><br>None.  If you find some combinations of CPython versions, functions, and objects, that happen to work, that's fine, but there's no guarantee they'll continue to work, not even across maintenance releases.  Although they'll _probably_ continue to work.<br><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div>Obviously releasing GIL and then calling C API is hacky, but from initial experiments, it seems to work (see <a href="https://stackoverflow.com/questions/51351609/can-i-const-access-cpython-objects-without-gil" target="_blank">https://stackoverflow.com/questions/51351609/can-i-const-access-cpython-objects-without-gil</a>). But I'm wondering if there's a more formal contract around this behaviour.</div></div></blockquote><div><br>Nope!  You're on your own here.<br><br>Which doesn't mean you can't do it.  Just that if things blow up, you're still on your own - since you're far outside what the documentation says is required (which I suspect you knew before you asked ;-) ), the project won't even accept a bug report.<br><br>If you want more help trying to guess which functions _may_ work outside the law, that's fine too, but "python-dev" (this mailing list) is for development _of_ Python itself, not for questions about _using_ Python.  The more general python-list would be more appropriate.  But, since you're trying to use the C API in unsupported ways it wasn't intended to be used, you'll likely have a hard time finding people with significant experience doing the same thing.  Since it's not at all an intended use, there are no "general principles" at work to ease the pain of staring at the CPython source code to try to guess what might go wrong across all code paths.</div></div></div>