[Python-Dev] Comment on PEP 562 (Module __getattr__ and __dir__)

Guido van Rossum guido at python.org
Sun Nov 19 20:02:50 EST 2017


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):
  def __getattribute__(self, name):
    try:
      return object.__getattribute__(self, name)
    except AttributeError:
      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))
      raise AttributeError("module has no attribute '%s'" % name)

The PEP changes the contents of the except clause to:

      if hasattr(self, '__dict__'):
        if '__getattr__' in self.__dict__:
          getter = self.__dict__['__getattr__']
          if not callable(getter):
            raise TypeError("module __getattr__ must be callable")
          return getter(name)
        # 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 at 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 at 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)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-dev/attachments/20171119/756ff919/attachment.html>


More information about the Python-Dev mailing list