[issue23276] hackcheck is broken in association with __setattr__

2020-11-30 Thread Irit Katriel


Change by Irit Katriel :


--
resolution:  -> out of date
stage:  -> resolved
status: pending -> closed

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue23276] hackcheck is broken in association with __setattr__

2020-11-08 Thread Irit Katriel


Irit Katriel  added the comment:

I tried to look up what pyqtWrapperType is and found that it has been removed 
from QtCore.

Is this issue still relevant?

--
nosy: +iritkatriel
status: open -> pending

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue23276] hackcheck is broken in association with __setattr__

2015-01-20 Thread Alfred Krohmer

Alfred Krohmer added the comment:

Can you elaborate what QtClass and QtMeta is in your case?

My original example was reduced to a minimal case and seems to work with your 
suggestions.

The complete example involving SQLalchemy is here:

http://stackoverflow.com/questions/28032928/sqlalchemy-multiple-base-classes-not-working

and does, however, not work.

If I try to do

# ...

def __setattr__(cls, key, value):
super(type(QMediaPlaylist), cls).__setattr__(cls, key, value)
return

The program segfaults when instantiating the Playlist class. However, this 
approach seems a little bit strange to me anyhow.

The same happens when I try to do:

# ...

def __setattr__(cls, key, value):
super(type(base), cls).__setattr__(cls, key, value)
return

I think that comes from PyQt specific attributes SQLalchemy is trying to set / 
replace.

So, coming back to the original question, how can I actually set an attribute 
of my class Playlist from within its metaclass without involving the parent 
classes of the subclass (type(base) and type(QMediaPlaylist))? Because the 
__setattr__ from PyQt won't work (segfault) and the one from SQLalchemy does 
stupid stuff.

--

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue23276
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue23276] hackcheck is broken in association with __setattr__

2015-01-20 Thread eryksun

eryksun added the comment:

def __setattr__(cls, key, value):
super(type(QMediaPlaylist), cls).__setattr__(cls, key, value)
return

 The program segfaults when instantiating the Playlist class.

I'd expect a TypeError because of the extra cls argument. It's already a bound 
method. 

FYI, the above finds the next metaclass after type(QMediaPlaylist) in 
PlaylistMeta.__mro__. It happens that type(QMediaPlaylist) inherits __setattr__ 
from the next in line (sip.wrappertype), so by a stroke of luck it 'works' (not 
really since this skips the incompatible sqlalchemy __setattr__).

Consider making a playlist class that *has* a SQL table, not one that *is* a 
SQL table, i.e. use composition instead of inheritance. That sidesteps the 
incompatible metaclasses.

--

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue23276
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue23276] hackcheck is broken in association with __setattr__

2015-01-20 Thread Alfred Krohmer

Alfred Krohmer added the comment:

 I'd expect a TypeError because of the extra cls argument. It's already a 
 bound method.

Sorry, that was a typo.

 Consider making a playlist class that *has* a SQL table, not one that *is* a 
 SQL table, i.e. use composition instead of inheritance. That sidesteps the 
 incompatible metaclasses.

That would be indeed a solution, but not for the original problem.

I think I have an example now that makes my point clear.

The following code works as it should:

import traceback
import sys

class MyMeta(type):
def __setattr__(cls, key, value):
print(OK)

class MyClass(metaclass=MyMeta):
pass

MyClass.abc = 12 # outputs OK
try:
print(MyClass.abc)
except:
traceback.print_exc(file=sys.stdout) # exception comes here as expected

type.__setattr__(MyClass, 'test', 42) # outputs nothing
print(MyClass.test) # outputs 42

If I get this right, this should be **valid code** (and it should **not** be a 
bug, that this actually works).

However, above define MyMeta like following:

from PyQt5.QtMultimedia import QMediaPlaylist

class MyMeta(type(QMediaPlaylist)):
def __setattr__(cls, key, value):
print(OK)

And you get:

TypeError: can't apply this __setattr__ to PyQt5.QtCore.pyqtWrapperType object

