Compare commits

...

3 Commits

Author SHA1 Message Date
Filipe Laíns 4ac923f275
bpo-42773: fix tests not being run on pushes (GH-24004)
There was a typo, we were checking if the "GITHUB_BASE_REF" string
literal was empty instead of the $GITHUB_BASE_REF value. When
$GITHUB_BASE_REF is empty, the action that triggered the run was not a
pull request, so we always run the full test suite.

Signed-off-by: Filipe Laíns <lains@riseup.net>
2020-12-30 06:53:58 -08:00
pxinwr 277ce3060b
bpo-27640: Add --disable-test-modules configure option (GH-23886)
Added --disable-test-modules option to the configure script:
don't build nor install test modules.

Patch by Xavier de Gaye, Thomas Petazzoni and Peixing Xin.

Co-Authored-By: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
Co-Authored-By: Xavier de Gaye <xdegaye@gmail.com>
2020-12-30 13:50:39 +01:00
Yurii Karabas c56387f80c
bpo-27794: Add `name` attribute to `property` class (GH-23967) 2020-12-30 01:51:24 -08:00
12 changed files with 236 additions and 54 deletions

View File

@ -28,7 +28,7 @@ jobs:
- name: Check for source changes
id: check
run: |
if [ -z "GITHUB_BASE_REF" ]; then
if [ -z "$GITHUB_BASE_REF" ]; then
echo '::set-output name=run_tests::true'
else
git fetch origin $GITHUB_BASE_REF --depth=1

View File

@ -934,32 +934,42 @@ here is a pure Python equivalent:
if doc is None and fget is not None:
doc = fget.__doc__
self.__doc__ = doc
self._name = ''
def __set_name__(self, owner, name):
self._name = name
def __get__(self, obj, objtype=None):
if obj is None:
return self
if self.fget is None:
raise AttributeError("unreadable attribute")
raise AttributeError(f'unreadable attribute {self._name}')
return self.fget(obj)
def __set__(self, obj, value):
if self.fset is None:
raise AttributeError("can't set attribute")
raise AttributeError(f"can't set attribute {self._name}")
self.fset(obj, value)
def __delete__(self, obj):
if self.fdel is None:
raise AttributeError("can't delete attribute")
raise AttributeError(f"can't delete attribute {self._name}")
self.fdel(obj)
def getter(self, fget):
return type(self)(fget, self.fset, self.fdel, self.__doc__)
prop = type(self)(fget, self.fset, self.fdel, self.__doc__)
prop._name = self._name
return prop
def setter(self, fset):
return type(self)(self.fget, fset, self.fdel, self.__doc__)
prop = type(self)(self.fget, fset, self.fdel, self.__doc__)
prop._name = self._name
return prop
def deleter(self, fdel):
return type(self)(self.fget, self.fset, fdel, self.__doc__)
prop = type(self)(self.fget, self.fset, fdel, self.__doc__)
prop._name = self._name
return prop
.. testcode::
:hide:

View File

@ -558,6 +558,10 @@ Build Changes
* The :mod:`atexit` module must now always be built as a built-in module.
(Contributed by Victor Stinner in :issue:`42639`.)
* Added ``--disable-test-modules`` option to the ``configure`` script:
don't build nor install test modules.
(Contributed by Xavier de Gaye, Thomas Petazzoni and Peixing Xin in :issue:`27640`.)
C API Changes
=============

View File

@ -204,6 +204,16 @@ class PropertyTests(unittest.TestCase):
return 'Second'
self.assertEqual(A.__doc__, 'Second')
def test_property_set_name_incorrect_args(self):
p = property()
for i in (0, 1, 3):
with self.assertRaisesRegex(
TypeError,
fr'^__set_name__\(\) takes 2 positional arguments but {i} were given$'
):
p.__set_name__(*([0] * i))
# Issue 5890: subclasses of property do not preserve method __doc__ strings
class PropertySub(property):
@ -299,6 +309,46 @@ class PropertySubclassTests(unittest.TestCase):
self.assertEqual(Foo.spam.__doc__, "a new docstring")
class _PropertyUnreachableAttribute:
msg_format = None
obj = None
cls = None
def _format_exc_msg(self, msg):
return self.msg_format.format(msg)
@classmethod
def setUpClass(cls):
cls.obj = cls.cls()
def test_get_property(self):
with self.assertRaisesRegex(AttributeError, self._format_exc_msg("unreadable attribute")):
self.obj.foo
def test_set_property(self):
with self.assertRaisesRegex(AttributeError, self._format_exc_msg("can't set attribute")):
self.obj.foo = None
def test_del_property(self):
with self.assertRaisesRegex(AttributeError, self._format_exc_msg("can't delete attribute")):
del self.obj.foo
class PropertyUnreachableAttributeWithName(_PropertyUnreachableAttribute, unittest.TestCase):
msg_format = "^{} 'foo'$"
class cls:
foo = property()
class PropertyUnreachableAttributeNoName(_PropertyUnreachableAttribute, unittest.TestCase):
msg_format = "^{}$"
class cls:
pass
cls.foo = property()
if __name__ == '__main__':
unittest.main()

