nonlocal can only applied in functions that have a nested scope. You only get a nested scope when you define your function inside of another function.
Python doesn't have block scopes; the for loop doesn't create a new scope, so you don't need to use nonlocal in a loop. Your variables are available throughout the rest of the function. Just drop the nonlocal statements altogether:
def min_diff(arry_):
max_ = 0
temp_ = 0
for i in arry_:
if i > max_:
temp_ = max_
max_ = i
return max_ - temp_
In Python, only functions, class definitions and comprehensions (list, set, and dict comprehensions as well as generator expressions) get their own scope, and only functions can act as a parent scope for closures (nonlocal variables).
There is also a bug in your code; if you pass in a list where the first value is also the maximum value in the list, temp_ is set to 0 and then never changes. You won't ever find the second-highest value in that case, because only for the very first i will if i > max_: be true. You'd also need to test if i is greater than temp_ in that case:
def min_diff(arry_):
max_ = 0
temp_ = 0
for i in arry_:
if i > max_:
temp_ = max_
max_ = i
elif i > temp_:
temp_ = i
return max_ - temp_
As a side note: you don't need to use trailing underscores in your local variables. Of all the local names used, only max_ would potentially shadow the built-in max() function, but since you don't use that function at all, using max_ instead of max in your function is not actually a requirement. I'd personally drop all the trailing _ underscores from all the names in the function. I'd also use different names; perhaps highest and secondhighest.
Last but not least, you could just use the heapq.nlargest() function to get those two largest values, efficiently:
from heapq import nlargest
def min_diff(values):
highest, secondhighest = nlargest(2, values)
return highest - secondhighest
You may want to add some length checks there; if len(values) < 2 is true, what should happen instead?