Move all function introspection/argument generation into new classes.
Review Request #10920 — Created Feb. 26, 2020 and submitted
As
FunctionSpy
got more complicated and continued to add compatibility
with newer versions of Python, the code got increasingly complex and
littered with Python version checks. This could make it more challenging
to reason about some parts of code.To address this, this change introduces a new set of
FunctionSig
classes, which consist ofBaseFunctionSig
,FunctionSigPy2
, and
FunctionSigPy3
.These are responsible for taking a function and storing information on
the function type, owner, and arguments. It's also responsible for
generating code for a function's argument signature or for referencing a
variable defined in a spy-generated function, for the purposes of
generating those functions.The
Py2
andPy3
versions of these classes implement the logic for
Python 2 and Python 3, respectively. There's some common logic in the
base class, but the bulk are in these. They also contain constants used
for function attribute states, which used to be defined per-version in
spies.py
.A
FunctionSig
alias exists that points to the appropriate class for
the current version of Python.
FunctionSpy
generates an instance of this for the provided function
up-front, and uses it to figure out the owner and other information. It
ditches the argspec-related methods in favor of calls to this. It also
provides some property wrappers for attributes on the signature, for
compatibility purposes.Version checks are still required in
FunctionSpy
for many purposes,
such as when filling out attributes for aCodeType
orFunctionType
,
but a lot of the complexities are now isolated to theFunctionSig
s.This should help keep the codebase more maintainable and future-proof as
we go on.
Unit tests pass on Python 2.7 and 3.5-3.8.
Ran Djblets and Review Board unit test suites with these Python
versions to make sure nothing broke in real-world usage.