This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Title: Support Py_tss_NEEDS_INIT outside of static initialisation
Type: enhancement Stage: patch review
Components: Extension Modules, Interpreter Core Versions: Python 3.7
Status: open Resolution:
Dependencies: Superseder:
Assigned To: Nosy List: erik.bray, masamoto, ncoghlan, scoder
Priority: normal Keywords: patch

Created on 2017-10-20 16:07 by scoder, last changed 2022-04-11 14:58 by admin.

Pull Requests
URL Status Linked Edit
PR 4060 open scoder, 2017-10-20 16:07
PR 4096 merged masamoto, 2017-10-23 21:38
Messages (4)
msg304661 - (view) Author: Stefan Behnel (scoder) * (Python committer) Date: 2017-10-20 16:07
Following up on issue 25658, it was found that the current definition of Py_tss_NEEDS_INIT restricts its use to initialisers in C and cannot be used for arbitrary assignments. It is currently declared as follows:

    #define Py_tss_NEEDS_INIT   {0}

which results in a C compiler error for assignments like "x = Py_tss_NEEDS_INIT".

I proposed to change this to

    #define Py_tss_NEEDS_INIT   ((Py_tss_t) {0})

in compliance with GCC and C99, but that fails to compile in MSVC and probably other old C++-ish compilers.

I'm not sure how to improve this declaration, but given that it's a public header file, restricting its applicability seems really unfortunate.
msg304697 - (view) Author: Nick Coghlan (ncoghlan) * (Python committer) Date: 2017-10-21 08:07
Right, the cases we were aiming to cover were:

- C variable declarations ("static Py_tss_t tss_key = Py_tss_NEEDS_INIT;")
- dynamic allocation with PyThread_tss_alloc
- resetting a key back to the uninitialised state with PyThread_tss_delete

The problem we have is that the second field in Py_tss_t is platform dependent, and not all platforms define a safe "unused" value for their NATIVE_TSS_KEY_T, which means Py_tss_NEEDS_INIT ends up being only a partial initialiser (earlier versions of the PEP used a field initialiser, but we were asked to switch it to a partial initialiser in order to support more compilers).

We *could* offer a `PyThread_tss_reset` (to reset a key back to Py_tss_NEEDS_INIT), but that's confusingly similar to PyThread_tss_delete.

Another option would be to check for typed partial initialiser support in the configure script, and declare Py_tss_NEEDS_INIT accordingly. However, that wouldn't solve the problem for any clients that are themselves also attempting to write cross-platform code.
msg304757 - (view) Author: Masayuki Yamamoto (masamoto) * Date: 2017-10-22 17:49
Or Py_tss_NEEDS_INIT is removed from the C API document to become a private feature; in other words, the Python interpreter will recommend that the static allocation for the TSS key shouldn't be used in the API client codes except for the interpreter core and built-in modules. (okay, I know it's an unfair suggestion)

BTW, it's my mistake which the word "default value" for Py_tss_NEEDS_INIT, actually it makes more sense "initializer". I'd like to fix the document and the PEP, would I open the PR with this issue?
msg304778 - (view) Author: Nick Coghlan (ncoghlan) * (Python committer) Date: 2017-10-23 03:53
For the wording fix, since it's just a trivial docs update, we can go ahead and fix it without an issue reference from the PRs.

As far as the API goes, I do want to support "static Py_tss_t my_tss_key = Py_tss_NEEDS_INIT;" in third party extension modules, which is what the current API gives us.

The question is whether there's a reasonable compiler independent way to also support struct *assignment*, in addition to initialisation.
Date User Action Args
2022-04-11 14:58:53adminsetgithub: 76009
2017-10-26 15:52:49erik.braysetnosy: + erik.bray
2017-10-23 21:38:03masamotosetkeywords: + patch
stage: patch review
pull_requests: + pull_request4067
2017-10-23 03:53:17ncoghlansetmessages: + msg304778
2017-10-22 17:49:38masamotosetmessages: + msg304757
2017-10-21 08:07:56ncoghlansetmessages: + msg304697
2017-10-20 16:07:56scodercreate