Skip to content

Commit

Permalink
pythongh-112205: Support @getter annotation from AC (pythongh-112396)
Browse files Browse the repository at this point in the history
  • Loading branch information
corona10 authored and Glyphack committed Jan 27, 2024
1 parent d4d2dbb commit 9bbf3ee
Show file tree
Hide file tree
Showing 5 changed files with 169 additions and 68 deletions.
21 changes: 21 additions & 0 deletions Lib/test/clinic.test.c
Original file line number Diff line number Diff line change
Expand Up @@ -4951,6 +4951,27 @@ static PyObject *
Test_meth_coexist_impl(TestObj *self)
/*[clinic end generated code: output=808a293d0cd27439 input=2a1d75b5e6fec6dd]*/

/*[clinic input]
@getter
Test.property
[clinic start generated code]*/

#define TEST_PROPERTY_GETTERDEF \
{"property", (getter)Test_property_get, NULL, NULL},

static PyObject *
Test_property_get_impl(TestObj *self);

static PyObject *
Test_property_get(TestObj *self, void *Py_UNUSED(context))
{
return Test_property_get_impl(self);
}

static PyObject *
Test_property_get_impl(TestObj *self)
/*[clinic end generated code: output=892b6fb351ff85fd input=2d92b3449fbc7d2b]*/


