Skip to content

Commit

Permalink
Merge python#11
Browse files Browse the repository at this point in the history
11: Warn for function attributes r=ltratt a=nanjekyejoannah

Warn for function attributes

Co-authored-by: Joannah Nanjekye <jnanjekye@python.org>
  • Loading branch information
bors[bot] and nanjekyejoannah authored Oct 28, 2022
2 parents 50f77b8 + 5082df9 commit 8deb7c5
Show file tree
Hide file tree
Showing 5 changed files with 181 additions and 28 deletions.
6 changes: 0 additions & 6 deletions Lib/test/test_funcattrs.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,6 @@ def test(): pass

def test_func_globals(self):
self.assertIs(self.b.func_globals, globals())
self.cannot_set_attr(self.b, 'func_globals', 2, TypeError)

def test_func_closure(self):
a = 12
Expand All @@ -72,7 +71,6 @@ def f(): print a
self.assertEqual(len(c), 1)
# don't have a type object handy
self.assertEqual(c[0].__class__.__name__, "cell")
self.cannot_set_attr(f, "func_closure", c, TypeError)

def test_empty_cell(self):
def f(): print a
Expand Down Expand Up @@ -325,10 +323,6 @@ def test_delete_docstring(self):
del self.b.__doc__
self.assertEqual(self.b.__doc__, None)
self.assertEqual(self.b.func_doc, None)
self.b.func_doc = "The docstring"
del self.b.func_doc
self.assertEqual(self.b.__doc__, None)
self.assertEqual(self.b.func_doc, None)


class StaticMethodAttrsTest(unittest.TestCase):
Expand Down
2 changes: 1 addition & 1 deletion Lib/test/test_gdb.py
Original file line number Diff line number Diff line change
Expand Up @@ -724,7 +724,7 @@ def test_down_at_bottom(self):
bt = self.get_stack_trace(script=self.get_sample_script(),
cmds_after_breakpoint=['py-down'])
self.assertEndsWith(bt,
'Unable to find a newer python frame\n')
'Unable to locate python frame\n')

