Steven D'Aprano added the comment:
The plot thickens.
I was wrong to say that type() always and only looks at the "real" underlying
type of the instance. type() does look at __class__ as well. But only sometimes.
>>> class A:
... __class__ = int
...
>>> type(A())
>>> a = A()
>>>
Gabriele N Tornetta added the comment:
@rhettinger
Apologies. You're totally right but I wasn't expecting this to become a lengthy
conversation.
So, to get closer to the initial issue, I believe that this ticket could be
closed provided that the documentation is improved by making
Steven D'Aprano added the comment:
On Fri, Dec 10, 2021 at 12:03:15AM +, Gabriele N Tornetta wrote:
> class Side(object):
> def __getattribute__(self, name):
> ValueError(name)
You forgot to actually *raise* the exception. That will just instantiate
the ValueError instance,
Steven D'Aprano added the comment:
I agree that the rules regarding type and `__class__` and isinstance are
not clear or well documented.
We have:
https://docs.python.org/3/library/stdtypes.html#instance.__class__
https://docs.python.org/3/library/functions.html#isinstance
but neither
Raymond Hettinger added the comment:
> Changing the way isinstance works internally might prove
> beneficial for such tools.
ISTM you're advocating a design change rather than discussing a bug report.
The python-ideas mail list would be a better forum than the tracker.
--
nosy:
Gabriele N Tornetta added the comment:
> Python is very much a language about responsibility. If Django is overriding
> `__getattribute__` then it is their responsibility to ensure that everything
> still works properly.
Perhaps I didn't stress observability enough. A tool like a tracer or
Ethan Furman added the comment:
$ python3
Python 3.8.10 (default, Sep 28 2021, 16:10:42)
[GCC 9.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> object
>>> import builtins
>>> builtins.object
>>> builtins.object = int
>>> object
Python is very
Gabriele N Tornetta added the comment:
> I tend to agree with Steven and David here. You define __getattribute__ and
> so that's the behaviour you get when an attribute of the class is requested
> (whether by the system or by your code).
I would agree if it was obvious or explicitly stated
Paul Moore added the comment:
I tend to agree with Steven and David here. You define __getattribute__ and so
that's the behaviour you get when an attribute of the class is requested
(whether by the system or by your code). The documentation (here:
Steven D'Aprano added the comment:
If you don't want to customise attribute access, don't overload
`__getattribute__`. The documentation for `__getattribute__` is clear
about what it does:
"Called unconditionally to implement attribute accesses for instances of
the class."
Gabriele N Tornetta added the comment:
I think the issue on display here is that isinstance could cause a side effect,
which I dare say it's unexpected (and not documented AFAIK). Are there any
reasons why __class__ cannot be retrieved with object.__getattribute__ instead?
In fact,
Steven D'Aprano added the comment:
I'd be inclined to see this as a bug in your code, if you are causing
side-effects from `__getattribute__`. If you don't want attribute access to
cause side-effects, then don't put code in `__getattribute__` that causes
side-effects :-)
isinstance has to
Gabriele N Tornetta added the comment:
The following example shows isinstance causing a side effect
class Side:
class Effect(Exception):
pass
def __getattribute__(self, name):
raise Side.Effect()
isinstance(Side(), str)
I'd be inclined to see this as a bug as I
Steven D'Aprano added the comment:
Dan, I don't understand what you think the code snippet shows: you're calling
isclass on an object which *actually is a class* and show that it returns True.
What did you expect it to return? How does the code snippet you give
R. David Murray added the comment:
I don't think this is a bug. There are many ways to lie in Python. If your
object lies, it is on your head when things break :) On the flip side, the
ability to lie is very handy in many circumstances, and is often a case of duck
New submission from Dan Snider :
It doesn't even care if the result it gets from
ob.__getattribute__("__class__") isn't a type.
Surely `isinstance` is intended to do what it is named and be guaranteed to
return True if an object `ob` is an instance of class `cls`.
16 matches
Mail list logo