View File

@ -1329,7 +1329,7 @@ class SizeofTest(unittest.TestCase):
def setx(self, value): self.__x = value
def delx(self): del self.__x
x = property(getx, setx, delx, "")
check(x, size('4Pi'))
check(x, size('5Pi'))
# PyCapsule
# XXX
# rangeiterator

View File

@ -1366,18 +1366,54 @@ maninstall: altmaninstall
# Install the library
XMLLIBSUBDIRS= xml xml/dom xml/etree xml/parsers xml/sax
LIBSUBDIRS= tkinter tkinter/test tkinter/test/test_tkinter \
tkinter/test/test_ttk site-packages test \
test/audiodata \
test/capath test/data \
test/cjkencodings test/decimaltestdata \
test/xmltestdata test/xmltestdata/c14n-20 \
test/dtracedata \
test/eintrdata \
test/imghdrdata \
test/libregrtest \
test/subprocessdata test/sndhdrdata test/support \
test/tracedmodules test/encoded_modules \
LIBSUBDIRS= asyncio \
collections \
concurrent concurrent/futures \
csv \
ctypes ctypes/macholib \
curses \
dbm \
distutils distutils/command \
email email/mime \
encodings \
ensurepip ensurepip/_bundled \
html \
http \
idlelib idlelib/Icons \
importlib importlib/metadata \
json \
lib2to3 lib2to3/fixes lib2to3/pgen2 \
logging \
multiprocessing multiprocessing/dummy \
pydoc_data \
site-packages \
sqlite3 \
tkinter \
turtledemo \
unittest \
urllib \
venv venv/scripts venv/scripts/common venv/scripts/posix \
wsgiref \
$(XMLLIBSUBDIRS) \
xmlrpc \
zoneinfo
TESTSUBDIRS= ctypes/test \
distutils/tests \
idlelib/idle_test \
lib2to3/tests \
lib2to3/tests/data \
lib2to3/tests/data/fixers \
lib2to3/tests/data/fixers/myfixes \
sqlite3/test \
test test/audiodata \
test/capath test/cjkencodings \
test/data test/decimaltestdata \
test/dtracedata test/eintrdata \
test/encoded_modules test/imghdrdata \
test/libregrtest test/sndhdrdata \
test/subprocessdata test/support \
test/test_asyncio \
test/test_email test/test_email/data \
test/test_import \
test/test_import/data \
test/test_import/data/circular_imports \
@ -1385,8 +1421,6 @@ LIBSUBDIRS= tkinter tkinter/test tkinter/test/test_tkinter \
test/test_import/data/package \
test/test_import/data/package2 \
test/test_import/data/unwritable \
importlib \
importlib/metadata \
test/test_importlib \
test/test_importlib/builtin \
test/test_importlib/data \
@ -1425,30 +1459,19 @@ LIBSUBDIRS= tkinter tkinter/test tkinter/test/test_tkinter \
test/test_importlib/source \
test/test_importlib/zipdata01 \
test/test_importlib/zipdata02 \
test/test_zoneinfo test/test_zoneinfo/data \
test/ziptestdata \
asyncio \
test/test_asyncio \
collections concurrent concurrent/futures encodings \
email email/mime test/test_email test/test_email/data \
ensurepip ensurepip/_bundled \
html json test/test_json http dbm xmlrpc \
sqlite3 sqlite3/test \
logging csv wsgiref urllib \
lib2to3 lib2to3/fixes lib2to3/pgen2 lib2to3/tests \
lib2to3/tests/data lib2to3/tests/data/fixers \
lib2to3/tests/data/fixers/myfixes \
ctypes ctypes/test ctypes/macholib \
idlelib idlelib/Icons idlelib/idle_test \
distutils distutils/command distutils/tests $(XMLLIBSUBDIRS) \
test/test_json \
test/test_peg_generator \
test/test_tools test/test_warnings test/test_warnings/data \
turtledemo \
multiprocessing multiprocessing/dummy \
unittest unittest/test unittest/test/testmock \
venv venv/scripts venv/scripts/common venv/scripts/posix \
curses pydoc_data \
zoneinfo
test/test_tools \
test/test_warnings test/test_warnings/data \
test/test_zoneinfo test/test_zoneinfo/data \
test/tracedmodules \
test/xmltestdata test/xmltestdata/c14n-20 \
test/ziptestdata \
tkinter/test tkinter/test/test_tkinter \
tkinter/test/test_ttk \
unittest/test unittest/test/testmock
TEST_MODULES=@TEST_MODULES@
libinstall: build_all $(srcdir)/Modules/xxmodule.c
@for i in $(SCRIPTDIR) $(LIBDEST); \
do \
@ -1458,7 +1481,12 @@ libinstall: build_all $(srcdir)/Modules/xxmodule.c
else true; \
fi; \
done
@for d in $(LIBSUBDIRS); \
@if test "$(TEST_MODULES)" = yes; then \
subdirs="$(LIBSUBDIRS) $(TESTSUBDIRS)"; \
else \
subdirs="$(LIBSUBDIRS)"; \
fi; \
for d in $$subdirs; \
do \
a=$(srcdir)/Lib/$$d; \
if test ! -d $$a; then continue; else true; fi; \
@ -1479,7 +1507,12 @@ libinstall: build_all $(srcdir)/Modules/xxmodule.c
echo $(INSTALL_DATA) $$i $(LIBDEST); \
fi; \
done
@for d in $(LIBSUBDIRS); \
@if test "$(TEST_MODULES)" = yes; then \
subdirs="$(LIBSUBDIRS) $(TESTSUBDIRS)"; \
else \
subdirs="$(LIBSUBDIRS)"; \
fi; \
for d in $$subdirs; \
do \
a=$(srcdir)/Lib/$$d; \
if test ! -d $$a; then continue; else true; fi; \