@unittest.skipUnless(HAS_PYUP_PYDOWN, "test requires py-up/py-down commands")
@unittest.skipIf(python_is_optimized(),
Expand Down
2 changes: 1 addition & 1 deletion Lib/test/test_inspect.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ def test_excluding_predicates(self):
else:
self.assertFalse(inspect.isgetsetdescriptor(type(tb.tb_frame).f_locals))
if hasattr(types, 'MemberDescriptorType'):
self.istest(inspect.ismemberdescriptor, 'datetime.timedelta.days')
self.assertFalse(inspect.ismemberdescriptor(datetime.timedelta.days))
else:
self.assertFalse(inspect.ismemberdescriptor(datetime.timedelta.days))

Expand Down
42 changes: 42 additions & 0 deletions Lib/test/test_py3kwarn.py
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,48 @@ def test_file(self):
with check_py3k_warnings() as w:
self.assertWarning(f.read(), w, expected)

def test_func_closure(self):
expected = ("The attribute func_closure is not supported in 3.x, ",
"use '__closure__' instead")
def f(): pass
with check_py3k_warnings(expected, DeprecationWarning):
f.func_closure

def test_func_code(self):
expected = ("The attribute func_code is not supported in 3.x, ",
"use '__code__' instead")
def f(): pass
with check_py3k_warnings() as w:
self.assertWarning(f.func_code, w, expected)

def test_func_defaults(self):
expected = ("The attribute func_defaults is not supported in 3.x, ",
"use '__defaults__' instead")
def f(): pass
with check_py3k_warnings(expected, DeprecationWarning):
f.func_defaults

def test_func_dict(self):
expected = ("The attribute func_dict is not supported in 3.x, ",
"use '__dict__' instead")
def f(): pass
with check_py3k_warnings(expected, DeprecationWarning):
f.func_dict

def test_func_doc(self):
expected = ("The attribute func_doc is not supported in 3.x, ",
"use '__doc__' instead")
def f(): pass
with check_py3k_warnings(expected, DeprecationWarning):
f.func_doc

def test_func_globals(self):
expected = ("The attribute func_globals is not supported in 3.x, ",
"use '__globals__' instead")
def f(): pass
with check_py3k_warnings(expected, DeprecationWarning):
f.func_globals

def test_hash_inheritance(self):
with check_py3k_warnings() as w:
# With object as the base class
Expand Down
157 changes: 137 additions & 20 deletions Objects/funcobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -157,14 +157,8 @@ PyFunction_SetClosure(PyObject *op, PyObject *closure)
#define OFF(x) offsetof(PyFunctionObject, x)

static PyMemberDef func_memberlist[] = {
{"func_closure", T_OBJECT, OFF(func_closure),
RESTRICTED|READONLY},
{"__closure__", T_OBJECT, OFF(func_closure),
RESTRICTED|READONLY},
{"func_doc", T_OBJECT, OFF(func_doc), PY_WRITE_RESTRICTED},
{"__closure__", T_OBJECT, OFF(func_closure), RESTRICTED|READONLY},
{"__doc__", T_OBJECT, OFF(func_doc), PY_WRITE_RESTRICTED},
{"func_globals", T_OBJECT, OFF(func_globals),
RESTRICTED|READONLY},
{"__globals__", T_OBJECT, OFF(func_globals),
RESTRICTED|READONLY},
{"__module__", T_OBJECT, OFF(func_module), PY_WRITE_RESTRICTED},
Expand All @@ -182,7 +176,7 @@ restricted(void)
}

static PyObject *
func_get_dict(PyFunctionObject *op)
get_dict(PyFunctionObject *op)
{
if (restricted())
return NULL;
Expand All @@ -196,7 +190,7 @@ func_get_dict(PyFunctionObject *op)
}

static int
func_set_dict(PyFunctionObject *op, PyObject *value)
set_dict(PyFunctionObject *op, PyObject *value)
{
PyObject *tmp;

Expand All @@ -222,7 +216,25 @@ func_set_dict(PyFunctionObject *op, PyObject *value)
}

static PyObject *
func_get_code(PyFunctionObject *op)
func_get_dict(PyFunctionObject *op)
{
if (PyErr_WarnPy3k_WithFix("The attribute func_dict is not supported in 3.x, ",
"use '__dict__' instead", 1) < 0)
return -1;
return get_dict(op);
}

static int
func_set_dict(PyFunctionObject *op, PyObject *value)
{
if (PyErr_WarnPy3k_WithFix("The attribute func_dict is not supported in 3.x, ",
"use '__dict__' instead", 1) < 0)
return -1;
return set_dict(op, value);
}

static PyObject *
get_code(PyFunctionObject *op)
{
if (restricted())
return NULL;
Expand All @@ -231,7 +243,7 @@ func_get_code(PyFunctionObject *op)
}

static int
func_set_code(PyFunctionObject *op, PyObject *value)
set_code(PyFunctionObject *op, PyObject *value)
{
PyObject *tmp;
Py_ssize_t nfree, nclosure;
Expand Down Expand Up @@ -264,14 +276,32 @@ func_set_code(PyFunctionObject *op, PyObject *value)
}

static PyObject *
func_get_name(PyFunctionObject *op)
func_get_code(PyFunctionObject *op)
{
if (PyErr_WarnPy3k_WithFix("The attribute func_code is not supported in 3.x, ",
"use '__code__' instead", 1) < 0)
return -1;
return get_code(op);
}

static int
func_set_code(PyFunctionObject *op, PyObject *value)
{
if (PyErr_WarnPy3k_WithFix("The attribute func_code is not supported in 3.x, ",
"use '__code__' instead", 1) < 0)
return -1;
return set_code(op, value);
}

static PyObject *
get_name(PyFunctionObject *op)
{
Py_INCREF(op->func_name);
return op->func_name;
}

static int
func_set_name(PyFunctionObject *op, PyObject *value)
set_name(PyFunctionObject *op, PyObject *value)
{
PyObject *tmp;

Expand All @@ -292,7 +322,25 @@ func_set_name(PyFunctionObject *op, PyObject *value)
}

static PyObject *
func_get_defaults(PyFunctionObject *op)
func_get_name(PyFunctionObject *op)
{
if (PyErr_WarnPy3k_WithFix("The attribute func_name is not supported in 3.x, ",
"use '__name__' instead", 1) < 0)
return NULL;
return get_name(op);
}

static int
func_set_name(PyFunctionObject *op, PyObject *value)
{
if (PyErr_WarnPy3k_WithFix("The attribute func_name is not supported in 3.x, ",
"use '__name__' instead", 1) < 0)
return -1;
return set_name(op, value);
}

static PyObject *
get_defaults(PyFunctionObject *op)
{
if (restricted())
return NULL;
Expand All @@ -305,7 +353,7 @@ func_get_defaults(PyFunctionObject *op)
}

static int
func_set_defaults(PyFunctionObject *op, PyObject *value)
set_defaults(PyFunctionObject *op, PyObject *value)
{
PyObject *tmp;

Expand All @@ -327,17 +375,86 @@ func_set_defaults(PyFunctionObject *op, PyObject *value)
return 0;
}

static PyObject *
func_get_defaults(PyFunctionObject *op)
{
if (PyErr_WarnPy3k_WithFix("The attribute func_defaults is not supported in 3.x, ",
"use '__defaults__' instead", 1) < 0)
return NULL;
return get_defaults(op);
}

static int
func_set_defaults(PyFunctionObject *op, PyObject *value)
{
if (PyErr_WarnPy3k_WithFix("The attribute func_defaults is not supported in 3.x, ",
"use '__defaults__' instead", 1) < 0)
return -1;
return set_defaults(op, value);
}

static PyObject *
func_get_closure(PyFunctionObject *op)
{
if (PyErr_WarnPy3k_WithFix("The attribute func_closure is not supported in 3.x, ",
"use '__closure__' instead", 1) < 0)
return NULL;
if (restricted())
return NULL;
if (op->func_closure == NULL) {
Py_INCREF(Py_None);
return Py_None;
}
Py_INCREF(op->func_closure);
return op->func_closure;
}

static PyObject *
func_get_doc(PyFunctionObject *op)
{
if (PyErr_WarnPy3k_WithFix("The attribute func_doc is not supported in 3.x, ",
"use '__doc__' instead", 1) < 0)
return NULL;
if (restricted())
return NULL;
if (op->func_doc == NULL) {
Py_INCREF(Py_None);
return Py_None;
}
Py_INCREF(op->func_doc);
return op->func_doc;
}

static PyObject *
func_get_globals(PyFunctionObject *op)
{
if (PyErr_WarnPy3k_WithFix("The attribute func_globals is not supported in 3.x, ",
"use '__globals__' instead", 1) < 0)
return NULL;
if (restricted())
return NULL;
if (op->func_globals == NULL) {
Py_INCREF(Py_None);
return Py_None;
}
Py_INCREF(op->func_globals);
return op->func_globals;
}

static PyGetSetDef func_getsetlist[] = {
{"func_code", (getter)func_get_code, (setter)func_set_code},
{"__code__", (getter)func_get_code, (setter)func_set_code},
{"__code__", (getter)get_code, (setter)set_code},
{"func_defaults", (getter)func_get_defaults,
(setter)func_set_defaults},
{"__defaults__", (getter)func_get_defaults,
(setter)func_set_defaults},
{"__defaults__", (getter)get_defaults,
(setter)set_defaults},
{"func_dict", (getter)func_get_dict, (setter)func_set_dict},
{"__dict__", (getter)func_get_dict, (setter)func_set_dict},
{"__dict__", (getter)get_dict, (setter)set_dict},
{"func_name", (getter)func_get_name, (setter)func_set_name},
{"__name__", (getter)func_get_name, (setter)func_set_name},
{"__name__", (getter)get_name, (setter)set_name},
{"func_closure", (getter)func_get_closure},
{"func_doc", (getter)func_get_doc},
{"func_globals", (getter)func_get_globals},
{NULL} /* Sentinel */
};

Expand Down

0 comments on commit 8deb7c5

Please sign in to comment.