Skip to content

Commit

Permalink
Sync with 'main' bco. pythonGH-27884
Browse files Browse the repository at this point in the history
  • Loading branch information
Erlend E. Aasland committed Aug 25, 2021
2 parents fe0fd6f + 3df0fc8 commit 0633095
Show file tree
Hide file tree
Showing 56 changed files with 2,161 additions and 389 deletions.
2 changes: 1 addition & 1 deletion Doc/c-api/exceptions.rst
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ For convenience, some of these functions will always return a
This is the most common way to set the error indicator. The first argument
specifies the exception type; it is normally one of the standard exceptions,
e.g. :c:data:`PyExc_RuntimeError`. You need not increment its reference count.
The second argument is an error message; it is decoded from ``'utf-8``'.
The second argument is an error message; it is decoded from ``'utf-8'``.
.. c:function:: void PyErr_SetObject(PyObject *type, PyObject *value)
Expand Down
49 changes: 49 additions & 0 deletions Doc/faq/programming.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1826,6 +1826,55 @@ For example, here is the implementation of
return True
return False


How can a subclass control what data is stored in an immutable instance?
------------------------------------------------------------------------

When subclassing an immutable type, override the :meth:`__new__` method
instead of the :meth:`__init__` method. The latter only runs *after* an
instance is created, which is too late to alter data in an immutable
instance.

All of these immutable classes have a different signature than their
parent class:

.. testcode::

from datetime import date

class FirstOfMonthDate(date):
"Always choose the first day of the month"
def __new__(cls, year, month, day):
return super().__new__(cls, year, month, 1)

class NamedInt(int):
"Allow text names for some numbers"
xlat = {'zero': 0, 'one': 1, 'ten': 10}
def __new__(cls, value):
value = cls.xlat.get(value, value)
return super().__new__(cls, value)

class TitleStr(str):
"Convert str to name suitable for a URL path"
def __new__(cls, s):
s = s.lower().replace(' ', '-')
s = ''.join([c for c in s if c.isalnum() or c == '-'])
return super().__new__(cls, s)

The classes can be used like this:

.. doctest::

>>> FirstOfMonthDate(2012, 2, 14)
FirstOfMonthDate(2012, 2, 1)
>>> NamedInt('ten')
10
>>> NamedInt(20)
20
>>> TitleStr('Blog: Why Python Rocks')
'blog-why-python-rocks'


How do I cache method calls?
----------------------------

Expand Down
Loading

0 comments on commit 0633095

Please sign in to comment.