How is is_bst_l, min_l, max_l = is_bst(node.left)

`def remove_none(nums):
return [x for x in nums if x is not None]

def is_bst(node):
if node is None:
return True, None, None

is_bst_l, min_l, max_l = is_bst(node.left)
is_bst_r, min_r, max_r = is_bst(node.right)

is_bst_node = (is_bst_l and is_bst_r and 
          (max_l is None or node.key > max_l) and 
          (min_r is None or node.key < min_r))

min_key = min(remove_none([min_l, node.key, min_r]))
max_key = max(remove_none([max_l, node.key, max_r]))

# print(node.key, min_key, max_key, is_bst_node)
    
return is_bst_node, min_key, max_key`

the max_l, min_r is seems to be always None, None.

how did you conclude that it always seem to be None, None? I am pretty sure that’s not the case and the code snippet you give here looks fine to me.

For your information, only the first return from callstack ,using recursion when you call is_bst(node.left) or is_bst(node.left) will be None. just once for each function call.