[Python-Dev] "Becoming a Python Developer"

Guido van Rossum guido@digicool.com
Thu, 05 Jul 2001 10:09:58 -0400


Nice work, Andrew!

I surely hope this will bring us some new contributors...

Some answers to your XXX marks:

> You like hacking on language interpreters.  (XXX is that a bit
> snarky? not sure I phrased that well...)

Sounds fine to me, or you could extend to "large software packages".

> Python is over 10 years old, and its development process is quite
> (XXX elaborate? evolved? mature?)

I'd say mature.

> Python is developed by a group of about 30 people,

True, but may sound off-putting to would-be contributors.  Maybe you
can add that lots of others contribute significantly?  (E.g. ask Fred
how many folks have contributed to the docs!)

> XXX should something be written about CPython / JPython / Stackless
> / Python.NET? I only know about CPython.

Explaining the distinction would be helpful, and you could add that
for Java programmers, participating in Jython would be a logical step.

> Guido van Rossum has the title of Benevolent Dictator For Life, or
> BDFL.

Lest people who aren't familiar with Python culture (or those who are
but lack a sense of humor) take this at face value, can you explain
that this is a tongue-in-cheek title?

The section on CVS is redundant -- this information is already on the
SF website, isn't it?  (Or most of it.)  I don't think detailed
instructions need to be in a high-level motivational article -- a link
to http://sourceforge.net/cvs/?group_id=5470 is all that's needed
(like you do for other services).

> diff -C2. (XXX is that correct?)

I use "diff -c" which seems to have the same effect.

> Python's standard style, described at XXX.


Alas, there's no description.  Let me try to summarize the rules here.


C dialect:

- Use ANSI/ISO standard C (the 1989 version of the standard).

- All function declarations and definitions must use full prototypes
  (i.e. specify the types of all arguments).

- Never use C++ style // one-line comments.

- No compiler warnings with major compilers (gcc, VC++, a few others).


Code lay-out:

- Use single-tab indents, where a tab is worth 8 spaces.

- No line should be longer than 79 characters.  If this and the
  previous rule together don't give you enough room to code, your code
  is too complicated -- consider using subroutines.

- Function definition style: function name in column 1, outermost
  curly braces in column 1, blank line after local variable
  declarations.

	static int
	extra_ivars(PyTypeObject *type, PyTypeObject *base)
	{
		int t_size = PyType_BASICSIZE(type);
		int b_size = PyType_BASICSIZE(base);

		assert(t_size >= b_size); /* type smaller than base! */
		...
		return 1;
	}

- Code structure: one space between keywords like 'if', 'for' and the
  following left paren; no spaces inside the paren; braces as shown:

	if (mro != NULL) {
		...
	}
	else {
		...
	}

- The return statement should *not* get redundant parentheses:

	return Py_None; /* correct */
	return(Py_None); /* incorrect */

- Function and macro call style: foo(a, b, c) -- no space before the
  open paren, no spaces inside the parens, no spaces before commas,
  one space after each comma.

- Always put spaces around assignment, Boolean and comparison
  operators.  In expressions using a lot of operators, add spaces
  around the outermost (lowest-priority) operators.

- Breaking long lines: if you can, break after commas in the outermost
  argument list.  Always indent continuation lines appropriately, e.g.:

	PyErr_Format(PyExc_TypeError,
		     "cannot create '%.100s' instances",
		     type->tp_name);

- When you break a long expression at a binary operator, the operator
  goes at the end of the previous line, e.g.:

	if (type->tp_dictoffset != 0 && base->tp_dictoffset == 0 &&
	    type->tp_dictoffset == b_size &&
	    (size_t)t_size == b_size + sizeof(PyObject *))
		return 0; /* "Forgive" adding a __dict__ only */

- Put blank lines around functions, structure definitions, and major
  sections inside functions.

- Comments go before the code they describe.

- All functions and global variables should be declared static unless
  they are to be part of a published interface

- For external functions and variables, we always have a declaration
  in an appropriate header file in the "Include" directory, which uses
  the DL_IMPORT() macro, like this:

	extern DL_IMPORT(PyObject *) PyObject_Repr(PyObject *);


Naming conventions:

- Use a Py prefix for public functions; never for static functions.
  The Py_ prefix is reserved for global service routines like
  Py_FatalError; specific groups of routines (e.g. specific object
  type APIs) use a longer prefix, e.g. PyString_ for string functions.

- Public functions and variables use MixedCase with underscores, like
  this: PyObject_GetAttr, Py_BuildValue, PyExc_TypeError.

- Occasionally an "internal" function has to be visible to the loader;
  we use the _Py prefix for this, e.g.: _PyObject_Dump.

- Macros should have a MixedCase prefix and then use upper case, for
  example: PyString_AS_STRING, Py_PRINT_RAW.


I'm sure there's more.  I'll make this into a PEP.

--Guido van Rossum (home page: http://www.python.org/~guido/)