(original) (raw)
Serhiy's definition sounds recursive (defining \_\_getattr\_\_ to define the behavior of \_\_getattr\_\_) but Mark's suggestion makes his intention unclear since the error message is still the same. Also the word "now" is confusing (does it mean "currently, before the PEP" or "once this PEP is accepted"?)
It would be clearer to first state that Module.\_\_getattribute\_\_ is currently (before the PEP) essentially defined as
class Module(object):It would be clearer to first state that Module.\_\_getattribute\_\_ is currently (before the PEP) essentially defined as
if hasattr(self, '\_\_dict\_\_'):
mod\_name = self.\_\_dict\_\_.get(name)
if isinstance(mod\_name, str):
raise AttributeError("module '%s' has no attribute '%s'" % (mod\_name, name)) if hasattr(self, '\_\_dict\_\_'):
if '\_\_getattr\_\_' in self.\_\_dict\_\_:
getter = self.\_\_dict\_\_\['\_\_getattr\_\_'\] if not callable(getter):
# Unchanged from here on
mod\_name = self.\_\_dict\_\_.get(name)
if isinstance(mod\_name, str):
raise AttributeError("module '%s' has no attribute '%s'" % (mod\_name, name))raise AttributeError("module has no attribute '%s'" % name)
(However exception chaining makes the equivalency still not perfect. And we ignore threading. But how far do we need to go when specifying "equivalent code" to what every implementation should implement natively?)
On Sun, Nov 19, 2017 at 12:48 PM, Mark Shannon <mark@hotpy.org> wrote:
On 19/11/17 20:41, Serhiy Storchaka wrote:
19.11.17 22:24, Mark Shannon пише:
Just one comment. Could the new behaviour of attribute lookup on a module be spelled out more explicitly please?
I'm guessing it is now something like:
\`module.\_\_getattribute\_\_\` is now equivalent to:
def \_\_getattribute\_\_(mod, name):
try:
return object.\_\_getattribute\_\_(mod, name)
except AttributeError:
try:
getter = mod.\_\_dict\_\_\["\_\_getattr\_\_"\]
except KeyError:
raise AttributeError(f"module has no attribute '{name}'")
return getter(name)
I think it is better to describe in the terms of \_\_getattr\_\_.
def ModuleType.\_\_getattr\_\_(mod, name):
try:
getter = mod.\_\_dict\_\_\["\_\_getattr\_\_"\]
except KeyError:
raise AttributeError(f"module has no attribute '{name}'")
return getter(name)
The implementation of ModuleType.\_\_getattribute\_\_ will be not changed (it is inherited from the object type).
Not quite, ModuleType overrides object.\_\_getattribute\_\_ in order to provide a better error message. So with your suggestion, the change would be to \*not\* override object.\_\_getattribute\_\_ and provide the above ModuleType.\_\_getattr\_\_
Cheers,
Mark.
\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: https://mail.python.org/mailman/options/python-dev/guido% 40python.org
--
--Guido van Rossum (python.org/\~guido)