Repository: missionpinball/mpf
Issue: Ball lock crash

https://groups.google.com/forum/m/#!topic/mpf-users/CFz5k2EB_Wg

Changed files:
mpf/devices/ball_lock.py, mpf/devices/ball_hold.py, mpf/tests/test_BallHold.py, mpf/tests/test_BallLock.py, mpf/devices/multiball_lock.py

diff --git a/mpf/devices/ball_hold.py b/mpf/devices/ball_hold.py
index 79250d7ac..bfc92e83c 100644
--- a/mpf/devices/ball_hold.py
+++ b/mpf/devices/ball_hold.py
@@ -128,6 +128,7 @@ class BallHold(SystemWideDevice, ModeDevice):
         if self._released_balls <= 0:
             if self._release_hold:
                 self._release_hold.clear()
+                self._release_hold = None
             self.debug_log("All released balls of ball_hold drained.")
             self.machine.events.remove_handler_by_event('ball_ending', self._wait_for_drain)
             self.machine.events.remove_handler_by_event('ball_drain', self._block_during_drain)
diff --git a/mpf/devices/ball_lock.py b/mpf/devices/ball_lock.py
index dc7957063..d58c1a321 100644
--- a/mpf/devices/ball_lock.py
+++ b/mpf/devices/ball_lock.py
@@ -123,6 +123,7 @@ class BallLock(SystemWideDevice, ModeDevice):
         if self._released_balls <= 0:
             if self._release_lock:
                 self._release_lock.clear()
+                self._release_lock = None
             self.log.debug("All released balls of lock drained.")
             self.machine.events.remove_handler_by_event('ball_ending', self._wait_for_drain)
             self.machine.events.remove_handler_by_event('ball_drain', self._block_during_drain)
diff --git a/mpf/devices/multiball_lock.py b/mpf/devices/multiball_lock.py
index a35fe519d..9ffc3e0f8 100644
--- a/mpf/devices/multiball_lock.py
+++ b/mpf/devices/multiball_lock.py
@@ -21,8 +21,6 @@ class MultiballLock(ModeDevice):
         # initialise variables
         self.enabled = False
         self.initialised = False    # remove when #715 is fixed
-        self._released_balls = 0
-        self._release_lock = None
 
         super().__init__(machine, name)
 
diff --git a/mpf/tests/test_BallHold.py b/mpf/tests/test_BallHold.py
index 066ca99f2..02e2c2ee5 100644
--- a/mpf/tests/test_BallHold.py
+++ b/mpf/tests/test_BallHold.py
@@ -1,5 +1,3 @@
-from mpf.tests.MpfFakeGameTestCase import MpfFakeGameTestCase
-
 from mpf.tests.MpfTestCase import MpfTestCase
 from unittest.mock import MagicMock
 
@@ -568,7 +566,8 @@ class TestBallHoldSmart(MpfTestCase):
         self.assertEqual(1, self.machine.playfield.balls)
 
         # drain ball on pf
-        self.hit_switch_and_run("s_ball_switch1", 1)
+        self.machine.default_platform.add_ball_to_device(self.machine.ball_devices.test_trough)
+        self.advance_time_and_run(1)
 
         # machine waits for the hold
         self.advance_time_and_run(10)
@@ -580,5 +579,17 @@ class TestBallHoldSmart(MpfTestCase):
         self.assertEqual(1, self.machine.playfield.balls)
 
         # once the ball drains move on to the ball 2
-        self.hit_switch_and_run("s_ball_switch2", 1)
-        self.assertEqual(2, self.machine.game.player.ball)
\\ No newline at end of file
+        self.machine.default_platform.add_ball_to_device(self.machine.ball_devices.test_trough)
+        self.advance_time_and_run(1)
+        self.assertEqual(2, self.machine.game.player.ball)
+
+        # next ball
+        self.advance_time_and_run(10)
+        self.assertBallsOnPlayfield(1)
+
+        # drain again
+        self.machine.default_platform.add_ball_to_device(self.machine.ball_devices.test_trough)
+        self.advance_time_and_run(1)
+
+        # there should be no hold this time
+        self.assertEqual(3, self.machine.game.player.ball)
\\ No newline at end of file
diff --git a/mpf/tests/test_BallLock.py b/mpf/tests/test_BallLock.py
index 41aaf6647..1efbbcbd3 100644
--- a/mpf/tests/test_BallLock.py
+++ b/mpf/tests/test_BallLock.py
@@ -1,5 +1,3 @@
-from mpf.tests.MpfFakeGameTestCase import MpfFakeGameTestCase
-
 from mpf.tests.MpfTestCase import MpfTestCase
 from unittest.mock import MagicMock