Skip to content
Prev Previous commit
Next Next commit
bpo-37645: rename PyObject_FunctionStr() -> _PyObject_FunctionStr()
  • Loading branch information
jdemeyer committed Aug 18, 2019
commit 4c0c877889b406d33a863005361afb1bd19149af
2 changes: 1 addition & 1 deletion Doc/c-api/object.rst
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ Object Protocol
does not silently discard an active exception.


.. c:function:: PyObject* PyObject_FunctionStr(PyObject *func)
.. c:function:: PyObject* _PyObject_FunctionStr(PyObject *func)
Comment thread
jdemeyer marked this conversation as resolved.
Outdated

Return a user-friendly string representation of the function-like object
*func*. This returns ``func.__qualname__ + "()"`` if there is a

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Returning __qualname__ without module is not particularly useful.

If you want to return a full qualified name (long but unambiguous), return __module__ + '.' + __qualname__. __module__ can be omitted if it is 'builtins'.

If you want to return a short name (it is enough in many times), return __name__.

if __qualname__ is not available, you can use __name__ instead.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if __qualname__ is not available, you can use __name__ instead.

This is mainly meant as replacement for PyEval_GetFuncName and all classes supported by that function implement __qualname__. So I see little reason for the additional complexity of supporting __name__.

Expand Down
2 changes: 1 addition & 1 deletion Include/cpython/object.h
Original file line number Diff line number Diff line change
Expand Up @@ -348,7 +348,7 @@ static inline void _Py_Dealloc_inline(PyObject *op)
}
#define _Py_Dealloc(op) _Py_Dealloc_inline(op)

PyAPI_FUNC(PyObject *) PyObject_FunctionStr(PyObject *);
PyAPI_FUNC(PyObject *) _PyObject_FunctionStr(PyObject *);

/* Safely decref `op` and set `op` to `op2`.
*
Expand Down
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
Add :c:func:`PyObject_FunctionStr` to get a user-friendly string representation
Add :c:func:`_PyObject_FunctionStr` to get a user-friendly string representation
of a function-like object.
8 changes: 4 additions & 4 deletions Objects/descrobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ method_check_args(PyObject *func, PyObject *const *args, Py_ssize_t nargs, PyObj
{
assert(!PyErr_Occurred());
if (nargs < 1) {
PyObject *funcstr = PyObject_FunctionStr(func);
PyObject *funcstr = _PyObject_FunctionStr(func);
if (funcstr != NULL) {
PyErr_Format(PyExc_TypeError,
"%U needs an argument", funcstr);
Expand All @@ -250,7 +250,7 @@ method_check_args(PyObject *func, PyObject *const *args, Py_ssize_t nargs, PyObj
return -1;
}
if (kwnames && PyTuple_GET_SIZE(kwnames)) {
PyObject *funcstr = PyObject_FunctionStr(func);
PyObject *funcstr = _PyObject_FunctionStr(func);
if (funcstr != NULL) {
PyErr_Format(PyExc_TypeError,
"%U takes no keyword arguments", funcstr);
Expand Down Expand Up @@ -375,7 +375,7 @@ method_vectorcall_NOARGS(
return NULL;
}
if (nargs != 1) {
PyObject *funcstr = PyObject_FunctionStr(func);
PyObject *funcstr = _PyObject_FunctionStr(func);
if (funcstr != NULL) {
PyErr_Format(PyExc_TypeError,
"%U takes no arguments (%zd given)", funcstr, nargs-1);
Expand All @@ -401,7 +401,7 @@ method_vectorcall_O(
return NULL;
}
if (nargs != 2) {
PyObject *funcstr = PyObject_FunctionStr(func);
PyObject *funcstr = _PyObject_FunctionStr(func);
if (funcstr != NULL) {
PyErr_Format(PyExc_TypeError,
"%U takes exactly one argument (%zd given)",
Expand Down
6 changes: 3 additions & 3 deletions Objects/methodobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -338,7 +338,7 @@ cfunction_check_kwargs(PyObject *func, PyObject *kwnames)
assert(!PyErr_Occurred());
assert(PyCFunction_Check(func));
if (kwnames && PyTuple_GET_SIZE(kwnames)) {
PyObject *funcstr = PyObject_FunctionStr(func);
PyObject *funcstr = _PyObject_FunctionStr(func);
if (funcstr != NULL) {
PyErr_Format(PyExc_TypeError,
"%U takes no keyword arguments", funcstr);
Expand Down Expand Up @@ -403,7 +403,7 @@ cfunction_vectorcall_NOARGS(
}
Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
if (nargs != 0) {
PyObject *funcstr = PyObject_FunctionStr(func);
PyObject *funcstr = _PyObject_FunctionStr(func);
if (funcstr != NULL) {
PyErr_Format(PyExc_TypeError,
"%U takes no arguments (%zd given)", funcstr, nargs);
Expand All @@ -429,7 +429,7 @@ cfunction_vectorcall_O(
}
Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
if (nargs != 1) {
PyObject *funcstr = PyObject_FunctionStr(func);
PyObject *funcstr = _PyObject_FunctionStr(func);
if (funcstr != NULL) {
PyErr_Format(PyExc_TypeError,
"%U takes exactly one argument (%zd given)", funcstr, nargs);
Expand Down
6 changes: 2 additions & 4 deletions Objects/object.c
Original file line number Diff line number Diff line change
Expand Up @@ -665,14 +665,14 @@ PyObject_Bytes(PyObject *v)


/*
def PyObject_FunctionStr(f):
def _PyObject_FunctionStr(f):
try:
return f.__qualname__ + "()"
except Exception:
return type(f).__name__ + " object"
*/
PyObject *
PyObject_FunctionStr(PyObject *f)
_PyObject_FunctionStr(PyObject *f)
{
Comment thread
jdemeyer marked this conversation as resolved.
Outdated
_Py_IDENTIFIER(__qualname__);
PyObject *name = _PyObject_GetAttrId(f, &PyId___qualname__);
Expand All @@ -683,8 +683,6 @@ PyObject_FunctionStr(PyObject *f)
}
/* __qualname__ lookup failed */
if (!PyErr_ExceptionMatches(PyExc_Exception)) {
Comment thread
jdemeyer marked this conversation as resolved.
Outdated
/* An exception not inheriting from Exception, like KeyboardInterrupt.
* Propagate it. */
return NULL;
}
PyErr_Clear();
Expand Down
2 changes: 1 addition & 1 deletion Python/ceval.c
Original file line number Diff line number Diff line change
Expand Up @@ -5344,7 +5344,7 @@ check_args_iterable(PyThreadState *tstate, PyObject *func, PyObject *args)
/* check_args_iterable() may be called with a live exception,
* clear it. */
Comment thread
jdemeyer marked this conversation as resolved.
Outdated
PyErr_Clear();
PyObject *funcstr = PyObject_FunctionStr(func);
PyObject *funcstr = _PyObject_FunctionStr(func);
if (funcstr != NULL) {
_PyErr_Format(tstate, PyExc_TypeError,
"%U argument after * must be an iterable, not %.200s",
Expand Down