Here are comments to what is happening.
makeInc is a function, which returns another function. Using closures, the returned function knows
about x being set to value as it was true at the moment it was created and returned.
Calling inc2 = makeInc(5) first makes x inside makeInc set to 5, and then creates a function
y. This inc function knows that x equals to 5 and will remember it as long as it lives - this is concept of closures (get in your backpack all needed variables in the environment at the moment of birth).
Calling inc5(12) executes inc(12). Inside if this call to inc it adds argument y being 12 to the value of x, which the inc5 remembers is 5, so the sum makes 17.
N.B.: Closures are used naturaly in languages like JavaScript. In Python, closures are available
too, but not used so often and some developers are considering them even evil - your question shows
very clearly, it is not trivial to understand, what is happening in the code - this goes against
"readibility counts" from Zen of Python. Also you can find some surprises related to scope and
visibility of variables. In case you do not get exactly what has happened in the code above, do
not worry, Python offers many other nice challenging structures, which you will use much more often
(list comprehension being one example).
inc5(12)being 17.inc5once in your code. The "first call" is to a completely separate functionmakeInc.