Opened 5 years ago

Last modified 6 months ago

#16682 new Bug

KeyboardInterrupt not handled properly in transaction aborting

Reported by: mtredinnick Owned by: nobody
Component: Database layer (models, ORM) Version: 1.3
Severity: Normal Keywords:
Cc: Triage Stage: Accepted
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no


Ticket #6928 was reopened to report this, so I (Malcolm) am moving it to a new ticket, since it's a separate issue. Following text is from comment:7 on that ticket:


After [14288] transaction.commit_on_success does not handle KeyboardInterrupt.

Problem in django.db.transaction.Transaction.__exit__ and default exiting function.

    def __exit__(self, exc_type, exc_value, traceback):
        self.exiting(exc_value, self.using)

exc_value is None after KeyboardInterrupt has been throwed, only exc_type and traceback has value.
But if raise KeyboardInterrupt manualy from code it's work ok.

Possible solution: use exc_type and exc_value in exiting function

I use python 2.6.6

Attachments (1)

16682-test.diff (1.1 KB) - added by claudep 4 years ago.
Failing test

Download all attachments as: .zip

Change History (6)

comment:1 Changed 5 years ago by aaugustin

  • Resolution set to needsinfo
  • Status changed from new to closed

I'm sorry, but this report doesn't contain enough information to reproduce the problem. How can you get a KeyboardInterrupt within transaction.commit_on_success?

I wrote this test code:


from django.db import models

class FooModel(models.Model):
    foo = models.CharField(max_length=42)


import time
from django.db import transaction
from .models import FooModel

def interrupt_me(request):
    print "Hit Ctrl-C now!"
    print "Too late, and I didn't bother to return a HttpResponse"

and hooked the view in the URLconf.

Then I ran: ./ runserver --traceback

I open the URL in a browser, and during the sleep, I hit Ctrl-C in the console. runserver exits cleanly, with or without transaction.commit_on_success.

Please provide a test case or instructions to reproduce your problem and re-open the ticket.

comment:4 Changed 4 years ago by claudep

  • Resolution needsinfo deleted
  • Status changed from closed to reopened
  • Triage Stage changed from Unreviewed to Accepted

I've been able to reproduce it with the following code (you can insert it in regressiontests/transactions_regress/

    def test_rollback_on_keyboardinterrupt(self):
        import time
            with transaction.commit_on_success():
                print "Hit Ctrl-C now!"
                print "Too late, and I didn't bother to return a HttpResponse"
        except KeyboardInterrupt:
        self.assertEqual(Mod.objects.all().count(), 0)

Unfortunately, I didn't manage to simulate a Ctrl-C programmatically, so as to be able to include a real test. Ideas welcome.

comment:5 Changed 4 years ago by claudep

#17624 is a duplicate with a patch

Changed 4 years ago by claudep

Failing test

comment:6 Changed 4 years ago by claudep

I eventually found a trick to generate the KeyboardInterrupt to create a failing test. Don't ask me why the os.kill has to be called twice...

comment:7 Changed 3 years ago by aaugustin

  • Status changed from reopened to new
Note: See TracTickets for help on using tickets.
Back to Top