diff --git a/mode/python/index.html b/mode/python/index.html
index dcd7fe5a82823c2b6db51a2f35e26c02e9f76203..86eb3d52f78802703a52972182dd28120c22cb2b 100644
--- a/mode/python/index.html
+++ b/mode/python/index.html
@@ -65,13 +65,25 @@ __a__
 a.b
 a.b.c
 
+#Unicode identifiers on Python3
+# a = x\ddot
+a⃗ = ẍ
+# a = v\dot
+a⃗ = v̇
+
+#F\vec = m \cdot a\vec
+F⃗ = m•a⃗ 
+
 # Operators
 + - * / % & | ^ ~ < >
 == != <= >= <> << >> // **
 and or not in is
 
+#infix matrix multiplication operator (PEP 465)
+A @ B
+
 # Delimiters
-() [] {} , : ` = ; @ .  # Note that @ and . require the proper context.
+() [] {} , : ` = ; @ .  # Note that @ and . require the proper context on Python 2.
 += -= *= /= %= &= |= ^=
 //= >>= <<= **=
 
@@ -146,7 +158,7 @@ def pairwise_cython(double[:, ::1] X):
     <script>
       var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
         mode: {name: "python",
-               version: 2,
+               version: 3,
                singleLineStringErrors: false},
         lineNumbers: true,
         indentUnit: 4,
@@ -171,12 +183,12 @@ def pairwise_cython(double[:, ::1] X):
     <h2>Advanced Configuration Options:</h2>
     <p>Usefull for superset of python syntax like Enthought enaml, IPython magics and  questionmark help</p>
     <ul>
-      <li>singleOperators - RegEx - Regular Expression for single operator matching,  default : <pre>^[\\+\\-\\*/%&amp;|\\^~&lt;&gt;!]</pre></li>
+      <li>singleOperators - RegEx - Regular Expression for single operator matching,  default : <pre>^[\\+\\-\\*/%&amp;|\\^~&lt;&gt;!]</pre> including <pre>@</pre> on Python 3</li>
       <li>singleDelimiters - RegEx - Regular Expression for single delimiter matching, default :  <pre>^[\\(\\)\\[\\]\\{\\}@,:`=;\\.]</pre></li>
       <li>doubleOperators - RegEx - Regular Expression for double operators matching, default : <pre>^((==)|(!=)|(&lt;=)|(&gt;=)|(&lt;&gt;)|(&lt;&lt;)|(&gt;&gt;)|(//)|(\\*\\*))</pre></li>
       <li>doubleDelimiters - RegEx - Regular Expressoin for double delimiters matching, default : <pre>^((\\+=)|(\\-=)|(\\*=)|(%=)|(/=)|(&amp;=)|(\\|=)|(\\^=))</pre></li>
       <li>tripleDelimiters - RegEx - Regular Expression for triple delimiters matching, default : <pre>^((//=)|(&gt;&gt;=)|(&lt;&lt;=)|(\\*\\*=))</pre></li>
-      <li>identifiers - RegEx - Regular Expression for identifier, default : <pre>^[_A-Za-z][_A-Za-z0-9]*</pre></li>
+      <li>identifiers - RegEx - Regular Expression for identifier, default : <pre>^[_A-Za-z][_A-Za-z0-9]*</pre> on Python 2 and <pre>^[_A-Za-z\u00A1-\uFFFF][_A-Za-z0-9\u00A1-\uFFFF]*</pre> on Python 3.</li>
       <li>extra_keywords - list of string - List of extra words ton consider as keywords</li>
       <li>extra_builtins - list of string - List of extra words ton consider as builtins</li>
     </ul>
diff --git a/mode/python/python.js b/mode/python/python.js
index 4e1f296ae1cd888f16163c4198554deec01f71a5..98c0409ae2e014b8df8c4c928fd31b8e27f0235e 100644
--- a/mode/python/python.js
+++ b/mode/python/python.js
@@ -48,12 +48,20 @@
   CodeMirror.defineMode("python", function(conf, parserConf) {
     var ERRORCLASS = "error";
 
-    var singleOperators = parserConf.singleOperators || new RegExp("^[\\+\\-\\*/%&|\\^~<>!]");
     var singleDelimiters = parserConf.singleDelimiters || new RegExp("^[\\(\\)\\[\\]\\{\\}@,:`=;\\.]");
     var doubleOperators = parserConf.doubleOperators || new RegExp("^((==)|(!=)|(<=)|(>=)|(<>)|(<<)|(>>)|(//)|(\\*\\*))");
     var doubleDelimiters = parserConf.doubleDelimiters || new RegExp("^((\\+=)|(\\-=)|(\\*=)|(%=)|(/=)|(&=)|(\\|=)|(\\^=))");
     var tripleDelimiters = parserConf.tripleDelimiters || new RegExp("^((//=)|(>>=)|(<<=)|(\\*\\*=))");
-    var identifiers = parserConf.identifiers|| new RegExp("^[_A-Za-z][_A-Za-z0-9]*");
+
+    if (parserConf.version && parseInt(parserConf.version, 10) == 3){
+        // since http://legacy.python.org/dev/peps/pep-0465/ @ is also an operator
+        var singleOperators = parserConf.singleOperators || new RegExp("^[\\+\\-\\*/%&|\\^~<>!@]");
+        var identifiers = parserConf.identifiers|| new RegExp("^[_A-Za-z\u00A1-\uFFFF][_A-Za-z0-9\u00A1-\uFFFF]*");
+    } else {
+        var singleOperators = parserConf.singleOperators || new RegExp("^[\\+\\-\\*/%&|\\^~<>!]");
+        var identifiers = parserConf.identifiers|| new RegExp("^[_A-Za-z][_A-Za-z0-9]*");
+    }
+
     var hangingIndent = parserConf.hangingIndent || conf.indentUnit;
 
     var myKeywords = commonKeywords, myBuiltins = commonBuiltins;
@@ -252,8 +260,13 @@
       }
 
       // Handle decorators
-      if (current == "@")
-        return stream.match(identifiers, false) ? "meta" : ERRORCLASS;
+      if (current == "@"){
+        if(parserConf.version && parseInt(parserConf.version, 10) == 3){
+            return stream.match(identifiers, false) ? "meta" : "operator";
+        } else {
+            return stream.match(identifiers, false) ? "meta" : ERRORCLASS;
+        }
+      }
 
       if ((style == "variable" || style == "builtin")
           && state.lastStyle == "meta")