From f19d7e5b972e60c843acb3389e8ae07eb6043818 Mon Sep 17 00:00:00 2001 From: Taavi Burns Date: Fri, 19 Nov 2010 17:44:39 -0500 Subject: [PATCH] Fix memory leaks in the cprocessors DecimalResultProcessor, including tests. [ticket:1978] --- lib/sqlalchemy/cextension/processors.c | 11 ++++++- test/aaa_profiling/test_memusage.py | 42 +++++++++++++++++++++++++- 2 files changed, 51 insertions(+), 2 deletions(-) diff --git a/lib/sqlalchemy/cextension/processors.c b/lib/sqlalchemy/cextension/processors.c index 327462fa89..193fb19f30 100644 --- a/lib/sqlalchemy/cextension/processors.c +++ b/lib/sqlalchemy/cextension/processors.c @@ -289,6 +289,7 @@ DecimalResultProcessor_process(DecimalResultProcessor *self, PyObject *value) return NULL; str = PyString_Format(self->format, args); + Py_DECREF(args); if (str == NULL) return NULL; @@ -300,6 +301,14 @@ DecimalResultProcessor_process(DecimalResultProcessor *self, PyObject *value) } } +static void +DecimalResultProcessor_dealloc(DecimalResultProcessor *self) +{ + Py_XDECREF(self->type); + Py_XDECREF(self->format); + self->ob_type->tp_free((PyObject*)self); +} + static PyMethodDef DecimalResultProcessor_methods[] = { {"process", (PyCFunction)DecimalResultProcessor_process, METH_O, "The value processor itself."}, @@ -312,7 +321,7 @@ static PyTypeObject DecimalResultProcessorType = { "sqlalchemy.DecimalResultProcessor", /* tp_name */ sizeof(DecimalResultProcessor), /* tp_basicsize */ 0, /* tp_itemsize */ - 0, /* tp_dealloc */ + (destructor)DecimalResultProcessor_dealloc, /* tp_dealloc */ 0, /* tp_print */ 0, /* tp_getattr */ 0, /* tp_setattr */ diff --git a/test/aaa_profiling/test_memusage.py b/test/aaa_profiling/test_memusage.py index 5fa40a9978..3fb6bfa55a 100644 --- a/test/aaa_profiling/test_memusage.py +++ b/test/aaa_profiling/test_memusage.py @@ -7,10 +7,11 @@ from sqlalchemy.util import jython import operator from sqlalchemy.test import testing, engines from sqlalchemy import MetaData, Integer, String, ForeignKey, \ - PickleType, create_engine, Unicode + PickleType, create_engine, Unicode, Float from sqlalchemy.test.schema import Table, Column import sqlalchemy as sa from sqlalchemy.sql import column +from sqlalchemy.processors import to_decimal_processor_factory from sqlalchemy.test.util import gc_collect import gc import weakref @@ -566,3 +567,42 @@ class MemUsageTest(EnsureZeroed): cast.compile(dialect=dialect) go() + def test_DecimalResultProcessor_processing(self): + metadata = MetaData(testing.db) + + table1 = Table("mytable", metadata, + Column('col1', Integer, primary_key=True, + test_needs_autoincrement=True), + Column('col2', Float(asdecimal=True)) + ) + + class Foo(object): + def __init__(self, col2): + self.col2 = col2 + + mapper(Foo, table1) + metadata.create_all() + + session = create_session() + session.begin() + session.add(Foo(1.1)) + session.commit() + session.close() + del session + + @profile_memory + def go(): + session = create_session() + session.query(Foo).all() + session.rollback() + session.close() + try: + go() + finally: + metadata.drop_all() + + def test_DecimalResultProcessor_dealloc(self): + @profile_memory + def go(): + to_decimal_processor_factory({}, 10) + go() -- 2.47.2