• TITLE
``````PROMPT
``````

• HINT1

Solution:

``````SOLUTION
``````

EXPLANATION

• Members of Room 6 occasionally pose riddles involving lesser-known quirks of the Python language. These riddles are reproduced here.

(Click the title of a riddle to expand it.)

### Regular Riddles

1. Inequality Loop (Python 2.7 only)
``````>>> # create x, y, z such that
>>> x < y < z < x
True
``````
Solution:
``````>>> x = b"Z"
>>> y = ()
>>> z = u"A"
>>> x < y < z < x
True
``````

The default method of comparison between dissimilar non-number types is to compare their type names alphabetically. “str” comes before “tuple” and “tuple” comes before “unicode”, so x < y and y < z. Strings and unicode are compared by converting the 8-bit string to unicode and comparing their values alphabetically. u"A" < u"Z", so z < x.

2. Circumvent a contextmanager’s `__exit__`
``````>>> class CM:
...     def __enter__(self):
...         return self
...     def __exit__(self, *args):
...         print('hello world')
...
>>> with CM() as cm:
...     ...
...     # your code
...
goodbye world
```
no patching out print or any lame hack like that
```
Solution:
``````with CM() as cm:
def my_exit(*args):
print('goodbye world')

CM.__exit__.__code__ = my_exit.__code__
``````
3. Importing modules after deleting `__builtins__.__import__`
``````\$ python3 -ic 'url = "http://httpbin.org/status/402"'
>>> del __builtins__.__import__
>>> # your code here
...
>>> requests.get(url).text
'F**k you, pay me!'
``````
Solution:
``````__builtins__.__spec__.loader.create_module(__builtins__.__spec__); import requests
``````
4. Importing modules after deleting `__builtins__.__import__` and `__builtins__`
``````\$ python3 -ic 'url = "http://httpbin.org/status/402"'
>>> del __builtins__.__import__, __builtins__
>>> # your code here
...
>>> requests.get(url).text
'F**k you, pay me!'
``````
Solution:
``````__builtins__ = __loader__.create_module(__loader__.find_spec('builtins')); import requests
``````
5. Importing modules after deleting `__builtins__.__import__` and clearing globals()
``````\$ python3 -ic 'url = "http://httpbin.org/status/402"'
>>> del __builtins__.__import__
>>> globals().clear()
>>> # your code here
...
>>> requests.get(url).text
'F**k you, pay me!'
``````
Solution:
``````type = ''.__class__.__class__
ABCMeta = type.__subclasses__(type)
abc_globals = ABCMeta.register.__globals__
importlib_globals = abc_globals['__loader__'].get_data.__globals__
__builtins__ = importlib_globals['sys'].modules['builtins']
__builtins__.__spec__.loader.create_module(__builtins__.__spec__)
import requests
``````
6. Crash a function with code that’s never executed
``````x = 23

def f():
print(x)
return
#add a statement here that will make this program crash with something other than a Syntax Error

f()
``````
Solution:
``````x = 23

def f():
print(x)
return
x = 1

f()
``````

One way that python determines whether a name is global/nonlocal/local is by looking for assignment statements using that name. Whether that statement ever actually executes is irrelevant.

7. Crash a function with code that’s never executed #2
``````seq = []
def a():
def b():
seq.append(23)
return b()
#add one statement here that will make this program crash
a()
``````
Solution:
``````seq = []
def a():
def b():
seq.append(23)
return b()
seq = None
a()
``````

Same as riddle 1. Oops, this is redundant, isn’t it?

8. Sometimes `return None` is different from no `return` at all
``````# Write a function that fulfils the following criteria:
#
# 1. The function ends with `return None`.
# 2. If `return None` is changed to `pass`, the function's behavior changes.
``````
• The solution is related to exceptions. Kind of.
Solution:
``````def fn():
try:
return 42
finally:
return None
``````

Since the code in the `finally` block is executed after the code in the `try` block, it overrides the previous return value.

9. Same code, different output
``````#a.py
try:
#some statement goes here
except:
print("Oh no, something went wrong!")

#output:
#Oh no, something went wrong!

#b.py
#some statement goes here
#output: nothing

# Determine the contents of "some statement goes here" so these programs produce the output described.
``````
Solution:
``````raise SystemExit
``````

