diff --git a/mode/python/python.js b/mode/python/python.js
index 9160b8e74b7ccd6efe6be5b9c105cdf96dd449f0..95e4d1fe904ac05bea2250e152b4b9803eba0eae 100644
--- a/mode/python/python.js
+++ b/mode/python/python.js
@@ -249,15 +249,24 @@
     }
 
     function tokenLexer(stream, state) {
+      var sol = stream.sol();
+      if (sol){
+          state.whiteSpaceAtBeginningOfLine = true;
+      }
       var style = state.tokenize(stream, state);
       var current = stream.current();
 
       // Handle decorators
-      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 (state.whiteSpaceAtBeginningOfLine){
+          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(!current.match(/^ +$/, false)){
+          state.whiteSpaceAtBeginningOfLine = false;
       }
 
       if ((style == "variable" || style == "builtin")
diff --git a/mode/python/test.js b/mode/python/test.js
new file mode 100644
index 0000000000000000000000000000000000000000..342c6cf33aae1135422da3285f0bb19e29b5e1ed
--- /dev/null
+++ b/mode/python/test.js
@@ -0,0 +1,28 @@
+// CodeMirror, copyright (c) by Marijn Haverbeke and others
+// Distributed under an MIT license: http://codemirror.net/LICENSE
+
+(function() {
+  var mode = CodeMirror.getMode({indentUnit: 4},
+              {name: "python",
+               version: 3,
+               singleLineStringErrors: false});
+  function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1)); }
+
+  // Error, because "foobarhello" is neither a known type or property, but
+  // property was expected (after "and"), and it should be in parentheses.
+  MT("decoratorStartOfLine",
+     "[meta @dec]",
+     "[keyword def] [def function]():",
+     "    [keyword pass]");
+
+  MT("decoratorIndented",
+     "[keyword class] [def Foo]:",
+     "    [meta @dec]",
+     "    [keyword def] [def function]():",
+     "        [keyword pass]");
+
+  MT("matmulWithSpace:", "[variable a] [operator @] [variable b]");
+  MT("matmulWithoutSpace:", "[variable a][operator @][variable b]");
+  MT("matmulSpaceBefore:", "[variable a] [operator @][variable b]");
+
+})();
diff --git a/test/index.html b/test/index.html
index 68dc4dfc0671502a2d3183a4caef43af3254447c..90c0335171c8264673378c88232ba902763af56d 100644
--- a/test/index.html
+++ b/test/index.html
@@ -27,6 +27,7 @@
 <script src="../mode/jsx/jsx.js"></script>
 <script src="../mode/markdown/markdown.js"></script>
 <script src="../mode/php/php.js"></script>
+<script src="../mode/python/python.js"></script>
 <script src="../mode/powershell/powershell.js"></script>
 <script src="../mode/ruby/ruby.js"></script>
 <script src="../mode/shell/shell.js"></script>
@@ -123,6 +124,7 @@
     <script src="../mode/verilog/test.js"></script>
     <script src="../mode/xml/test.js"></script>
     <script src="../mode/xquery/test.js"></script>
+    <script src="../mode/python/test.js"></script>
     <script src="../mode/rust/test.js"></script>
     <script src="../mode/mscgen/mscgen_test.js"></script>
     <script src="../mode/mscgen/xu_test.js"></script>