View File

@ -0,0 +1,3 @@
Added ``--disable-test-modules`` option to the ``configure`` script:
don't build nor install test modules.
Patch by Xavier de Gaye, Thomas Petazzoni and Peixing Xin.

View File

@ -0,0 +1,3 @@
Improve the error message for failed writes/deletes to property objects.
When possible, the attribute name is now shown. Patch provided by
Yurii Karabas.

View File

@ -1490,6 +1490,7 @@ typedef struct {
PyObject *prop_set;
PyObject *prop_del;
PyObject *prop_doc;
PyObject *prop_name;
int getter_doc;
} propertyobject;
@ -1535,10 +1536,33 @@ property_deleter(PyObject *self, PyObject *deleter)
}
PyDoc_STRVAR(set_name_doc,
"Method to set name of a property.");
static PyObject *
property_set_name(PyObject *self, PyObject *args) {
if (PyTuple_GET_SIZE(args) != 2) {
PyErr_Format(
PyExc_TypeError,
"__set_name__() takes 2 positional arguments but %d were given",
PyTuple_GET_SIZE(args));
return NULL;
}
propertyobject *prop = (propertyobject *)self;
PyObject *name = PyTuple_GET_ITEM(args, 1);
Py_XINCREF(name);
Py_XSETREF(prop->prop_name, name);
Py_RETURN_NONE;
}
static PyMethodDef property_methods[] = {
{"getter", property_getter, METH_O, getter_doc},
{"setter", property_setter, METH_O, setter_doc},
{"deleter", property_deleter, METH_O, deleter_doc},
{"__set_name__", property_set_name, METH_VARARGS, set_name_doc},
{0}
};
@ -1553,6 +1577,7 @@ property_dealloc(PyObject *self)
Py_XDECREF(gs->prop_set);
Py_XDECREF(gs->prop_del);
Py_XDECREF(gs->prop_doc);
Py_XDECREF(gs->prop_name);
Py_TYPE(self)->tp_free(self);
}
@ -1566,7 +1591,12 @@ property_descr_get(PyObject *self, PyObject *obj, PyObject *type)
propertyobject *gs = (propertyobject *)self;
if (gs->prop_get == NULL) {
PyErr_SetString(PyExc_AttributeError, "unreadable attribute");
if (gs->prop_name != NULL) {
PyErr_Format(PyExc_AttributeError, "unreadable attribute %R", gs->prop_name);
} else {
PyErr_SetString(PyExc_AttributeError, "unreadable attribute");
}
return NULL;
}
@ -1584,10 +1614,18 @@ property_descr_set(PyObject *self, PyObject *obj, PyObject *value)
else
func = gs->prop_set;
if (func == NULL) {
PyErr_SetString(PyExc_AttributeError,
if (gs->prop_name != NULL) {
PyErr_Format(PyExc_AttributeError,
value == NULL ?
"can't delete attribute" :
"can't set attribute");
"can't delete attribute %R" :
"can't set attribute %R",
gs->prop_name);
} else {
PyErr_SetString(PyExc_AttributeError,
value == NULL ?
"can't delete attribute" :
"can't set attribute");
}
return -1;
}
if (value == NULL)
@ -1634,6 +1672,9 @@ property_copy(PyObject *old, PyObject *get, PyObject *set, PyObject *del)
Py_DECREF(type);
if (new == NULL)
return NULL;
Py_XINCREF(pold->prop_name);
Py_XSETREF(((propertyobject *) new)->prop_name, pold->prop_name);
return new;
}
@ -1695,6 +1736,8 @@ property_init_impl(propertyobject *self, PyObject *fget, PyObject *fset,
Py_XSETREF(self->prop_set, fset);
Py_XSETREF(self->prop_del, fdel);
Py_XSETREF(self->prop_doc, doc);
Py_XSETREF(self->prop_name, NULL);
self->getter_doc = 0;
/* if no docstring given and the getter has one, use that one */
@ -1769,6 +1812,7 @@ property_traverse(PyObject *self, visitproc visit, void *arg)
Py_VISIT(pp->prop_set);
Py_VISIT(pp->prop_del);
Py_VISIT(pp->prop_doc);
Py_VISIT(pp->prop_name);
return 0;
}

