CPython style conventions

Let me say firstly I’m not suggesting to rewrite all the CPython code…

I see that in CPython code there’s a prevalent style:

1: type *var vs type* var
2: function\n{ vs function {
3: type var; [later] var = 0; vs type var = 0;
4: if (something) single_line; vs if (something) {single_line};
5: gotos

Apart the first, the other conventions seems to me a little “unpythonic”. Well, yes, you can say… it’s C! But I think also the CPython code could follow a PEP 8-like style.
About goto, sometime is inevitable, but I found that many times can be removed without speed problems.

Do you mean something like PEP 7?

3 Likes

Yes :smiley:

Okay, #3 and #4 are explained. I continue to have some perplexity about the others and, after reading PEP 7, some other:

  1. “No line should end in whitespace”. Why? I find it really useful, especially when I’m breaking a long line, then I find that I do not need breaking and I de-break it.

  2. “Breaking long lines”. I usually break them (conditionals apart, in every language) this way, for example:

function(
    param1, 
    param2, 
    [...]
    paramN, 
);

type *var vs type* var

This is likely to avoid mistakes like PyObject* x, y, z;, when what was meant was PyObject *x, *y, *z;. I know that’s why I do it in my own code.

function\n{ vs function {

I find it’s often a nice visual separation between what are likely to be a list of parameter declarations and a list of variable declarations.

"No line should end in whitespace”. Why?

As PEP 7 says in the very next sentence: “If you think you need significant trailing whitespace, think again – somebody’s editor might delete it as a matter of routine.”

5: gotos

Personal preference. They’re great for error handling, for example.

2 Likes

Well, I usually prefer

PyObject* x;
PyObject* y;
PyObject* z;

It’s a bit more verbose I admit. Maybe it’s a matter of taste. I think this way it’s more clear that x, y and z are pointers of type PyObject.
PS: honestly speaking, I don’t know why int* a, b it’s not equal int* a; int* b.

Not sure I’ve understood. Where is braces in variable declarations? When you declare an array?

Oh, editor’s can do a lot of things… for example they can remove whitespaces in empty lines, so it’s impossible to copy/paste in REPL.

I’m referring to the difference in readability between something like this:

PyObject*
spam(PyObject **eggs, Py_ssize_t cheese) {
    PyObject *foo, *bar, *baz;
    Py_ssize_t i, j, k;
    ...
} 

…and something like this:

PyObject*
spam(PyObject **eggs, Py_ssize_t cheese)
{
    PyObject *foo, *bar, *baz;
    Py_ssize_t i, j, k;
    ...
}

That’s also an example of stripping trailing whitespace.

2 Likes

Mh, no, I continue to not understand. The two versions seems to me both perfectly readable. My preference to the first version is that:

  1. is equal to the other similar statements (as if)
  2. it’s more simple to see that this is a function declaration if you use grep

So you understand, but disagree. That’s fine, and it’s why we have style guides like PEP 7.

? No, I do not disagree, I do not understand why in your opinion it’s more readable the second choice.

goto is often used to implement a Python like try: ... finally: ... code, to factorize the code of the finally block.

Before C99, it was simply not possible to use the second style.

I strongly prefer type var = expr; to make variables scope smaller. It makes review simpler. For example, to manually count references, it prevents to have to review the whole function, if a variable is only used in a small scope (ex: near the function end).

2 Likes