   runtimeGlobals:
     __pythonRuntime: parser.pythonRuntime
 
-  hasChangedSignificantly: (a, b) ->
-    true
+  hasChangedASTs: (a, b) ->
+    try
+      [aAST, bAST] = [null, null]
+      options = {locations: false, ranges: false}
+      aAST = parser_loose.parse_dammit a, options
+      bAST = parser_loose.parse_dammit b, options
+      unless aAST and bAST
+        return true
+      return not _.isEqual(aAST, bAST)
+    catch error
+      return true
 
   # Wrap the user code in a function. Store @wrappedCodePrefix and @wrappedCodeSuffix.
   wrap: (rawCode, aether) ->

Language = require './language'

parser = require 'filbert'

estraverse = require 'estraverse'
escodegen = require 'escodegen'
esprima = require 'esprima'

module.exports = class Python extends Language
  name: 'Python'


  # Using a third-party parser, produce an AST in the standardized Mozilla format.
  parse: (code, aether) ->
    ast = parser.parse code, {locations: false, ranges: true}
    selfToThis ast
    ast

  parseDammit: (code, aether) ->
    try
      ast = parser_loose.parse_dammit code, {locations: false, ranges: true}
      selfToThis ast
    catch error
      ast = {type: "Program", body:[{"type": "EmptyStatement"}]}
    ast


# 'this' is not a keyword in Python, so it does not parse to a ThisExpression
# Instead, we expect the variable 'self', and map it to a ThisExpression
selfToThis = (ast) ->
  ast.body[0].body.body.unshift {"type": "VariableDeclaration","declarations": [{ "type": "VariableDeclarator", "id": {"type": "Identifier", "name": "self" },"init": {"type": "ThisExpression"} }],"kind": "var"}
  ast