__slots__ is negated by MemoizedSlots at the base

Issue #3494 resolved
Gregory Bronner created an issue

When trying to run a very simple example, I get the following error:

AttributeError: '_ListenerCollection' object has no attribute '_exec_once'

Code is as follows:

import sqlalchemy 
import urllib
params = urllib.quote_plus("DRIVER={SQL Server};SERVER=XXXX;DATABASE=YYYY;UID=ZZZZ;PWD=AAAA")


engine = sqlalchemy.create_engine('mssql+pypyodbc:////?odbc_connect=%s' %params )
for row in engine.execute('select 1+1 from TestRun'):
    print (row)

Complete stack trace is:

Traceback (most recent call last):

  File "c:\program files (x86)\IronPython 2.7\lib\site-packages\sqlalchemy\pool.py", line 1052, in _do_get

  File "c:\program files (x86)\IronPython 2.7\lib\site-packages\sqlalchemy\pool.py", line 323, in _create_connection

  File "c:\program files (x86)\IronPython 2.7\lib\site-packages\sqlalchemy\pool.py", line 452, in __init__

  File "c:\program files (x86)\IronPython 2.7\lib\site-packages\sqlalchemy\event\attr.py", line 258, in exec_once

AttributeError: '_ListenerCollection' object has no attribute '_exec_once'

Setup is as follows: * IronPython 2.7.5 * pypyodbc 1.2.1 * sqlalchemy 1.0.7 *

Source of Bug

Source of the bug seems to be in attr.py in the _CompoundListener; the object

_exec_once_mutex

never gets created, and the

_exec_once 

object is referred to by self, when it is a class variable.

class _X(object):
    def __enter__(self):
        pass
    def __exit__(self,a,b,c):
        pass

class _CompoundListener(_InstanceLevelDispatch):
    _exec_once = False
    #_exec_once_mutex= _X()

    __slots__ = '_exec_once_mutex',

    def _memoized_attr__exec_once_mutex(self):
        return threading.Lock()

    def exec_once(self, *args, **kw):
        """Execute this event, but only if it has not been
        executed already for this collection."""
        #change to _CompoundListener._exec_once
        if not self._exec_once:

I was able to get it to run (mostly) by furnishing an object for the _exec_once_mutex, as well as by changing uses of _exec_once to be class, rather than instance variables. Still, I had other issues.

The sample code works nicely on .0.9.9, so this is a regression.

Comments (4)

  1. Mike Bayer repo owner

    we dont support IronPython. The code works in cPython and Pypy so the bug is in IronPython.

  2. Mike Bayer repo owner
    • Fixed an issue where a particular base class within utils didn't implement __slots__, and therefore meant all subclasses of that class didn't either, negating the rationale for __slots__ to be in use. Didn't cause any issue except on IronPython which apparently does not implement __slots__ behavior compatibly with cPython. Fixes #3494

    → <<cset 575f080850a0>>

  3. Mike Bayer repo owner

    thanks for reporting. not a regression since we don't support IronPython and had no way of testing on that platform.

  4. Log in to comment