24
configure vendored
View File

@ -623,6 +623,7 @@ ac_includes_default="\
#endif"
ac_subst_vars='LTLIBOBJS
TEST_MODULES
OPENSSL_LDFLAGS
OPENSSL_LIBS
OPENSSL_INCLUDES
@ -852,6 +853,7 @@ with_openssl
with_ssl_default_suites
with_builtin_hashlib_hashes
with_experimental_isolated_subinterpreters
enable_test_modules
'
ac_precious_vars='build_alias
host_alias
@ -1503,6 +1505,7 @@ Optional Features:
--enable-big-digits[=15|30]
use big digits (30 or 15 bits) for Python longs
(default is system-dependent)]
--disable-test-modules don't build nor install test modules
Optional Packages:
--with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
@ -17725,6 +17728,26 @@ $as_echo "no" >&6; }
fi
# Check whether to disable test modules. Once set, setup.py will not build
# test extension modules and "make install" will not install test suites.
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for --disable-test-modules" >&5
$as_echo_n "checking for --disable-test-modules... " >&6; }
# Check whether --enable-test-modules was given.
if test "${enable_test_modules+set}" = set; then :
enableval=$enable_test_modules;
fi
if test "$enable_test_modules" = no; then
TEST_MODULES=no
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
else
TEST_MODULES=yes
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi
# generate output files
ac_config_files="$ac_config_files Makefile.pre Misc/python.pc Misc/python-embed.pc Misc/python-config.sh"
@ -19051,4 +19074,3 @@ if test "$Py_OPT" = 'false' -a "$Py_DEBUG" != 'true'; then
echo "" >&6
echo "" >&6
fi

View File

@ -5834,6 +5834,20 @@ else
fi],
[AC_MSG_RESULT(no)])
# Check whether to disable test modules. Once set, setup.py will not build
# test extension modules and "make install" will not install test suites.
AC_MSG_CHECKING(for --disable-test-modules)
AC_ARG_ENABLE(test-modules,
AS_HELP_STRING([--disable-test-modules], [don't build nor install test modules]))
if test "$enable_test_modules" = no; then
TEST_MODULES=no
AC_MSG_RESULT(yes)
else
TEST_MODULES=yes
AC_MSG_RESULT(no)
fi
AC_SUBST(TEST_MODULES)
# generate output files
AC_CONFIG_FILES(Makefile.pre Misc/python.pc Misc/python-embed.pc Misc/python-config.sh)
@ -5860,4 +5874,3 @@ if test "$Py_OPT" = 'false' -a "$Py_DEBUG" != 'true'; then
echo "" >&AS_MESSAGE_FD
echo "" >&AS_MESSAGE_FD
fi

View File

@ -41,7 +41,7 @@ from distutils.spawn import find_executable
# Compile extensions used to test Python?
TEST_EXTENSIONS = True
TEST_EXTENSIONS = (sysconfig.get_config_var('TEST_MODULES') == 'yes')
# This global variable is used to hold the list of modules to be disabled.
DISABLED_MODULE_LIST = []