From 30f2ad122267c1b5041f8bf78bab2b18b3f93708 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Thu, 9 Mar 2017 19:10:40 +0200 Subject: [PATCH 1/3] bpo-29776: Use decorator syntax for properties. --- Lib/_pydecimal.py | 4 +- Lib/lib2to3/pytree.py | 16 ++++---- Lib/multiprocessing/connection.py | 9 ++++- Lib/multiprocessing/dummy/__init__.py | 10 +++-- Lib/multiprocessing/dummy/connection.py | 4 +- Lib/multiprocessing/managers.py | 4 +- Lib/pydoc.py | 9 ++++- Lib/tarfile.py | 16 +++++--- Lib/tkinter/ttk.py | 11 ++---- Lib/xml/dom/minicompat.py | 20 +++++----- Lib/xml/dom/minidom.py | 49 +++++++++++++++---------- 11 files changed, 91 insertions(+), 61 deletions(-) diff --git a/Lib/_pydecimal.py b/Lib/_pydecimal.py index 0fa152c2a6f8ef..edabf72aa7a3b8 100644 --- a/Lib/_pydecimal.py +++ b/Lib/_pydecimal.py @@ -1674,13 +1674,13 @@ def __int__(self): __trunc__ = __int__ + @property def real(self): return self - real = property(real) + @property def imag(self): return Decimal(0) - imag = property(imag) def conjugate(self): return self diff --git a/Lib/lib2to3/pytree.py b/Lib/lib2to3/pytree.py index c425fe68274246..2a6ef2ef5240a2 100644 --- a/Lib/lib2to3/pytree.py +++ b/Lib/lib2to3/pytree.py @@ -271,7 +271,8 @@ def pre_order(self): for child in self.children: yield from child.pre_order() - def _prefix_getter(self): + @property + def prefix(self): """ The whitespace and comments preceding this node in the input. """ @@ -279,12 +280,11 @@ def _prefix_getter(self): return "" return self.children[0].prefix - def _prefix_setter(self, prefix): + @prefix.setter + def prefix(self, prefix): if self.children: self.children[0].prefix = prefix - prefix = property(_prefix_getter, _prefix_setter) - def set_child(self, i, child): """ Equivalent to 'node.children[i] = child'. This method also sets the @@ -380,18 +380,18 @@ def pre_order(self): """Return a pre-order iterator for the tree.""" yield self - def _prefix_getter(self): + @property + def prefix(self): """ The whitespace and comments preceding this token in the input. """ return self._prefix - def _prefix_setter(self, prefix): + @prefix.setter + def prefix(self, prefix): self.changed() self._prefix = prefix - prefix = property(_prefix_getter, _prefix_setter) - def convert(gr, raw_node): """ Convert raw node information to a Node or Leaf instance. diff --git a/Lib/multiprocessing/connection.py b/Lib/multiprocessing/connection.py index d49e8f0d32b62a..ba9b17cee1b1b5 100644 --- a/Lib/multiprocessing/connection.py +++ b/Lib/multiprocessing/connection.py @@ -465,8 +465,13 @@ def close(self): self._listener = None listener.close() - address = property(lambda self: self._listener._address) - last_accepted = property(lambda self: self._listener._last_accepted) + @property + def address(self): + return self._listener._address + + @property + def last_accepted(self): + return self._listener._last_accepted def __enter__(self): return self diff --git a/Lib/multiprocessing/dummy/__init__.py b/Lib/multiprocessing/dummy/__init__.py index 1abea64419b280..cbb7f4909cb55c 100644 --- a/Lib/multiprocessing/dummy/__init__.py +++ b/Lib/multiprocessing/dummy/__init__.py @@ -98,11 +98,15 @@ class Value(object): def __init__(self, typecode, value, lock=True): self._typecode = typecode self._value = value - def _get(self): + + @property + def value(self): return self._value - def _set(self, value): + + @value.setter + def value(self, value): self._value = value - value = property(_get, _set) + def __repr__(self): return '<%s(%r, %r)>'%(type(self).__name__,self._typecode,self._value) diff --git a/Lib/multiprocessing/dummy/connection.py b/Lib/multiprocessing/dummy/connection.py index 19843751c0c67d..f0ce320fcf5140 100644 --- a/Lib/multiprocessing/dummy/connection.py +++ b/Lib/multiprocessing/dummy/connection.py @@ -26,7 +26,9 @@ def accept(self): def close(self): self._backlog_queue = None - address = property(lambda self: self._backlog_queue) + @property + def address(self): + return self._backlog_queue def __enter__(self): return self diff --git a/Lib/multiprocessing/managers.py b/Lib/multiprocessing/managers.py index b9ce84b2d85ddc..43dd02a5a391c1 100644 --- a/Lib/multiprocessing/managers.py +++ b/Lib/multiprocessing/managers.py @@ -628,7 +628,9 @@ def _finalize_manager(process, address, authkey, state, _Client): except KeyError: pass - address = property(lambda self: self._address) + @property + def address(self): + return self._address @classmethod def register(cls, typeid, callable=None, proxytype=None, exposed=None, diff --git a/Lib/pydoc.py b/Lib/pydoc.py index 49555405c56016..376c4459fe6b00 100644 --- a/Lib/pydoc.py +++ b/Lib/pydoc.py @@ -1868,8 +1868,13 @@ def __init__(self, input=None, output=None): self._input = input self._output = output - input = property(lambda self: self._input or sys.stdin) - output = property(lambda self: self._output or sys.stdout) + @property + def input(self): + return self._input or sys.stdin + + @property + def output(self): + return self._output or sys.stdout def __repr__(self): if inspect.stack()[1][3] == '?': diff --git a/Lib/tarfile.py b/Lib/tarfile.py index c3777ff2dde5f0..2d702dd2ec6af9 100755 --- a/Lib/tarfile.py +++ b/Lib/tarfile.py @@ -761,17 +761,21 @@ def __init__(self, name=""): # In pax headers the "name" and "linkname" field are called # "path" and "linkpath". - def _getpath(self): + @property + def path(self): return self.name - def _setpath(self, name): + + @path.setter + def path(self, name): self.name = name - path = property(_getpath, _setpath) - def _getlinkpath(self): + @property + def linkpath(self): return self.linkname - def _setlinkpath(self, linkname): + + @linkpath.setter + def linkpath(self, linkname): self.linkname = linkname - linkpath = property(_getlinkpath, _setlinkpath) def __repr__(self): return "<%s %r at %#x>" % (self.__class__.__name__,self.name,id(self)) diff --git a/Lib/tkinter/ttk.py b/Lib/tkinter/ttk.py index c474e60713f75e..cbaad76e0084e1 100644 --- a/Lib/tkinter/ttk.py +++ b/Lib/tkinter/ttk.py @@ -1577,20 +1577,17 @@ def adjust_label(): self.label['text'] = newval self.after_idle(adjust_label) - - def _get_value(self): + @property + def value(self): """Return current scale value.""" return self._variable.get() - - def _set_value(self, val): + @value.setter + def value(self, val): """Set new scale value.""" self._variable.set(val) - value = property(_get_value, _set_value) - - class OptionMenu(Menubutton): """Themed OptionMenu, based after tkinter's OptionMenu, which allows the user to select a value from a menu.""" diff --git a/Lib/xml/dom/minicompat.py b/Lib/xml/dom/minicompat.py index 5d6fae9a2575bf..85ef7f346a762a 100644 --- a/Lib/xml/dom/minicompat.py +++ b/Lib/xml/dom/minicompat.py @@ -54,16 +54,16 @@ def item(self, index): if 0 <= index < len(self): return self[index] - def _get_length(self): + @property + def length(self): + """The number of nodes in the NodeList.""" return len(self) - def _set_length(self, value): + @length.setter + def length(self, value): raise xml.dom.NoModificationAllowedErr( "attempt to modify read-only attribute 'length'") - length = property(_get_length, _set_length, - doc="The number of nodes in the NodeList.") - # For backward compatibility def __setstate__(self, state): if state is None: @@ -87,16 +87,16 @@ def __radd__(self, other): def item(self, index): return None - def _get_length(self): + @property + def length(self): + """The number of nodes in the NodeList.""" return 0 - def _set_length(self, value): + @length.setter + def length(self, value): raise xml.dom.NoModificationAllowedErr( "attempt to modify read-only attribute 'length'") - length = property(_get_length, _set_length, - doc="The number of nodes in the NodeList.") - def defproperty(klass, name, doc): get = getattr(klass, ("_get_" + name)) diff --git a/Lib/xml/dom/minidom.py b/Lib/xml/dom/minidom.py index a5d813f932ace3..4558aacc19dd8f 100644 --- a/Lib/xml/dom/minidom.py +++ b/Lib/xml/dom/minidom.py @@ -373,32 +373,38 @@ def _get_localName(self): def _get_specified(self): return self.specified - def _get_name(self): + @property + def name(self): return self._name - def _set_name(self, value): + @name.setter + def name(self, value): self._name = value if self.ownerElement is not None: _clear_id_cache(self.ownerElement) - nodeName = name = property(_get_name, _set_name) + nodeName = name - def _get_value(self): + @property + def value(self): return self._value - def _set_value(self, value): + @value.setter + def value(self, value): self._value = value self.childNodes[0].data = value if self.ownerElement is not None: _clear_id_cache(self.ownerElement) self.childNodes[0].data = value - nodeValue = value = property(_get_value, _set_value) + nodeValue = value - def _get_prefix(self): + @property + def prefix(self): return self._prefix - def _set_prefix(self, prefix): + @prefix.setter + def prefix(self, prefix): nsuri = self.namespaceURI if prefix == "xmlns": if nsuri and nsuri != XMLNS_NAMESPACE: @@ -413,8 +419,6 @@ def _set_prefix(self, prefix): _clear_id_cache(self.ownerElement) self.name = newName - prefix = property(_get_prefix, _set_prefix) - def unlink(self): # This implementation does not call the base implementation # since most of that is not needed, and the expense of the @@ -971,18 +975,22 @@ def __init__(self, target, data): self.data = data # nodeValue is an alias for data - def _get_nodeValue(self): + @property + def nodeValue(self): return self.data - def _set_nodeValue(self, value): + + @nodeValue.setter + def nodeValue(self, value): self.data = value - nodeValue = property(_get_nodeValue, _set_nodeValue) # nodeName is an alias for target - def _get_nodeName(self): + @property + def nodeName(self): return self.target - def _set_nodeName(self, value): + + @nodeName.setter + def nodeName(self, value): self.target = value - nodeName = property(_get_nodeName, _set_nodeName) def writexml(self, writer, indent="", addindent="", newl=""): writer.write("%s%s" % (indent,self.target, self.data, newl)) @@ -1001,12 +1009,15 @@ def _get_length(self): return len(self.data) __len__ = _get_length - def _get_data(self): + @property + def data(self): return self._data - def _set_data(self, data): + + @data.setter + def data(self, data): self._data = data - data = nodeValue = property(_get_data, _set_data) + nodeValue = data def __repr__(self): data = self.data From 703cc7986f702a94c62273a111f3ae950507d3b7 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Thu, 9 Mar 2017 22:05:51 +0200 Subject: [PATCH 2/3] Revert changes for Lib/xml/dom/. --- Lib/xml/dom/minicompat.py | 20 ++++++++-------- Lib/xml/dom/minidom.py | 49 +++++++++++++++------------------------ 2 files changed, 29 insertions(+), 40 deletions(-) diff --git a/Lib/xml/dom/minicompat.py b/Lib/xml/dom/minicompat.py index 85ef7f346a762a..5d6fae9a2575bf 100644 --- a/Lib/xml/dom/minicompat.py +++ b/Lib/xml/dom/minicompat.py @@ -54,16 +54,16 @@ def item(self, index): if 0 <= index < len(self): return self[index] - @property - def length(self): - """The number of nodes in the NodeList.""" + def _get_length(self): return len(self) - @length.setter - def length(self, value): + def _set_length(self, value): raise xml.dom.NoModificationAllowedErr( "attempt to modify read-only attribute 'length'") + length = property(_get_length, _set_length, + doc="The number of nodes in the NodeList.") + # For backward compatibility def __setstate__(self, state): if state is None: @@ -87,16 +87,16 @@ def __radd__(self, other): def item(self, index): return None - @property - def length(self): - """The number of nodes in the NodeList.""" + def _get_length(self): return 0 - @length.setter - def length(self, value): + def _set_length(self, value): raise xml.dom.NoModificationAllowedErr( "attempt to modify read-only attribute 'length'") + length = property(_get_length, _set_length, + doc="The number of nodes in the NodeList.") + def defproperty(klass, name, doc): get = getattr(klass, ("_get_" + name)) diff --git a/Lib/xml/dom/minidom.py b/Lib/xml/dom/minidom.py index 4558aacc19dd8f..a5d813f932ace3 100644 --- a/Lib/xml/dom/minidom.py +++ b/Lib/xml/dom/minidom.py @@ -373,38 +373,32 @@ def _get_localName(self): def _get_specified(self): return self.specified - @property - def name(self): + def _get_name(self): return self._name - @name.setter - def name(self, value): + def _set_name(self, value): self._name = value if self.ownerElement is not None: _clear_id_cache(self.ownerElement) - nodeName = name + nodeName = name = property(_get_name, _set_name) - @property - def value(self): + def _get_value(self): return self._value - @value.setter - def value(self, value): + def _set_value(self, value): self._value = value self.childNodes[0].data = value if self.ownerElement is not None: _clear_id_cache(self.ownerElement) self.childNodes[0].data = value - nodeValue = value + nodeValue = value = property(_get_value, _set_value) - @property - def prefix(self): + def _get_prefix(self): return self._prefix - @prefix.setter - def prefix(self, prefix): + def _set_prefix(self, prefix): nsuri = self.namespaceURI if prefix == "xmlns": if nsuri and nsuri != XMLNS_NAMESPACE: @@ -419,6 +413,8 @@ def prefix(self, prefix): _clear_id_cache(self.ownerElement) self.name = newName + prefix = property(_get_prefix, _set_prefix) + def unlink(self): # This implementation does not call the base implementation # since most of that is not needed, and the expense of the @@ -975,22 +971,18 @@ def __init__(self, target, data): self.data = data # nodeValue is an alias for data - @property - def nodeValue(self): + def _get_nodeValue(self): return self.data - - @nodeValue.setter - def nodeValue(self, value): + def _set_nodeValue(self, value): self.data = value + nodeValue = property(_get_nodeValue, _set_nodeValue) # nodeName is an alias for target - @property - def nodeName(self): + def _get_nodeName(self): return self.target - - @nodeName.setter - def nodeName(self, value): + def _set_nodeName(self, value): self.target = value + nodeName = property(_get_nodeName, _set_nodeName) def writexml(self, writer, indent="", addindent="", newl=""): writer.write("%s%s" % (indent,self.target, self.data, newl)) @@ -1009,15 +1001,12 @@ def _get_length(self): return len(self.data) __len__ = _get_length - @property - def data(self): + def _get_data(self): return self._data - - @data.setter - def data(self, data): + def _set_data(self, data): self._data = data - nodeValue = data + data = nodeValue = property(_get_data, _set_data) def __repr__(self): data = self.data From bb751ec1210a17e2616aad95d11e8bdb19ad8f7d Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Fri, 10 Mar 2017 10:48:50 +0200 Subject: [PATCH 3/3] Fixed test_pyclbr. The test doesn't support properties. --- Lib/test/test_pyclbr.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/test/test_pyclbr.py b/Lib/test/test_pyclbr.py index 2cff1c526ed455..9c216d3eb7b81a 100644 --- a/Lib/test/test_pyclbr.py +++ b/Lib/test/test_pyclbr.py @@ -160,7 +160,7 @@ def test_others(self): cm('aifc', ignore=('openfp', '_aifc_params')) # set with = in module cm('sre_parse', ignore=('dump', 'groups', 'pos')) # from sre_constants import *; property cm('pdb') - cm('pydoc') + cm('pydoc', ignore=('input', 'output',)) # properties # Tests for modules inside packages cm('email.parser')