`SystemExit` exceptions are treated in a special way by the interpreter. If a `SystemExit` is raised and not caught, the process will exit without printing a stack trace.

10. Create an instance without executing `__init__`
``````# Create an instance of Bomb without crashing the program.
# Monkeypatching __init__ is not allowed.

class Bomb:
def __init__(self):
raise RuntimeError('BOOM')

bomb = ...  # YOUR CODE HERE

assert type(bomb) is Bomb, "You didn't create a Bomb instance, did you?"
print('You win!')
``````
Solution:
``````bomb = Bomb.__new__(Bomb)
``````

When a class is called (like `Bomb()`), python first calls `__new__` to create a new instance of that class, and then automatically calls `__init__` to initialize the newly created instance. By calling `__new__` directly, we can avoid `__init__` being called automatically.

11. Delete a variable without using `del`
``````# Delete the `x` variable without using the `del` statement, and without
# accessing the globals dictionary.

import builtins
del builtins.globals, builtins.locals, builtins.vars

x = 5

... # your code here

try:
x
assert False, 'x still exists'
except NameError:
print('You win!')
``````
• The solution is related to exceptions.
Solution:
``````try:
raise whatever
except Exception as x:
pass
``````

In newer python versions, the `except` clause automatically deletes the name the exception was bound to.

12. Prevent an exception from being raised
``````def f():
raise Exception("Oops")
#add a statement here so this program does not crash

f()
``````
Solution:
``````def f():
raise Exception("Oops")
yield

f()
``````

A function with a yield statement is considered a generator function. This is true even if the yield statement can never be reached. Generators do not execute their code unless you iterate over them, so just calling f() here does not raise the Exception.

13. A curious interaction with `nonlocal`
``````# replace '???' in this program with a single statement, satisfying these constraints:
# - the statement is not an assignment statement or augmented assignment statement.
# - the program runs without crashing.
# - if you delete `nonlocal x`, the program crashes.

def a():
x = 1
def b():
nonlocal x
#???
b()
a()
``````
Solution:
``````exec("x")
``````

Normal code can see names in any containing scope, but code in exec can only see the local scope and the global scope. Without `nonlocal x`, x won’t be in the locals() dict.

14. Find the builtin class that returns a subclass instance
``````# Find a builtin class (and a corresponding argument tuple) that returns an
# instance of a subclass when it's called. For example, if int('True') returned
# a boolean, it would be a solution to this puzzle.

...  # your code here
cls = ...  # your code here
args = ...  # your code here

assert isinstance(cls(*args), cls), "Calling that class didn't return an instance of that class"
assert type(cls(*args)) is not cls, "Calling that class returned a direct instance of that class"
print('You win!')
``````
Solution:
``````class Meta(type):
pass

class ClsWithMeta(metaclass=Meta):
pass

cls = type
args = 'foo', (ClsWithMeta,), {}
``````

In addition to the well-known single-argument form `type(obj)`, `type` also has a 3-argument form: `type(cls_name, base_classes, attr_dict)` creates a new class.

15. Create a recursive list in a single line
``````Using a single statement, create a self-referential list a such that a is a.
``````
Solution:
``````a = a = 
``````

An assignment with multiple target lists evaluates the right-hand expression, and assigns it to each of the target lists from left to right. So `a = a = ` is equivalent to `a = ` followed by `a = `. Note that `a = ; a = ` does not have the same effect because the two `` literals resolve to two different objects.

16. Check if a bunch of iterables are empty without using any variables
``````# Complete the following function, which checks whether all iterables in
# the input list are empty. Your function may not use any variables or other
# functions (including lambdas) or list/dict/whatever comprehensions. Recursion
# is also forbidden.

def empty_test(list_of_iterables):
... # your code here

assert empty_test(['', (), {}, iter([])]) == True
assert empty_test(['foo']) == False

import types
assert len(empty_test.__code__.co_varnames) == 1, "You're not allowed to use variables"
assert not empty_test.__code__.co_names, "You're not allowed to use functions"
assert not any(isinstance(c, types.CodeType) for c in empty_test.__code__.co_consts), "You're not allowed to use lambdas"

print('You win!')
``````
• Python lets us assign values to multiple variables in a single statement. But why am I telling you this if you’re not allowed to use variables? Hmm…
Solution:
``````def empty_test(list_of_iterables):
try:
for () in list_of_iterables:
pass
return True
except:
return False
``````

