{
 "metadata": {
  "name": ""
 },
 "nbformat": 3,
 "nbformat_minor": 0,
 "worksheets": [
  {
   "cells": [
    {
     "cell_type": "heading",
     "level": 2,
     "metadata": {},
     "source": [
      "``object`` special methods"
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "import sys\n",
      "sys.version"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "metadata": {},
       "output_type": "pyout",
       "prompt_number": 1,
       "text": [
        "'2.7.6 (default, Mar 22 2014, 22:59:56) \\n[GCC 4.8.2]'"
       ]
      }
     ],
     "prompt_number": 1
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "from builtins import object"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [],
     "prompt_number": 2
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "object??"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [],
     "prompt_number": 2
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "# Py3-style iterators written as new-style classes (subclasses of\n",
      "# future.builtins.object) are backward compatible with Py2:\n",
      "class Upper(object):\n",
      "    def __init__(self, iterable):\n",
      "        self._iter = iter(iterable)\n",
      "    def __next__(self):                 # note the Py3 interface\n",
      "        return next(self._iter).upper()\n",
      "    def __iter__(self):\n",
      "        return self"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [],
     "prompt_number": 3
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "assert list(Upper('hello')) == list('HELLO')"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [],
     "prompt_number": 5
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "class AllOrNothing(object):\n",
      "    def __init__(self, l):\n",
      "        self.l = l\n",
      "    def __bool__(self):\n",
      "        return all(self.l)"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [],
     "prompt_number": 6
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "container = AllOrNothing([0, 100, 200])\n",
      "bool(container)"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "metadata": {},
       "output_type": "pyout",
       "prompt_number": 8,
       "text": [
        "False"
       ]
      }
     ],
     "prompt_number": 8
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "container2 = AllOrNothing([-100, 100, 200])\n",
      "bool(container2)"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "metadata": {},
       "output_type": "pyout",
       "prompt_number": 9,
       "text": [
        "True"
       ]
      }
     ],
     "prompt_number": 9
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "Classes derived from Python builtins don't have this behaviour:"
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "class AllOrNothingBroken(list):\n",
      "    def __bool__(self):\n",
      "        print('Called!')\n",
      "        return all(self)"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [],
     "prompt_number": 13
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "container3 = AllOrNothingBroken([0, 1, 2])\n",
      "bool(container3)"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "metadata": {},
       "output_type": "pyout",
       "prompt_number": 14,
       "text": [
        "True"
       ]
      }
     ],
     "prompt_number": 14
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "But subclasses of ``future`` types do:"
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "from builtins import list\n",
      "\n",
      "class AllOrNothingFixed(list):\n",
      "    def __bool__(self):\n",
      "        print('Called!')\n",
      "        return all(self)"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [],
     "prompt_number": 15
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "container4 = AllOrNothingFixed([0, 1, 2])\n",
      "bool(container4)"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "metadata": {},
       "output_type": "pyout",
       "prompt_number": 17,
       "text": [
        "True"
       ]
      }
     ],
     "prompt_number": 17
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [],
     "language": "python",
     "metadata": {},
     "outputs": []
    }
   ],
   "metadata": {}
  }
 ]
}
