Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

gh-112205: Support @getter annotation from AC #112396

Merged
merged 18 commits into from
Nov 30, 2023
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 *context)
{
return Test_property_get_impl(self);
}

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


/*[clinic input]
output push
Expand Down
21 changes: 12 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, not a classmethod, staticmethod or getter!"
self.expect_failure(block, err, lineno=8)

def test_validate_cloned_new(self):
Expand Down Expand Up @@ -2180,14 +2180,17 @@ 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 = "'__init__' must be a normal method, not a classmethod, staticmethod or getter!"
annotations = ["@classmethod", "@staticmethod", "@getter"]
for annotation in annotations:
with self.subTest(annotation=annotation):
block = f"""
module foo
class Foo "" ""
{annotation}
Foo.__init__
"""
self.expect_failure(block, err, 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
Loading