Python allows us to assign values to multiple variables at the same time with the `a, b = [1, 2]` syntax. What most people don’t realize is that the left-hand side of the assignment is actually parsed like a tuple (`(a, b)`). And it turns out that assigning to an empty tuple is perfectly valid: `() = an_empty_iterable`. If the iterable isn’t empty, an exception is thrown because the number of variables doesn’t match the number of values - the function simply needs to catch that exception and return `False`.

17. Create two identical variables in a single line
``````try:
w, x = x, w = ...  # Your Code Here
except:
raise Exception('Does Not Compute.  Try Again.')

assert w == x, 'Not Equal!'
print('You win!')
``````
Solution:
``````w, x = x, w = [{}] * 2
``````
18. Arbitrary code execution with `pickle.load`
``````# Write a class that sets the global `winner` variable to `True` when unpickled.

import pickle

class Evil:
...  # YOUR CODE HERE

data = pickle.dumps(Evil())
del Evil
winner = False
pickle.loads(data)

assert winner, "You didn't toggle the variable"
print('You win!')
``````
Solution:
``````class Evil:
def __reduce__(self):
return (exec, ("globals()['winner'] = True",))
``````

The `__reduce__` method allows us to customize how instances of our class are pickled. It can return a factory function and an argument tuple that will be used to re-create the pickled instance. Using `exec` as the factory is an easy way to run arbitrary code.

19. In python you can choose your friends and your family
``````# Kid has inherited a bad hobby from its Dad. Find a way to remove the Kid's
# hobby - without removing it from the Dad. Hacks that raise AttributeError
# when the hobby is accessed are forbidden. Overwriting Kid isn't allowed.

class Mom:
talent = 'singing'

class Dad:
hobby = 'drinking'

class Kid(Mom, Dad):
pass

...  # YOUR CODE HERE (not limited to 1 line)

assert not hasattr(Kid, 'hobby'), "You didn't remove the Kid's hobby"
assert 'hobby' not in vars(Kid), "Kid must not have a 'hobby' property"
assert hasattr(Dad, 'hobby'), "Removing the dad's hobby is not allowed"
assert vars(Dad)['hobby'] == 'drinking', "Overwriting the dad's hobby is not allowed"
print('You win!')
``````
• You have to help `Kid`’s parents get a divorce.
Solution:
``````Kid.__bases__ = (Mom,)
``````

`__bases__` is a tuple that contains a class’s parents - and it turns out that you can change a class’s parents by assigning to it!

20. Another curious interaction with `nonlocal`
``````# Fix the foo function without binding the name x!
# (https://docs.python.org/3/reference/executionmodel.html#binding-of-names)

def foo():
...  # YOUR CODE HERE

def bar():
nonlocal x
x = 3

bar()
return x

assert foo() == 3
print('You win!')
``````
• “hints”. That’s the hint. The hint is “hints”.
Solution:
``````x: int
``````

It turns out that `nonlocal` interacts with type hints.

21. Create 3 dicts that are equal, but not really
Create dict instances x,y,z such that `x == y` and `y == z` but not `x == z`
• In 2.7 it is possible with normal dicts. In 3.x the 2.7 trick no longer works, but it’s still possible using dict subclass from `collections`.
Solution:
``````from collections import OrderedDict

