A few days earlier, I was checking what all builtins could be inherited from, and found out that enumerate
and filter
could also be inherited from.
yesterday, I was checking what all arguments could be provided to defaultdict, and gave the same enumerate
and filter
to it, it did not give an error.
but it turns out that there is no way to use it.
again, I ran the check for more builtins, similar for the inheritance case.
from collections import defaultdict
import keyword, re
passed = set()
failed = set()
for i, j in keyword.__builtins__.items():
if not re.search('Error|Warning|__|ipython', i):
try:
x = defaultdict(eval(i))
passed.add(i)
except:
failed.add(i)
passed
{'BaseException', 'Exception', 'GeneratorExit', 'KeyboardInterrupt', 'None',
'StopAsyncIteration', 'StopIteration', 'SystemExit', 'abs', 'all', 'any',
'ascii', 'bin', 'bool', 'breakpoint', 'bytearray', 'bytes', 'callable', 'chr',
'classmethod', 'compile', 'complex', 'copyright', 'credits', 'delattr', 'dict',
'dir', 'display', 'divmod', 'dreload', 'enumerate', 'eval', 'exec', 'execfile',
'filter', 'float', 'format', 'frozenset', 'getattr', 'globals', 'hasattr',
'hash', 'help', 'hex', 'id', 'input', 'int', 'isinstance', 'issubclass',
'iter', 'len', 'license', 'list', 'locals', 'map', 'max', 'memoryview', 'min',
'next', 'object', 'oct', 'open', 'ord', 'pow', 'print', 'property', 'range',
'repr', 'reversed', 'round', 'runfile', 'set', 'setattr', 'slice', 'sorted',
'staticmethod', 'str', 'sum', 'super', 'tuple', 'type', 'vars', 'zip'}
failed
{'Ellipsis', 'False', 'NotImplemented', 'True'}
running the same check with keyword.kwlist
gives passed
as None
and rest all are in failed
.
I did further check, if an element could be accessed like x['a']
passed_both = set()
passed_first_failed_second = set()
for i in passed:
try:
x = defaultdict(eval(i))
y = x['a']
passed_both.add(i)
except:
passed_first_failed_second.add(i)
I think so, some of it is triggering debugger, so, I had to press q
four times.
passed_both
{'BaseException', 'Exception', 'GeneratorExit', 'KeyboardInterrupt',
'StopAsyncIteration', 'StopIteration', 'SystemExit', 'bool', 'bytearray',
'bytes', 'complex', 'copyright', 'credits', 'dict', 'dir', 'display', 'float',
'frozenset', 'globals', 'help', 'input', 'int', 'license', 'list', 'locals',
'object', 'print', 'property', 'set', 'str', 'tuple', 'vars', 'zip'}
passed_first_failed_second
{'None', 'abs', 'all', 'any', 'ascii', 'bin', 'breakpoint', 'callable', 'chr',
'classmethod', 'compile', 'delattr', 'divmod', 'dreload', 'enumerate', 'eval',
'exec', 'execfile', 'filter', 'format', 'getattr', 'hasattr', 'hash', 'hex',
'id', 'isinstance', 'issubclass', 'iter', 'len', 'map', 'max', 'memoryview',
'min', 'next', 'oct', 'open', 'ord', 'pow', 'range', 'repr', 'reversed',
'round', 'runfile', 'setattr', 'slice', 'sorted', 'staticmethod', 'sum',
'super', 'type'}
probably, it should raise an error as soon as the user specifies keywords in passed_first_failed_second
just like it does for True
, False
.
x = defaultdict(super)
y = defaultdict(staticmethod)
they cannot be used, so, why not raise an error directly?
one more thing I did was to specify a function with one of those names, for example,
def enumerate():
return 1
x = defaultdict(enumerate)
x['a']
gives 1
for such a case, shouldn’t it raise an error if the function requires arguments?
def enumerate(a, b):
return 1
x = defaultdict(enumerate)
is it possible to check that the function provided to defaultdict
does not take any argument here itself, else raise an error?
something like this,
import inspect
class CustomDefaultDict(defaultdict):
def __init__(self, arg):
if inspect.isfunction(arg):
if arg.__code__.co_argcount > 0:
raise TypeError('function with more than one argument not allowed')
super().__init__(arg)
but this would not work for builtin functions.