update from Atlas with major reorg
This commit is contained in:
45
attic/interfaces/dict_subclass.py
Normal file
45
attic/interfaces/dict_subclass.py
Normal file
@@ -0,0 +1,45 @@
|
||||
# Code and text by BitBucket user "enigmacurry" posted to
|
||||
# https://bitbucket.org/pypy/pypy/issue/708/discrepancy-in-dict-subclass-__getitem__
|
||||
# Adapted by Luciano Ramalho:
|
||||
# - changed comments to docstring to run with doctest;
|
||||
# - added test for Test class raising exception
|
||||
# - and added () to print.
|
||||
|
||||
"""
|
||||
This is a test case to describe a bug I'm seeing in PyPy 1.5. I have
|
||||
a Cache object that is a dictionary that supports lookup via regular
|
||||
attribute access. For instance:
|
||||
|
||||
>>> c = Cache()
|
||||
>>> c["asdf"] = "asdf"
|
||||
>>> c.asdf == c["asdf"]
|
||||
True
|
||||
>>> t = Test()
|
||||
>>> t["asdf"] = "asdf"
|
||||
>>> t.asdf == t["asdf"]
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
Exception: Trying to getitem: asdf
|
||||
|
||||
When looking up keys via attribute, PyPy 1.5 calls __getitem__
|
||||
whereas CPython 2.7.1 does not.
|
||||
"""
|
||||
|
||||
class Cache(dict):
|
||||
"A dictionary that supports attribute style key lookup"
|
||||
def __init__(self, **kw):
|
||||
dict.__init__(self, kw)
|
||||
self.__dict__ = self
|
||||
|
||||
class Test(Cache):
|
||||
def __getitem__(self, item):
|
||||
# I want to process items differently than attributes:
|
||||
raise Exception("Trying to getitem: %s" % item)
|
||||
|
||||
if __name__ == "__main__":
|
||||
t = Test()
|
||||
t["asdf"] = "asdf"
|
||||
#CPython does not call __getitem__ .. PyPy does:
|
||||
print(t.asdf)
|
||||
#Doesn't matter if it's a member of __dict__ or not:
|
||||
print(t.__getattribute__)
|
||||
61
attic/interfaces/exceptions-tree.txt
Normal file
61
attic/interfaces/exceptions-tree.txt
Normal file
@@ -0,0 +1,61 @@
|
||||
BaseException
|
||||
├── SystemExit
|
||||
├── KeyboardInterrupt
|
||||
├── GeneratorExit
|
||||
└── Exception
|
||||
├── StopIteration
|
||||
├── ArithmeticError
|
||||
│ ├── FloatingPointError
|
||||
│ ├── OverflowError
|
||||
│ └── ZeroDivisionError
|
||||
├── AssertionError
|
||||
├── AttributeError
|
||||
├── BufferError
|
||||
├── EOFError
|
||||
├── ImportError
|
||||
├── LookupError
|
||||
│ ├── IndexError
|
||||
│ └── KeyError
|
||||
├── MemoryError
|
||||
├── NameError
|
||||
│ └── UnboundLocalError
|
||||
├── OSError
|
||||
│ ├── BlockingIOError
|
||||
│ ├── ChildProcessError
|
||||
│ ├── ConnectionError
|
||||
│ │ ├── BrokenPipeError
|
||||
│ │ ├── ConnectionAbortedError
|
||||
│ │ ├── ConnectionRefusedError
|
||||
│ │ └── ConnectionResetError
|
||||
│ ├── FileExistsError
|
||||
│ ├── FileNotFoundError
|
||||
│ ├── InterruptedError
|
||||
│ ├── IsADirectoryError
|
||||
│ ├── NotADirectoryError
|
||||
│ ├── PermissionError
|
||||
│ ├── ProcessLookupError
|
||||
│ └── TimeoutError
|
||||
├── ReferenceError
|
||||
├── RuntimeError
|
||||
│ └── NotImplementedError
|
||||
├── SyntaxError
|
||||
│ └── IndentationError
|
||||
│ └── TabError
|
||||
├── SystemError
|
||||
├── TypeError
|
||||
├── ValueError
|
||||
│ └── UnicodeError
|
||||
│ ├── UnicodeDecodeError
|
||||
│ ├── UnicodeEncodeError
|
||||
│ └── UnicodeTranslateError
|
||||
└── Warning
|
||||
├── DeprecationWarning
|
||||
├── PendingDeprecationWarning
|
||||
├── RuntimeWarning
|
||||
├── SyntaxWarning
|
||||
├── UserWarning
|
||||
├── FutureWarning
|
||||
├── ImportWarning
|
||||
├── UnicodeWarning
|
||||
├── BytesWarning
|
||||
└── ResourceWarning
|
||||
40
attic/interfaces/pypy_difference.rst
Normal file
40
attic/interfaces/pypy_difference.rst
Normal file
@@ -0,0 +1,40 @@
|
||||
|
||||
====================================
|
||||
Differences between PyPy and CPython
|
||||
====================================
|
||||
|
||||
Note: this is an excerpt from the `PyPy`_ documentation. On Nov. 19, 2014 I ran this test on PyPy 2.4.0 and PyPy3 2.4.0 and the result was not as described, but was the same as with CPython: 'foo'.
|
||||
|
||||
.. _PyPy: http://pypy.readthedocs.org/en/latest/cpython_differences.html#subclasses-of-built-in-types
|
||||
|
||||
Subclasses of built-in types
|
||||
----------------------------
|
||||
|
||||
Officially, CPython has no rule at all for when exactly
|
||||
overridden method of subclasses of built-in types get
|
||||
implicitly called or not. As an approximation, these methods
|
||||
are never called by other built-in methods of the same object.
|
||||
For example, an overridden ``__getitem__()`` in a subclass of
|
||||
``dict`` will not be called by e.g. the built-in ``get()``
|
||||
method.
|
||||
|
||||
The above is true both in CPython and in PyPy. Differences
|
||||
can occur about whether a built-in function or method will
|
||||
call an overridden method of *another* object than ``self``.
|
||||
In PyPy, they are generally always called, whereas not in
|
||||
CPython. For example, in PyPy, ``dict1.update(dict2)``
|
||||
considers that ``dict2`` is just a general mapping object, and
|
||||
will thus call overridden ``keys()`` and ``__getitem__()``
|
||||
methods on it. So the following code prints ``42`` on PyPy
|
||||
but ``foo`` on CPython::
|
||||
|
||||
>>> class D(dict):
|
||||
... def __getitem__(self, key):
|
||||
... return 42
|
||||
...
|
||||
>>>
|
||||
>>> d1 = {}
|
||||
>>> d2 = D(a='foo')
|
||||
>>> d1.update(d2)
|
||||
>>> print(d1['a'])
|
||||
42
|
||||
31
attic/interfaces/subclassing_builtins.rst
Normal file
31
attic/interfaces/subclassing_builtins.rst
Normal file
@@ -0,0 +1,31 @@
|
||||
====================================
|
||||
Subclassing built-in caveats
|
||||
====================================
|
||||
|
||||
::
|
||||
|
||||
>>> class D1(dict):
|
||||
... def __getitem__(self, key):
|
||||
... return 42
|
||||
...
|
||||
>>> d1 = D1(a='foo')
|
||||
>>> d1
|
||||
{'a': 'foo'}
|
||||
>>> d1['a']
|
||||
42
|
||||
>>> d1.get('a')
|
||||
'foo'
|
||||
|
||||
::
|
||||
|
||||
>>> class D2(dict):
|
||||
... def get(self, key):
|
||||
... return 42
|
||||
...
|
||||
>>> d2 = D2(a='foo')
|
||||
>>> d2
|
||||
{'a': 'foo'}
|
||||
>>> d2['a']
|
||||
'foo'
|
||||
>>> d2.get('a')
|
||||
42
|
||||
Reference in New Issue
Block a user