Description
There is an issue with PoolConnectionProxy with how it wraps connection methods, in regards to the addition of the connection_class
option you can pass into Pool
.
- asyncpg version: 0.11.0
- PostgreSQL version: not relevant
- Python version: 3.6
- Platform: linux
- Do you use pgbouncer?: not relevant
- Did you install asyncpg with pip?: yes
- Can the issue be reproduced under both asyncio and
uvloop?: Not relevant
in the PoolConnectionProxyMeta
class, the new wraps the connection proxy with the methods defined on Connection. Seen on line 30: https://github.com/MagicStack/asyncpg/blob/master/asyncpg/pool.py#L30
The pool then wraps the connection in the proxy class.
What this means is that if connection_class
set in the pool overides any public methods such as fetch
it doesnt matter, as all methods used will be the definitions of the connection
class and not the passed in subclass.
This makes subclassing only useful for overriding underscore methods and not public ones.
In order for subclassing to work, here are some alternatives:
- implement
__getattr__
to "pass the buck" to the self._con class. I assume the meta class was used instead because of performance reasons. Rather than "looking up" every time. However, the way it is implemented,_dispatch_method_call
is called every time, and would in theory be only slightly faster than just using__getattr__
on the class. Actually, here is proof: (code found here)
with metaclass: 1.97497710099924
with __getattr__ 2.10569577699971
- We could "wrap" the subclass during
__init__
instead of the metaclass. That would Again, be a performance issue, as the wrapping would occur on every new proxy instead of when the class is defined. This is potentially a bigger performance impact.
Any other ideas?
I would be happy to implement this and submit a PR, but want to hear your thoughts on the implementation details.