/*[clinic input]
output push
Expand Down
26 changes: 17 additions & 9 deletions Lib/test/test_clinic.py
Original file line number Diff line number Diff line change
Expand Up @@ -638,7 +638,7 @@ class C "void *" ""
C.__init__ = C.meth
[clinic start generated code]*/
"""
err = "'__init__' must be a normal method, not a class or static method"
err = "'__init__' must be a normal method; got 'FunctionKind.CLASS_METHOD'!"
self.expect_failure(block, err, lineno=8)

def test_validate_cloned_new(self):
Expand Down Expand Up @@ -2180,14 +2180,22 @@ class Foo "" ""
self.expect_failure(block, err, lineno=2)

def test_init_must_be_a_normal_method(self):
err = "'__init__' must be a normal method, not a class or static method!"
block = """
module foo
class Foo "" ""
@classmethod
Foo.__init__
"""
self.expect_failure(block, err, lineno=3)
err_template = "'__init__' must be a normal method; got 'FunctionKind.{}'!"
annotations = {
"@classmethod": "CLASS_METHOD",
"@staticmethod": "STATIC_METHOD",
"@getter": "GETTER",
}
for annotation, invalid_kind in annotations.items():
with self.subTest(annotation=annotation, invalid_kind=invalid_kind):
block = f"""
module foo
class Foo "" ""
{annotation}
Foo.__init__
"""
expected_error = err_template.format(invalid_kind)
self.expect_failure(block, expected_error, lineno=3)

def test_duplicate_coexist(self):
err = "Called @coexist twice"
Expand Down
81 changes: 33 additions & 48 deletions Modules/_io/bufferedio.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
#include "Python.h"
#include "pycore_bytesobject.h" // _PyBytes_Join()
#include "pycore_call.h" // _PyObject_CallNoArgs()
#include "pycore_critical_section.h" // Py_BEGIN_CRITICAL_SECTION()
#include "pycore_object.h" // _PyObject_GC_UNTRACK()
#include "pycore_pyerrors.h" // _Py_FatalErrorFormat()
#include "pycore_pylifecycle.h" // _Py_IsInterpreterFinalizing()
Expand Down Expand Up @@ -518,25 +517,20 @@ buffered_closed(buffered *self)
return closed;
}

/*[clinic input]
@critical_section
@getter
_io._Buffered.closed
[clinic start generated code]*/

static PyObject *
buffered_closed_get_impl(buffered *self, void *context)
_io__Buffered_closed_get_impl(buffered *self)
/*[clinic end generated code: output=f08ce57290703a1a input=18eddefdfe4a3d2f]*/
{
CHECK_INITIALIZED(self)
return PyObject_GetAttr(self->raw, &_Py_ID(closed));
}

static PyObject *
buffered_closed_get(buffered *self, void *context)
{
PyObject *return_value = NULL;

Py_BEGIN_CRITICAL_SECTION(self);
return_value = buffered_closed_get_impl(self, context);
Py_END_CRITICAL_SECTION();

return return_value;
}

/*[clinic input]
@critical_section
_io._Buffered.close
Expand Down Expand Up @@ -662,44 +656,35 @@ _io__Buffered_writable_impl(buffered *self)
return PyObject_CallMethodNoArgs(self->raw, &_Py_ID(writable));
}


/*[clinic input]
@critical_section
@getter
_io._Buffered.name
[clinic start generated code]*/

static PyObject *
buffered_name_get_impl(buffered *self, void *context)
_io__Buffered_name_get_impl(buffered *self)
/*[clinic end generated code: output=d2adf384051d3d10 input=6b84a0e6126f545e]*/
{
CHECK_INITIALIZED(self)
return PyObject_GetAttr(self->raw, &_Py_ID(name));
}

static PyObject *
buffered_name_get(buffered *self, void *context)
{
PyObject *return_value = NULL;

Py_BEGIN_CRITICAL_SECTION(self);
return_value = buffered_name_get_impl(self, context);
Py_END_CRITICAL_SECTION();

return return_value;
}
/*[clinic input]
@critical_section
@getter
_io._Buffered.mode
[clinic start generated code]*/

static PyObject *
buffered_mode_get_impl(buffered *self, void *context)
_io__Buffered_mode_get_impl(buffered *self)
/*[clinic end generated code: output=0feb205748892fa4 input=0762d5e28542fd8c]*/
{
CHECK_INITIALIZED(self)
return PyObject_GetAttr(self->raw, &_Py_ID(mode));
}

static PyObject *
buffered_mode_get(buffered *self, void *context)
{
PyObject *return_value = NULL;

Py_BEGIN_CRITICAL_SECTION(self);
return_value = buffered_mode_get_impl(self, context);
Py_END_CRITICAL_SECTION();

return return_value;
}

/* Lower-level APIs */

/*[clinic input]
Expand Down Expand Up @@ -2541,9 +2526,9 @@ static PyMemberDef bufferedreader_members[] = {
};

static PyGetSetDef bufferedreader_getset[] = {
{"closed", (getter)buffered_closed_get, NULL, NULL},
{"name", (getter)buffered_name_get, NULL, NULL},
{"mode", (getter)buffered_mode_get, NULL, NULL},
_IO__BUFFERED_CLOSED_GETTERDEF
_IO__BUFFERED_NAME_GETTERDEF
_IO__BUFFERED_MODE_GETTERDEF
{NULL}
};

Expand Down Expand Up @@ -2601,9 +2586,9 @@ static PyMemberDef bufferedwriter_members[] = {
};

static PyGetSetDef bufferedwriter_getset[] = {
{"closed", (getter)buffered_closed_get, NULL, NULL},
{"name", (getter)buffered_name_get, NULL, NULL},
{"mode", (getter)buffered_mode_get, NULL, NULL},
_IO__BUFFERED_CLOSED_GETTERDEF
_IO__BUFFERED_NAME_GETTERDEF
_IO__BUFFERED_MODE_GETTERDEF
{NULL}
};

Expand Down Expand Up @@ -2719,9 +2704,9 @@ static PyMemberDef bufferedrandom_members[] = {
};

static PyGetSetDef bufferedrandom_getset[] = {
{"closed", (getter)buffered_closed_get, NULL, NULL},
{"name", (getter)buffered_name_get, NULL, NULL},
{"mode", (getter)buffered_mode_get, NULL, NULL},
_IO__BUFFERED_CLOSED_GETTERDEF
_IO__BUFFERED_NAME_GETTERDEF
_IO__BUFFERED_MODE_GETTERDEF
{NULL}
};

Expand Down
56 changes: 55 additions & 1 deletion Modules/_io/clinic/bufferedio.c.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 9bbf3ee

Please sign in to comment.