I think that this actually **is** unexpected behaviour. I'm **not** trying to 
apply __setattr__ to PyQt5.QtCore.pyqtWrapperType but to MyClass!

--

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue23276
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue23276] hackcheck is broken in association with __setattr__

2015-01-19 Thread eryksun

eryksun added the comment:

super(type, cls).__setattr__(key, value)

In your case, super(type, cls).__setattr__ references object.__setattr__.

 super(type, MyClass).__setattr__.__objclass__
class 'object'

That's from the method resolution order (__mro__):

 print(*MyMeta.__mro__, sep='\n')
class '__main__.MyMeta'
class '__main__.MetaA'
class '__main__.MetaB'
class 'type'
class 'object'

Instead use super(MyMeta, cls), or in Python 3 just use super() in a method 
(under the hood the function uses a closure variable named __class__).

 super(MyMeta, MyClass).__setattr__.__objclass__
class 'type'

type.__setattr__(MyClass, 'test', 42)

The above won't work for a Qt subclass. You need __setattr__ from 
sip.wrappertype.

 type.__setattr__(QtClass, 'test', 42)
Traceback (most recent call last):
  File stdin, line 1, in module
TypeError: can't apply this __setattr__ to sip.wrappertype object

 print(*QtMeta.__mro__, sep='\n')
class '__main__.QtMeta'
class '__main__.MetaA'
class 'sip.wrappertype'
class 'type'
class 'object'

 super(QtMeta, QtClass).__setattr__.__objclass__
class 'sip.wrappertype'
 super(QtMeta, QtClass).__setattr__('test', 42)
 QtClass.test
42

--
nosy: +eryksun

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue23276
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue23276] hackcheck is broken in association with __setattr__

2015-01-19 Thread Alfred Krohmer

New submission from Alfred Krohmer:

The following code:


import traceback
import sys

from PyQt5.QtCore import Qt

class MetaA(type):
pass

class A(metaclass=MetaA):
pass

class MetaB(type):
pass

class B(metaclass=MetaB):
pass

for ClassB in B, Qt:

print(Trying class %s % (ClassB.__name__, ))

class MyMeta(type(A), type(ClassB)):
def __setattr__(cls, key, value):
print(cls)
super(type, cls).__setattr__(key, value)

class MyClass(A, ClassB, metaclass=MyMeta):
pass

try:
setattr(MyClass, 'abc', 123)
except:
traceback.print_exc(file=sys.stdout)

try:
type.__setattr__(MyClass, 'test', 42)
except:
traceback.print_exc(file=sys.stdout)


Fails with the following output:


Trying class B
class '__main__.MyClass'
Traceback (most recent call last):
  File test3.py, line 31, in module
setattr(MyClass, 'abc', 123)
  File test3.py, line 25, in __setattr__
super(type, cls).__setattr__(key, value)
TypeError: can't apply this __setattr__ to type object
Trying class Qt
class '__main__.MyClass'
Traceback (most recent call last):
  File test3.py, line 31, in module
setattr(MyClass, 'abc', 123)
  File test3.py, line 25, in __setattr__
super(type, cls).__setattr__(key, value)
TypeError: can't apply this __setattr__ to sip.wrappertype object
Traceback (most recent call last):
  File test3.py, line 36, in module
type.__setattr__(MyClass, 'test', 42)
TypeError: can't apply this __setattr__ to sip.wrappertype object


The metaclass of a class should be able to update its class' __dict__ my 
calling super(type, cls).__setattr__ (there is no other way known to me to do 
this). Furthermore, if subclassing an external class, like Qt, it should be 
possible to use type.__setattr__(MyClass, ...) externally to change the class' 
attributes.

The error is caused by the hackcheck function in objects/typeobject.c.

--
components: Interpreter Core, Library (Lib)
messages: 234329
nosy: devkid
priority: normal
severity: normal
status: open
title: hackcheck is broken in association with __setattr__
type: behavior
versions: Python 2.7, Python 3.2, Python 3.3, Python 3.4

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue23276
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com