Buggy python submission (verdict: Runtime Error):
import heapq
from itertools import chain
from operator import mul

exp10 = [10 ** a for a in range(8, -1, -1)]
movables = [{1, 3}, {0, 2, 4}, {1, 5}, {0, 4, 6}, {1, 3, 5, 7}, {2, 4, 8}, {3, 7}, {4, 6, 8}, {5, 7}]

destination = 123456780


def swap(board, move_from, move_to):
    return board + (exp10[move_to] - exp10[move_from]) * (board // exp10[move_from] % 10)


board0 = sum(map(mul, exp10, chain.from_iterable(map(int, input().split()) for _ in range(3))))
p0 = str(board0).index('0')

appeared = {board0}
queue = list((0, move_from, p0, board0) for move_from in movables[p0])
heapq.heapify(queue)

while True:
    total_cost, move_from, move_to, board = heapq.heappop(queue)
    if board == destination:
        print(total_cost)
        break
    new_board = swap(board, move_from, move_to)
    if new_board in appeared:
        continue
    for move_from2 in movables[move_from]:
        if move_from2 != move_to:
            heapq.heappush(queue, (total_cost + 1, move_from2, move_from, new_board))

Fixed submission:
import heapq
from itertools import chain
from operator import mul

exp10 = [10 ** a for a in range(8, -1, -1)]
movables = [{1, 3}, {0, 2, 4}, {1, 5}, {0, 4, 6}, {1, 3, 5, 7}, {2, 4, 8}, {3, 7}, {4, 6, 8}, {5, 7}]

destination = 123456780


def swap(board, move_from, move_to):
    return board + (exp10[move_to] - exp10[move_from]) * (board // exp10[move_from] % 10)


board0 = sum(map(mul, exp10, chain.from_iterable(map(int, input().split()) for _ in range(3))))
p0 = ('0' + str(board0))[-9:].index('0')

appeared = ({board0: 0}, {destination: 0})
queue = []
queue.extend((0, 0, move_from, p0, board0) for move_from in movables[p0])
queue.extend((0, 1, move_from, 8, destination) for move_from in movables[8])
heapq.heapify(queue)

while True:
    total_cost, direction, move_from, move_to, board = heapq.heappop(queue)
    if board in appeared[not direction]:
        print(total_cost + appeared[not direction][board])
        break
    new_board = swap(board, move_from, move_to)
    if new_board in appeared[direction]:
        continue
    appeared[direction][new_board] = total_cost + 1
    for move_from2 in movables[move_from]:
        if move_from2 != move_to:
            heapq.heappush(queue, (total_cost + 1, direction, move_from2, move_from, new_board))

Buggy python submission (verdict: Time Limit Exceeded):
import heapq
from itertools import chain
from operator import mul

exp10 = [10 ** a for a in range(8, -1, -1)]
movables = [{1, 3}, {0, 2, 4}, {1, 5}, {0, 4, 6}, {1, 3, 5, 7}, {2, 4, 8}, {3, 7}, {4, 6, 8}, {5, 7}]

destination = 123456780


def swap(board, move_from, move_to):
    return board + (exp10[move_to] - exp10[move_from]) * (board // exp10[move_from] % 10)


board0 = sum(map(mul, exp10, chain.from_iterable(map(int, input().split()) for _ in range(3))))
p0 = ('0' + str(board0))[-9:].index('0')

appeared = {board0}
queue = list((0, move_from, p0, board0) for move_from in movables[p0])
heapq.heapify(queue)

while True:
    total_cost, move_from, move_to, board = heapq.heappop(queue)
    if board == destination:
        print(total_cost)
        break
    new_board = swap(board, move_from, move_to)
    if new_board in appeared:
        continue
    for move_from2 in movables[move_from]:
        if move_from2 != move_to:
            heapq.heappush(queue, (total_cost + 1, move_from2, move_from, new_board))

Fixed submission:
import heapq
from itertools import chain
from operator import mul

exp10 = [10 ** a for a in range(8, -1, -1)]
movables = [{1, 3}, {0, 2, 4}, {1, 5}, {0, 4, 6}, {1, 3, 5, 7}, {2, 4, 8}, {3, 7}, {4, 6, 8}, {5, 7}]

destination = 123456780


def swap(board, move_from, move_to):
    return board + (exp10[move_to] - exp10[move_from]) * (board // exp10[move_from] % 10)


board0 = sum(map(mul, exp10, chain.from_iterable(map(int, input().split()) for _ in range(3))))
p0 = ('0' + str(board0))[-9:].index('0')

appeared = ({board0: 0}, {destination: 0})
queue = []
queue.extend((0, 0, move_from, p0, board0) for move_from in movables[p0])
queue.extend((0, 1, move_from, 8, destination) for move_from in movables[8])
heapq.heapify(queue)

while True:
    total_cost, direction, move_from, move_to, board = heapq.heappop(queue)
    if board in appeared[not direction]:
        print(total_cost + appeared[not direction][board])
        break
    new_board = swap(board, move_from, move_to)
    if new_board in appeared[direction]:
        continue
    appeared[direction][new_board] = total_cost + 1
    for move_from2 in movables[move_from]:
        if move_from2 != move_to:
            heapq.heappush(queue, (total_cost + 1, direction, move_from2, move_from, new_board))