Issue 20456: Argument Clinic rollup patch, 2014/01/31 (original) (raw)
Probably the last rollup patch for a while; I need to move on to code reviewing.
Here's a list of changes in this patch:
I added the oft-requested "rename the C variable for a parameter" functionality. That works as follows:
os.rename path as stinky: path_t Here the Python name is "path", and the C name is "stinky". Internally the "name" of the parameter is the Python name, and the "name" of the converter is the C name. (But the converter gets the Python name too, because it needs it sometimes, e.g. for the keywords array.)
Fixed a minor but difficult-to-fix problem: when cloning a function, the cloned function would still refer to the original function's name. (You can see this in the PATH_T_INITIALIZE macros in os_replace in posixmodule.c.)
While fixing the above I stumbled over a new problem: rendering often changes internal state of a parameter, which could cause problems if we clone an already-rendered parameter object. The solution: make a copy of all the Parameter objects before rendering, then render from the copies.
Fixing the above forced me to add a new initalizer to CConverter objects: pre_render(), which is called just before rendering.
This change also means it's pretty important to call up to the super() for converter_init() and pre_render().
Fixing the above also required new semantics for converter_init(): you are no longer permitted to examine the function object in that method. (I made it fail noisily with a "LandMine".)
"clinic.py --converters" was broken, I fixed it. (It was confused by object_converter having format_unit=None.)
I fixed the unit tests too.
You can now specify blank lines between directives without Clinic getting angry at you.
I redid how I store all those little C code snippet template. Originally they were inline, but flush left, and that made reading them tiresome--the indent was jumping around on you. Changing to a central list removed the jumping around but now you had to scroll back and forth to correlate the template with where it was used. The final solution: have them inline again, but indented, and simply outdent the text before use. Go ahead, tell me that's not an improvement. :D (The outdenting function uses functools.lru_cache, so processing is really no slower.)
And last but certainly not least...!
Following a suggestion by Serhiy Storchaka, Argument Clinic is now incredibly sophisticated with respect to #if'd out code. In less than 200 lines, I wrote a reasonable C preprocessor monitor class. The monitor parses C files in parallel to Argument Clinic. At any time you can ask the monitor "what's the current preprocessor conditional state?" If the current code is potentially if'd out, Argument Clinic uses the same conditional to potentially #if out the parser function, the docstring, etc, when writing those to buffer or file. It even adds this to the end:
#ifndef YOUR_FUNCTION_METHODDEF #define YOUR_FUNCTION_METHODDEF #endif /* !defined(YOUR_FUNCTION_METHODDEF) */
But only when necessary.
You can see this in action in the diff for Modules/clinic/zlibmodule.c.h.
I think this is a huge improvement! (Thanks for the suggestion, Serhiy!)
Updated the patch.
The "methoddef_ifndef" template is now sent to the "buffer" destination by default. I expected posixmodule to have an #ifndef, I was surprised to find _import had one too. Both files touched to move the buffer to an appropriate spot.
Fixed the "original" "preset" so it explicitly sets all three new templates just like the actual default.
Forgot a minor fix that was in revision 1: when generating the docstring for a function using optional groups, suppress the "self/type/module" first argument in the signature. (The signature isn't parsable by inspect.Signature, so we go ahead and insert something user-readable like the docstrings before Argument Clinic used to do.)
Changed _dbm.dbm.get to no longer use optional groups. Why was it doing that in the first place? There's now exactly one function checked in using optional groups, curses.window.addch.