Since enums are themselves iterable there's no need to maintain a list
of the elements of the enum dating from back before the enum when its
values were just independent constants that hung out together.
This refactoring greatly reduces the base-internal use of packet kinds
and will make much simpler a future change distinguishing front-to-back
packet kinds from back-to-front packet kinds.
deadline is passed by address to PyArg_ParseTuple to update its value.
However, deadline is a const double, so attempting to change its value
is undefined behavior. Remove the const to have well-defined behavior.
The assembly and face layers were mostly redundant except that the
assembly layer had far-better interfaces and the face layer had more
of a reason to exist. Now they are merged.
This makes grpc.early_adopter much more independent of RPC
Framework and cleaner at the cost of reexporting most of the
interfaces and writing several delegation classes.
These will be used in generated code in circumstances in which we
don't necessarily want to be asking calling code to have a thread
pool readily available.
This provides for now what should be a nicer interface for code
generation than that of the Face layer. In terms of abstraction
it's conceptually very similar so the two should probably be
merged as soon as is reasonable.
Successful operations were leaking the thread used for expiration
monitoring. This change ensures that the ExpirationManager for the
operation always has its abort() method called when the
TerminationManager for the operation judges the operation to have
terminated.
- Use METH_O and METH_NOARGS where appropriate, modifying the C functions
appropriately. METH_O is for functions that take a single PyObject, and
it's passed directly instead of 'args'. METH_NOARGS is for functions
that take no arguments, and they get called with just one argument
('self'.)
- In PyArg_ParseTuple*() calls, specify the callable's name for more
descriptive exception messages.
- For tp_init functions (which always take keyword arguments) introduce
keyword argument parsing (using the C local variables as keywords,
although I don't know if they're the best names to use.) This is mostly
as a way to show how keyword arguments are done in C. An alternative
method is to use _PyArg_NoKeywords(kwds) (see
https://hg.python.org/cpython/file/70a55b2dee71/Python/getargs.c#l1820,
but unfortunately it's not part of the official API,) or check manually
that the dict is empty.
- Check the return value of Python API functions that can return an error
indicator (NULL or -1.) PyFloat_AsDouble is also one of these, but we
don't check the return type (we would have to compare the result to 1.0
with ==, which is not a thing you should do) so just call PyErr_Occurred
unconditionally.
- Change Py_BuildValue() calls with just "O" formats into PyTuple_Pack
calls. It requires less runtime checking.
- Replace Py_BuildValue()/PyObject_CallObject pairs with
PyObject_CallFunctionObjArgs (since all of them have just PyObject*
arguments.) If the Py_BuildValue formats had included other types,
PyObject_CallFunction() would have been easier, but no need in these
cases.
- Replace Py_BuildValue("f", ...) with PyFloat_FromDouble(...). Less
runtime checking and parsing necessary, and more obvious in what it does.
- In the PyType structs, replace "PyObject_HEAD_INIT(NULL) 0" with
"PyVarObject_HEAD_INIT(NULL, 0)". Anything with an ob_size struct member
is a PyVarObject, although the distinction isn't all that import; it's
just a more convenient macro.
- Assign tp_new in the PyType structs directly, like all other struct
members, rather than right before the PyType_Ready() call.
- Remove PyErr_SetString() calls in places that already have a (meaningful)
exception set.
- Add a PyErr_Format() for an error return that wasn't setting an exception
(PyObject_TypeCheck() doesn't set an exception.)
- Remove NULL assignments to struct members in the error paths of the
tp_init functions. PyObject structs are always zeroed after allocation,
guaranteed. (If there's a way for them to already contain an object
you'd use Py_CLEAR() to clear them, but that can't happen in these
cases.)
- Remove a few unnecessary parentheses.
The source code is moved from src/python to
src/python/src. A setup.py is added at
src/python. The build_python.sh and
run_python.sh scripts are updated to build
and run the Python tests by building a
package and installing it in the developer's
Python 2.7 virtual environment.