clarete / forbiddenfruit

Patch built-in python objects
https://clarete.li/forbiddenfruit/
GNU General Public License v3.0
817 stars 52 forks source link

Patching datetime crashes Python 2.7.13,2.7.14 on Debian/Ubuntu #22

Open evanj opened 6 years ago

evanj commented 6 years ago

The following program crashes Python with various memory corruption related errors on Debian 9 and Ubuntu 17.10. The program works fine on my Mac.

forbiddenfruit version 0.1.2 installed with pip install forbiddenfruit

Working system

Failing systems

Reproducing the errors

On a new virtual machine, run the following:

sudo apt-get install gcc libpython2.7-dev virtualenv virtualenv bugvenv bugvenv/bin/pip install forbiddenfruit bugvenv/bin/python bug.py

Example failing output

before datetime.now: 2017-12-17 15:03:16.985094
after datetime.now: 2017-12-17 15:03:16.985267
before datetime.now: 2017-12-17 15:03:16.985314
Traceback (most recent call last):
  File "bug.py", line 21, in <module>
    activate_deactivate()
  File "bug.py", line 14, in activate_deactivate
    f = datetime.datetime.now()
TypeError: &traceback' object is not callable
Fatal Python error: Inconsistent interned string state.
Aborted

Correct output

before datetime.now: 2017-12-17 10:04:33.392523
after datetime.now: 2017-12-17 15:04:33.392366
before datetime.now: 2017-12-17 15:04:33.392366
after datetime.now: 2017-12-17 15:04:33.392366
before datetime.now: 2017-12-17 15:04:33.392366
after datetime.now: 2017-12-17 15:04:33.392366

Script

import datetime
import forbiddenfruit

datetime_now = datetime.datetime.utcnow()
def fake_now(cls):
    return datetime_now

def activate_deactivate():
    now = datetime.datetime.now()
    print 'before datetime.now:', now
    forbiddenfruit.curse(datetime.datetime, 'now', classmethod(fake_now))
    f = datetime.datetime.now()
    print 'after datetime.now:', f

if __name__ == '__main__':
    for i in xrange(3):
        activate_deactivate()
Arnie97 commented 5 years ago

Seems Python 2-specific. The same script works on Debian 9 with Python 3.5.3 (after replacing print and xrange with their Python 3 counterpart, of course).

clarete commented 5 years ago

Hehehe I can wait til the end of the year to close this lol

evanj commented 5 years ago

At this point, that is probably a reasonable strategy :)