diff --git a/mode/python/python.js b/mode/python/python.js
index 4310f9fb6b009bfa17ac4387292af138a7fa36ce..b539d84aa6a9229a4e1f8eecf2f01fa1f97a4015 100644
--- a/mode/python/python.js
+++ b/mode/python/python.js
@@ -113,8 +113,8 @@
       if (stream.match(/^[0-9\.]/, false)) {
         var floatLiteral = false;
         // Floats
-        if (stream.match(/^\d*\.\d+(e[\+\-]?\d+)?/i)) { floatLiteral = true; }
-        if (stream.match(/^\d+\.\d*/)) { floatLiteral = true; }
+        if (stream.match(/^[\d_]*\.\d+(e[\+\-]?\d+)?/i)) { floatLiteral = true; }
+        if (stream.match(/^[\d_]+\.\d*/)) { floatLiteral = true; }
         if (stream.match(/^\.\d+/)) { floatLiteral = true; }
         if (floatLiteral) {
           // Float literals may be "imaginary"
@@ -124,13 +124,13 @@
         // Integers
         var intLiteral = false;
         // Hex
-        if (stream.match(/^0x[0-9a-f]+/i)) intLiteral = true;
+        if (stream.match(/^0x[0-9a-f_]+/i)) intLiteral = true;
         // Binary
-        if (stream.match(/^0b[01]+/i)) intLiteral = true;
+        if (stream.match(/^0b[01_]+/i)) intLiteral = true;
         // Octal
-        if (stream.match(/^0o[0-7]+/i)) intLiteral = true;
+        if (stream.match(/^0o[0-7_]+/i)) intLiteral = true;
         // Decimal
-        if (stream.match(/^[1-9]\d*(e[\+\-]?\d+)?/)) {
+        if (stream.match(/^[1-9][\d_]*(e[\+\-]?[\d_]+)?/)) {
           // Decimal literals may be "imaginary"
           stream.eat(/J/i);
           // TODO - Can you have imaginary longs?