x = OrderedDict(["ab", "cd"])
y = {"a": "b", "c": "d"}
z = OrderedDict(["cd", "ab"])
``````
22. Create 3 datetimes that are equal, but not really
Create datetime instances x,y,z such that `x == y` and `y == z` but not `x == z`
Solution:
``````No solution posted yet :(
``````
23. Create an attribute that doesn’t show up in the `__dict__`
``````# Create a class with an attribute that doesn't show up in the __dict__
# without using descriptors or __setattr__. (Note: Technically, the solution
# DOES create descriptors... but it's against the rules to make your own.)

class ValidatorMeta(type):
def __new__(mcs, name, bases, attrs):
assert 'x' not in attrs, "Using descriptors isn't allowed"
assert '__setattr__' not in attrs, "Using __setattr__ isn't allowed"
assert '__dict__' not in attrs, "Shadowing __dict__ isn't allowed"
return super().__new__(mcs, name, bases, attrs)

class SomeClass(metaclass=ValidatorMeta):
...  # YOUR CODE HERE

obj = SomeClass()
obj.x = 3
obj.y = 5
assert vars(obj) == {'y': 5}

print('You win!')
``````
Solution:
``````__slots__ = ('x', '__dict__')
``````

From the docs:

`__slots__` allow us to explicitly declare data members (like properties) and deny the creation of `__dict__` and `__weakref__` (unless explicitly declared in `__slots__` or available in a parent.)
We create a `__dict__` slot so that `obj` will have a dict to store `y` in, and by creating an `x` slot we ensure that `x` isn’t stored in the __dict__ as well.

24. Making `__slots__` disappear
``````# Complete the following class in such a way that its instances have a
# __dict__, yet "__dict__" can't be found in the __slots__ definition.
# WARNING: Some weasel words were used in the previous sentence.
# The solution is a single line of code; no semicolons and no shadowing builtins.

class Cls:
__slots__ = ...  # YOUR CODE HERE

obj = Cls()
assert hasattr(obj, '__dict__'), "You didn't create a __dict__ slot"
assert '__dict__' not in Cls.__slots__, "__dict__ may not appear in __slots__"
print('You win!')
``````
• The description said `"__dict__"` can’t be found in the `__slots__` definition", but that doesn’t mean it was never there. How can you make it disappear?
Solution:
``````__slots__ = iter(['__dict__'])
``````

Any kind of iterable can be assigned to `__slots__`. Using an iterator allows python to see `"__dict__"` in the `__slots__` definition, but afterwards the iterator is exhausted and empty, and the assertions pass.

### Open Ended Riddles

These riddles have no known solution, or many possible solutions.

1. The recursive tuple
Is it possible to construct a tuple that contains itself? e.g. `t is t` is True.
Solution:

Unknown. Experimentation with the ctypes module has had some success (example), but this causes reference counting problems and occasionally segfaults.

2. Implement `super` in pure python
``````# Implement the super function in pure python! (Specifically, the
# super(class, instance) form.)

class my_super:
...  # YOUR CODE HERE
``````
Solution:
``````class my_super:
def __init__(self, cls, inst):
self.cls = cls
self.inst = inst

def __getattr__(self, attr):
# from self.inst's class's MRO, get a list of classes that
# appear AFTER self.cls
mro = type(self.inst).mro()
i = mro.index(self.cls)
mro = mro[i+1:]

# see if any of those classes has the requested attribute
for cls in mro:
try:
result = vars(cls)[attr]
break
except KeyError:
pass
else:
# if no class has it, throw an exception
raise AttributeError(attr)

# if the result is a descriptor, call its __get__ method
if hasattr(type(result), '__get__'):
result = result.__get__(self.inst, type(self.inst))

return result
``````
3. Implement the `@classmethod` decorator
Implement a clone of the `@classmethod` decorator. (Without using `classmethod`, duh.)
Solution:
``````from functools import partial

# this class is a descriptor: https://docs.python.org/3/howto/descriptor.html
class my_classmethod:
def __init__(self, func):
self.func = func

def __get__(self, instance, owner):
# If accessed from an instance:
#   instance = the instance
#   owner = type(instance)
# If accessed from a class:
#   instance = None
#   owner = the class

# return a callable with the class baked in as the first argument
return partial(self.func, owner)
``````

Functions are descriptors - when they’re accessed via an instance, they return a bound method, where the first argument is implicitly set to the instance. In order to prevent this from happening, we implement `classmethod` as a descriptor that binds the class (instead of the instance) to the method.

### Code Golf Riddles

These riddles ask you to achieve a certain goal with as little code as possible.

1. Cause a `RecursionError`
Raise a `RecursionError`.
Solutions:
``````# 24 characters
x,y=x,y={},{};x==y

# 20 characters
raise RecursionError

# 19 characters
s="eval(s)";eval(s)

# 16 characters
f=lambda:f();f()

# 15 characters
def f():f()
f()

# 14 characters (REPL only)
lambda:_();_()
``````
2. Cause a `TypeError`
Raise a `TypeError`.
Solutions:
``````# 3 characters
0()
+''
1@1
``````

### Guess-The-Output Riddles

These riddles do not ask you to write code; rather, they ask you to predict what the output of the code is without running it first.

1. Fun with multiple target lists in assignment
``````>>> x, y = x[y] = {}, 0
>>> x
<you guess the output>
``````
Solution:
``````{0: ({...}, 0)}
``````

The leftmost target list gets assigned first, so `x` binds to `{}` and `y` binds to `0`. Then the next target list is assigned, so `x` gets set to `(x, 0)`. So ultimately x is a dict with a single key `0` and a self-referential tuple value.

2. Class scope resolution curiosities
```Guess the output of these two programs:
```#PART 1
x = 0
def f():
x = 1
class A:
x = 2
class B:
print(x)

f()

#PART 2
x = 0
def f():
x = 1
class A:
x = 2
class B:
print(x)
x = 3
f()
``````
Solution:
``````1
0
``````

There are two quirks of the name resolution system that cause this behavior. Refer to the docs. First, “the scope of names defined in a class block is limited to the class block”. This means that in part 1, The `x = 2` bound inside class A is not visible to class B, even though class B’s context is inside class A. The next closest visible nonlocal `x` is the one in `f`, so `print(x)` prints 1. Second, “[in a class definition] unbound local variables are looked up in the global namespace”. By adding `x = 3` to the `class B` scope, `x` becomes a local variable. Since it hasn’t been assigned to yet when `print(x)` executes, it is an unbound local variable. In a normal context, this would crash with `UnboundLocalError`. But because it’s inside a class definition, `x` is looked up in the global namespace instead. So `print(x)` prints 0.

3. What happens if you inherit from an object?
``````# What's the output of this code?

class Mystery:
def __init__(self, *args):
if args:
print(args)

obj = Mystery()

class Unknown(obj):
pass
``````
• Metaclasses!
Solution:
``````Unknown
#(Which is not to say that it's not known what the output is. The output is literally the word "Unknown")
``````

When you create a class, the first thing python does is to determine the metaclass. A metaclass is a class’s type. Python determines which metaclass to use by checking the metaclasses of all parent classes, and choosing the one that’s a child class of all the others (if no such class exists, a “metaclass conflict” exception is raised.) Once the metaclass has been determined, python calls it with 3 arguments: The name of the new class, a list of base classes, and a dict of class attributes. The return value is your new class.
So what does this have to with the riddle? Well, it turns out that python doesn’t really care if you’re inheriting from classes or from something else. When we inherit from `obj`, python determines its metaclass by calling `type(obj)`. This returns `Mystery`, so `Mystery` will be used as the metaclass for `Unknown`. Python then calls `Mystery` with the usual 3 arguments passed to metaclasses: `Mystery("Unknown", [obj], {})`. `Mystery` prints the first of these 3 arguments, which gives us the output “Unknown”.

4. Name mangling
``````#What's the output of this code?
__var = 'option 1'
_Cls__var = 'option 2'

class Cls:
__var = 'option 3'

def test(self):
return __var

print(Cls().test())
``````
Solution:
option 2

It turns out that python’s name-mangling mechanism for double-underscore variables doesn’t only apply to class or instance attributes.

5. Overriding `__type__` does weird things
``````class A(object):
def hello(self):
print("A")

class B(object):
__class__ = A

def hello(self):
print("B")

obj = B()

print(type(obj).__name__)
print(obj.__class__.__name__)
print(isinstance(obj, A))
print(isinstance(obj, B))
obj.hello()
``````
Solution:
``````B
A
True
True
B
``````
6. Nested f-strings
``````char = 't'
num = 4
t = 'foo'

print(f'{char}')
print(f'{f"{char}"}')
print(f'{f"{char}":z<{num}}')
print(f'{f"{char}":z<{f"{num+1}"}}')
``````
Solution:
``````t
t
tzzz
tzzzz
``````
7. Using `@classmethod` on a class
``````class Foo:
@classmethod
class Bar:
def __new__(*args):
print(*args)

Foo.Bar(5)
``````
• Don’t make it more complicated than it needs to be… Just remember that `classmethod` adds the class as the first argument, and that `__new__` is also a classmethod.
Solution:
``````<class '__main__.Foo.Bar'> <class '__main__.Foo'> 5
``````

Like the hint said, `classmethod` adds the class as the first argument. Initially, the arguments are just `5`. Since `Foo.Bar` is a classmethod, it adds `Foo`, so now the arguments are `Foo, 5`. `Bar.__new__` is also a classmethod, so it adds `Bar`, resulting in `Bar, Foo, 5`.